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 XSLTsymbols 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 dictionary of tables required and the SQL command needed
56 "XSLTsymbols" : """CREATE TABLE XSLTsymbols (
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 "XSLTwords" : """CREATE TABLE XSLTwords (
64 name varchar(50) BINARY NOT NULL,
65 symbol varchar(255) BINARY NOT NULL,
69 UNIQUE KEY ID (name, symbol))""",
70 "XSLTwordsHTML" : """CREATE TABLE XSLTwordsHTML (
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 "XSLTwordsArchive" : """CREATE TABLE XSLTwordsArchive (
80 name varchar(50) BINARY NOT NULL,
84 UNIQUE KEY ref (name, ID))""",
85 "XSLTpages" : """CREATE TABLE XSLTpages (
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)),
105 # The XML API description file to parse
107 API="libxslt-api.xml"
110 #########################################################################
112 # MySQL database interfaces #
114 #########################################################################
115 def createTable(db, name):
124 ret = c.execute("DROP TABLE IF EXISTS %s" % (name))
126 print "Removed table %s" % (name)
127 print "Creating table %s" % (name)
129 ret = c.execute(TABLES[name])
131 print "Failed to create table %s" % (name)
141 nbtables = c.execute("show tables")
142 print "Found %d tables" % (nbtables)
151 for table in TABLES.keys():
152 if not tables.has_key(table):
153 print "table %s missing" % (table)
154 createTable(db, table)
156 ret = c.execute("SELECT count(*) from %s" % table);
158 print "Table %s contains %d records" % (table, row[0])
160 print "Troubles with table %s : repairing" % (table)
161 ret = c.execute("repair table %s" % table);
162 print "repairing returned %d" % (ret)
163 ret = c.execute("SELECT count(*) from %s" % table);
165 print "Table %s contains %d records" % (table, row[0])
166 print "checkTables finished"
168 # make sure apache can access the tables read-only
170 ret = c.execute("GRANT SELECT ON xmlsoft.* TO nobody@localhost")
171 ret = c.execute("GRANT INSERT,SELECT,UPDATE ON xmlsoft.Queries TO nobody@localhost")
176 def openMySQL(db="xmlsoft", passwd=None):
181 passwd = os.environ["MySQL_PASS"]
183 print "No password available, set environment MySQL_PASS"
186 DB = MySQLdb.connect(passwd=passwd, db=db)
189 ret = checkTables(DB)
192 def updateWord(name, symbol, relevance):
207 """INSERT INTO XSLTwords (name, symbol, relevance) VALUES ('%s','%s', %d)""" %
208 (name, symbol, relevance))
212 """UPDATE XSLTwords SET relevance = %d where name = '%s' and symbol = '%s'""" %
213 (relevance, name, symbol))
215 print "Update word (%s, %s, %s) failed command" % (name, symbol, relevance)
216 print "UPDATE XSLTwords SET relevance = %d where name = '%s' and symbol = '%s'" % (relevance, name, symbol)
217 print sys.exc_type, sys.exc_value
222 def updateSymbol(name, module, type, desc):
225 updateWord(name, name, 50)
238 desc = string.replace(desc, "'", " ")
239 l = string.split(desc, ".")
248 """INSERT INTO XSLTsymbols (name, module, type, descr) VALUES ('%s','%s', '%s', '%s')""" %
249 (name, module, type, desc))
253 """UPDATE XSLTsymbols SET module='%s', type='%s', descr='%s' where name='%s'""" %
254 (module, type, desc, name))
256 print "Update symbol (%s, %s, %s) failed command" % (name, module, type)
257 print """UPDATE XSLTsymbols SET module='%s', type='%s', descr='%s' where name='%s'""" % (module, type, desc, name)
258 print sys.exc_type, sys.exc_value
263 def addFunction(name, module, desc = ""):
264 return updateSymbol(name, module, 'function', desc)
266 def addMacro(name, module, desc = ""):
267 return updateSymbol(name, module, 'macro', desc)
269 def addEnum(name, module, desc = ""):
270 return updateSymbol(name, module, 'enum', desc)
272 def addStruct(name, module, desc = ""):
273 return updateSymbol(name, module, 'struct', desc)
275 def addConst(name, module, desc = ""):
276 return updateSymbol(name, module, 'const', desc)
278 def addType(name, module, desc = ""):
279 return updateSymbol(name, module, 'type', desc)
281 def addFunctype(name, module, desc = ""):
282 return updateSymbol(name, module, 'functype', desc)
284 def addPage(resource, title):
297 """INSERT INTO XSLTpages (resource, title) VALUES ('%s','%s')""" %
302 """UPDATE XSLTpages SET title='%s' WHERE resource='%s'""" %
305 print "Update symbol (%s, %s, %s) failed command" % (name, module, type)
306 print """UPDATE XSLTpages SET title='%s' WHERE resource='%s'""" % (title, resource)
307 print sys.exc_type, sys.exc_value
312 def updateWordHTML(name, resource, desc, id, relevance):
329 desc = string.replace(desc, "'", " ")
337 """INSERT INTO XSLTwordsHTML (name, resource, section, id, relevance) VALUES ('%s','%s', '%s', '%s', '%d')""" %
338 (name, resource, desc, id, relevance))
342 """UPDATE XSLTwordsHTML SET section='%s', id='%s', relevance='%d' where name='%s' and resource='%s'""" %
343 (desc, id, relevance, name, resource))
345 print "Update symbol (%s, %s, %d) failed command" % (name, resource, relevance)
346 print """UPDATE XSLTwordsHTML SET section='%s', id='%s', relevance='%d' where name='%s' and resource='%s'""" % (desc, id, relevance, name, resource)
347 print sys.exc_type, sys.exc_value
352 def checkXMLMsgArchive(url):
365 """SELECT ID FROM archives WHERE resource='%s'""" % (url))
374 def addXMLMsgArchive(url, title):
386 title = string.replace(title, "'", " ")
391 cmd = """INSERT INTO archives (resource, title) VALUES ('%s','%s')""" % (url, title)
393 cmd = """SELECT ID FROM archives WHERE resource='%s'""" % (url)
397 print "addXMLMsgArchive failed to get the ID: %s" % (url)
400 print "addXMLMsgArchive failed command: %s" % (cmd)
403 return((int)(row[0]))
405 def updateWordArchive(name, id, relevance):
420 """INSERT INTO XSLTwordsArchive (name, id, relevance) VALUES ('%s', '%d', '%d')""" %
421 (name, id, relevance))
425 """UPDATE XSLTwordsArchive SET relevance='%d' where name='%s' and ID='%d'""" %
426 (relevance, name, id))
428 print "Update word archive (%s, %d, %d) failed command" % (name, id, relevance)
429 print """UPDATE XSLTwordsArchive SET relevance='%d' where name='%s' and ID='%d'""" % (relevance, name, id)
430 print sys.exc_type, sys.exc_value
435 #########################################################################
437 # Word dictionary and analysis routines #
439 #########################################################################
442 # top 100 english word without the one len < 3 + own set
445 'the':0, 'this':0, 'can':0, 'man':0, 'had':0, 'him':0, 'only':0,
446 'and':0, 'not':0, 'been':0, 'other':0, 'even':0, 'are':0, 'was':0,
447 'new':0, 'most':0, 'but':0, 'when':0, 'some':0, 'made':0, 'from':0,
448 'who':0, 'could':0, 'after':0, 'that':0, 'will':0, 'time':0, 'also':0,
449 'have':0, 'more':0, 'these':0, 'did':0, 'was':0, 'two':0, 'many':0,
450 'they':0, 'may':0, 'before':0, 'for':0, 'which':0, 'out':0, 'then':0,
451 'must':0, 'one':0, 'through':0, 'with':0, 'you':0, 'said':0,
452 'first':0, 'back':0, 'were':0, 'what':0, 'any':0, 'years':0, 'his':0,
453 'her':0, 'where':0, 'all':0, 'its':0, 'now':0, 'much':0, 'she':0,
454 'about':0, 'such':0, 'your':0, 'there':0, 'into':0, 'like':0, 'may':0,
455 'would':0, 'than':0, 'our':0, 'well':0, 'their':0, 'them':0, 'over':0,
457 'net':0, 'www':0, 'bad':0, 'Okay':0, 'bin':0, 'cur':0,
462 wordsDictArchive = {}
464 def cleanupWordsString(str):
465 str = string.replace(str, ".", " ")
466 str = string.replace(str, "!", " ")
467 str = string.replace(str, "?", " ")
468 str = string.replace(str, ",", " ")
469 str = string.replace(str, "'", " ")
470 str = string.replace(str, '"', " ")
471 str = string.replace(str, ";", " ")
472 str = string.replace(str, "(", " ")
473 str = string.replace(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, "\n", " ")
485 str = string.replace(str, "\r", " ")
486 str = string.replace(str, "\xc2", " ")
487 str = string.replace(str, "\xa0", " ")
490 def cleanupDescrString(str):
491 str = string.replace(str, "'", " ")
492 str = string.replace(str, "\n", " ")
493 str = string.replace(str, "\r", " ")
494 str = string.replace(str, "\xc2", " ")
495 str = string.replace(str, "\xa0", " ")
496 l = string.split(str)
497 str = string.join(str)
500 def splitIdentifier(str):
503 cur = string.lower(str[0])
505 if ((cur < 'a') or (cur > 'z')):
507 while (str != "") and (str[0] >= 'A') and (str[0] <= 'Z'):
508 cur = cur + string.lower(str[0])
510 while (str != "") and (str[0] >= 'a') and (str[0] <= 'z'):
513 while (str != "") and (str[0] >= '0') and (str[0] <= '9'):
518 def addWord(word, module, symbol, relevance):
521 if word == None or len(word) < 3:
523 if module == None or symbol == None:
525 if dropWords.has_key(word):
527 if ord(word[0]) > 0x80:
530 if wordsDict.has_key(word):
535 wordsDict[word] = None
538 relevance = relevance + d[(module, symbol)]
543 wordsDict[word][(module, symbol)] = relevance
546 def addString(str, module, symbol, relevance):
547 if str == None or len(str) < 3:
550 str = cleanupWordsString(str)
551 l = string.split(str)
554 ret = ret + addWord(word, module, symbol, 5)
558 def addWordHTML(word, resource, id, section, relevance):
561 if word == None or len(word) < 3:
563 if resource == None or section == None:
565 if dropWords.has_key(word):
567 if ord(word[0]) > 0x80:
570 section = cleanupDescrString(section)
572 if wordsDictHTML.has_key(word):
573 d = wordsDictHTML[word]
575 print "skipped %s" % (word)
578 (r,i,s) = d[resource]
583 relevance = relevance + r
587 wordsDictHTML[word] = {}
588 d = wordsDictHTML[word];
589 d[resource] = (relevance, id, section)
592 def addStringHTML(str, resource, id, section, relevance):
593 if str == None or len(str) < 3:
596 str = cleanupWordsString(str)
597 l = string.split(str)
601 r = addWordHTML(word, resource, id, section, relevance)
603 print "addWordHTML failed: %s %s" % (word, resource)
606 print "addWordHTML failed: %s %s %d" % (word, resource, relevance)
607 print sys.exc_type, sys.exc_value
611 def addWordArchive(word, id, relevance):
612 global wordsDictArchive
614 if word == None or len(word) < 3:
616 if id == None or id == -1:
618 if dropWords.has_key(word):
620 if ord(word[0]) > 0x80:
623 if wordsDictArchive.has_key(word):
624 d = wordsDictArchive[word]
626 print "skipped %s" % (word)
630 relevance = relevance + r
634 wordsDictArchive[word] = {}
635 d = wordsDictArchive[word];
639 def addStringArchive(str, id, relevance):
640 if str == None or len(str) < 3:
643 str = cleanupWordsString(str)
644 l = string.split(str)
649 r = addWordArchive(word, id, relevance)
651 print "addWordArchive failed: %s %s" % (word, id)
655 print "addWordArchive failed: %s %s %d" % (word, id, relevance)
656 print sys.exc_type, sys.exc_value
659 #########################################################################
661 # XML API description analysis #
663 #########################################################################
665 def loadAPI(filename):
666 doc = libxml2.parseFile(filename)
667 print "loaded %s" % (filename)
670 def foundExport(file, symbol):
675 addFunction(symbol, file)
676 l = splitIdentifier(symbol)
678 addWord(word, file, symbol, 10)
681 def analyzeAPIFile(top):
683 name = top.prop("name")
686 if cur.type == 'text':
689 if cur.name == "exports":
690 count = count + foundExport(name, cur.prop("symbol"))
692 print "unexpected element %s in API doc <file name='%s'>" % (name)
696 def analyzeAPIFiles(top):
701 if cur.type == 'text':
704 if cur.name == "file":
705 count = count + analyzeAPIFile(cur)
707 print "unexpected element %s in API doc <files>" % (cur.name)
711 def analyzeAPIEnum(top):
712 file = top.prop("file")
715 symbol = top.prop("name")
719 addEnum(symbol, file)
720 l = splitIdentifier(symbol)
722 addWord(word, file, symbol, 10)
726 def analyzeAPIConst(top):
727 file = top.prop("file")
730 symbol = top.prop("name")
734 addConst(symbol, file)
735 l = splitIdentifier(symbol)
737 addWord(word, file, symbol, 10)
741 def analyzeAPIType(top):
742 file = top.prop("file")
745 symbol = top.prop("name")
749 addType(symbol, file)
750 l = splitIdentifier(symbol)
752 addWord(word, file, symbol, 10)
755 def analyzeAPIFunctype(top):
756 file = top.prop("file")
759 symbol = top.prop("name")
763 addFunctype(symbol, file)
764 l = splitIdentifier(symbol)
766 addWord(word, file, symbol, 10)
769 def analyzeAPIStruct(top):
770 file = top.prop("file")
773 symbol = top.prop("name")
777 addStruct(symbol, file)
778 l = splitIdentifier(symbol)
780 addWord(word, file, symbol, 10)
782 info = top.prop("info")
784 info = string.replace(info, "'", " ")
785 info = string.strip(info)
786 l = string.split(info)
789 addWord(word, file, symbol, 5)
792 def analyzeAPIMacro(top):
793 file = top.prop("file")
796 symbol = top.prop("name")
799 symbol = string.replace(symbol, "'", " ")
800 symbol = string.strip(symbol)
805 if cur.type == 'text':
808 if cur.name == "info":
813 l = splitIdentifier(symbol)
815 addWord(word, file, symbol, 10)
818 addMacro(symbol, file)
819 print "Macro %s description has no <info>" % (symbol)
822 info = string.replace(info, "'", " ")
823 info = string.strip(info)
824 addMacro(symbol, file, info)
825 l = string.split(info)
828 addWord(word, file, symbol, 5)
831 def analyzeAPIFunction(top):
832 file = top.prop("file")
835 symbol = top.prop("name")
839 symbol = string.replace(symbol, "'", " ")
840 symbol = string.strip(symbol)
844 if cur.type == 'text':
847 if cur.name == "info":
849 elif cur.name == "return":
850 rinfo = cur.prop("info")
852 rinfo = string.replace(rinfo, "'", " ")
853 rinfo = string.strip(rinfo)
854 addString(rinfo, file, symbol, 7)
855 elif cur.name == "arg":
856 ainfo = cur.prop("info")
858 ainfo = string.replace(ainfo, "'", " ")
859 ainfo = string.strip(ainfo)
860 addString(ainfo, file, symbol, 5)
861 name = cur.prop("name")
863 name = string.replace(name, "'", " ")
864 name = string.strip(name)
865 addWord(name, file, symbol, 7)
868 print "Function %s description has no <info>" % (symbol)
869 addFunction(symbol, file, "")
871 info = string.replace(info, "'", " ")
872 info = string.strip(info)
873 addFunction(symbol, file, info)
874 addString(info, file, symbol, 5)
876 l = splitIdentifier(symbol)
878 addWord(word, file, symbol, 10)
882 def analyzeAPISymbols(top):
887 if cur.type == 'text':
890 if cur.name == "macro":
891 count = count + analyzeAPIMacro(cur)
892 elif cur.name == "function":
893 count = count + analyzeAPIFunction(cur)
894 elif cur.name == "const":
895 count = count + analyzeAPIConst(cur)
896 elif cur.name == "typedef":
897 count = count + analyzeAPIType(cur)
898 elif cur.name == "struct":
899 count = count + analyzeAPIStruct(cur)
900 elif cur.name == "enum":
901 count = count + analyzeAPIEnum(cur)
902 elif cur.name == "functype":
903 count = count + analyzeAPIFunctype(cur)
905 print "unexpected element %s in API doc <files>" % (cur.name)
913 root = doc.getRootElement()
914 if root.name != "api":
915 print "Unexpected root name"
919 if cur.type == 'text':
922 if cur.name == "files":
924 # count = count + analyzeAPIFiles(cur)
925 elif cur.name == "symbols":
926 count = count + analyzeAPISymbols(cur)
928 print "unexpected element %s in API doc" % (cur.name)
932 #########################################################################
934 # Web pages parsing and analysis #
936 #########################################################################
940 def analyzeHTMLText(doc, resource, p, section, id):
944 words = words + addStringHTML(content, resource, id, section, 5)
949 def analyzeHTMLPara(doc, resource, p, section, id):
953 words = words + addStringHTML(content, resource, id, section, 5)
958 def analyzeHTMLPre(doc, resource, p, section, id):
962 words = words + addStringHTML(content, resource, id, section, 5)
967 def analyzeHTML(doc, resource, p, section, id):
971 words = words + addStringHTML(content, resource, id, section, 5)
976 def analyzeHTML(doc, resource):
978 ctxt = doc.xpathNewContext()
980 res = ctxt.xpathEval("//head/title")
981 title = res[0].content
983 title = "Page %s" % (resource)
984 addPage(resource, title)
986 items = ctxt.xpathEval("//h1 | //h2 | //h3 | //text()")
990 if item.name == 'h1' or item.name == 'h2' or item.name == 'h3':
991 section = item.content
994 elif item.prop("name"):
995 id = item.prop("name")
996 elif item.type == 'text':
997 analyzeHTMLText(doc, resource, item, section, id)
999 elif item.name == 'p':
1000 analyzeHTMLPara(doc, resource, item, section, id)
1002 elif item.name == 'pre':
1003 analyzeHTMLPre(doc, resource, item, section, id)
1006 print "Page %s, unexpected %s element" % (resource, item.name)
1008 print "Page %s: problem analyzing" % (resource)
1009 print sys.exc_type, sys.exc_value
1013 def analyzeHTMLPages():
1015 HTMLfiles = glob.glob("*.html") + glob.glob("tutorial/*.html")
1016 for html in HTMLfiles:
1017 if html[0:3] == "API":
1019 if html == "xslt.html":
1022 doc = libxml2.htmlParseFile(html, None)
1023 res = analyzeHTML(doc, html)
1024 print "Parsed %s : %d paragraphs" % (html, res)
1027 print "could not parse %s" % (html)
1030 #########################################################################
1032 # Mail archives parsing and analysis #
1034 #########################################################################
1038 def getXMLDateArchive(t = None):
1042 month = time.strftime("%B", T)
1044 url = "http://mail.gnome.org/archives/xslt/%d-%s/date.html" % (year, month)
1047 def scanXMLMsgArchive(url, title, force = 0):
1048 if url == None or title == None:
1051 ID = checkXMLMsgArchive(url)
1052 if force == 0 and ID != -1:
1056 ID = addXMLMsgArchive(url, title)
1061 print "Loading %s" % (url)
1062 doc = libxml2.htmlParseFile(url, None);
1066 print "Failed to parse %s" % (url)
1069 addStringArchive(title, ID, 20)
1070 ctxt = doc.xpathNewContext()
1071 texts = ctxt.xpathEval("//pre//text()")
1073 addStringArchive(text.content, ID, 5)
1077 def scanXMLDateArchive(t = None, force = 0):
1078 global wordsDictArchive
1080 wordsDictArchive = {}
1082 url = getXMLDateArchive(t)
1083 print "loading %s" % (url)
1085 doc = libxml2.htmlParseFile(url, None);
1089 print "Failed to parse %s" % (url)
1091 ctxt = doc.xpathNewContext()
1092 anchors = ctxt.xpathEval("//a[@href]")
1095 for anchor in anchors:
1096 href = anchor.prop("href")
1097 if href == None or href[0:3] != "msg":
1102 msg = libxml2.buildURI(href, url)
1103 title = anchor.content
1104 if title != None and title[0:4] == 'Re: ':
1106 if title != None and title[0:6] == '[xml] ':
1108 if title != None and title[0:7] == '[xslt] ':
1110 newmsg = newmsg + scanXMLMsgArchive(msg, title, force)
1118 #########################################################################
1120 # Main code: open the DB, the API XML and analyze it #
1122 #########################################################################
1126 print "Failed to open the database"
1127 print sys.exc_type, sys.exc_value
1130 def analyzeArchives(t = None, force = 0):
1131 global wordsDictArchive
1133 ret = scanXMLDateArchive(t, force)
1134 print "Indexed %d words in %d archive pages" % (len(wordsDictArchive), ret)
1138 for word in wordsDictArchive.keys():
1139 refs = wordsDictArchive[word]
1141 skipped = skipped + 1
1143 for id in refs.keys():
1144 relevance = refs[id]
1145 updateWordArchive(word, id, relevance)
1148 print "Found %d associations in HTML pages" % (i)
1150 def analyzeHTMLTop():
1151 global wordsDictHTML
1153 ret = analyzeHTMLPages()
1154 print "Indexed %d words in %d HTML pages" % (len(wordsDictHTML), ret)
1158 for word in wordsDictHTML.keys():
1159 refs = wordsDictHTML[word]
1161 skipped = skipped + 1
1163 for resource in refs.keys():
1164 (relevance, id, section) = refs[resource]
1165 updateWordHTML(word, resource, section, id, relevance)
1168 print "Found %d associations in HTML pages" % (i)
1170 def analyzeAPITop():
1176 ret = analyzeAPI(doc)
1177 print "Analyzed %d blocs" % (ret)
1180 print "Failed to parse and analyze %s" % (API)
1181 print sys.exc_type, sys.exc_value
1184 print "Indexed %d words" % (len(wordsDict))
1187 for word in wordsDict.keys():
1188 refs = wordsDict[word]
1190 skipped = skipped + 1
1192 for (module, symbol) in refs.keys():
1193 updateWord(word, symbol, refs[(module, symbol)])
1196 print "Found %d associations, skipped %d words" % (i, skipped)
1199 print "Usage index.py [--force] [--archive] [--archive-year year] [--archive-month month] [--API] [--docs]"
1207 while i < len(args):
1208 if args[i] == '--force':
1210 elif args[i] == '--archive':
1211 analyzeArchives(None, force)
1212 elif args[i] == '--archive-year':
1215 months = ["January" , "February", "March", "April", "May",
1216 "June", "July", "August", "September", "October",
1217 "November", "December"];
1218 for month in months:
1220 str = "%s-%s" % (year, month)
1221 T = time.strptime(str, "%Y-%B")
1222 t = time.mktime(T) + 3600 * 24 * 10;
1223 analyzeArchives(t, force)
1225 print "Failed to index month archive:"
1226 print sys.exc_type, sys.exc_value
1227 elif args[i] == '--archive-month':
1231 T = time.strptime(month, "%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] == '--API':
1239 elif args[i] == '--docs':
1247 if __name__ == "__main__":