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
15 static BString
PersonName(BNode & node)16 PersonName(BNode& node)
17 {
18 BString fullName;
19 node.ReadAttrString("META:name", &fullName);
20
21 return fullName;
22 }
23
24
25 static void
AddPersonAddresses(BNode & node,BStringList & addresses)26 AddPersonAddresses(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
47 static void
AddPersonGroups(BNode & node,BStringList & groups)48 AddPersonGroups(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
Person(const entry_ref & ref)75 Person::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
~Person()87 Person::~Person()
88 {
89 }
90
91
92 bool
IsInGroup(const char * group) const93 Person::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
PersonList(QueryList & query)106 PersonList::PersonList(QueryList& query)
107 :
108 fQueryList(query),
109 fPersons(10, true)
110 {
111 fQueryList.AddListener(this);
112 }
113
114
~PersonList()115 PersonList::~PersonList()
116 {
117 fQueryList.RemoveListener(this);
118 }
119
120
121 void
EntryCreated(QueryList & source,const entry_ref & ref,ino_t node)122 PersonList::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
132 void
EntryRemoved(QueryList & source,const node_ref & nodeRef)133 PersonList::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
GroupList(QueryList & query)149 GroupList::GroupList(QueryList& query)
150 :
151 fQueryList(query)
152 {
153 fQueryList.AddListener(this);
154 }
155
156
~GroupList()157 GroupList::~GroupList()
158 {
159 fQueryList.RemoveListener(this);
160 }
161
162
163 void
EntryCreated(QueryList & source,const entry_ref & ref,ino_t _node)164 GroupList::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
191 void
EntryRemoved(QueryList & source,const node_ref & nodeRef)192 GroupList::EntryRemoved(QueryList& source, const node_ref& nodeRef)
193 {
194 // TODO!
195 }
196