summaryrefslogtreecommitdiff
path: root/lib/mu-contacts-cache.hh
blob: a0a452ba0c019738bf8e5d653cff9a78b66e3260 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
/*
** Copyright (C) 2020-2025 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
**
** This program is free software; you can redistribute it and/or modify it
** under the terms of the GNU General Public License as published by the
** Free Software Foundation; either version 3, or (at your option) any
** later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software Foundation,
** Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**
*/

#ifndef __MU_CONTACTS_CACHE_HH__
#define __MU_CONTACTS_CACHE_HH__

#include <glib.h>
#include <time.h>
#include <memory>
#include <functional>
#include <chrono>
#include <string>
#include <time.h>
#include <inttypes.h>
#include <utils/mu-utils.hh>

#include "mu-config.hh"
#include <message/mu-message.hh>

namespace Mu {

class ContactsCache {
public:
	/**
	 * Construct a new ContactsCache object
	 *
	 * @param config db configuration database object
	 */
	ContactsCache(Config& config);

	/**
	 * DTOR
	 *
	 */
	~ContactsCache();

	/**
	 * Add a contact
	 *
	 * Invalid email address are not cached (but we log a warning); neither
	 * are "ignored" addresses (see --ignored-address in mu-init(1))
	 *
	 * @param contact a Contact object
	 */
	void add(Contact&& contact);


	/**
	 * Add a contacts sequence; this should be used for the contacts of a
	 * specific message, and determines if it is a "personal" message:
	 * if any of the contacts matches one of the personal addresses,
	 * any of the senders/recipients are considered "personal"
	 *
	 * Invalid email address are not cached (but we log a warning); neither
	 * are "ignored" addresses (see --ignored-address in mu-init(1))
	 *
	 * @param contacts a Contact object sequence
	 * @param is_personal receives true if any of the contacts was personal;
	 * false otherwise
	 */
	void add(Contacts&& contacts, bool& is_personal);
	void add(Contacts&& contacts) {
		bool _ignore;
		add(std::move(contacts), _ignore);
	}

	/**
	 * Clear all contacts
	 *
	 */
	void clear();

	/**
	 * Get the number of contacts
	 *

	 * @return number of contacts
	 */
	std::size_t size() const;

	/**
	 * Are there no contacts?
	 *
	 * @return true or false
	 */
	bool empty() const { return size() == 0; }

	/**
	 * Serialize contact information. This all marks the data as
	 * non-dirty
	 */
	void serialize() const;

	/**
	 * Does this look like a 'personal' address?
	 *
	 * @param addr some e-mail address
	 *
	 * @return true or false
	 */
	bool is_personal(const std::string& addr) const;

	/**
	 * Does this look like an email-address that should be ignored?
	 *
	 * @param addr some e-mail address
	 *
	 * @return true or false
	 */
	bool is_ignored(const std::string& addr) const;

	/**
	 * Does this look like a valid email-address?
	 *
	 * @param addr some e-mail address
	 *
	 * @return true or false
	 */
	bool is_valid(const std::string& addr) const;

	/**
	 * Find a contact based on the email address. This is not safe, since
	 * the returned ptr can be invalidated at any time; only for unit-tests.
	 *
	 * @param email email address
	 *
	 * @return contact info, or {} if not found
	 */
	const Contact* _find(const std::string& email) const;

	/**
	 * Prototype for a callable that receives a contact
	 *
	 * @param contact some contact
	 *
	 * @return to get more contacts; false otherwise
	 */
	using EachContactFunc = std::function<bool(const Contact& contact_info)>;

	/**
	 * Invoke some callable for each contact, in _descending_ order of rank (i.e., the
	 * highest ranked contacts come first).
	 *
	 * @param each_contact function invoked for each contact
	 *
	 * @return The number of times the callback was invoked or some error
	 */
	Result<size_t> for_each(const EachContactFunc& each_contact) const;

	/**
	 * Invoke some callable for each contact, in _descending_ order of rank
	 * (i.e., the highest ranked contacts come first).
	 *
	 * @param each_contact function invoked for each contact
	 * @param match_rx string with regular expression or "" for none
	 * @param personal if true, only include personal contacts
	 *        (i.e., contacts seen in message in which a personal address
	 *         was involved)
	 * @param after only consider messages after this time_t (seconds since epoch)
	 * @param maxnum maximum number of times the callback invoked
	 *
	 * @return The number of times the callback was invoked or some error
	 */
	Result<size_t> for_each(const EachContactFunc& each_contact,
				const std::string match_rx,
				bool personal = false,
				int64_t after = 0,
				size_t maxnum = 0) const;
private:
	struct Private;
	std::unique_ptr<Private> priv_;
};

} // namespace Mu

#endif /* __MU_CONTACTS_CACHE_HH__ */