patternpythonMinor
Auto backup Chrome bookmarks
Viewed 0 times
autobookmarkschromebackup
Problem
This script, once added to the Windows Scheduler, automatically creates a backup of your Google Chrome bookmarks.
import shutil
import os
import datetime
def setup():
print ('Enter your Chrome bookmark directory.')
print ('Standard one is: C:\\Users\\\\AppData\\Local\\Google\\Chrome\\User Data\\Default')
bookmarkfolder = input('> ')
print ('Enter the folder you want to save the backup files in.')
print ('For example: C:\\Users\\\\Desktop\\Chrome Bookmarks')
backupfolder = input('> ')
with open('user.txt', 'w') as txt:
txt.write(bookmarkfolder + '\n' + backupfolder)
copy()
def copy():
userList = []
date = datetime.date.today()
with open('user.txt', 'r') as txt:
for line in txt:
userList.append(line.strip())
shutil.copy(userList[0] + '\\Bookmarks', userList[1])
try:
os.rename('Bookmarks', 'Bookmarks' + str(date).replace('-',''))
except WindowsError:
os.remove('Bookmarks' + str(date).replace('-',''))
os.rename('Bookmarks', 'Bookmarks' + str(date).replace('-',''))
def checksetup():
with open('user.txt', 'r') as setupfile:
setupfile.seek(0)
for line in setupfile:
if '\\' in line:
copy()
else:
setup()
checksetup()Solution
The logic isn't so easy to follow, especially since the loops in
and
be only two at most, the bookmark and backup folder. I'd suggest making
that more obvious and avoiding
want to have a fixed number of lines in that file.
The code also doesn't work with no
more checks and error handling are necessary to handle that case as
well.
Some of the paths and other constructs are duplicated, I'd always try to
minimise the amount of duplication, so with that in mind, consider more
constants and variables to extract common code.
open a file (for reading) you'll already be at the start; however, the
mode should probably be
exist.
syntax instead.
that way this file could be imported and used without running
c.f. PEP8.
desired output directly.
folders exist.
would also be better to pass the two values necessary for the script
in the script as function arguments instead of parsing the file so
often; I'll leave that be for the moment though. In general I'd say
that
the values from the file instead of parsing it.
After all that you can also look into command line arguments using
e.g.
parsing options, that way users won't have to deal with pesky manual
input instead of reusing the shell completion (for specifying the
folders).
So, it should look more like this perhaps:
copyand
checksetup imply that there are more lines, but really there willbe only two at most, the bookmark and backup folder. I'd suggest making
that more obvious and avoiding
for line in file: in case you only everwant to have a fixed number of lines in that file.
The code also doesn't work with no
"user.txt" file present, so somemore checks and error handling are necessary to handle that case as
well.
Some of the paths and other constructs are duplicated, I'd always try to
minimise the amount of duplication, so with that in mind, consider more
constants and variables to extract common code.
- The
.seek(0)inchecksetupisn't necessary with mode'r'; if you
open a file (for reading) you'll already be at the start; however, the
mode should probably be
'a+' anyway to create the file if it doesn'texist.
- If you don't like the escapes all the time, consider using the
r""
syntax instead.
- Use the
if __name__ == "__main__": ...construct as is customary,
that way this file could be imported and used without running
checksetup as is it would currently.- Python typically uses lower case names with underscores between words,
c.f. PEP8.
- For the date formatting use the
strftimemethod instead to get the
desired output directly.
- The
setupmethod could use some more error checks, e.g. whether the
folders exist.
- The
"user.txt"file is opened three times in the worst case; it
would also be better to pass the two values necessary for the script
in the script as function arguments instead of parsing the file so
often; I'll leave that be for the moment though. In general I'd say
that
copy should have the signaturecopy(bookmark_directory, backup_directory) and should be called withthe values from the file instead of parsing it.
After all that you can also look into command line arguments using
e.g.
argparse forparsing options, that way users won't have to deal with pesky manual
input instead of reusing the shell completion (for specifying the
folders).
So, it should look more like this perhaps:
import shutil
import os
import datetime
SETUP_FILE = 'user.txt'
def setup():
print ('Enter your Chrome bookmark directory.')
print (r'Standard one is: C:\Users\\AppData\Local\Google\Chrome\User Data\Default')
bookmarkfolder = input('> ')
print ('Enter the folder you want to save the backup files in.')
print (r'For example: C:\Users\\Desktop\Chrome Bookmarks')
backupfolder = input('> ')
with open(SETUP_FILE, 'w') as txt:
txt.write(bookmarkfolder + '\n' + backupfolder + '\n')
copy()
def copy():
with open(SETUP_FILE, 'r') as txt:
user_list = [line.strip() for line in txt]
shutil.copy(user_list[0] + r'\Bookmarks', user_list[1])
new_name = datetime.date.today().strftime('Bookmarks%Y%m%d')
try:
os.rename('Bookmarks', new_name)
except WindowsError:
os.remove(new_name)
os.rename('Bookmarks', new_name)
def checksetup():
try:
with open(SETUP_FILE, 'r') as txt:
txt.seek(0)
line = txt.readline()
if '\\' in line:
copy()
else:
setup()
except FileNotFoundError:
setup()
if __name__ == "__main__":
checksetup()
Context
StackExchange Code Review Q#108734, answer score: 2
Revisions (0)
No revisions yet.