def record_comment(commenter_name, pid, cid): """XXX add karma to comment voting later - you get 1 karma for commenting """ u = User.get(commenter_name) u['comments'].append((pid, cid)) return User.replace(commenter_name, u)
def record_submission(submitter_name, pid): """Move to openjoural specific user api. Pushes pid onto user's posts set """ u = User.get(submitter_name) u['posts'].append(pid) return User.replace(submitter_name, u)
def record_submission(submitter_name, pid, cid=None): """A submission can be a paper or a journal""" u = User.get(submitter_name) if cid: u['comments'].append((pid, cid)) else: u['posts'].append(pid) return User.replace(submitter_name, u)
def record_comment(commenter_name, pid, cid): """XXX add karma to comment voting later - you get 1 karma for commenting """ pid, cid = map(int, (pid, cid)) u = User.get(commenter_name) u['comments'].append((pid, cid)) return User.replace(commenter_name, u)
def GET(self, username=""): if username: try: user = User.get(username, safe=True) return render().profiles.index(user) except: pass raise web.seeother('/')
def record_vote(yourname, submitter_name, pid, cid=None): """XXX Todo: expose as web api/v1/vote and require nonce?""" def inc_vote(user): user['votes'].append(pid) return user submitter = User.get(submitter_name) submitter['karma'] +=1 User.replace(submitter_name, submitter) return User.update(yourname, func=inc_vote)
def record_submission(submitter_name, pid, cid=None): """Pushes paper pid onto user's posts set. A submission can be a paper or a journal """ u = User.get(submitter_name) if cid: u.comments.append((pid, cid)) else: u.posts.append(pid) return User.replace(submitter_name, dict(u))
def POST(self): """TODO: handle redir""" i = web.input(username='', passwd='', redir='') if i.username and i.passwd: try: u = User.get(i.username) if User.easyauth(u, i.passwd): loadsession(u) raise web.seeother('/') except: raise err = "Incorrect username or password" else: err = "Please provide all required fields" return render().auth.login(err=err)
def test_users(self): """Test whether waltz.User (of base type Account) interfaces with LazyDB correctly and behaves expectedly """ # Setting up waltz web.py env variables for db() web.ctx.waltz = storage() web.ctx.waltz.db = "db" u1 = User.register(USERNAME, PASSWD, **USER_FIELDS) u1.email = EMAIL u1.save() u2 = User.get(USERNAME) u3 = User.register(USERNAME[::-1], PASSWD, **USER_FIELDS) self.assertTrue(u1["username"] == USERNAME, "<waltz.User.register> Registration " "returned invalid user dict") print User.get(USERNAME) self.assertTrue(User.get(USERNAME).email == EMAIL, "Failed to save / update User record") self.assertTrue(u1.authenticate(PASSWD), "User.authenticate Failed") self.assertTrue( u2 is not None, "<waltz.User.register> " "Registration failed, no such entry " "indexed by {'username': '******'}" % USERNAME, ) self.assertTrue( all(item in u2.items() for item in USER_FIELDS.items()), "<waltz.User.get> Expected stored data did not match " "actual data indexed by waltz 'user' LazyDB.", ) User.replace(USERNAME, u3) self.assertTrue( User.get(USERNAME)["username"] == USERNAME[::-1], "<waltz.User.replace> Failed to replace username" ) u4 = User.get(USERNAME[::-1], safe=True) self.assertTrue( not getattr(u4, "uhash", False), "User.get(%s, safe=True) did not remove uhash field " "as would be expected" % USERNAME[::-1], ) users = User.getall() self.assertTrue(len(users) == 2, "Users db has incorrect # users: " "%s (%s)" % (len(users), users)) users2 = User.getall(safe=True) self.assertTrue( "uhash" not in users2[USERNAME].keys(), "User.getall(safe=True) did not remove uhash field " "as would be expected", ) self.assertTrue( User.delete(USERNAME) is not None, "<waltz.User.delete> " "Failed to delete user: %s" % USERNAME )
def POST(self): def defusr(): return {'karma': 0, 'comments': [], 'votes': [], 'posts': [], 'created': datetime.datetime.utcnow(), 'bio': '', 'email': ''} i = web.input(username='', passwd='', redir='') if i.username and i.passwd: if re.match(username_regex, i.username): if re.match(passwd_regex, i.passwd): try: # treat as login if creds are right u = User.get(i.username) if User.easyauth(u, i.passwd): loadsession(u) raise web.seeother('/') except: pass try: u = User.register(i.username, i.passwd, **defusr()) loadsession(u) raise web.seeother('/') except: err = "Username unavailable" else: err = passwd_err else: err = username_err else: err = "Please enter all required fields" return render().auth.register(err=err)
def GET(self): """Research http://news.ycombinator.com/item?id=1781013 how hacker news voting works and emulate XXX Restrict voting to session().logged users + element id must not already exist in user['votes'] set. XXX Requires accounting + record keeping XXX Preserve the web.ctx GET query params to preserve sorting / ordering Algo: 1. Add karma to paper['submitter'] if vote 2. Record vote in user['votes'] set by id - calc unique vote id via some linear combination of paper pid (and or comment id [cid], if it exists) """ msg = None i = web.input(pid=None, sort="popular") if not session().logged: raise web.seeother('/register') db = Db('db/openjournal') ps = db.get('papers') u = User.get(session()['uname']) if i.pid: i.pid = int(i.pid) if canvote(u, i.pid): try: ps[i.pid]['votes'] += 1 db.put('papers', ps) submitter_uname = ps[i.pid]['submitter'] record_vote(u['username'], submitter_uname, i.pid) except IndexError: return "No such items exists to vote on" raise web.seeother('/?sort=%s' % i.sort)
def canvote(username, pid, cid=None): """Predicate which returns a boolean which answers the question, can user (pkey username) vote for paper (pkey pid) and/or a paper's comment (pkey (pid, cid)) """ return pid not in User.get(username)['votes']
def canvote(username, pid, cid=None): """Predicate which returns a boolean which answers the question, can user (pkey username) vote for paper (pkey pid) and/or a paper's comment (pkey (pid, cid)) """ return int(pid) not in User.get(username)['votes']
urls = ('/submit/?', 'routes.submit.Submit', '/item/?', 'routes.item.Item', '/upvote/?', 'routes.item.Vote', '/search/?', 'routes.search.Search', '/admin', 'subapps.admin.Edit', '/login/?', 'routes.auth.Login', '/register/?', 'routes.auth.Register', '/logout/?', 'routes.auth.Logout', '/users/(.*)/?', 'routes.profiles.Profile', '/x/?', 'routes.auth.Register', '/404/?', 'routes.responses.NotFound', '/admin/?', 'routes.admin.Analytics', '/?', 'routes.index.Index', '(.*)', 'routes.responses.NotFound') env = {'random': random, 'time': lambda x: web.datestr(str2datetime(x), now=datetime.datetime.utcnow()), 'karma': lambda: User.get(session()['uname'])['karma'], 'voted': lambda pid: int(pid) in \ User.get(session()['uname'])['votes'], } sessions = {'logged': False, 'uname': ''} app = waltz.setup.dancefloor(urls, globals(), env=env, sessions=sessions, db='%s/db/waltz' % os.getcwd(), autoreload=False) if __name__ == "__main__": app.run()