Index: trunk/wikiation/installer/installer_util.py |
— | — | @@ -32,15 +32,14 @@ |
33 | 33 | print "wikiation installer, interactive mode" |
34 | 34 | print "help: get help" |
35 | 35 | print "quit: quit" |
36 | | - print "ls [item]: list information on available versions " |
37 | | - print "ls2 [item]: list information on extensions or wikiation components" |
38 | | - print "install <version>: installs the version specified" |
39 | | - print "install <version> as <name>: installs the version specified under an alternate name" |
40 | | - print "install latest ; install latest as <name>: installs the latest version available in svn." |
41 | | - print "uninstall <version/name>: uninstalls the version specified" |
42 | | - print "check_isolation <version/name>: shows all changes made to mediawiki or database since it was installed." |
| 36 | + print "ls <path>: list information on available versions " |
| 37 | + print "install <path>: installs the version specified" |
| 38 | + print "install <path> as <name>: installs the version specified under an alternate name" |
| 39 | + print "uninstall <path>: uninstalls the version specified" |
| 40 | + print "check_isolation <instance name>: shows all changes made to mediawiki or database since it was installed." |
43 | 41 | print "update_self: updates the installer and restarts in interactive mode" |
44 | | - print "revision [new revision]: query current default revision, or set a new one (will be implemented over time)" |
| 42 | + print "update_tags: manually force an update of the tag cache (do this from time to time, if you're referring to things by tag)" |
| 43 | + print "TODO: Implement help path , for now, see documentation for info on how to specify <path>" |
45 | 44 | print |
46 | 45 | print "instead of interactive mode, you can also access commands directly from the shell:" |
47 | 46 | print "wikiation_installer command [args]..." |
Index: trunk/wikiation/installer/settings_handler.py |
— | — | @@ -18,12 +18,15 @@ |
19 | 19 | # where to find .install directories and the files contained therein |
20 | 20 | installfiles=os.path.join(installerdir,'installfiles') |
21 | 21 | |
| 22 | +# where do we store the _tagcache file |
| 23 | +tagcache=os.path.join(installerdir,"_tagcache") |
22 | 24 | |
23 | 25 | # where to find mediawiki tags and trunk on svn |
24 | 26 | tagsdir="http://svn.wikimedia.org/svnroot/mediawiki/tags" |
25 | 27 | trunkdir="http://svn.wikimedia.org/svnroot/mediawiki/trunk" |
26 | 28 | # we could alternately/additionally take a tag version for extensions. (future) |
27 | | -extensionsdir=trunkdir+"/extensions" |
| 29 | +extensionssubdir="extensions" |
| 30 | +extensionsdir=trunkdir+"/"+extensionssubdir |
28 | 31 | |
29 | 32 | # where to install diverse revisions |
30 | 33 | instancesdir='/var/www/revisions' |
Index: trunk/wikiation/installer/installer.py |
— | — | @@ -30,6 +30,7 @@ |
31 | 31 | from installer_util import * |
32 | 32 | from isolation import * |
33 | 33 | from getch import getch |
| 34 | +from tags import Tags |
34 | 35 | |
35 | 36 | def intro(): |
36 | 37 | """a nice banner/intro text for interactive mode""" |
— | — | @@ -138,12 +139,17 @@ |
139 | 140 | elif len(args)>=2: |
140 | 141 | print "I'm not sure what to do with "+ (" ".join(args[1:])) |
141 | 142 | |
| 143 | + os.unlink(settings.tagcache) #paranoia is good for you |
| 144 | + |
142 | 145 | print "\n\n" |
143 | 146 | print "wikiation_installer update attempted/completed. Restarting" |
144 | 147 | print "----------------------------------------------------------" |
145 | 148 | print "\n\n" |
146 | 149 | os.execl("/usr/bin/python","/usr/bin/python",__file__) |
147 | 150 | |
| 151 | +def update_tags(args): |
| 152 | + """manually force update of the tag cache""" |
| 153 | + Tags.update_cache_file() |
148 | 154 | |
149 | 155 | def main(): |
150 | 156 | """main function. start of execution when run from shell""" |
— | — | @@ -184,6 +190,7 @@ |
185 | 191 | "info":info, |
186 | 192 | "check_isolation":check_isolation, |
187 | 193 | "update_self":update_self, |
| 194 | + "update_tags":update_tags |
188 | 195 | } |
189 | 196 | |
190 | 197 | # additional help texts for some commands. |
Index: trunk/wikiation/installer/tags.py |
— | — | @@ -0,0 +1,103 @@ |
| 2 | +import sys,os |
| 3 | +import os.path |
| 4 | +import settings_handler as settings |
| 5 | +import copy |
| 6 | +import cPickle as pickle |
| 7 | +import subprocess |
| 8 | + |
| 9 | +class TagsException(Exception): |
| 10 | + pass |
| 11 | + |
| 12 | +class Tags: |
| 13 | + """keep track of extension tags in svn. |
| 14 | + the current repository is not optimised for the kinds |
| 15 | + of queries the installer needs. We do the query once |
| 16 | + and cache it.""" |
| 17 | + |
| 18 | + def __init__(self): |
| 19 | + # try to load preexisting cache |
| 20 | + self.cache=self.load_cache() |
| 21 | + # No joy? Let's generate one. |
| 22 | + if not self.cache: |
| 23 | + self.cache=self.update_cache() |
| 24 | + # Still no joy? |
| 25 | + if not self.cache: |
| 26 | + raise Exception("Internal error: cannot obtain a tag cache") |
| 27 | + |
| 28 | + @classmethod |
| 29 | + def load_cache(self): |
| 30 | + """load tags from cache""" |
| 31 | + if not os.path.isfile(settings.tagcache): |
| 32 | + return None |
| 33 | + |
| 34 | + cache=pickle.load(file(settings.tagcache)) |
| 35 | + return cache |
| 36 | + |
| 37 | + @classmethod |
| 38 | + def svnlist(self,dir): |
| 39 | + """generic obtain data from svn ls |
| 40 | + (TODO: refactor, overlaps with DownloadInstaller get_installers)""" |
| 41 | + |
| 42 | + command=['svn','ls',dir] |
| 43 | + process=subprocess.Popen(command,stdout=subprocess.PIPE, stderr=subprocess.PIPE) |
| 44 | + failp=process.stderr.read() |
| 45 | + if failp: |
| 46 | + return None |
| 47 | + l=list(process.stdout) |
| 48 | + # tidy l in place |
| 49 | + for i in range(len(l)): |
| 50 | + l[i]=l[i].strip() |
| 51 | + if l[i].endswith("/"): |
| 52 | + l[i]=l[i][:-1] |
| 53 | + return l |
| 54 | + |
| 55 | + def update_cache(self): |
| 56 | + """update cache to disk and to memory""" |
| 57 | + self.cache=self.update_cache_file() |
| 58 | + return self.cache |
| 59 | + |
| 60 | + @classmethod |
| 61 | + def update_cache_file(self): |
| 62 | + """update cache to disk. returns a cache. This is an expensive operation. |
| 63 | + (cache format is {"extension name":["tag1", "tag2", "tag3", ...]}, ...) |
| 64 | + """ |
| 65 | + print "Updating tags cache, this takes a minute or so." |
| 66 | + print "(Items marked with '*' do not seem to contain extensions)" |
| 67 | + cache={} |
| 68 | + tags=self.svnlist(settings.tagsdir) |
| 69 | + for tag in tags: |
| 70 | + sys.stdout.write(tag) |
| 71 | + sys.stdout.flush() |
| 72 | + |
| 73 | + extensions=self.svnlist(settings.tagsdir+"/"+tag+"/"+settings.extensionssubdir) |
| 74 | + if extensions==None: |
| 75 | + extensions=[] |
| 76 | + sys.stdout.write('*') |
| 77 | + sys.stdout.flush() |
| 78 | + for extension in extensions: |
| 79 | + if extension not in cache: |
| 80 | + cache[extension]=[] |
| 81 | + cache[extension].append(tag) |
| 82 | + sys.stdout.write('; ') |
| 83 | + sys.stdout.flush() |
| 84 | + |
| 85 | + #store cache to disk |
| 86 | + pickle.dump(cache, file(settings.tagcache,"w"),pickle.HIGHEST_PROTOCOL) |
| 87 | + |
| 88 | + #make empty line |
| 89 | + print |
| 90 | + print "completed." |
| 91 | + return cache |
| 92 | + |
| 93 | + def gettags(self,extension): |
| 94 | + if extension not in self.cache: |
| 95 | + raise TagsException("Could not find extension "+str(extension)+".") |
| 96 | + |
| 97 | + tags=self.cache[extension] |
| 98 | + return copy.copy(tags) |
| 99 | + |
| 100 | +if __name__=="__main__": |
| 101 | + tags=Tags() |
| 102 | + print "Imagemap: ",tags.gettags("ImageMap") |
| 103 | + print "Cite: ", tags.gettags("Cite") |
| 104 | + |
Index: trunk/wikiation/installer/installation_system.py |
— | — | @@ -6,6 +6,7 @@ |
7 | 7 | import settings_handler as settings |
8 | 8 | import os, os.path, shutil |
9 | 9 | import subprocess |
| 10 | +from tags import Tags |
10 | 11 | |
11 | 12 | |
12 | 13 | class Installer_Exception (Exception): |
— | — | @@ -45,8 +46,10 @@ |
46 | 47 | if line.endswith(".install"): |
47 | 48 | installers2.append(line.replace(".install","")) |
48 | 49 | |
| 50 | + installers2.sort() |
49 | 51 | return installers2 |
50 | 52 | |
| 53 | + # XXX This should be a mixin |
51 | 54 | def get_revisions(self,installer_name): |
52 | 55 | """list the revisions a particular installer can install""" |
53 | 56 | if not self.exists(installer_name): |
— | — | @@ -54,6 +57,7 @@ |
55 | 58 | |
56 | 59 | return self.do_get_revisions(installer_name) |
57 | 60 | |
| 61 | + # XXX this should be a mixin |
58 | 62 | def do_get_revisions(self, installer_name): |
59 | 63 | """actually perform the task of getting revisions for get_revisions |
60 | 64 | First checks to see if someone has provided a script to determine |
— | — | @@ -66,6 +70,12 @@ |
67 | 71 | |
68 | 72 | return None |
69 | 73 | |
| 74 | + # XXX should be a mixin |
| 75 | + def get_tags(self, installer_name): |
| 76 | + """get list of tags available for this installer.""" |
| 77 | + return Tags().gettags(installer_name) |
| 78 | + |
| 79 | + |
70 | 80 | def get_svnbase(): |
71 | 81 | return None |
72 | 82 | |
Index: trunk/wikiation/installer/installers.py |
— | — | @@ -20,6 +20,8 @@ |
21 | 21 | from installation_system import Installer_Exception |
22 | 22 | from download_installer import Download_Installer |
23 | 23 | |
| 24 | +from tags import Tags, TagsException |
| 25 | + |
24 | 26 | class Parse_Exception(Exception): |
25 | 27 | pass |
26 | 28 | |
— | — | @@ -110,10 +112,17 @@ |
111 | 113 | |
112 | 114 | |
113 | 115 | def ls_tags(ppath): |
114 | | - print "To be implemented." |
| 116 | + if not ppath["installer"]: |
| 117 | + raise Listing_Exception("What extension would you like to know the available revisions for?") |
115 | 118 | |
| 119 | + system=get_system(ppath["system"]) |
| 120 | + try: |
| 121 | + tags=system.get_tags(ppath["installer"]) |
| 122 | + except TagsException, e: |
| 123 | + raise Listing_Exception(e.message) |
| 124 | + |
| 125 | + return tags |
116 | 126 | |
117 | | - |
118 | 127 | def info(args): |
119 | 128 | if len(args)<1: |
120 | 129 | print "info: Internal error: expected more arguments" |
— | — | @@ -331,8 +340,11 @@ |
332 | 341 | |
333 | 342 | return sYstem() |
334 | 343 | |
| 344 | +# Constants |
| 345 | + |
335 | 346 | systems={'wikiation_toolkit':Toolkit_Installer,'extension': Extension_Installer, 'mediawiki':Mediawiki_Installer,'naive': Naive_Installer, 'download':Download_Installer} |
336 | 347 | |
| 348 | + |
337 | 349 | if __name__=="__main__": |
338 | 350 | print "testing installers.py module" |
339 | 351 | print "CTRL-C to abort. run installer.py to actually use the installer" |