]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/blob - src/allmydata/scripts/common.py
add option to show version and path to the tahoe executable
[tahoe-lafs/tahoe-lafs.git] / src / allmydata / scripts / common.py
1
2 import os, sys, urllib
3 from twisted.python import usage
4
5
6 class BaseOptions:
7     # unit tests can override these to point at StringIO instances
8     stdin = sys.stdin
9     stdout = sys.stdout
10     stderr = sys.stderr
11
12     optFlags = [
13         ["quiet", "q", "Operate silently."],
14         ["version", "V", "Display version numbers and exit."],
15         ["version-and-path", "v", "Display version numbers and paths to their locations and exit."],
16         ]
17
18     def opt_version(self):
19         import allmydata
20         print allmydata.get_package_versions_string()
21         sys.exit(0)
22
23     def opt_version_and_path(self):
24         import allmydata
25         print allmydata.get_package_versions_string(show_paths=True)
26         sys.exit(0)
27
28
29 class BasedirMixin:
30     optFlags = [
31         ["multiple", "m", "allow multiple basedirs to be specified at once"],
32         ]
33
34     def postOptions(self):
35         if not self.basedirs:
36             raise usage.UsageError("<basedir> parameter is required")
37         if self['basedir']:
38             del self['basedir']
39         self['basedirs'] = [os.path.abspath(os.path.expanduser(b))
40                             for b in self.basedirs]
41
42     def parseArgs(self, *args):
43         self.basedirs = []
44         if self['basedir']:
45             self.basedirs.append(self['basedir'])
46         if self['multiple']:
47             self.basedirs.extend(args)
48         else:
49             if len(args) == 0 and not self.basedirs:
50                 if sys.platform == 'win32':
51                     from allmydata.windows import registry
52                     self.basedirs.append(registry.get_base_dir_path())
53                 else:
54                     self.basedirs.append(os.path.expanduser("~/.tahoe"))
55             if len(args) > 0:
56                 self.basedirs.append(args[0])
57             if len(args) > 1:
58                 raise usage.UsageError("I wasn't expecting so many arguments")
59
60 class NoDefaultBasedirMixin(BasedirMixin):
61     def parseArgs(self, *args):
62         # create-client won't default to --basedir=~/.tahoe
63         self.basedirs = []
64         if self['basedir']:
65             self.basedirs.append(self['basedir'])
66         if self['multiple']:
67             self.basedirs.extend(args)
68         else:
69             if len(args) > 0:
70                 self.basedirs.append(args[0])
71             if len(args) > 1:
72                 raise usage.UsageError("I wasn't expecting so many arguments")
73         if not self.basedirs:
74             raise usage.UsageError("--basedir must be provided")
75
76 DEFAULT_ALIAS = "tahoe"
77
78
79 def get_aliases(nodedir):
80     from allmydata import uri
81     aliases = {}
82     aliasfile = os.path.join(nodedir, "private", "aliases")
83     rootfile = os.path.join(nodedir, "private", "root_dir.cap")
84     try:
85         f = open(rootfile, "r")
86         rootcap = f.read().strip()
87         if rootcap:
88             aliases["tahoe"] = uri.from_string_dirnode(rootcap).to_string()
89     except EnvironmentError:
90         pass
91     try:
92         f = open(aliasfile, "r")
93         for line in f.readlines():
94             line = line.strip()
95             if line.startswith("#") or not line:
96                 continue
97             name, cap = line.split(":", 1)
98             # normalize it: remove http: prefix, urldecode
99             cap = cap.strip()
100             aliases[name] = uri.from_string_dirnode(cap).to_string()
101     except EnvironmentError:
102         pass
103     return aliases
104
105 class DefaultAliasMarker:
106     pass
107
108 def get_alias(aliases, path, default):
109     # transform "work:path/filename" into (aliases["work"], "path/filename").
110     # If default=None, then an empty alias is indicated by returning
111     # DefaultAliasMarker. We special-case "URI:" to make it easy to access
112     # specific files/directories by their read-cap.
113     path = path.strip()
114     if path.startswith("URI:"):
115         # The only way to get a sub-path is to use URI:blah:./foo, and we
116         # strip out the :./ sequence.
117         sep = path.find(":./")
118         if sep != -1:
119             return path[:sep], path[sep+3:]
120         return path, ""
121     colon = path.find(":")
122     if colon == -1:
123         # no alias
124         if default == None:
125             return DefaultAliasMarker, path
126         return aliases[default], path
127     alias = path[:colon]
128     if "/" in alias:
129         # no alias, but there's a colon in a dirname/filename, like
130         # "foo/bar:7"
131         if default == None:
132             return DefaultAliasMarker, path
133         return aliases[default], path
134     return aliases[alias], path[colon+1:]
135
136 def escape_path(path):
137     segments = path.split("/")
138     return "/".join([urllib.quote(s) for s in segments])