]> git.phdru.name Git - bookmarks_db.git/blob - check_db.py
This commit was manufactured by cvs2svn to create branch 'phd'.
[bookmarks_db.git] / check_db.py
1 #! /usr/local/bin/python -O
2 """
3    Test FLAD database for: duplicate URLs, too big indent, incorrect record
4    format, spare keys.
5
6    Written by BroytMann, Jun 1997 - Feb 2000. Copyright (C) 1997-2000 PhiloSoft Design
7 """
8
9 import sys, string
10 from getopt import getopt
11 from copy import _copy_dict
12
13 import fladm
14
15
16 def error(err_str):
17    global errors_found, report_stats
18    if errors_found == 0:
19       if report_stats:
20          print "errors found"
21
22    errors_found = errors_found + 1
23    sys.stderr.write("%s\n" % err_str)
24
25    if logfile:
26       logfile.write("%s\n" % err_str)
27
28
29 def check_key(record_no, record, key, allow_empty=1):
30    if not record.has_key(key):
31       error("Expected `%s' in record %d -- %s" % (key, record_no, str(record)))
32       return
33
34    if not allow_empty and not record[key]:
35       error("Empty key `%s' in record %d -- %s" % (key, record_no, str(record)))
36
37    del record[key]
38
39 def check_date(record_no, record, key):
40    if not record.has_key(key):
41       error("Expected `%s' in record %d -- %s" % (key, record_no, str(record)))
42    else:
43       try:
44          _date = string.atoi(record[key])
45       except string.atoi_error:
46          error("Bad `%s' format in record %d -- %s" % (key, record_no, str(record)))
47
48       del record[key]
49
50 def check_empty(record_no, record):
51    if record <> {}:
52       error("Spare keys in record %d -- %s" % (record_no, str(record)))
53
54 def check_url(record_no, record):
55    # I am not testing here check_url("Level") because it is impossible
56    # to come here without "Level" key - fladm.check_record has to reject
57    # entire database if there is record without this "must key".
58    # If someone adds record without "Level" manually - it is serious error
59    # and the following line raise exception.
60    del record["Level"]
61
62    check_key(record_no, record, "Title")
63    check_key(record_no, record, "URL")
64    check_key(record_no, record, "Comment")
65
66    check_date(record_no, record, "AddDate")
67    check_date(record_no, record, "LastVisit")
68    check_date(record_no, record, "LastModified")
69
70    check_empty(record_no, record)
71
72 def check_folder(record_no, record):
73    # Read comment above - in the beginning of check_url()
74    del record["Level"]
75
76    check_key(record_no, record, "Folder")
77    check_key(record_no, record, "Comment")
78
79    check_date(record_no, record, "AddDate")
80    check_empty(record_no, record)
81
82 def check_ruler(record_no, record):
83    # Read comment above - in the beginning of check_url()
84    del record["Level"]
85
86    if not record.has_key("Ruler"):
87       error("No `Ruler' in record %d -- %s" % (record_no, str(record)))
88    else:
89       if record["Ruler"] <> "YES": # Impossible: ruler saying it is not ruler
90          error("Ruler saying it is not ruler in record %d -- %s" % (record_no, str(record)))
91       del record["Ruler"]
92
93    check_empty(record_no, record)
94
95
96 def run():
97    optlist, args = getopt(sys.argv[1:], "l:s")
98
99    global errors_found, report_stats, logfile
100    report_stats = 1
101
102    logfile = None
103    logfname = None
104
105    for _opt, _arg in optlist:
106       if _opt == '-l':
107          logfname = _arg
108       if _opt == '-s':
109          report_stats = 0
110    try:
111       del _opt, _arg
112    except NameError:
113       pass
114
115    if len(args) > 1:
116       sys.stderr.write("check_db: too many arguments\n")
117       sys.exit(1)
118
119
120    if logfname:
121       logfile = open(logfname, 'w')
122
123    if report_stats:
124       sys.stdout.write("Loading: ")
125       sys.stdout.flush()
126
127    bookmarks_db = fladm.load_from_file("bookmarks.db", fladm.check_record, ["Level"])
128
129    if report_stats:
130       print "Ok"
131       sys.stdout.write("Testing: ")
132       sys.stdout.flush()
133
134    record_no = 0
135    save_level = 1
136    got_folder = 1 # Start as if we already have one folder
137    errors_found = 0
138
139    URL_d = {} # Create hash table full of URLs
140
141    for record in bookmarks_db:
142       record_no = record_no + 1
143       level = string.atoi(record["Level"])
144
145       if record.has_key("URL"):
146          if URL_d.has_key(record["URL"]):
147             error("Duplicate URL (rec. %d, 1st at rec. %d): %s" % (record_no, URL_d[record["URL"]], str(record["URL"])))
148          else:
149             URL_d[record["URL"]] = record_no
150
151          check_url(record_no, _copy_dict(record))
152
153       elif record.has_key("Folder"):
154          check_folder(record_no, _copy_dict(record))
155
156       elif record.has_key("Ruler"):
157          check_ruler(record_no, _copy_dict(record))
158
159       else:
160          raise KeyError, "neither \"URL\" nor \"Folder\" nor \"Ruler\" in record " + str(record)
161
162       if got_folder:
163          if (level > save_level + 1):
164             error("Indent %d too big (want %d at rec. %d), record: %s" % (level, save_level, record_no, str(record)))
165       else:
166          if (level > save_level):
167             error("Indent %d without folder (rec. %d), record: %s" % (level, record_no, str(record)))
168
169       save_level = level
170       got_folder = record.has_key("Folder") # Test here to save got_folder for next loop
171
172    # End of loop
173
174    if logfname:
175       logfile.close()
176
177    if report_stats:
178       print record_no, "records tested"
179       if errors_found == 0:
180          print "Ok (no errors found)"
181       else:
182          print "%d errors found" % errors_found
183
184
185 if __name__ == '__main__':
186    run()