83ea066 by Aurélien Bompard at 2010-04-26 1
#!/usr/bin/env python
2
# vim: set fileencoding=utf-8 tabstop=4 shiftwidth=4 expandtab smartindent:
3
u"""
7581434 by Aurélien Bompard at 2011-04-03 4
5
Backup Delicious
6
----------------
7
83ea066 by Aurélien Bompard at 2010-04-26 8
Backs up the bookmarks stored on Delicious.com into an XML file.
9
7581434 by Aurélien Bompard at 2011-04-03 10
.. :Authors:
11
       Aurélien Bompard <aurelien@bompard.org> <http://aurelien.bompard.org>
83ea066 by Aurélien Bompard at 2010-04-26 12
7581434 by Aurélien Bompard at 2011-04-03 13
.. :License:
14
       GNU GPL v3 or later
83ea066 by Aurélien Bompard at 2010-04-26 15
"""
16
17
import os
18
import sys
19
import optparse
20
import urllib2
21
from xml.etree import ElementTree as etree
22
import datetime
23
24
backup = os.path.expanduser("~/tmp/bookmarks.xml")
25
26
def setup_url_opener(username, password):
27
    auth_handler = urllib2.HTTPBasicAuthHandler()
28
    auth_handler.add_password(realm="del.icio.us API",
29
                              uri='https://api.del.icio.us/v1/posts/',
30
                              user=username, passwd=password)
31
    opener = urllib2.build_opener(auth_handler)
9a60da9 by Aurélien Bompard at 2011-10-14 32
    opener.addheaders = [('User-agent', 'Mozilla/5.0')]
83ea066 by Aurélien Bompard at 2010-04-26 33
    urllib2.install_opener(opener)
34
35
def get_update_time():
36
    update_page = urllib2.urlopen("https://api.del.icio.us/v1/posts/update")
37
    update = etree.parse(update_page)
38
    update_page.close()
39
    update_time = datetime.datetime.strptime(
40
                    update.getroot().get("time"),
41
                    "%Y-%m-%dT%H:%M:%SZ")
42
    return update_time
43
44
def get_backup_time(backup_file):
45
    if not os.path.exists(backup_file):
46
        return datetime.datetime(1970,1,1,0,0,0)
47
    statinfo = os.stat(backup_file)
48
    return datetime.datetime.fromtimestamp(statinfo.st_mtime)
49
50
def backup_delicious(backup_file):
51
    backup_file = open(backup_file, "w")
52
    bookmarks_page = urllib2.urlopen("https://api.del.icio.us/v1/posts/all")
53
    backup_file.write(bookmarks_page.read())
54
    backup_file.close()
55
    bookmarks_page.close()
56
57
def parse_opts():
58
    parser = optparse.OptionParser()
59
    parser.add_option("-u", "--username", dest="username",
60
                      help="User name on Delicious.com")
61
    parser.add_option("-p", "--password", dest="password",
62
                      help="Password on Delicious.com")
63
    parser.add_option("-f", "--file", dest="backup",
64
                      help="File to store the backup into")
65
    options, args = parser.parse_args()
66
    if len(args):
67
        parser.error("No arguments allowed.")
68
    if not options.username or not options.password:
69
        parser.error("You must provide credentials to Delicious.com.")
70
    if not options.backup:
71
        parser.error("You must provide a file to backup into.")
72
    return options
73
74
def main():
75
    options = parse_opts()
76
    setup_url_opener(options.username, options.password)
77
    backup_file = os.path.expanduser(options.backup)
78
    update_time = get_update_time()
79
    backup_time = get_backup_time(backup_file)
80
81
    if update_time > backup_time:
82
        print "Bookmarks have been updated, backing up...   ",
83
        sys.stdout.flush()
84
        backup_delicious(backup_file)
85
        print "done."
86
    else:
87
        print "No update available, backup cancelled."
88
89
if __name__ == "__main__":
90
    main()