Пример #1
0
	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
Пример #2
0
	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
Пример #3
0
	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
Пример #4
0
	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)
Пример #5
0
	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()
Пример #6
0
	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
Пример #7
0
	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)))
Пример #8
0
	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
Пример #9
0
	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,
		)
Пример #10
0
	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
Пример #11
0
	def count(self):
		return str(len(Link))
Пример #12
0
			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)