def _binary(self, field, request, id, content): link = list(filter(lambda x: x.id == id, Link)) if len(link) == 0: return routing.HTTP_404() link = link[0] if request.method == 'PUT': setattr(link, field, content.read()) link.save() return None elif request.method == 'DELETE': setattr(link, field, None) link.save() return None # GET data = getattr(link, field) if data is None: return routing.HTTP_204() import magic m = magic.open(magic.MAGIC_MIME) m.load() mime = m.buffer(data) m.close() if mime is not None and len(mime) > 0: request.setHeader('Content-Type', mime.split(';')[0]) request.write(str(getattr(link, field))) request.finish() return server.NOT_DONE_YET
def POST(self, *args, **kwargs): """ if id is set, we edit corresponding link, else we create new one """ if 'id' in kwargs: #link = filter(lambda x: x.id == int(kwargs['id']), Link) lid = int(kwargs['id']) link = list(filter(lambda x: x.id == lid, Link)) if len(link) == 0: return routing.HTTP_400("'%s' id not found" % kwargs['id']) link = link[0] else: link = Link() errors = {} # simple fields for name, mandatory in {'link': True, 'name': True, 'description': False}.iteritems(): #NOTE: mandatory fields must be non-null (or empty size) # others can be unset or empty if mandatory and (name not in kwargs or len(kwargs[name])) == 0: errors[name] = (10, 'field required'); continue elif name not in kwargs: continue try: value = link.fieldesc(name).cast(kwargs[name]) except ValueError: errors[name] = (11, 'invalid type'); continue setattr(link, name, value) # test link is unique #TODO: must be done at ORM level (with save() method) _link = link.link if 'name' not in errors and not link.saved() and\ len(filter(lambda x: x.link == _link, Link)) > 0: errors['link'] = (13, 'not unique') # relational field: tags. we get tag names as input... tagnames = kwargs['tags'] # tentacles workaroung if len(tagnames) == 0: errors['tags'] = (12, 'at least one value required') else: tags = list(filter(lambda t: t.name in tagnames, Tag)) newtags = [Tag(name=name) for name in tagnames if name not in [t.name for t in tags]] for t in link.tags: tags.remove(t) if t in tags else link.tags.remove(t) for t in set(tags).union(newtags): link.tags.append(t) if len(errors) > 0: return routing.HTTP_409(errors), link link.save() return routing.HTTP_200(link.id), link
def PUT(self, content): if 'link' not in content or 'name' not in content: return routing.HTTP_400("link, name are mandatory keys") if 'id' in content and len(filter(lambda x: x.id == content['id'], Link)) > 0: return routing.HTTP_400("id already exists") if len(filter(lambda x: x.link == content['link'], Link)) > 0: return routing.HTTP_400("link must be unique") link = Link() for key, value in content.iteritems(): if key == 'tags': continue if not key in link.__fields__: return routing.HTTP_409("unknown field '%s'" % key) setattr(link, key, value) """We query all tags (by tagname), and create new ones""" if 'tags' in content: link.tags = list(filter(lambda t: t.name in content['tags'], Tag)) link.tags.extend([Tag(name=t) for t in content['tags'] if t not in [tag.name for tag in link.tags]]) link.save() return link.id
def DELETE(self, id): """ NOTE: associated tags, even if specially created for this link, are not deleted """ tags = list(filter(lambda x: x.id == id, Tag)) if len(tags) == 0: return (404, "not found") elif len(tags) > 1: return (500, "return several tags for the same id") tags[0].delete() return (200, True)
def DELETE(self, id): """ NOTE: associated tags, even if specially created for this link, are not deleted """ links = list(filter(lambda x: x.id == id, Link)) if len(links) == 0: return routing.HTTP_404("not found") elif len(links) > 1: return routing.HTTP_500("return several links for the same id") links[0].delete() return routing.HTTP_200()
def PUT(self, content): if 'name' not in content: return (400, "*name* key is mandatory") if 'id' in content and len(filter(lambda x: x.id == content['id'], Tag)) > 0: return (400, "id already exists") if len(filter(lambda x: x.link == content['name'], Tag)) > 0: return (400, "name must be unique") tag = Tag() for key, value in content.iteritems(): if not key in tag.__fields__: return(409, "unknown field '%s'" % key) setattr(tag, key, value) tag.save() return tag.id
def bytag(self, tagname): #short query form is not available for now #res = list(filter(lambda x: tagname in [name for tag in x.tags], Link)) tags = list(filter(lambda l: l.name == tagname, Tag)) if len(tags) == 0: return routing.HTTP_404() tag0 = tags[0] return list(map(lambda l: l.id, filter(lambda l: tag0 in l.tags, Link)))
def GET(self, id, **kwargs): tag = list(filter(lambda x: x.id == id, Tag)) if len(tag) == 0: return (404, None) tag = tag[0] res = {} for name, fld in tag.__fields__.iteritems(): if isinstance(fld, Reference): continue res[name] = getattr(tag, name) return res
def html_POST(self, __callback__, __referer__, **kwargs): # cleanup POST args if kwargs.get('link', None) == 'Enter/Paste your url': del kwargs['link'] if kwargs.get('name', None) == 'Enter/Paste url name': del kwargs['name'] # remove duplicate values, create list if tags was a single value kwargs['tags'] = list(set(kwargs.get('tags',[]))) for dft in ('', 'nop', 'or enter new one(s)'): try: kwargs['tags'].remove(dft) except: pass if kwargs.get('description', None) == 'Enter your description here': del kwargs['description'] # generic callback ret, link = __callback__(**kwargs) """Handle HTTP routing depending of POST returned values 4XX: redisplay edit page with error 200: redirect to referer """ #if ret.code == routing.HTTP_200: if isinstance(ret, routing.HTTP_200): import strawberry return routing.Redirect(kwargs['referer'] if len(kwargs.get('referer','')) > 0 else strawberry) # errors: we redisplay the form #return url(strawberry.Link, id=values['id']) if 'id' in values else url(strawberry.Link) if 'id' not in kwargs: return ret # redisplay page from mother.template import Template from tentacles.queryset import BaseQuerySet return Template('addoredit.html', title='Edit ☄ '+link.name, tags=list(BaseQuerySet(Tag)), values=kwargs, mode='edit', referer=kwargs.get('referer', ''), errors=ret.msg, )
def GET(self, id, __referer__=None, **kwargs): link = list(filter(lambda x: x.id == id, Link)) if len(link) == 0: return routing.HTTP_404("%s link not found" % id) link = link[0] res = {} for name, fld in link.__fields__.iteritems(): if isinstance(fld, Reference): continue res[name] = getattr(link, name) #TODO: should be done in a generic way # the best way should probably be to have a tentacles json backend # For that, we need to be able to switch backend for an object # JSON encoder should also understand datetime object if isinstance(fld, Datetime) and res[name] is not None: res[name] = str(res[name]) res['tags'] = dict([(t.name, None) for t in link.tags]) return res
def count(self): return str(len(Link))
f = urllib2.urlopen(req) except urllib2.HTTPError, e: return getattr(routing, 'HTTP_'+str(e.code)) except urllib2.URLError, e: return routing.HTTP_503 except ValueError: return routing.HTTP_400 tree = soup(f.read()) # we get interesting datas to return infos = {'title': tree.html.head.title.string.strip()} for meta in ('description', 'keywords'): value = tree.html.head.findAll('meta', attrs={'name': meta}) if len(value) > 0: infos[meta] = value[0]['content'] if 'keywords' in infos: infos['keywords'] = [i.strip() for i in infos['keywords'].split(',')] # icon # <link rel="icon" href="/chrome/common/trac.ico" type="image/x-icon" /> icon = [l['href'] for l in tree.html.head.findAll('link') if l['rel'].lower() in ('icon', 'shortcut icon')] if len(icon) > 0: icon = icon[0] _icon = urlparse.urlsplit(icon) if _icon.scheme == '': # relative url icon = urlparse.urljoin(url, icon)