summaryrefslogtreecommitdiff
path: root/src/visited.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/visited.c')
-rw-r--r--src/visited.c128
1 files changed, 128 insertions, 0 deletions
diff --git a/src/visited.c b/src/visited.c
new file mode 100644
index 00000000..af976be5
--- /dev/null
+++ b/src/visited.c
@@ -0,0 +1,128 @@
1#include "visited.h"
2#include "app.h"
3
4#include <the_Foundation/file.h>
5#include <the_Foundation/path.h>
6#include <the_Foundation/sortedarray.h>
7
8static const size_t maxAgeVisited_Visited_ = 3600 * 24 * 30; /* one month */
9
10void init_VisitedUrl(iVisitedUrl *d) {
11 initCurrent_Time(&d->when);
12 init_String(&d->url);
13}
14
15void deinit_VisitedUrl(iVisitedUrl *d) {
16 deinit_String(&d->url);
17}
18
19static int cmpUrl_VisitedUrl_(const void *a, const void *b) {
20 return cmpString_String(&((const iVisitedUrl *) a)->url, &((const iVisitedUrl *) b)->url);
21}
22
23static int cmpNewer_VisitedUrl_(const void *insert, const void *existing) {
24 return seconds_Time(&((const iVisitedUrl *) insert )->when) >
25 seconds_Time(&((const iVisitedUrl *) existing)->when);
26}
27
28/*----------------------------------------------------------------------------------------------*/
29
30struct Impl_Visited {
31 iSortedArray visited;
32};
33
34iDefineTypeConstruction(Visited)
35
36void init_Visited(iVisited *d) {
37 init_SortedArray(&d->visited, sizeof(iVisitedUrl), cmpUrl_VisitedUrl_);
38}
39
40void deinit_Visited(iVisited *d) {
41 clear_Visited(d);
42 deinit_SortedArray(&d->visited);
43}
44
45void save_Visited(const iVisited *d, const char *dirPath) {
46 iString *line = new_String();
47 iFile *f = newCStr_File(concatPath_CStr(dirPath, "visited.txt"));
48 if (open_File(f, writeOnly_FileMode | text_FileMode)) {
49 iConstForEach(Array, i, &d->visited.values) {
50 const iVisitedUrl *item = i.value;
51 iDate date;
52 init_Date(&date, &item->when);
53 format_String(line,
54 "%04d-%02d-%02dT%02d:%02d:%02d %s\n",
55 date.year,
56 date.month,
57 date.day,
58 date.hour,
59 date.minute,
60 date.second,
61 cstr_String(&item->url));
62 writeData_File(f, cstr_String(line), size_String(line));
63 }
64 }
65 iRelease(f);
66 delete_String(line);
67}
68
69void load_Visited(iVisited *d, const char *dirPath) {
70 iFile *f = newCStr_File(concatPath_CStr(dirPath, "visited.txt"));
71 if (open_File(f, readOnly_FileMode | text_FileMode)) {
72 const iRangecc src = range_Block(collect_Block(readAll_File(f)));
73 iRangecc line = iNullRange;
74 iTime now;
75 initCurrent_Time(&now);
76 while (nextSplit_Rangecc(&src, "\n", &line)) {
77 int y, m, D, H, M, S;
78 sscanf(line.start, "%04d-%02d-%02dT%02d:%02d:%02d ", &y, &m, &D, &H, &M, &S);
79 if (!y) break;
80 iVisitedUrl item;
81 init_VisitedUrl(&item);
82 init_Time(
83 &item.when,
84 &(iDate){ .year = y, .month = m, .day = D, .hour = H, .minute = M, .second = S });
85 if (secondsSince_Time(&now, &item.when) > maxAgeVisited_Visited_) {
86 continue; /* Too old. */
87 }
88 initRange_String(&item.url, (iRangecc){ line.start + 20, line.end });
89 insert_SortedArray(&d->visited, &item);
90 }
91 }
92 iRelease(f);
93}
94
95void clear_Visited(iVisited *d) {
96 iForEach(Array, v, &d->visited.values) {
97 deinit_VisitedUrl(v.value);
98 }
99 clear_SortedArray(&d->visited);
100}
101
102void visitUrl_Visited(iVisited *d, const iString *url) {
103 iVisitedUrl visit;
104 init_VisitedUrl(&visit);
105 set_String(&visit.url, url);
106 size_t pos;
107 if (locate_SortedArray(&d->visited, &visit, &pos)) {
108 iVisitedUrl *old = at_SortedArray(&d->visited, pos);
109 if (cmpNewer_VisitedUrl_(&visit, old)) {
110 old->when = visit.when;
111 deinit_VisitedUrl(&visit);
112 return;
113 }
114 }
115 insert_SortedArray(&d->visited, &visit);
116}
117
118iTime urlVisitTime_Visited(const iVisited *d, const iString *url) {
119 iVisitedUrl item;
120 size_t pos;
121 iZap(item);
122 initCopy_String(&item.url, url);
123 if (locate_SortedArray(&d->visited, &item, &pos)) {
124 item.when = ((const iVisitedUrl *) constAt_SortedArray(&d->visited, pos))->when;
125 }
126 deinit_String(&item.url);
127 return item.when;
128}