-
Notifications
You must be signed in to change notification settings - Fork 80
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #91 from squirrelo/webfleshout
Base meta-analysis workflow interface
- Loading branch information
Showing
38 changed files
with
893 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#!/usr/bin/env python | ||
from __future__ import division | ||
|
||
# ----------------------------------------------------------------------------- | ||
# Copyright (c) 2014--, The Qiita Development Team. | ||
# | ||
# Distributed under the terms of the BSD 3-clause License. | ||
# | ||
# The full license is in the file LICENSE, distributed with this software. | ||
# ----------------------------------------------------------------------------- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
from tornado.web import authenticated | ||
|
||
from qiita_pet.handlers.base_handlers import BaseHandler | ||
from qiita_db.user import User | ||
from qiita_db.analysis import Analysis | ||
from qiita_db.study import Study | ||
# login code modified from https://gist.github.com/guillaumevincent/4771570 | ||
|
||
|
||
class CreateAnalysisHandler(BaseHandler): | ||
"""Analysis creation""" | ||
@authenticated | ||
def get(self): | ||
self.render('create_analysis.html', user=self.get_current_user()) | ||
|
||
|
||
class SelectStudiesHandler(BaseHandler): | ||
"""Study selection""" | ||
@authenticated | ||
def post(self): | ||
name = self.get_argument('name') | ||
description = self.get_argument('description') | ||
user = self.get_current_user() | ||
# create list of studies | ||
study_ids = {s.id for s in Study.get_public()} | ||
userobj = User(user) | ||
[study_ids.add(x) for x in userobj.private_studies] | ||
[study_ids.add(x) for x in userobj.shared_studies] | ||
|
||
studies = [Study(i) for i in study_ids] | ||
analysis = Analysis.create(User(user), name, description) | ||
|
||
self.render('select_studies.html', user=user, aid=analysis.id, | ||
studies=studies) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
#!/usr/bin/env python | ||
|
||
from tornado.escape import url_escape, json_encode | ||
|
||
from qiita_pet.handlers.base_handlers import BaseHandler | ||
from qiita_core.util import send_email | ||
from qiita_core.exceptions import IncorrectPasswordError, IncorrectEmailError | ||
from qiita_db.user import User | ||
from qiita_db.exceptions import QiitaDBUnknownIDError | ||
# login code modified from https://gist.github.com/guillaumevincent/4771570 | ||
|
||
|
||
class AuthCreateHandler(BaseHandler): | ||
"""User Creation""" | ||
def get(self): | ||
try: | ||
error_message = self.get_argument("error") | ||
# Tornado can raise an Exception directly, not a defined type | ||
except: | ||
error_message = "" | ||
self.render("create_user.html", user=self.get_current_user(), | ||
error=error_message) | ||
|
||
def post(self): | ||
username = self.get_argument("username", "") | ||
password = self.get_argument("pass", "") | ||
info = {} | ||
for info_column in ("name", "affiliation", "address", "phone"): | ||
hold = self.get_argument(info_column, None) | ||
if hold: | ||
info[info_column] = hold | ||
|
||
created = User.create(username, password, info) | ||
|
||
if created: | ||
send_email(username, "FORGE: Verify Email Address", "Please click " | ||
"the following link to verify email address: " | ||
"http://forge-dev.colorado.edu/auth/verify/%s" % msg) | ||
self.redirect(u"/") | ||
else: | ||
error_msg = u"?error=" + url_escape(msg) | ||
self.redirect(u"/auth/create/" + error_msg) | ||
|
||
|
||
class AuthVerifyHandler(BaseHandler): | ||
def get(self): | ||
email = self.get_argument("email") | ||
code = self.get_argument("code") | ||
try: | ||
User(email).level = 3 | ||
msg = "Successfully verified user!" | ||
except QiitaDBUnknownIDError: | ||
msg = "Code not valid!" | ||
|
||
self.render("user_verified.html", user=None, error=msg) | ||
|
||
|
||
class AuthLoginHandler(BaseHandler): | ||
"""user login, no page necessary""" | ||
def post(self): | ||
username = self.get_argument("username", "") | ||
passwd = self.get_argument("password", "") | ||
# check the user level | ||
try: | ||
if User(username).level == 4: # 4 is id for unverified | ||
# email not verified so dont log in | ||
msg = "Email not verified" | ||
except QiitaDBUnknownIDError: | ||
msg = "Unknown user" | ||
|
||
# Check the login information | ||
login = None | ||
try: | ||
login = User.login(username, passwd) | ||
except IncorrectEmailError: | ||
msg = "Unknown user" | ||
except IncorrectPasswordError: | ||
msg = "Incorrect password" | ||
|
||
if login: | ||
# everthing good so log in | ||
self.set_current_user(username) | ||
self.redirect("/") | ||
return | ||
self.render("index.html", user=None, loginerror=msg) | ||
|
||
def set_current_user(self, user): | ||
if user: | ||
self.set_secure_cookie("user", json_encode(user)) | ||
else: | ||
self.clear_cookie("user") | ||
|
||
|
||
class AuthLogoutHandler(BaseHandler): | ||
"""Logout handler, no page necessary""" | ||
def get(self): | ||
self.clear_cookie("user") | ||
self.redirect("/") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
from tornado.web import RequestHandler | ||
|
||
|
||
class BaseHandler(RequestHandler): | ||
def get_current_user(self): | ||
'''Overrides default method of returning user curently connected''' | ||
user = self.get_secure_cookie("user") | ||
if user is None: | ||
self.clear_cookie("user") | ||
return '' | ||
else: | ||
return user.strip('" ') | ||
|
||
def write_error(self, status_code, **kwargs): | ||
'''Overrides the error page created by Tornado''' | ||
from traceback import format_exception | ||
if self.settings.get("debug") and "exc_info" in kwargs: | ||
exc_info = kwargs["exc_info"] | ||
trace_info = ''.join(["%s<br />" % line for line in | ||
format_exception(*exc_info)]) | ||
request_info = ''.join(["<strong>%s</strong>: %s<br />" % | ||
(k, self.request.__dict__[k]) for k in | ||
self.request.__dict__.keys()]) | ||
error = exc_info[1] | ||
|
||
self.render('error.html', error=error, trace_info=trace_info, | ||
request_info=request_info, | ||
user=self.get_current_user()) | ||
|
||
|
||
class MainHandler(BaseHandler): | ||
'''Index page''' | ||
def get(self): | ||
username = self.get_current_user() | ||
completedanalyses = [] | ||
self.render("index.html", user=username, analyses=completedanalyses) | ||
|
||
|
||
class MockupHandler(BaseHandler): | ||
def get(self): | ||
self.render("mockup.html", user=self.get_current_user()) | ||
|
||
|
||
class NoPageHandler(BaseHandler): | ||
def get(self): | ||
self.render("404.html", user=self.get_current_user()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
# adapted from | ||
# https://github.com/leporo/tornado-redis/blob/master/demos/websockets | ||
|
||
from redis import Redis | ||
from tornadoredis import Client | ||
from tornado.websocket import WebSocketHandler | ||
import tornado.gen | ||
from json import loads | ||
|
||
# all messages are in json format. They must have the following format: | ||
# 'job': jobname | ||
# 'msg': message to print | ||
# 'analysis': what analysis this is from in format datatype:analysis | ||
# 'results': list of files created if any | ||
|
||
|
||
class MessageHandler(WebSocketHandler): | ||
def __init__(self, *args, **kwargs): | ||
super(MessageHandler, self).__init__(*args, **kwargs) | ||
self.r_server = Redis() | ||
self.redis = Client() | ||
self.redis.connect() | ||
|
||
def get_current_user(self): | ||
user = self.get_secure_cookie("user") | ||
if user is None: | ||
return '' | ||
else: | ||
return user.strip('" ') | ||
|
||
def on_message(self, msg): | ||
msginfo = loads(msg) | ||
# listens for handshake from page | ||
if "user:" in msginfo['msg']: | ||
self.channel = msginfo['msg'].split(':')[1] | ||
# need to split the rest off to new func so it can be asynchronous | ||
self.listen() | ||
|
||
# decorator turns the function into an asynchronous generator object | ||
@tornado.gen.engine | ||
def listen(self): | ||
# runs task given, with the yield required to get returned value | ||
# equivalent of callback/wait pairing from tornado.gen | ||
yield tornado.gen.Task(self.redis.subscribe, self.channel) | ||
if not self.redis.subscribed: | ||
self.write_message('ERROR IN SUBSCRIPTION') | ||
# listen from tornadoredis makes the listen object asynchronous | ||
# if using standard redis lib, it blocks while listening | ||
self.redis.listen(self.callback) | ||
# fight race condition by loading from redis after listen started | ||
# need to use std redis lib because tornadoredis is in subscribed state | ||
oldmessages = self.r_server.lrange(self.channel + ':messages', 0, -1) | ||
if oldmessages is not None: | ||
for message in oldmessages: | ||
self.write_message(message) | ||
|
||
def callback(self, msg): | ||
if msg.kind == 'message': | ||
self.write_message(str(msg.body)) | ||
|
||
@tornado.gen.engine | ||
def on_close(self): | ||
yield tornado.gen.Task(self.redis.unsubscribe, self.channel) | ||
self.redis.disconnect() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
THIS SHOULD SHOW UP! |
Oops, something went wrong.