Bug 374876 - write out bookmarks.html and archives (r=sspitzer)

This commit is contained in:
dietrich@mozilla.com 2007-03-25 13:14:28 -07:00
parent ce5da1c499
commit 2719851c0d
3 changed files with 171 additions and 0 deletions

View File

@ -2280,6 +2280,168 @@ nsNavBookmarks::RemoveObserver(nsINavBookmarkObserver *aObserver)
return mObservers.RemoveWeakElement(aObserver); return mObservers.RemoveWeakElement(aObserver);
} }
/**
* Called by the History service when shutting down
*/
nsresult
nsNavBookmarks::OnQuit()
{
// get bookmarks file
nsCOMPtr<nsIFile> bookmarksFile;
nsresult rv = NS_GetSpecialDirectory(NS_APP_BOOKMARKS_50_FILE,
getter_AddRefs(bookmarksFile));
NS_ENSURE_SUCCESS(rv, rv);
// create if it doesn't exist
PRBool exists;
rv = bookmarksFile->Exists(&exists);
if (NS_FAILED(rv) || !exists) {
rv = bookmarksFile->Create(nsIFile::NORMAL_FILE_TYPE, 0600);
NS_ASSERTION(rv, "Unable to create bookmarks.html!");
return rv;
}
// export bookmarks.html
rv = ExportBookmarksHTML(bookmarksFile);
NS_ENSURE_SUCCESS(rv, rv);
// archive if needed
nsCOMPtr<nsIPrefService> prefServ(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIPrefBranch> bookmarksPrefs;
rv = prefServ->GetBranch("browser.bookmarks.", getter_AddRefs(bookmarksPrefs));
NS_ENSURE_SUCCESS(rv, rv);
PRInt32 numberOfBackups;
rv = bookmarksPrefs->GetIntPref("max_backups", &numberOfBackups);
if (NS_FAILED(rv))
numberOfBackups = 5;
if (numberOfBackups > 0) {
rv = ArchiveBookmarksFile(numberOfBackups, PR_FALSE);
NS_ENSURE_SUCCESS(rv, rv);
}
return NS_OK;
}
/**
* ArchiveBookmarksFile()
*
* Creates a dated backup once a day in <profile>/bookmarkbackups
*
* PRInt32 numberOfBackups - the maximum number of backups to keep
*
* PRBool forceArchive - forces creating an archive even if one was
* already created that day (overwrites)
*/
nsresult
nsNavBookmarks::ArchiveBookmarksFile(PRInt32 numberOfBackups,
PRBool forceArchive)
{
nsCOMPtr<nsIFile> bookmarksBackupDir;
nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
getter_AddRefs(bookmarksBackupDir));
NS_ENSURE_SUCCESS(rv, rv);
nsDependentCString dirName("bookmarkbackups");
rv = bookmarksBackupDir->AppendNative(dirName);
NS_ENSURE_SUCCESS(rv, rv);
PRBool exists;
rv = bookmarksBackupDir->Exists(&exists);
if (NS_FAILED(rv) || !exists) {
rv = bookmarksBackupDir->Create(nsIFile::DIRECTORY_TYPE, 0700);
// if there's no backup folder, there's no backup, fail
NS_ENSURE_SUCCESS(rv, rv);
}
// construct the new leafname
PRTime now64 = PR_Now();
PRExplodedTime nowInfo;
PR_ExplodeTime(now64, PR_LocalTimeParameters, &nowInfo);
PR_NormalizeTime(&nowInfo, PR_LocalTimeParameters);
char timeString[128];
PR_FormatTime(timeString, 128, "bookmarks-%Y-%m-%d.html", &nowInfo);
nsCAutoString backupFilenameCString(timeString);
nsAutoString backupFilenameString = NS_ConvertUTF8toUTF16(backupFilenameCString);
nsCOMPtr<nsIFile> backupFile;
if (forceArchive) {
// if we have a backup from today, nuke it
nsCOMPtr<nsIFile> currentBackup;
rv = bookmarksBackupDir->Clone(getter_AddRefs(currentBackup));
NS_ENSURE_SUCCESS(rv, rv);
rv = currentBackup->Append(backupFilenameString);
NS_ENSURE_SUCCESS(rv, rv);
rv = currentBackup->Exists(&exists);
if (!NS_FAILED(rv) && exists) {
rv = currentBackup->Remove(PR_FALSE);
NS_ENSURE_SUCCESS(rv, rv);
}
} else {
nsCOMPtr<nsISimpleEnumerator> existingBackups;
rv = bookmarksBackupDir->GetDirectoryEntries(getter_AddRefs(existingBackups));
NS_ENSURE_SUCCESS(rv, rv);
nsStringArray backupFileNames;
PRBool hasMoreElements = PR_FALSE;
PRBool hasCurrentBackup = PR_FALSE;
while (NS_SUCCEEDED(existingBackups->HasMoreElements(&hasMoreElements)) &&
hasMoreElements)
{
rv = existingBackups->GetNext(getter_AddRefs(backupFile));
NS_ENSURE_SUCCESS(rv, rv);
nsAutoString backupName;
rv = backupFile->GetLeafName(backupName);
NS_ENSURE_SUCCESS(rv, rv);
// the backup for today exists, do not create later
if (backupName == backupFilenameString) {
hasCurrentBackup = PR_TRUE;
continue;
}
// mark the rest for possible removal
if (Substring(backupName, 0, 10) == NS_LITERAL_STRING("bookmarks-"))
backupFileNames.AppendString(backupName);
}
if (numberOfBackups > 0 && backupFileNames.Count() >= numberOfBackups) {
PRInt32 numberOfBackupsToDelete = backupFileNames.Count() - numberOfBackups + 1;
backupFileNames.Sort();
while (numberOfBackupsToDelete--) {
(void)bookmarksBackupDir->Clone(getter_AddRefs(backupFile));
(void)backupFile->Append(*backupFileNames[0]);
(void)backupFile->Remove(PR_FALSE);
backupFileNames.RemoveStringAt(0);
}
}
if (hasCurrentBackup)
return NS_OK;
}
nsCOMPtr<nsIFile> bookmarksFile;
rv = NS_GetSpecialDirectory(NS_APP_BOOKMARKS_50_FILE,
getter_AddRefs(bookmarksFile));
NS_ENSURE_SUCCESS(rv, rv);
rv = bookmarksFile->CopyTo(bookmarksBackupDir, backupFilenameString);
// at least dump something out in case this fails in a debug build
NS_ENSURE_SUCCESS(rv, rv);
return rv;
}
// nsNavBookmarks::nsINavHistoryObserver // nsNavBookmarks::nsINavHistoryObserver
NS_IMETHODIMP NS_IMETHODIMP

View File

@ -108,6 +108,10 @@ public:
static const PRInt32 kGetFolderInfoIndex_Title; static const PRInt32 kGetFolderInfoIndex_Title;
static const PRInt32 kGetFolderInfoIndex_Type; static const PRInt32 kGetFolderInfoIndex_Type;
// Called by History service when quitting.
nsresult OnQuit();
nsresult ArchiveBookmarksFile(PRInt32 aNumberOfBackups, PRBool aForceArchive);
private: private:
static nsNavBookmarks *sInstance; static nsNavBookmarks *sInstance;

View File

@ -2899,6 +2899,11 @@ nsNavHistory::Observe(nsISupports *aSubject, const char *aTopic,
// notify expiring system that we're quitting, it may want to do stuff // notify expiring system that we're quitting, it may want to do stuff
mExpire.OnQuit(); mExpire.OnQuit();
// notify the bookmarks service we're quitting
nsNavBookmarks* bookmarks = nsNavBookmarks::GetBookmarksService();
NS_ENSURE_TRUE(bookmarks, NS_ERROR_OUT_OF_MEMORY);
(void)bookmarks->OnQuit();
} else if (nsCRT::strcmp(aTopic, gXpcomShutdown) == 0) { } else if (nsCRT::strcmp(aTopic, gXpcomShutdown) == 0) {
nsresult rv; nsresult rv;
nsCOMPtr<nsIObserverService> observerService = nsCOMPtr<nsIObserverService> observerService =