| 1 |
#!/usr/bin/python |
|---|
| 2 |
# |
|---|
| 3 |
# Check/update default wiki pages from the Trac project website. |
|---|
| 4 |
# |
|---|
| 5 |
# Note: This is a development tool used in Trac packaging/QA, not something |
|---|
| 6 |
# particularly useful for end-users. |
|---|
| 7 |
# |
|---|
| 8 |
# Author: Daniel Lundin <daniel@edgewall.com> |
|---|
| 9 |
|
|---|
| 10 |
import httplib |
|---|
| 11 |
import re |
|---|
| 12 |
import sys |
|---|
| 13 |
import getopt |
|---|
| 14 |
|
|---|
| 15 |
# Pages to include in distribution |
|---|
| 16 |
wiki_pages = [ |
|---|
| 17 |
"CamelCase", |
|---|
| 18 |
"InterMapTxt", |
|---|
| 19 |
"InterTrac", |
|---|
| 20 |
"InterWiki", |
|---|
| 21 |
"PageTemplates", |
|---|
| 22 |
"RecentChanges", |
|---|
| 23 |
"TitleIndex", |
|---|
| 24 |
"TracAccessibility", |
|---|
| 25 |
"TracAdmin", |
|---|
| 26 |
"TracBackup", |
|---|
| 27 |
"TracBrowser", |
|---|
| 28 |
"TracCgi", |
|---|
| 29 |
"TracChangeset", |
|---|
| 30 |
"TracEnvironment", |
|---|
| 31 |
"TracFastCgi", |
|---|
| 32 |
"TracFineGrainedPermissions", |
|---|
| 33 |
"TracGuide", |
|---|
| 34 |
"TracImport", |
|---|
| 35 |
"TracIni", |
|---|
| 36 |
"TracInstall", |
|---|
| 37 |
"TracInterfaceCustomization", |
|---|
| 38 |
"TracLinks", |
|---|
| 39 |
"TracLogging", |
|---|
| 40 |
"TracModPython", |
|---|
| 41 |
"TracNavigation", |
|---|
| 42 |
"TracNotification", |
|---|
| 43 |
"TracPermissions", |
|---|
| 44 |
"TracPlugins", |
|---|
| 45 |
"TracQuery", |
|---|
| 46 |
"TracReports", |
|---|
| 47 |
"TracRevisionLog", |
|---|
| 48 |
"TracRoadmap", |
|---|
| 49 |
"TracRss", |
|---|
| 50 |
"TracSearch", |
|---|
| 51 |
"TracStandalone", |
|---|
| 52 |
"TracSupport", |
|---|
| 53 |
"TracSyntaxColoring", |
|---|
| 54 |
"TracTickets", |
|---|
| 55 |
"TracTicketsCustomFields", |
|---|
| 56 |
"TracTimeline", |
|---|
| 57 |
"TracUnicode", |
|---|
| 58 |
"TracUpgrade", |
|---|
| 59 |
"TracWiki", |
|---|
| 60 |
"TracWikiMacros", |
|---|
| 61 |
"TracWorkflow", |
|---|
| 62 |
"WikiDeletePage", |
|---|
| 63 |
"WikiFormatting", |
|---|
| 64 |
"WikiHtml", |
|---|
| 65 |
"WikiNewPage", |
|---|
| 66 |
"WikiPageNames", |
|---|
| 67 |
"WikiProcessors", |
|---|
| 68 |
"WikiRestructuredText", |
|---|
| 69 |
"WikiRestructuredTextLinks" |
|---|
| 70 |
] |
|---|
| 71 |
|
|---|
| 72 |
def get_page_from_file (pname): |
|---|
| 73 |
d = '' |
|---|
| 74 |
try: |
|---|
| 75 |
f = open(pname ,'r') |
|---|
| 76 |
d = f.read() |
|---|
| 77 |
f.close() |
|---|
| 78 |
except: |
|---|
| 79 |
print "Missing page: %s" % pname |
|---|
| 80 |
return d |
|---|
| 81 |
|
|---|
| 82 |
def get_page_from_web (pname): |
|---|
| 83 |
host = "trac.edgewall.org" |
|---|
| 84 |
rfile = "/wiki/%s?format=txt" % pname |
|---|
| 85 |
c = httplib.HTTPConnection(host) |
|---|
| 86 |
c.request("GET", rfile) |
|---|
| 87 |
r = c.getresponse() |
|---|
| 88 |
d = r.read() |
|---|
| 89 |
if r.status != 200 or d == ("describe %s here\n" % pname): |
|---|
| 90 |
c.close() |
|---|
| 91 |
print "Missing page: %s" % pname |
|---|
| 92 |
c.close() |
|---|
| 93 |
f = open(pname, 'w+') |
|---|
| 94 |
f.write(d) |
|---|
| 95 |
f.close() |
|---|
| 96 |
return d |
|---|
| 97 |
|
|---|
| 98 |
def check_links (data): |
|---|
| 99 |
def get_refs(t, refs=[]): |
|---|
| 100 |
r = "(?P<wikilink>(^|(?<=[^A-Za-z]))[!]?[A-Z][a-z/]+(?:[A-Z][a-z/]+)+)" |
|---|
| 101 |
m = re.search (r, t) |
|---|
| 102 |
if not m: |
|---|
| 103 |
refs.sort() |
|---|
| 104 |
result = [] |
|---|
| 105 |
orf = None |
|---|
| 106 |
for rf in refs: |
|---|
| 107 |
if rf != orf: |
|---|
| 108 |
result.append(rf) |
|---|
| 109 |
orf = rf |
|---|
| 110 |
return result |
|---|
| 111 |
refs.append(m.group()) |
|---|
| 112 |
return get_refs( t[m.end():], refs) |
|---|
| 113 |
for p in data.keys(): |
|---|
| 114 |
links = get_refs(data[p], []) |
|---|
| 115 |
for l in links: |
|---|
| 116 |
if l not in data.keys(): |
|---|
| 117 |
print "Broken link: %s -> %s" % (p, l) |
|---|
| 118 |
|
|---|
| 119 |
if __name__ == '__main__': |
|---|
| 120 |
try: |
|---|
| 121 |
opts, args = getopt.getopt(sys.argv[1:], "d") |
|---|
| 122 |
except getopt.GetoptError: |
|---|
| 123 |
# print help information and exit: |
|---|
| 124 |
print "%s [-d]" % sys.argv[0] |
|---|
| 125 |
print "\t-d -- Download pages from the main project wiki." |
|---|
| 126 |
sys.exit() |
|---|
| 127 |
get_page = get_page_from_file |
|---|
| 128 |
for o,a in opts: |
|---|
| 129 |
if o == '-d': |
|---|
| 130 |
get_page = get_page_from_web |
|---|
| 131 |
data = {} |
|---|
| 132 |
for p in wiki_pages: |
|---|
| 133 |
data[p] = get_page (p) |
|---|
| 134 |
check_links(data) |
|---|
| 135 |
|
|---|