Package gavo :: Package svcs :: Module vanity
[frames] | no frames]

Source Code for Module gavo.svcs.vanity

  1  """ 
  2  Parsing and maintaining URL shortcuts. 
  3  """ 
  4   
  5  #c Copyright 2008-2019, the GAVO project 
  6  #c 
  7  #c This program is free software, covered by the GNU GPL.  See the 
  8  #c COPYING file in the source distribution. 
  9   
 10   
 11  import os 
 12   
 13  from gavo import base 
 14  from gavo import utils 
 15   
 16   
17 -class VanityLineError(base.Error):
18 """parse error in vanity file. 19 """
20 - def __init__(self, msg, lineNo, src):
21 base.Error.__init__(msg) 22 self.msg, self.lineNo, self.src = msg, lineNo, src
23
24 - def __str__(self):
25 return "Mapping file %s, line %d: %s"%( 26 repr(self.src), self.msg, self.lineNo)
27 28 29 BUILTIN_VANITY = """ 30 __system__/products/p/get getproduct 31 __system__/products/p/dlasync datalinkuws 32 __system__/services/registry/pubreg.xml oai.xml 33 __system__/services/overview/external odoc 34 __system__/dc_tables/show/tablenote tablenote 35 __system__/dc_tables/show/tableinfo tableinfo 36 __system__/services/overview/admin seffe 37 __system__/services/overview/rdinfo browse 38 __system__/tap/run/tap tap 39 __system__/adql/query/form adql !redirect 40 __system__/run/genrd genrd 41 """ 42 43
44 -class _VanityMap(object):
45 """a map of short resource paths to longer resource paths. 46 47 This is only used as singleton through getVanityMap. 48 49 There are two mappings: shortToLong, going from vanityName to 50 (fullPath,flags), and longToShort, mapping fullPath -> vanityName. 51 52 flags, in both cases, is a frozenset of flags. The only one defined 53 at this point is "!redirect". 54 """ 55 knownVanityOptions = set(["!redirect"]) 56
57 - def __init__(self):
58 self.shortToLong = {} 59 self.longToShort = {}
60
61 - def _parseVanityLines(self, src):
62 lineNo = 0 63 for ln in src: 64 lineNo += 1 65 ln = ln.strip() 66 if not ln or ln.startswith("#"): 67 continue 68 69 parts = ln.split() 70 if not 1<len(parts)<4: 71 raise VanityLineError("Wrong number of words in '%s'"%ln, lineNo, src) 72 73 options = [] 74 if len(parts)>2: 75 options.append(parts.pop()) 76 if options[-1] not in self.knownVanityOptions: 77 raise VanityLineError("Bad option '%s'"%options[-1], lineNo, src) 78 dest, src = parts 79 yield src, dest, frozenset(options)
80
81 - def _buildDicts(self, triples):
82 """builds the child mappings from triples as yielded by _parseVanityLines. 83 """ 84 for short, long, flags in triples: 85 self.shortToLong[short] = (long, flags) 86 self.longToShort[long] = short
87
88 - def addFromString(self, s):
89 """adds vanity mappings from a string literal. 90 """ 91 self._buildDicts( 92 self._parseVanityLines(s.split("\n")))
93
94 - def addFromFile(self, f):
95 """adds vanity mappings from an open file. 96 """ 97 self._buildDicts( 98 self._parseVanityLines(f))
99 100
101 -def _loadVanityMap():
102 """helps getVanityMap. 103 """ 104 vm = _VanityMap() 105 vm.addFromString(BUILTIN_VANITY) 106 107 fSrc = os.path.join(base.getConfig("configDir"), "vanitynames.txt") 108 if os.path.exists(fSrc): 109 with open(fSrc) as f: 110 vm.addFromFile(f) 111 112 return vm
113 114
115 -def getVanityMap():
116 """returns "the" vanity map on this data center. 117 118 It consists of built-in vanity (without which things like product 119 delivery would actually break) and things read from etc/vanitynames.txt. 120 121 The input file format is documented in the DaCHS tutorial (The Vanity Map). 122 """ 123 try: 124 anchorRD = base.resolveCrossId("//services") 125 except AttributeError: 126 # We're somewhere where we don't already have rscdesc loaded. 127 # Let's assume that means the VanityMap will not need to be reloaded 128 # during the runtime, and it's ok if we anchor on the funcition. 129 anchorRD = getVanityMap 130 131 return utils.memoizeOn( 132 anchorRD, 133 _VanityMap, 134 _loadVanityMap)
135