3
# imports the API description and fills up a database with
4
# name relevance to modules, functions or web pages
9
# install mysqld, the python wrappers for mysql and libxml2, start mysqld
10
# Change the root passwd of mysql:
11
# mysqladmin -u root password new_password
12
# Create the new database xmlsoft
13
# mysqladmin -p create xmlsoft
14
# Create a database user 'veillard' and give him passord access
15
# change veillard and abcde with the right user name and passwd
18
# mysql> GRANT ALL PRIVILEGES ON xmlsoft TO veillard@localhost
19
# IDENTIFIED BY 'abcde' WITH GRANT OPTION;
21
# As the user check the access:
24
# Welcome to the MySQL monitor....
30
# Then run the script in the doc subdir, it will create the symbols and
31
# word tables and populate them with informations extracted from
32
# the libxml2-api.xml API description, and make then accessible read-only
33
# by nobody@loaclhost the user expected to be Apache's one
35
# On the Apache configuration, make sure you have php support enabled
45
# We are not interested in parsing errors here
47
def callback(ctx, str):
49
libxml2.registerErrorHandler(callback, None)
52
# The dictionnary of tables required and the SQL command needed
56
"symbols" : """CREATE TABLE symbols (
57
name varchar(255) BINARY NOT NULL,
58
module varchar(255) BINARY NOT NULL,
59
type varchar(25) NOT NULL,
61
UNIQUE KEY name (name),
62
KEY module (module))""",
63
"words" : """CREATE TABLE words (
64
name varchar(50) BINARY NOT NULL,
65
symbol varchar(255) BINARY NOT NULL,
69
UNIQUE KEY ID (name, symbol))""",
70
"wordsHTML" : """CREATE TABLE wordsHTML (
71
name varchar(50) BINARY NOT NULL,
72
resource varchar(255) BINARY NOT NULL,
77
KEY resource (resource),
78
UNIQUE KEY ref (name, resource))""",
79
"wordsArchive" : """CREATE TABLE wordsArchive (
80
name varchar(50) BINARY NOT NULL,
84
UNIQUE KEY ref (name, ID))""",
85
"pages" : """CREATE TABLE pages (
86
resource varchar(255) BINARY NOT NULL,
87
title varchar(255) BINARY NOT NULL,
88
UNIQUE KEY name (resource))""",
89
"archives" : """CREATE TABLE archives (
90
ID int(11) NOT NULL auto_increment,
91
resource varchar(255) BINARY NOT NULL,
92
title varchar(255) BINARY NOT NULL,
93
UNIQUE KEY id (ID,resource(255)),
96
"Queries" : """CREATE TABLE Queries (
97
ID int(11) NOT NULL auto_increment,
98
Value varchar(50) NOT NULL,
99
Count int(11) NOT NULL,
100
UNIQUE KEY id (ID,Value(35)),
102
"AllQueries" : """CREATE TABLE AllQueries (
103
ID int(11) NOT NULL auto_increment,
104
Value varchar(50) NOT NULL,
105
Count int(11) NOT NULL,
106
UNIQUE KEY id (ID,Value(35)),
111
# The XML API description file to parse
113
API="libxml2-api.xml"
116
#########################################################################
118
# MySQL database interfaces #
120
#########################################################################
121
def createTable(db, name):
130
ret = c.execute("DROP TABLE IF EXISTS %s" % (name))
132
print "Removed table %s" % (name)
133
print "Creating table %s" % (name)
135
ret = c.execute(TABLES[name])
137
print "Failed to create table %s" % (name)
141
def checkTables(db, verbose = 1):
147
nbtables = c.execute("show tables")
149
print "Found %d tables" % (nbtables)
158
for table in TABLES.keys():
159
if not tables.has_key(table):
160
print "table %s missing" % (table)
161
createTable(db, table)
163
ret = c.execute("SELECT count(*) from %s" % table);
166
print "Table %s contains %d records" % (table, row[0])
168
print "Troubles with table %s : repairing" % (table)
169
ret = c.execute("repair table %s" % table);
170
print "repairing returned %d" % (ret)
171
ret = c.execute("SELECT count(*) from %s" % table);
173
print "Table %s contains %d records" % (table, row[0])
175
print "checkTables finished"
177
# make sure apache can access the tables read-only
179
ret = c.execute("GRANT SELECT ON xmlsoft.* TO nobody@localhost")
180
ret = c.execute("GRANT INSERT,SELECT,UPDATE ON xmlsoft.Queries TO nobody@localhost")
185
def openMySQL(db="xmlsoft", passwd=None, verbose = 1):
190
passwd = os.environ["MySQL_PASS"]
192
print "No password available, set environment MySQL_PASS"
195
DB = MySQLdb.connect(passwd=passwd, db=db)
198
ret = checkTables(DB, verbose)
201
def updateWord(name, symbol, relevance):
216
"""INSERT INTO words (name, symbol, relevance) VALUES ('%s','%s', %d)""" %
217
(name, symbol, relevance))
221
"""UPDATE words SET relevance = %d where name = '%s' and symbol = '%s'""" %
222
(relevance, name, symbol))
224
print "Update word (%s, %s, %s) failed command" % (name, symbol, relevance)
225
print "UPDATE words SET relevance = %d where name = '%s' and symbol = '%s'" % (relevance, name, symbol)
226
print sys.exc_type, sys.exc_value
231
def updateSymbol(name, module, type, desc):
234
updateWord(name, name, 50)
247
desc = string.replace(desc, "'", " ")
248
l = string.split(desc, ".")
257
"""INSERT INTO symbols (name, module, type, descr) VALUES ('%s','%s', '%s', '%s')""" %
258
(name, module, type, desc))
262
"""UPDATE symbols SET module='%s', type='%s', descr='%s' where name='%s'""" %
263
(module, type, desc, name))
265
print "Update symbol (%s, %s, %s) failed command" % (name, module, type)
266
print """UPDATE symbols SET module='%s', type='%s', descr='%s' where name='%s'""" % (module, type, desc, name)
267
print sys.exc_type, sys.exc_value
272
def addFunction(name, module, desc = ""):
273
return updateSymbol(name, module, 'function', desc)
275
def addMacro(name, module, desc = ""):
276
return updateSymbol(name, module, 'macro', desc)
278
def addEnum(name, module, desc = ""):
279
return updateSymbol(name, module, 'enum', desc)
281
def addStruct(name, module, desc = ""):
282
return updateSymbol(name, module, 'struct', desc)
284
def addConst(name, module, desc = ""):
285
return updateSymbol(name, module, 'const', desc)
287
def addType(name, module, desc = ""):
288
return updateSymbol(name, module, 'type', desc)
290
def addFunctype(name, module, desc = ""):
291
return updateSymbol(name, module, 'functype', desc)
293
def addPage(resource, title):
306
"""INSERT INTO pages (resource, title) VALUES ('%s','%s')""" %
311
"""UPDATE pages SET title='%s' WHERE resource='%s'""" %
314
print "Update symbol (%s, %s, %s) failed command" % (name, module, type)
315
print """UPDATE pages SET title='%s' WHERE resource='%s'""" % (title, resource)
316
print sys.exc_type, sys.exc_value
321
def updateWordHTML(name, resource, desc, id, relevance):
338
desc = string.replace(desc, "'", " ")
346
"""INSERT INTO wordsHTML (name, resource, section, id, relevance) VALUES ('%s','%s', '%s', '%s', '%d')""" %
347
(name, resource, desc, id, relevance))
351
"""UPDATE wordsHTML SET section='%s', id='%s', relevance='%d' where name='%s' and resource='%s'""" %
352
(desc, id, relevance, name, resource))
354
print "Update symbol (%s, %s, %d) failed command" % (name, resource, relevance)
355
print """UPDATE wordsHTML SET section='%s', id='%s', relevance='%d' where name='%s' and resource='%s'""" % (desc, id, relevance, name, resource)
356
print sys.exc_type, sys.exc_value
361
def checkXMLMsgArchive(url):
374
"""SELECT ID FROM archives WHERE resource='%s'""" % (url))
383
def addXMLMsgArchive(url, title):
395
title = string.replace(title, "'", " ")
400
cmd = """INSERT INTO archives (resource, title) VALUES ('%s','%s')""" % (url, title)
402
cmd = """SELECT ID FROM archives WHERE resource='%s'""" % (url)
406
print "addXMLMsgArchive failed to get the ID: %s" % (url)
409
print "addXMLMsgArchive failed command: %s" % (cmd)
412
return((int)(row[0]))
414
def updateWordArchive(name, id, relevance):
429
"""INSERT INTO wordsArchive (name, id, relevance) VALUES ('%s', '%d', '%d')""" %
430
(name, id, relevance))
434
"""UPDATE wordsArchive SET relevance='%d' where name='%s' and ID='%d'""" %
435
(relevance, name, id))
437
print "Update word archive (%s, %d, %d) failed command" % (name, id, relevance)
438
print """UPDATE wordsArchive SET relevance='%d' where name='%s' and ID='%d'""" % (relevance, name, id)
439
print sys.exc_type, sys.exc_value
444
#########################################################################
446
# Word dictionnary and analysis routines #
448
#########################################################################
451
# top 100 english word without the one len < 3 + own set
454
'the':0, 'this':0, 'can':0, 'man':0, 'had':0, 'him':0, 'only':0,
455
'and':0, 'not':0, 'been':0, 'other':0, 'even':0, 'are':0, 'was':0,
456
'new':0, 'most':0, 'but':0, 'when':0, 'some':0, 'made':0, 'from':0,
457
'who':0, 'could':0, 'after':0, 'that':0, 'will':0, 'time':0, 'also':0,
458
'have':0, 'more':0, 'these':0, 'did':0, 'was':0, 'two':0, 'many':0,
459
'they':0, 'may':0, 'before':0, 'for':0, 'which':0, 'out':0, 'then':0,
460
'must':0, 'one':0, 'through':0, 'with':0, 'you':0, 'said':0,
461
'first':0, 'back':0, 'were':0, 'what':0, 'any':0, 'years':0, 'his':0,
462
'her':0, 'where':0, 'all':0, 'its':0, 'now':0, 'much':0, 'she':0,
463
'about':0, 'such':0, 'your':0, 'there':0, 'into':0, 'like':0, 'may':0,
464
'would':0, 'than':0, 'our':0, 'well':0, 'their':0, 'them':0, 'over':0,
466
'net':0, 'www':0, 'bad':0, 'Okay':0, 'bin':0, 'cur':0,
471
wordsDictArchive = {}
473
def cleanupWordsString(str):
474
str = string.replace(str, ".", " ")
475
str = string.replace(str, "!", " ")
476
str = string.replace(str, "?", " ")
477
str = string.replace(str, ",", " ")
478
str = string.replace(str, "'", " ")
479
str = string.replace(str, '"', " ")
480
str = string.replace(str, ";", " ")
481
str = string.replace(str, "(", " ")
482
str = string.replace(str, ")", " ")
483
str = string.replace(str, "{", " ")
484
str = string.replace(str, "}", " ")
485
str = string.replace(str, "<", " ")
486
str = string.replace(str, ">", " ")
487
str = string.replace(str, "=", " ")
488
str = string.replace(str, "/", " ")
489
str = string.replace(str, "*", " ")
490
str = string.replace(str, ":", " ")
491
str = string.replace(str, "#", " ")
492
str = string.replace(str, "\\", " ")
493
str = string.replace(str, "\n", " ")
494
str = string.replace(str, "\r", " ")
495
str = string.replace(str, "\xc2", " ")
496
str = string.replace(str, "\xa0", " ")
499
def cleanupDescrString(str):
500
str = string.replace(str, "'", " ")
501
str = string.replace(str, "\n", " ")
502
str = string.replace(str, "\r", " ")
503
str = string.replace(str, "\xc2", " ")
504
str = string.replace(str, "\xa0", " ")
505
l = string.split(str)
506
str = string.join(str)
509
def splitIdentifier(str):
512
cur = string.lower(str[0])
514
if ((cur < 'a') or (cur > 'z')):
516
while (str != "") and (str[0] >= 'A') and (str[0] <= 'Z'):
517
cur = cur + string.lower(str[0])
519
while (str != "") and (str[0] >= 'a') and (str[0] <= 'z'):
522
while (str != "") and (str[0] >= '0') and (str[0] <= '9'):
527
def addWord(word, module, symbol, relevance):
530
if word == None or len(word) < 3:
532
if module == None or symbol == None:
534
if dropWords.has_key(word):
536
if ord(word[0]) > 0x80:
539
if wordsDict.has_key(word):
544
wordsDict[word] = None
547
relevance = relevance + d[(module, symbol)]
552
wordsDict[word][(module, symbol)] = relevance
555
def addString(str, module, symbol, relevance):
556
if str == None or len(str) < 3:
559
str = cleanupWordsString(str)
560
l = string.split(str)
563
ret = ret + addWord(word, module, symbol, 5)
567
def addWordHTML(word, resource, id, section, relevance):
570
if word == None or len(word) < 3:
572
if resource == None or section == None:
574
if dropWords.has_key(word):
576
if ord(word[0]) > 0x80:
579
section = cleanupDescrString(section)
581
if wordsDictHTML.has_key(word):
582
d = wordsDictHTML[word]
584
print "skipped %s" % (word)
587
(r,i,s) = d[resource]
592
relevance = relevance + r
596
wordsDictHTML[word] = {}
597
d = wordsDictHTML[word];
598
d[resource] = (relevance, id, section)
601
def addStringHTML(str, resource, id, section, relevance):
602
if str == None or len(str) < 3:
605
str = cleanupWordsString(str)
606
l = string.split(str)
610
r = addWordHTML(word, resource, id, section, relevance)
612
print "addWordHTML failed: %s %s" % (word, resource)
615
print "addWordHTML failed: %s %s %d" % (word, resource, relevance)
616
print sys.exc_type, sys.exc_value
620
def addWordArchive(word, id, relevance):
621
global wordsDictArchive
623
if word == None or len(word) < 3:
625
if id == None or id == -1:
627
if dropWords.has_key(word):
629
if ord(word[0]) > 0x80:
632
if wordsDictArchive.has_key(word):
633
d = wordsDictArchive[word]
635
print "skipped %s" % (word)
639
relevance = relevance + r
643
wordsDictArchive[word] = {}
644
d = wordsDictArchive[word];
648
def addStringArchive(str, id, relevance):
649
if str == None or len(str) < 3:
652
str = cleanupWordsString(str)
653
l = string.split(str)
658
r = addWordArchive(word, id, relevance)
660
print "addWordArchive failed: %s %s" % (word, id)
664
print "addWordArchive failed: %s %s %d" % (word, id, relevance)
665
print sys.exc_type, sys.exc_value
668
#########################################################################
670
# XML API description analysis #
672
#########################################################################
674
def loadAPI(filename):
675
doc = libxml2.parseFile(filename)
676
print "loaded %s" % (filename)
679
def foundExport(file, symbol):
684
addFunction(symbol, file)
685
l = splitIdentifier(symbol)
687
addWord(word, file, symbol, 10)
690
def analyzeAPIFile(top):
692
name = top.prop("name")
695
if cur.type == 'text':
698
if cur.name == "exports":
699
count = count + foundExport(name, cur.prop("symbol"))
701
print "unexpected element %s in API doc <file name='%s'>" % (name)
705
def analyzeAPIFiles(top):
710
if cur.type == 'text':
713
if cur.name == "file":
714
count = count + analyzeAPIFile(cur)
716
print "unexpected element %s in API doc <files>" % (cur.name)
720
def analyzeAPIEnum(top):
721
file = top.prop("file")
724
symbol = top.prop("name")
728
addEnum(symbol, file)
729
l = splitIdentifier(symbol)
731
addWord(word, file, symbol, 10)
735
def analyzeAPIConst(top):
736
file = top.prop("file")
739
symbol = top.prop("name")
743
addConst(symbol, file)
744
l = splitIdentifier(symbol)
746
addWord(word, file, symbol, 10)
750
def analyzeAPIType(top):
751
file = top.prop("file")
754
symbol = top.prop("name")
758
addType(symbol, file)
759
l = splitIdentifier(symbol)
761
addWord(word, file, symbol, 10)
764
def analyzeAPIFunctype(top):
765
file = top.prop("file")
768
symbol = top.prop("name")
772
addFunctype(symbol, file)
773
l = splitIdentifier(symbol)
775
addWord(word, file, symbol, 10)
778
def analyzeAPIStruct(top):
779
file = top.prop("file")
782
symbol = top.prop("name")
786
addStruct(symbol, file)
787
l = splitIdentifier(symbol)
789
addWord(word, file, symbol, 10)
791
info = top.prop("info")
793
info = string.replace(info, "'", " ")
794
info = string.strip(info)
795
l = string.split(info)
798
addWord(word, file, symbol, 5)
801
def analyzeAPIMacro(top):
802
file = top.prop("file")
805
symbol = top.prop("name")
808
symbol = string.replace(symbol, "'", " ")
809
symbol = string.strip(symbol)
814
if cur.type == 'text':
817
if cur.name == "info":
822
l = splitIdentifier(symbol)
824
addWord(word, file, symbol, 10)
827
addMacro(symbol, file)
828
print "Macro %s description has no <info>" % (symbol)
831
info = string.replace(info, "'", " ")
832
info = string.strip(info)
833
addMacro(symbol, file, info)
834
l = string.split(info)
837
addWord(word, file, symbol, 5)
840
def analyzeAPIFunction(top):
841
file = top.prop("file")
844
symbol = top.prop("name")
848
symbol = string.replace(symbol, "'", " ")
849
symbol = string.strip(symbol)
853
if cur.type == 'text':
856
if cur.name == "info":
858
elif cur.name == "return":
859
rinfo = cur.prop("info")
861
rinfo = string.replace(rinfo, "'", " ")
862
rinfo = string.strip(rinfo)
863
addString(rinfo, file, symbol, 7)
864
elif cur.name == "arg":
865
ainfo = cur.prop("info")
867
ainfo = string.replace(ainfo, "'", " ")
868
ainfo = string.strip(ainfo)
869
addString(ainfo, file, symbol, 5)
870
name = cur.prop("name")
872
name = string.replace(name, "'", " ")
873
name = string.strip(name)
874
addWord(name, file, symbol, 7)
877
print "Function %s description has no <info>" % (symbol)
878
addFunction(symbol, file, "")
880
info = string.replace(info, "'", " ")
881
info = string.strip(info)
882
addFunction(symbol, file, info)
883
addString(info, file, symbol, 5)
885
l = splitIdentifier(symbol)
887
addWord(word, file, symbol, 10)
891
def analyzeAPISymbols(top):
896
if cur.type == 'text':
899
if cur.name == "macro":
900
count = count + analyzeAPIMacro(cur)
901
elif cur.name == "function":
902
count = count + analyzeAPIFunction(cur)
903
elif cur.name == "const":
904
count = count + analyzeAPIConst(cur)
905
elif cur.name == "typedef":
906
count = count + analyzeAPIType(cur)
907
elif cur.name == "struct":
908
count = count + analyzeAPIStruct(cur)
909
elif cur.name == "enum":
910
count = count + analyzeAPIEnum(cur)
911
elif cur.name == "functype":
912
count = count + analyzeAPIFunctype(cur)
914
print "unexpected element %s in API doc <files>" % (cur.name)
922
root = doc.getRootElement()
923
if root.name != "api":
924
print "Unexpected root name"
928
if cur.type == 'text':
931
if cur.name == "files":
933
# count = count + analyzeAPIFiles(cur)
934
elif cur.name == "symbols":
935
count = count + analyzeAPISymbols(cur)
937
print "unexpected element %s in API doc" % (cur.name)
941
#########################################################################
943
# Web pages parsing and analysis #
945
#########################################################################
949
def analyzeHTMLText(doc, resource, p, section, id):
953
words = words + addStringHTML(content, resource, id, section, 5)
958
def analyzeHTMLPara(doc, resource, p, section, id):
962
words = words + addStringHTML(content, resource, id, section, 5)
967
def analyzeHTMLPre(doc, resource, p, section, id):
971
words = words + addStringHTML(content, resource, id, section, 5)
976
def analyzeHTML(doc, resource, p, section, id):
980
words = words + addStringHTML(content, resource, id, section, 5)
985
def analyzeHTML(doc, resource):
987
ctxt = doc.xpathNewContext()
989
res = ctxt.xpathEval("//head/title")
990
title = res[0].content
992
title = "Page %s" % (resource)
993
addPage(resource, title)
995
items = ctxt.xpathEval("//h1 | //h2 | //h3 | //text()")
999
if item.name == 'h1' or item.name == 'h2' or item.name == 'h3':
1000
section = item.content
1002
id = item.prop("id")
1003
elif item.prop("name"):
1004
id = item.prop("name")
1005
elif item.type == 'text':
1006
analyzeHTMLText(doc, resource, item, section, id)
1008
elif item.name == 'p':
1009
analyzeHTMLPara(doc, resource, item, section, id)
1011
elif item.name == 'pre':
1012
analyzeHTMLPre(doc, resource, item, section, id)
1015
print "Page %s, unexpected %s element" % (resource, item.name)
1017
print "Page %s: problem analyzing" % (resource)
1018
print sys.exc_type, sys.exc_value
1022
def analyzeHTMLPages():
1024
HTMLfiles = glob.glob("*.html") + glob.glob("tutorial/*.html")
1025
for html in HTMLfiles:
1026
if html[0:3] == "API":
1028
if html == "xml.html":
1031
doc = libxml2.parseFile(html)
1033
doc = libxml2.htmlParseFile(html, None)
1035
res = analyzeHTML(doc, html)
1036
print "Parsed %s : %d paragraphs" % (html, res)
1039
print "could not parse %s" % (html)
1042
#########################################################################
1044
# Mail archives parsing and analysis #
1046
#########################################################################
1050
def getXMLDateArchive(t = None):
1054
month = time.strftime("%B", T)
1056
url = "http://mail.gnome.org/archives/xml/%d-%s/date.html" % (year, month)
1059
def scanXMLMsgArchive(url, title, force = 0):
1060
if url == None or title == None:
1063
ID = checkXMLMsgArchive(url)
1064
if force == 0 and ID != -1:
1068
ID = addXMLMsgArchive(url, title)
1073
print "Loading %s" % (url)
1074
doc = libxml2.htmlParseFile(url, None);
1078
print "Failed to parse %s" % (url)
1081
addStringArchive(title, ID, 20)
1082
ctxt = doc.xpathNewContext()
1083
texts = ctxt.xpathEval("//pre//text()")
1085
addStringArchive(text.content, ID, 5)
1089
def scanXMLDateArchive(t = None, force = 0):
1090
global wordsDictArchive
1092
wordsDictArchive = {}
1094
url = getXMLDateArchive(t)
1095
print "loading %s" % (url)
1097
doc = libxml2.htmlParseFile(url, None);
1101
print "Failed to parse %s" % (url)
1103
ctxt = doc.xpathNewContext()
1104
anchors = ctxt.xpathEval("//a[@href]")
1107
for anchor in anchors:
1108
href = anchor.prop("href")
1109
if href == None or href[0:3] != "msg":
1114
msg = libxml2.buildURI(href, url)
1115
title = anchor.content
1116
if title != None and title[0:4] == 'Re: ':
1118
if title != None and title[0:6] == '[xml] ':
1120
newmsg = newmsg + scanXMLMsgArchive(msg, title, force)
1128
#########################################################################
1130
# Main code: open the DB, the API XML and analyze it #
1132
#########################################################################
1133
def analyzeArchives(t = None, force = 0):
1134
global wordsDictArchive
1136
ret = scanXMLDateArchive(t, force)
1137
print "Indexed %d words in %d archive pages" % (len(wordsDictArchive), ret)
1141
for word in wordsDictArchive.keys():
1142
refs = wordsDictArchive[word]
1144
skipped = skipped + 1
1146
for id in refs.keys():
1147
relevance = refs[id]
1148
updateWordArchive(word, id, relevance)
1151
print "Found %d associations in HTML pages" % (i)
1153
def analyzeHTMLTop():
1154
global wordsDictHTML
1156
ret = analyzeHTMLPages()
1157
print "Indexed %d words in %d HTML pages" % (len(wordsDictHTML), ret)
1161
for word in wordsDictHTML.keys():
1162
refs = wordsDictHTML[word]
1164
skipped = skipped + 1
1166
for resource in refs.keys():
1167
(relevance, id, section) = refs[resource]
1168
updateWordHTML(word, resource, section, id, relevance)
1171
print "Found %d associations in HTML pages" % (i)
1173
def analyzeAPITop():
1179
ret = analyzeAPI(doc)
1180
print "Analyzed %d blocs" % (ret)
1183
print "Failed to parse and analyze %s" % (API)
1184
print sys.exc_type, sys.exc_value
1187
print "Indexed %d words" % (len(wordsDict))
1190
for word in wordsDict.keys():
1191
refs = wordsDict[word]
1193
skipped = skipped + 1
1195
for (module, symbol) in refs.keys():
1196
updateWord(word, symbol, refs[(module, symbol)])
1199
print "Found %d associations, skipped %d words" % (i, skipped)
1202
print "Usage index.py [--force] [--archive] [--archive-year year] [--archive-month month] [--API] [--docs]"
1209
print "Failed to open the database"
1210
print sys.exc_type, sys.exc_value
1217
while i < len(args):
1218
if args[i] == '--force':
1220
elif args[i] == '--archive':
1221
analyzeArchives(None, force)
1222
elif args[i] == '--archive-year':
1225
months = ["January" , "February", "March", "April", "May",
1226
"June", "July", "August", "September", "October",
1227
"November", "December"];
1228
for month in months:
1230
str = "%s-%s" % (year, month)
1231
T = time.strptime(str, "%Y-%B")
1232
t = time.mktime(T) + 3600 * 24 * 10;
1233
analyzeArchives(t, force)
1235
print "Failed to index month archive:"
1236
print sys.exc_type, sys.exc_value
1237
elif args[i] == '--archive-month':
1241
T = time.strptime(month, "%Y-%B")
1242
t = time.mktime(T) + 3600 * 24 * 10;
1243
analyzeArchives(t, force)
1245
print "Failed to index month archive:"
1246
print sys.exc_type, sys.exc_value
1247
elif args[i] == '--API':
1249
elif args[i] == '--docs':
1257
if __name__ == "__main__":