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