import sys import hashlib, urllib import tg, pylons from webob.exc import HTTPNotFound from bazbase import conversion, structure from bazbase.wiki import (get_overridden_element, recursive_get, NoContentException) from bazki import translators, auth from bazki.getting import (BaseGetter, get, filename_split, DEFAULT_DEFAULT, type_to_suffix) from gameki import restricted def ename_to_hash(ename): return hashlib.md5(ename).hexdigest()[:8] class ProdGetter(BaseGetter): @tg.expose() def _default(self, hash, username, name, *args): print >>sys.stderr, 'Here!' name = unicode(name, 'utf-8') if len(args) > 0: args = [unicode(a, 'utf-8') for a in args] args[-1],typ = filename_split(args[-1]) id = args[-1] else: name,typ = filename_split(name) name = name.replace('_', ' ') name = name.replace('~:', '/') id = name if name[0] == '+': pname = None #maybe_pname elm = structure.get_element(name[1:]) if ename_to_hash(elm.ename) != hash: raise HTTPNotFound((hash, name)) else: if len(args) == 1: pname = args[0] else: assert len(args) == 0, args pname = None args = [] for p in structure.search_elements({u'name': name}): if ename_to_hash(p.ename) == hash: elm = p break else: print >>sys.stderr, 'hash mismatch', ename_to_hash(p.ename), hash else: print >>sys.stderr, 'zoip' raise HTTPNotFound((hash, name)) # Check access control visible_only = restricted.OMNISCIENT_ONLY logged_in = restricted.logged_in_user() if restricted.is_omniscient(): # We're good. visible_only = None elif logged_in is None: print >>sys.stderr, 'li' raise restricted.log_in() elif username != conversion.render(logged_in, u'username'): print >>sys.stderr, 'ny' raise restricted.not_you() else: # The usernames match, but does this character have access to # this thing? # Specifically, is it in their stuff, excluding stuff that's # folded or owned by folded things? if elm in recursive_get(logged_in, u'stuff', 'exclude', folded=False): pass else: print >>sys.stderr, 'oo' raise restricted.omniscient_only() filters = {'metadata': {'pdfurl': tg.url('/prod/%s/%s/%s.pdf' % (hash, username, '%s/%s' % (name, pname) if pname else name))}, 'let': {}} # Only set owner if the element being produced is owned. if username != '_' and conversion.to_python(elm, u'owned'): owner = auth.user_by_username(username) assert owner is not None, username filters['let'][u'owner'] = owner.ename if args: for i in xrange(len(args)): filters['let'][unicode(i + 1)] = args[i] print >>sys.stderr, 'preget' return get(id, typ, elm, pname, filters, visible_only=visible_only) def get_url_for(self, element, dep, render, type=None, prefixtype='', args=None): if args is None: if dep: dep.addDep(element[u'name']) name = render(element, u'name') if not name: raise KeyError("%s has an empty name!" % element.ename) # TODO(xavid): TurboGears still doesn't handle /s right, because # dumb. Ideally, these'd get urlencoded, the args below # wouldn't, and it'll all be fine. name = name.replace('/', '~:') else: # TODO(xavid): Should be encoded in some way. # TODO(xavid): Handle name starting with + name = u"+%s/%s" % (element.ename, '/'.join(args)) name = urllib.quote(name.encode('utf-8'), '+/') if type is False: typesuffix = '' elif type is not None: typesuffix = type_to_suffix(type) if typesuffix == DEFAULT_DEFAULT and '.' not in name: typesuffix = '' else: if '.' in name: typesuffix = DEFAULT_DEFAULT else: typesuffix = '' username = '_' #if u'owner' in let: # owner = let[u'owner'] #else: if True: owner = get_overridden_element(u'owner') if owner is not None: if element != owner: if dep: dep.addPropvalDep(owner, u'username') if owner.has_propval(u'username'): username = render(owner, u'username') return translators.absolute_url(self.get_path + '/' + ename_to_hash(element.ename) + '/' + username + '/' + name + typesuffix, dep, prefixtype=prefixtype, render=render) def has_get_url(self, element, dep=None, render=conversion.render): if dep: dep.addPropvalDep(element, u'name') dep.addPropvalDep(element, u'product') try: return (render(element, u'name') and element.has_propval(u'product')) except KeyError: return False except NoContentException: return False def attachment_url_for(self, element, pname, dep, render, type, prefixtype=''): endbit = '/' + pname + type_to_suffix(type) #if self.has_get_url(element,dep,render): try: return (self.get_url_for(element,dep,render, type=False, prefixtype=prefixtype) + endbit) except KeyError: return BaseGetter.attachment_url_for(self, element, pname, dep, render, type, prefixtype=prefixtype)