Permalink
Browse files

changes to work with new version of scarecrow

  • Loading branch information...
1 parent ebb611b commit da54ca5b94beb32ca98c0bb9005e19bd671c107e @ysimonson ysimonson committed Nov 23, 2009
View
2 setup.py
@@ -70,6 +70,6 @@ def add_test_users(db):
"""Adds the users that are used in the test cases to the database"""
for account in SAMPLE_DATA_ACCOUNTS:
- model.create_user(db, account, 'sandbox')
+ model.create_account(db, account, 'sandbox')
if __name__ == '__main__': main()
View
3 shared/cache.py
@@ -120,7 +120,8 @@ def __init__(self, db, count):
def __getitem__(self, obj):
#Try to get the item from the cache first
- if obj in self: return LRU.__getitem__(self, obj)
+ if obj in self:
+ return LRU.__getitem__(self, obj)
#Pull the item from the database otherwise
value = self.db[obj]
View
49 shared/model/__init__.py
@@ -14,10 +14,7 @@
# You should have received a copy of the GNU Affero General Public License
# along with Snowball. If not, see <http://www.gnu.org/licenses/>.
-import hashlib, os
-
-import sys
-sys.path.append('../../lib/Scarecrow')
+import hashlib, os, scarecrow
SALT = '4815162342>'
@@ -65,28 +62,44 @@ def __init__(self, id, type):
self.id = id
self.type = type
-def create_user(db, name, password):
+def create_account(db, name, password):
+ """Creates a new account with the given name and password"""
+
+ ident = scarecrow.ident(account_key(name))
+ if ident in db: return False
+
account = Entity(name, 'account')
account.password_hash = account_pass(password)
- db[account_key(name)] = account
+ db[ident] = account
+ return True
-def auth_user(db, name, password):
- account = db[account_key(name)]
+def delete_account(db, name):
+ """Deletes a given account"""
- if not account: return False
- return account['password_hash'] == account_pass(password)
+ try:
+ del db[name]
+ return True
+ except KeyError:
+ return False
-def key(value):
- return hashlib.md5(value).digest()
+def auth_account(db, name, password):
+ try:
+ db[account_key(name)]
+ return account['password_hash'] == account_pass(password)
+ except KeyError:
+ return False
-def node_key(uri):
- return key('node:' + uri)
+def node_key(name):
+ return 'node:' + name
-def rec_key(uri):
- return key('rec:' + uri)
+def rec_key(name):
+ return 'rec:' + name
def account_key(name):
- return key('account:' + name)
+ return 'account:' + name
+
+def settings_key():
+ return 'settings'
def account_pass(pw):
- return key(SALT + pw)
+ return hashlib.md5(SALT + pw).digest()
View
29 shared/model/mysql.py
@@ -14,7 +14,7 @@
# You should have received a copy of the GNU Affero General Public License
# along with Snowball. If not, see <http://www.gnu.org/licenses/>.
-import model, pickle
+import model, pickle, scarecrow
from scarecrow import mysql
class MysqlLinksIndex(object):
@@ -33,15 +33,18 @@ def install(self, db):
def map(self, db, obj_id, obj):
if 'links' in obj and 'type' in obj and obj['type'] == 'node':
for link_uri in obj.links:
- link_hash = model.node_key(link_uri)
+ link_hash = scarecrow.ident(model.node_key(link_uri))
link_obj = self.model[link_hash]
if link_obj == None: continue
- link_owner = model.account_key(link_obj.owner)
+ link_owner = scarecrow.ident(model.account_key(link_obj.owner))
db.execute("INSERT INTO " + self.name + " VALUES (%s, %s, %s)", obj_id, link_hash, link_owner)
def get(self, db, to_link, owner=None):
+ to_link = scarecrow.ident(to_link)
+ if owner: owner = scarecrow.ident(owner)
+
query = "SELECT body FROM entities JOIN %s ON entities.id=%s.entity_id WHERE to_link=%s" % (self.name, self.name, '%s')
if owner:
@@ -50,12 +53,16 @@ def get(self, db, to_link, owner=None):
else:
results = db.query(query, to_link)
- if results == None: return
+ if results == None:
+ return
for row in results:
yield pickle.loads(row.body)
def get_ids(self, db, to_link, owner=None):
+ to_link = scarecrow.ident(to_link)
+ if owner: owner = scarecrow.ident(owner)
+
query = "SELECT entity_id FROM entities JOIN %s ON entities.id=%s.entity_id WHERE to_link=%s" % (self.name, self.name, '%s')
if owner:
@@ -64,17 +71,21 @@ def get_ids(self, db, to_link, owner=None):
else:
results = db.query(query, to_link)
- if results == None: return
+ if results == None:
+ return
for row in results:
- yield row.entity_id
+ yield scarecrow.ScarecrowIdent(row.entity_id)
def random(self, db, seed='', count=1):
- if seed != '': int(seed)
- int(count)
+ if seed != '':
+ assert isinstance(seed, int)
+
+ assert isinstance(count, int)
results = db.query("SELECT entity_id, to_link FROM %s ORDER BY RAND(%s) LIMIT %s" % (self.name, seed, count))
- for row in results: yield row.entity_id, row.to_link
+ for row in results:
+ yield scarecrow.ScarecrowIdent(row.entity_id), scarerow.ScarecrowIdent(row.to_link)
def db(host, dbname, user, password):
links_index = MysqlLinksIndex('links_index')
View
7 shared/settings_parser.py
@@ -27,15 +27,18 @@ def __init__(self, raw_args, usage):
for arg in raw_args[1:]:
if arg.startswith('-'):
- if opt is not None: self.opts.append((opt, val))
+ if opt is not None:
+ self.opts.append((opt, val))
+
opt = arg[1:]
val = None
elif opt is not None and val is None:
val = arg
else:
self.args.append(arg)
- if opt is not None: self.opts.append((opt, val))
+ if opt is not None:
+ self.opts.append((opt, val))
def show_usage(self):
print self.usage
View
4 tests/recommendations/testrec.py
@@ -45,7 +45,9 @@ def main():
from_node = db[from_hash]
to_node = db[to_hash]
- if not to_node.id in from_node.links: continue
+ if not to_node.id in from_node.links:
+ continue
+
link = from_node.links[to_node.id]
del from_node.links[to_node.id]
db[from_hash] = from_node
View
12 util/trainer.py
@@ -26,11 +26,15 @@ def main():
timeout = parser.get('timeout', '5', int)
db = settings_parser.acquire_model(parser)
- if not server.startswith('http://'): server = 'http://' + server
- if server.endswith('/'): server = server[:len(server) - 1]
- if options.timeout > 0: socket.timeout = options.timeout
+ if not server.startswith('http://'):
+ server = 'http://' + server
+ if server.endswith('/'):
+ server = server[:len(server) - 1]
+ if options.timeout > 0:
+ socket.timeout = options.timeout
- successful = failed = 0
+ successful = 0
+ failed = 0
http = httplib2.Http()
for node in db.index('type_index', 'get', 'node'):
View
8 web/admin/accounts.html
@@ -17,11 +17,7 @@
-->
{% include header.html %}
-<p>
- URI:
- <input id="nodeURI" type="text" />
- <a href="javascript:getNode()" class="button">query &raquo;</a>
-</p>
-<p id="nodeResults"></p>
+
+
{% include footer.html %}
View
28 web/admin/admin.py
@@ -18,6 +18,7 @@
from web import util
from web.serialization import *
from oz.handler import *
+import model
REALM = 'Administrator Control Panel'
@@ -37,4 +38,29 @@ def get(self, path):
elif path == '/recommendations':
self.render('recommendations.html', page='recommendations')
elif path == '/accounts':
- self.render('accounts.html', page='accounts')
+ self.render('accounts.html', page='accounts')
+ else:
+ raise web.HTTPError(404, 'not found')
+
+ @basic_auth(REALM, admin_auth)
+ def put(self, path):
+ if path.startswith('/controller/accounts/'):
+ name = path[21:]
+ password = self.get_argument('password')
+
+ if not model.create_account(self.db, name, password):
+ raise web.HTTPError(409, 'account already exists')
+
+ else:
+ raise web.HTTPError(404, 'not found')
+
+ @basic_auth(REALM, admin_auth)
+ def delete(self, path):
+ if path.startswith('/controller/accounts/'):
+ name = path[21:]
+
+ if not model.delete_account(self.db, name):
+ raise web.HTTPError(404, 'could not find account')
+
+ else:
+ raise web.HTTPError(404, 'not found')
View
14 web/engine.py
@@ -58,7 +58,8 @@ def similarity(node_store, first, second):
numerator = (mul_sum - first_sum * second_sum / len(links))
divisor = sqrt(first_divisor * second_divisor)
- if divisor == 0.0: return 0.0
+ if divisor == 0.0:
+ return 0.0
return numerator / divisor
def bridging(node_store, node):
@@ -108,9 +109,9 @@ def recommendation(node_store, from_node, to_node, settings):
def recommendations(node_store, node, tags, settings):
"""Gets the recommendations for a given node"""
- max_nodes = int(settings['recommendations']['max_nodes'])
- max_visit = int(settings['recommendations']['max_visit'])
- min_threshold = float(settings['recommendations']['min_threshold'])
+ max_nodes = settings['recommendations']['max_nodes']
+ max_visit = settings['recommendations']['max_visit']
+ min_threshold = settings['recommendations']['min_threshold']
recommended = []
@@ -119,7 +120,8 @@ def recommendations(node_store, node, tags, settings):
to_node = node_store[model.node_key(candidate_uri)]
#Skip the candidate if it doesn't have any of the requested tags
- if not has_any_tag(to_node, tags): continue
+ if not has_any_tag(to_node, tags):
+ continue
#Get the recommendation score between the two nodes and add it to the
#list if it is high enough
@@ -155,7 +157,7 @@ def candidates(node_store, root, max_visit):
for a given node. It is a list of sub-lists, where each sub-list contains
the uri and resized weight.
"""
- owner = model.account_key(root.owner)
+ owner = scarecrow.ident(model.account_key(root.owner))
candidates = {}
#Store a list of already visited links so we don't revisit them
View
18 web/serialization.py
@@ -78,11 +78,13 @@ def _flatten(obj):
for key in dir(obj):
#Ignore 'private' attributes that start with an underscore
- if key.startswith('_'): continue
+ if key.startswith('_'):
+ continue
#Do not add functions to the filtered dict
value = getattr(obj, key)
- if type(value) is types.FunctionType: continue
+ if type(value) is types.FunctionType:
+ continue
new_obj[key] = _flatten(value)
@@ -97,11 +99,13 @@ def serialize(request, obj, finish=True):
#Get the format if it was explicitly specified by the client
format = request.get_argument('format', None)
- if format == None: format = default_format
+ if format == None:
+ format = default_format
#Get the serializer method for the format
serializer = SERIALIZERS.get(format, None)
- if serializer == None: serializer = SERIALIZERS[default_format]
+ if serializer == None:
+ serializer = SERIALIZERS[default_format]
#If it's an error, change the object to fit a standard error message schema
if isinstance(obj, web.HTTPError):
@@ -134,8 +138,10 @@ def _to_xml_item(root, obj):
if isinstance(obj, objdict):
#Type and id attributes are special; handle them as such
- if 'type' in obj: root.tag = obj['type']
- if 'id' in obj: root.set('id', obj['id'])
+ if 'type' in obj:
+ root.tag = obj['type']
+ if 'id' in obj:
+ root.set('id', obj['id'])
for key in obj:
if key != 'id' and key != 'type':
View
44 web/util.py
@@ -13,24 +13,22 @@
#
# You should have received a copy of the GNU Affero General Public License
# along with Snowball. If not, see <http://www.gnu.org/licenses/>.
-from tornado import web
-
-import re, iso8601, ConfigParser, urllib
+import re, iso8601, ConfigParser, urllib, model, scarecrow
from datetime import datetime
-import model
+from tornado import web
from web.serialization import *
-
from oz.handler import *
REALM = 'Snowball'
def auth(req, realm, name, password):
"""Authenticates the given credentials"""
- if realm != REALM: return False
+ if realm != REALM:
+ return False
db = req.application.settings['db']
- return model.auth_user(db, name, password)
+ return model.auth_account(db, name, password)
def assert_string(name, value, max_length):
"""
@@ -47,7 +45,9 @@ def check_tags(tag_arg):
tags
"""
- if tag_arg == None: return None
+ if tag_arg == None:
+ return None
+
tags = tag_arg.split()
for tag in tags:
@@ -65,7 +65,8 @@ def check_datetime(datetime_arg):
object
"""
- if datetime_arg == None: return None
+ if datetime_arg == None:
+ return None
try:
return iso8601.parse_date(datetime_arg)
@@ -79,7 +80,8 @@ def assert_direction(direction):
def check_weight(weight):
"""Ensures that a given argument is a valid weight, i.e. a float >= -1 and <= 1"""
try:
- if weight == None: return weight
+ if weight == None:
+ return weight
try:
weight = float(weight)
@@ -110,23 +112,23 @@ def get_dynamic_setting(db, name):
Gets a setting that can be altered dynamically by Snowball (i.e. a non-user
defined setting)
"""
- settings = db[model.key('settings')]
-
- if settings is None or not name in settings:
+ try:
+ settings = db[model.settings_key()]
+ return settings[name]
+ except KeyError:
return None
- else:
- return settings.name
def save_dynamic_setting(db, name, value):
"""Sets a dynamic setting (i.e. a non-user defined setting)"""
- settings_key = model.key('settings')
+ settings_ident = scarecrow.ident(model.settings_key())
- settings = db[settings_key]
- if settings is None: settings = model.Storage()
-
- settings.name = value
+ try:
+ settings = db[settings_ident]
+ except KeyError:
+ settings = model.Storage()
- db[settings_key] = settings
+ settings[name] = value
+ db[settings_ident] = settings
class SnowballHandler(OzHandler):
""""
View
112 web/view/links.py
@@ -19,7 +19,7 @@
from tornado import web
from oz.handler import *
-import model
+import model, scarecrow
from web import *
from web import util
@@ -30,41 +30,54 @@ class LinkHandler(util.SnowballHandler):
@util.error_handler
def get(self, from_node, to_node):
- #Return a not found if the node doesn't exist
- node = self.db[model.node_key(from_node)]
- if not node: raise web.HTTPError(404, 'could not find node')
+ try:
+ node = self.db[model.node_key(from_node)]
+ except KeyError:
+ #Return a not found if the node doesn't exist
+ raise web.HTTPError(404, 'could not find node')
- #Return a not found if the link doesn't exist
- link = node.links.get(to_node, None)
- if not link: raise web.HTTPError(404, 'could not find link')
+ try:
+ link = node.links[to_node]
+ except KeyError:
+ #Return a not found if the link doesn't exist
+ raise web.HTTPError(404, 'could not find link')
serialize(self, link)
@basic_auth(util.REALM, util.auth)
@util.error_handler
def put(self, from_node, to_node):
- from_hash = model.node_key(from_node)
- to_hash = model.node_key(to_node)
+ from_hash = scarecrow.ident(model.node_key(from_node))
+ to_hash = scarecrow.ident(model.node_key(to_node))
weight = util.check_weight(self.get_argument('weight', None))
tags = util.check_tags(self.get_argument('tags', None))
- node = self.db[from_hash]
-
- #Return a not found if the node doesn't exist
- if not node or not self.db[to_hash]: raise web.HTTPError(404, 'could not find to node')
+ try:
+ node = self.db[from_hash]
+ except KeyError:
+ #Return a not found if the node doesn't exist
+ raise web.HTTPError(404, 'could not find from node')
+
+ if not to_hash in db:
+ #Return a not found if the node doesn't exist
+ raise web.HTTPError(404, 'could not find to node')
#Return a forbidden if the current user doesn't own the node
- if node.owner != self.current_user: raise web.HTTPError(403, 'you do not own the from node')
+ if node.owner != self.current_user:
+ raise web.HTTPError(403, 'you do not own the from node')
if to_node in node.links:
#Update the link if it already exists
link = node.links[to_node]
- if weight != None: link.weight = weight
- if tags: link.tags = tags
+ if weight != None:
+ link.weight = weight
+ if tags:
+ link.tags = tags
else:
#Require the weight parameter if the link doesn't exist yet
- if weight == None: raise web.HTTPError(400, "requires 'weight' parameter")
+ if weight == None:
+ raise web.HTTPError(400, "requires 'weight' parameter")
#Create a new link if it doesn't exist yet
link = model.Storage()
@@ -80,14 +93,17 @@ def put(self, from_node, to_node):
@basic_auth(util.REALM, util.auth)
@util.error_handler
def delete(self, from_node, to_node):
- from_hash = model.node_key(from_node)
- node = self.db[from_hash]
+ from_hash = scarecrow.ident(model.node_key(from_node))
- #Return a not found if the node doesn't exist
- if not node: raise web.HTTPError(404, 'could not find node')
+ try:
+ node = self.db[from_hash]
+ except KeyError:
+ #Return a not found if the node doesn't exist
+ raise web.HTTPError(404, 'could not find node')
#Return a forbidden if the current user doesn't own the node
- if node.owner != self.current_user: raise web.HTTPError(403, 'you do not own the from node')
+ if node.owner != self.current_user:
+ raise web.HTTPError(403, 'you do not own the from node')
if to_node in node.links:
del node.links[to_node]
@@ -100,31 +116,34 @@ def delete(self, from_node, to_node):
class LinkSetHandler(util.SnowballHandler):
@util.error_handler
def get_from(self, uri):
- node = self.db[model.node_key(uri)]
-
- #Return a not found if the node doesn't exist
- if not node: raise web.HTTPError(404, 'could not find node')
+ try:
+ node = self.db[model.node_key(uri)]
+ except KeyError:
+ #Return a not found if the node doesn't exist
+ raise web.HTTPError(404, 'could not find node')
serialize(self, node.links)
@util.error_handler
def get_to(self, uri):
- hash = model.node_key(uri)
+ hash = scarecrow.ident(model.node_key(uri))
nodes = self.db.index('links_index', 'get', hash)
links = {}
#Iterate through all the linked nodes and ensure the link still exists
#since the index could be stale
for node in nodes:
- link = node.links.get(uri, None)
- if link: links[node.id] = link
+ try:
+ link = node.links[uri]
+ links[node.id] = link
+ except:
+ pass
#If there were no results, check to see that the node exists; if not,
#return a not found
- if len(links) == 0:
- node = self.db[hash]
- if not node: raise web.HTTPError(404, 'could not find node')
+ if len(links) == 0 and not hash in self.db:
+ raise web.HTTPError(404, 'could not find node')
serialize(self, links)
@@ -140,38 +159,41 @@ def get(self, uri):
@util.error_handler
def delete_from(self, uri):
- hash = model.node_key(uri)
- node = self.db[hash]
+ hash = scarecrow.ident(model.node_key(uri))
- #Return a not found if the node doesn't exist
- if not node: raise web.HTTPError(404, 'could not find node')
+ try:
+ node = self.db[hash]
+ except KeyError:
+ #Return a not found if the node doesn't exist
+ raise web.HTTPError(404, 'could not find node')
#Return a forbidden if the current user doesn't own the node
- if node.owner != self.current_user: raise web.HTTPError(403, 'you do not own the node')
+ if node.owner != self.current_user:
+ raise web.HTTPError(403, 'you do not own the node')
node.links = {}
self.db[hash] = node
@util.error_handler
def delete_to(self, uri):
- hash = model.node_key(uri)
+ hash = scarecrow.ident(model.node_key(uri))
results = False
- owner_id = model.account_key(self.current_user)
- #iterate through all the linked nodes and delete the link if it still
+ #Iterate through all the linked nodes and delete the link if it still
#exists
- for node in self.db.index('links_index', 'get', hash, owner_id):
- if not uri in node.links: continue
+ for node in self.db.index('links_index', 'get', hash, model.account_key(self.current_user)):
+ if not uri in node.links:
+ continue
+
results = True
del node.links[uri]
self.db[model.node_key(node.id)] = node
#If no changes were made, the node might not exist; throw a not found
#if it doesn't
- if not results:
- node = self.db[hash]
- if not node: raise web.HTTPError(404, 'could not find node')
+ if not results and not node in self.db:
+ raise web.HTTPError(404, 'could not find node')
@basic_auth(util.REALM, util.auth)
@util.error_handler
View
57 web/view/nodes.py
@@ -19,23 +19,33 @@
from tornado import web
from oz.handler import *
-import model
+import model, scarecrow
from web import *
from web import util
from web.serialization import *
def put_node(request, uri):
"""Updates an existing or creates a new node identified by the given URI"""
- hash = model.node_key(uri)
- node = request.db[hash]
-
+ hash = scarecrow.ident(model.node_key(uri))
tags = util.check_tags(request.get_argument('tags', None))
date = util.check_datetime(request.get_argument('creation_date', None))
- if not node:
- if not tags: tags = set([])
- if not date: date = datetime.now()
+ try:
+ node = request.db[hash]
+
+ #Update an existing node
+ if node.owner != request.current_user:
+ raise web.HTTPError(403, 'you do not own the node')
+ if tags:
+ node.tags = tags
+ if date:
+ node.creation_date = date
+ except KeyError:
+ if not tags:
+ tags = set([])
+ if not date:
+ date = datetime.now()
#Create a new node if it doesn't exist
node = model.Entity(uri, 'node')
@@ -47,11 +57,6 @@ def put_node(request, uri):
node._cache = model.Storage()
node._cache.candidates = model.Storage()
node._cache.expired = False
- else:
- #Update an existing node
- if node.owner != request.current_user: raise web.HTTPError(403, 'you do not own the node')
- if tags: node.tags = tags
- if date: node.creation_date = date
node.update_date = datetime.now()
request.db[hash] = node
@@ -62,10 +67,11 @@ class NodeHandler(util.SnowballHandler):
@util.error_handler
def get(self, uri):
- node = self.db[model.node_key(uri)]
-
- #Return a not found if the node doesn't exist
- if not node: raise web.HTTPError(404, 'could not find node')
+ try:
+ node = self.db[model.node_key(uri)]
+ except KeyError:
+ #Return a not found if the node doesn't exist
+ raise web.HTTPError(404, 'could not find node')
serialize(self, node)
@@ -77,18 +83,23 @@ def put(self, uri):
@basic_auth(util.REALM, util.auth)
@util.error_handler
def delete(self, uri):
- hash = model.node_key(uri)
- node = self.db[hash]
-
- #Return a not found if the node doesn't exist
- if not node: raise web.HTTPError(404, 'could not find node')
+ hash = scarecrow.ident(model.node_key(uri))
+
+ try:
+ node = self.db[hash]
+ except KeyError:
+ #Return a not found if the node doesn't exist
+ raise web.HTTPError(404, 'could not find node')
#Return a forbidden if the current user doesn't own the node
- if node.owner != self.current_user: raise web.HTTPError(403, 'you do not own the node')
+ if node.owner != self.current_user:
+ raise web.HTTPError(403, 'you do not own the node')
#Iterate through each linked node and delete the link
for link_node in self.db.index('links_index', 'get', hash):
- if uri in link_node.links: del link_node.links[uri]
+ if uri in link_node.links:
+ del link_node.links[uri]
+
self.db[model.node_key(link_node.id)] = link_node
del self.db[hash]
View
23 web/view/recommendations.py
@@ -30,14 +30,19 @@ class RecommendationHandler(util.SnowballHandler):
def get(self, from_uri, to_uri):
node_store = cache.NodeStore(self.db, 4)
- from_node = node_store[model.node_key(from_uri)]
- if not from_node: raise web.HTTPError(404, 'could not find from node')
+ try:
+ from_node = node_store[model.node_key(from_uri)]
+ except KeyError:
+ raise web.HTTPError(404, 'could not find from node')
- to_node = node_store[model.node_key(to_uri)]
- if not to_node: raise web.HTTPError(404, 'could not find to node')
+ try:
+ to_node = node_store[model.node_key(to_uri)]
+ except KeyError:
+ raise web.HTTPError(404, 'could not find to node')
rec = engine.recommendation(node_store, from_node, to_node, self.application.settings)
- if not rec: rec = 0.0
+ if not rec:
+ rec = 0.0
serialize(self, rec)
@@ -46,13 +51,15 @@ class RecommendationSetHandler(util.SnowballHandler):
@util.error_handler
def get(self, uri):
- max_visit = int(self.application.settings['recommendations']['max_visit'])
+ max_visit = self.application.settings['recommendations']['max_visit']
tags = util.check_tags(self.get_argument('tags', ''))
node_store = cache.NodeStore(self.db, max_visit + 1)
- from_node = node_store[model.node_key(uri)]
- if not from_node: raise web.HTTPError(404, 'could not find node')
+ try:
+ from_node = node_store[model.node_key(uri)]
+ except KeyError:
+ raise web.HTTPError(404, 'could not find node')
recs = engine.recommendations(node_store, from_node, tags, self.application.settings)
serialize(self, recs)
View
48 web/view/tags.py
@@ -14,12 +14,9 @@
# You should have received a copy of the GNU Affero General Public License
# along with Snowball. If not, see <http://www.gnu.org/licenses/>.
-import uuid
-import datetime
-
from tornado import web
from oz.handler import *
-import model
+import model, scarecrow, uuid, datetime
from web import *
from web import util
@@ -30,53 +27,54 @@ class TagHandler(util.SnowballHandler):
@util.error_handler
def get(self, uri):
- hash = model.node_key(uri)
+ hash = scarecrow.ident(model.node_key(uri))
node = request.db[hash]
- node = self.db[hash]
- if node == None: raise web.HTTPError(404)
+ try:
+ node = self.db[hash]
+ except KeyError:
+ raise web.HTTPError(404)
serialize(self, node.tags)
@basic_auth(util.REALM, util.auth)
@util.error_handler
def put(self, uri):
- hash = model.node_key(uri)
- new_tags = util.check_tags(self.get_argument('tags', None))
+ hash = scarecrow.ident(model.node_key(uri))
- if new_tags == None:
- raise web.HTTPError(400)
+ tags = util.check_tags(self.get_argument('tags', None))
+ if not tags:
+ raise web.HTTPError(400, "requires 'tags' parameter")
- node = self.db[hash]
-
- if node == None:
+ try:
+ node = self.db[hash]
+ except KeyError:
#return a not found if the node doesn't exist
raise web.HTTPError(404)
- elif node['owner'] != self.current_user:
+
+ if node.owner != self.current_user:
#return a forbidden if the current user doesn't own the node
raise web.HTTPError(403)
- tags = node.tags
- for new_tag in new_tags:
- tags.add(new_tag)
-
- node.tags = tags
+ for tag in tags:
+ node.tags.add(tag)
self.db[hash] = node
serialize(self, tags)
@basic_auth(util.REALM, util.auth)
@util.error_handler
def delete(self, uri):
- hash = model.node_key(uri)
+ hash = scarecrow.ident(model.node_key(uri))
delete_tags = util.check_tags(self.get_argument('tags', None))
- node = self.db[hash]
-
- if node == None:
+ try:
+ node = self.db[hash]
+ except KeyError:
#return a not found if the node doesn't exist
raise web.HTTPError(404)
- elif node['owner'] != self.current_user:
+
+ if node['owner'] != self.current_user:
#return a forbidden if the current user doesn't own the node
raise web.HTTPError(403)

0 comments on commit da54ca5

Please sign in to comment.