summaryrefslogtreecommitdiff
path: root/src/visited.c
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2020-08-08 08:06:22 +0300
committerJaakko Keränen <jaakko.keranen@iki.fi>2020-08-08 08:06:22 +0300
commitd6875fba63cc674d2d9cac64a66c3b4c9f3eaba1 (patch)
treea12111a19b594fc17792a7a851d1526597470121 /src/visited.c
parent9abe27c63e088bf1e139d108cbc29ac39222d74c (diff)
Moved recent URLs history to DocumentWidget
App maintains the visited URLs database, but each DocumentWidget has its own stack of recent URLs for timeline navigation.
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}