1/* 2 * Copyright 2015-2016, Axel Dörfler, axeld@pinc-software.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7#include "People.h" 8 9#include <stdio.h> 10 11#include <Autolock.h> 12#include <Node.h> 13 14 15static BString 16PersonName(BNode& node) 17{ 18 BString fullName; 19 node.ReadAttrString("META:name", &fullName); 20 21 return fullName; 22} 23 24 25static void 26AddPersonAddresses(BNode& node, BStringList& addresses) 27{ 28 BString email; 29 if (node.ReadAttrString("META:email", &email) != B_OK || email.IsEmpty()) 30 return; 31 32 addresses.Add(email); 33 34 // Support for 3rd-party People apps 35 for (int i = 2; i < 99; i++) { 36 char attr[32]; 37 snprintf(attr, sizeof(attr), "META:email%d", i); 38 39 if (node.ReadAttrString(attr, &email) != B_OK) 40 break; 41 42 addresses.Add(email); 43 } 44} 45 46 47static void 48AddPersonGroups(BNode& node, BStringList& groups) 49{ 50 BString groupString; 51 if (node.ReadAttrString("META:group", &groupString) != B_OK 52 || groupString.IsEmpty()) { 53 return; 54 } 55 56 int first = 0; 57 while (first < groupString.Length()) { 58 int end = groupString.FindFirst(',', first); 59 if (end < 0) 60 end = groupString.Length(); 61 62 BString group; 63 groupString.CopyInto(group, first, end - first); 64 group.Trim(); 65 groups.Add(group); 66 67 first = end + 1; 68 } 69} 70 71 72// #pragma mark - Person 73 74 75Person::Person(const entry_ref& ref) 76{ 77 BNode node(&ref); 78 if (node.InitCheck() != B_OK) 79 return; 80 81 fName = PersonName(node); 82 AddPersonAddresses(node, fAddresses); 83 AddPersonGroups(node, fGroups); 84} 85 86 87Person::~Person() 88{ 89} 90 91 92bool 93Person::IsInGroup(const char* group) const 94{ 95 for (int32 index = 0; index < CountGroups(); index++) { 96 if (GroupAt(index) == group) 97 return true; 98 } 99 return false; 100} 101 102 103// #pragma mark - PersonList 104 105 106PersonList::PersonList(QueryList& query) 107 : 108 fQueryList(query), 109 fPersons(10, true) 110{ 111 fQueryList.AddListener(this); 112} 113 114 115PersonList::~PersonList() 116{ 117 fQueryList.RemoveListener(this); 118} 119 120 121void 122PersonList::EntryCreated(QueryList& source, const entry_ref& ref, ino_t node) 123{ 124 BAutolock locker(this); 125 126 Person* person = new Person(ref); 127 fPersons.AddItem(person); 128 fPersonMap.insert(std::make_pair(node_ref(ref.device, node), person)); 129} 130 131 132void 133PersonList::EntryRemoved(QueryList& source, const node_ref& nodeRef) 134{ 135 BAutolock locker(this); 136 137 PersonMap::iterator found = fPersonMap.find(nodeRef); 138 if (found != fPersonMap.end()) { 139 Person* person = found->second; 140 fPersonMap.erase(found); 141 fPersons.RemoveItem(person); 142 } 143} 144 145 146// #pragma mark - GroupList 147 148 149GroupList::GroupList(QueryList& query) 150 : 151 fQueryList(query) 152{ 153 fQueryList.AddListener(this); 154} 155 156 157GroupList::~GroupList() 158{ 159 fQueryList.RemoveListener(this); 160} 161 162 163void 164GroupList::EntryCreated(QueryList& source, const entry_ref& ref, ino_t _node) 165{ 166 BNode node(&ref); 167 if (node.InitCheck() != B_OK) 168 return; 169 170 BAutolock locker(this); 171 172 BStringList groups; 173 AddPersonGroups(node, groups); 174 175 for (int32 index = 0; index < groups.CountStrings(); index++) { 176 BString group = groups.StringAt(index); 177 178 StringCountMap::iterator found = fGroupMap.find(group); 179 if (found != fGroupMap.end()) 180 found->second++; 181 else { 182 fGroupMap[group] = 1; 183 fGroups.Add(group); 184 } 185 } 186 187 // TODO: sort groups 188} 189 190 191void 192GroupList::EntryRemoved(QueryList& source, const node_ref& nodeRef) 193{ 194 // TODO! 195} 196