From c2da77f0a02fbf8c7c967ea95ed276a17f7d0411 Mon Sep 17 00:00:00 2001 From: anthony Date: Tue, 15 Mar 2022 09:43:43 +0000 Subject: [PATCH] Clear history older than certain date (Untested) --- frontends/gnustep/AppDelegate.h | 1 + frontends/gnustep/AppDelegate.m | 11 ++ .../gnustep/PreferencesWindowController.m | 1 + frontends/gnustep/Website.h | 6 +- frontends/gnustep/Website.m | 109 ++++++++++++++++++ 5 files changed, 127 insertions(+), 1 deletion(-) diff --git a/frontends/gnustep/AppDelegate.h b/frontends/gnustep/AppDelegate.h index 93fba535e..bb71c10cb 100644 --- a/frontends/gnustep/AppDelegate.h +++ b/frontends/gnustep/AppDelegate.h @@ -48,6 +48,7 @@ id preferencesWindowController; -(NSURL*)requestFileLocation; -(void)openWebsite: (Website*)aWebsite; -(void)openDeveloperFileAtPath: (NSString*)path; +-(void)clearBrowsingHistory; -(NSString*)currentUrl; -(BrowserWindowController*)activeBrowserWindow; @end diff --git a/frontends/gnustep/AppDelegate.m b/frontends/gnustep/AppDelegate.m index 597101f44..28c3f94d3 100644 --- a/frontends/gnustep/AppDelegate.m +++ b/frontends/gnustep/AppDelegate.m @@ -46,6 +46,7 @@ static nserror set_defaults(struct nsoption_s *defaults) -(void)applicationDidFinishLaunching: (NSNotification*)aNotification { NSLog(@"NSApp did finish launching.."); [NSBundle loadNibNamed: @"Menu" owner: NSApp]; + [self clearBrowsingHistory]; } -(void)historyUpdated: (NSNotification*)aNotification { @@ -229,6 +230,16 @@ static NSMenuItem *menuItemForItem(id item) { return nil; } +-(void)clearBrowsingHistory { + NSUInteger days = [[Preferences defaultPreferences] browsingHistoryDays]; + if (days > 0) { + NSLog(@"Clearing history older thna %u", days); + [Website deleteHistoryOlderThanDays: days]; + } else { + NSLog(@"browsingHistoryDays preference set to 0, won't clear history"); + } +} + -(NSString*)currentUrl { return [[self activeBrowserWindow] visibleUrl]; } diff --git a/frontends/gnustep/PreferencesWindowController.m b/frontends/gnustep/PreferencesWindowController.m index 15029be01..c896b2618 100644 --- a/frontends/gnustep/PreferencesWindowController.m +++ b/frontends/gnustep/PreferencesWindowController.m @@ -401,6 +401,7 @@ NSLog(@"didChangeBrowsingHistory", sender); [[Preferences defaultPreferences] setBrowsingHistoryDays: (NSUInteger)[[sender stringValue] integerValue]]; + [[NSApp delegate] clearBrowsingHistory]; } -(void)didChangeMemCacheSize: (id)sender { diff --git a/frontends/gnustep/Website.h b/frontends/gnustep/Website.h index 827e1fa52..854778896 100644 --- a/frontends/gnustep/Website.h +++ b/frontends/gnustep/Website.h @@ -1,7 +1,7 @@ #import #define WebsiteHistoryUpdatedNotificationName @"WebsiteHistoryUpdatedNotification" -#define HISTORY_PATH @"/.config/NetSurf" +#define HISTORY_PATH @"/.config/NetSurf/history" struct website_data { int len_name; @@ -9,6 +9,7 @@ struct website_data { // ignored. In this case, len_name will be the entire length of the structure. // See HistoryWindowController for the impl of this. int len_url; + NSTimeInterval timeIntervalSinceReferenceDate; char data[]; }; @@ -17,6 +18,7 @@ struct website_data { BookmarkFolder *parentFolder; NSString *filename; long fileOffset; + NSDate *dateViewed; struct website_data *data; } @@ -39,4 +41,6 @@ struct website_data { +(NSArray*)getAllHistoryFiles; +(NSMutableArray*)getHistoryFromFile: (NSString*)file matching: (NSString*)queryString; ++(void)deleteHistoryOlderThanDays: (NSUInteger)days; ++(void)deleteHistoryOlderThanDate: (NSDate*)date; @end diff --git a/frontends/gnustep/Website.m b/frontends/gnustep/Website.m index 72a92f92d..a8acc8250 100644 --- a/frontends/gnustep/Website.m +++ b/frontends/gnustep/Website.m @@ -6,6 +6,10 @@ #import "Website.h" #import "AppDelegate.h" +@interface Website(Private) ++(void)truncateHistoryFileAtPath: (NSString*)path olderThanDate: (NSDate*)date; +@end + @implementation Website -(id)initWithName: (NSString*)aName url: (NSString*)aUrl { @@ -15,6 +19,8 @@ data = malloc(sizeof (struct website_data) + nlen + urlen); data->len_name = nlen; data->len_url = urlen; + data->timeIntervalSinceReferenceDate = [[NSDate date] + timeIntervalSinceReferenceDate]; memcpy(data->data, [aName cString], nlen); memcpy(data->data + nlen, [aUrl cString], urlen); fileOffset = -1; @@ -57,6 +63,11 @@ data->len_url]; } +-(NSDate*)dateViewed { + return [NSDate dateWithTimeIntervalSinceReferenceDate: + data->timeIntervalSinceReferenceDate]; +} + -(void)setName: (NSString*)aName { NSString *url = [self url]; int nlen = [aName length]; @@ -196,4 +207,102 @@ return files; } ++(void)deleteHistoryOlderThanDays: (NSUInteger)days { + NSCalendarDate *now = [NSCalendarDate date]; + NSCalendarDate *deletionThreshold = [now dateByAddingYears: 0 months: 0 + days: -days hours: 0 minutes: 0 seconds: 0]; + [Website deleteHistoryOlderThanDate: deletionThreshold]; +} + ++(void)deleteHistoryOlderThanDate: (NSDate*)date { + // Get month&year for month + NSCalendarDate *calendarDate = [NSCalendarDate + dateWithTimeIntervalSinceReferenceDate: + [date timeIntervalSinceReferenceDate]]; + NSInteger targetMonth = [calendarDate monthOfYear]; + NSInteger targetYear = [calendarDate yearOfCommonEra]; + // Iterate through all history files & delete older + NSArray *historyFiles = [Website getAllHistoryFiles]; + NSArray *yearAndDate; + NSEnumerator *fileEnumerator = [historyFiles objectEnumerator]; + NSString *filename, *fullPath; + NSInteger fileYear, fileMonth; + BOOL isFileOld; + NSError *err = nil; + NSString *historyPath = [NSString stringWithFormat: @"%@/%@", + NSHomeDirectory(), HISTORY_PATH]; + while ((filename = [fileEnumerator nextObject]) != nil) { + yearAndDate = [[filename substringFromIndex: 8] + componentsSeparatedByString: @"_"]; + fileYear = [[yearAndDate firstObject] integerValue]; + fileMonth = [[yearAndDate objectAtIndex: 1] integerValue]; + isFileOld = fileYear < targetYear || (fileYear == targetYear && + fileMonth < targetMonth); + if (isFileOld) { + fullPath = [NSString stringWithFormat: @"%@/%@", historyPath, + filename]; + err = nil; + [[NSFileManager defaultManager] removeItemAtPath: fullPath + error: &err]; + if (err != nil) + NSLog(@"Error removing file at: %@", fullPath); + } + } + // Open history file for current month or done if not exist + NSString *currentMonth = [historyFiles lastObject]; + yearAndDate = [[currentMonth substringFromIndex: 8] + componentsSeparatedByString: @"_"]; + fileYear = [[yearAndDate firstObject] integerValue]; + fileMonth = [[yearAndDate objectAtIndex: 1] integerValue]; + if (fileYear == targetYear || fileMonth == targetMonth) { + fullPath = [NSString stringWithFormat: @"%@/%@", historyPath, + currentMonth]; + [Website truncateHistoryFileAtPath: fullPath olderThanDate: date]; + } +} + ++(void)truncateHistoryFileAtPath: (NSString*)path olderThanDate: (NSDate*)date { + NSFileHandle *handle = [NSFileHandle fileHandleForUpdatingAtPath: path]; + if (handle == nil) { + NSLog(@"Failed to open history file for updating at path: %@", path); + return; + } + NSTimeInterval ival = [date timeIntervalSinceReferenceDate]; + struct website_data buf[10]; + NSUInteger nread, i; + NSData *data; + do { + data = [handle readDataUpToLength: sizeof(buf)]; + if (data == nil) { + NSLog(@"readDataUpToLength failed"); + return; + } + nread = [data length] / sizeof (struct website_data); + [data getBytes: buf length: nread * sizeof (struct website_data)]; + for (i = 0; i < nread; i++) { + if (buf[i].timeIntervalSinceReferenceDate < ival) + break; + } + } while (nread == 10); + // If we didn't iterate to the end, must thave found a point with older time. + if (i == nread) { + NSLog(@"Reached the end of history file without finding older entries"); + return; + } + // Rewind the file back to the start of that point. + unsigned long long offset; + long long rwnd = (long long)((i - nread) * sizeof (struct website_data)); + NSError *err = nil; + [handle getOffset: &offset error: &err]; + if (err != nil) { + NSLog(@"Failed to get file offset"); + return; + } + offset += rwnd; + [handle truncateAtOffset: offset error: &err]; + if (err != nil) { + NSLog(@"Failed to truncate history file"); + return; + } +} @end