/
main.py
144 lines (132 loc) · 5.6 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
import subprocess
import os.path
import tornado.ioloop
import tornado.options
import tornado.web
import logging
import rethinkdb as r
import signal
import time
from handlers.base_handler import BaseHandler
from models.basemodel import BaseModel
from models.course import Course
from models.instructor import Instructor
from models.question import Question
from models.section import Section
from models.student import Student
from models.survey import Survey
from models.user import User
from tornado.httpserver import HTTPServer
from test.test_runner import run_tests
from config.application import make_application, initialize_settings
from tornado import ioloop, gen
from tornado.concurrent import Future, chain_future
from tornado.options import define, options
application = None
settings = {}
define('debug', default=True, help='set True for debug mode', type=bool)
define('test', default=False, help='set True to run Tests', type=bool)
define('dump', default=False, help='dumps certain database tables for accessing the rawdump', type=bool)
define('backup', default=False, help='makes a backup of the database', type=bool)
define('wipe_user_data', default=False, help='set True to violently wipe user survey and course data', type=bool)
define('bootstrap_data', default=False, help='set True to provision a user with surveys and courses', type=bool)
define('port', default=8000, help='run on the given port', type=int)
define('database_name', default='scq', help='rethink database name', type=str)
define('database_host', default='localhost', help='rethink database host', type=str)
define('database_port', default=28015, help='rethink database port', type=int)
def main():
tornado.options.parse_command_line()
settings = initialize_settings()
application = make_application(settings)
httpserver = HTTPServer(application, xheaders=True)
# signal handler
def sig_handler(sig, frame):
logging.warn("Caught Signal: %s" % sig)
tornado.ioloop.IOLoop.instance().add_callback(shutdown)
# signal handler's callback
def shutdown():
logging.info("Stopping HttpServer ...")
httpserver.stop() # No longer accept new http traffic
instance = tornado.ioloop.IOLoop.instance()
deadline = time.time() + settings['sigint_timeout']
# recursion for terminate IOLoop.instance()
def terminate():
now = time.time()
if now < deadline and (instance._callbacks or instance._timeouts):
instance.add_timeout(now + 1, terminate)
else:
instance.stop() # After process all _callbacks and _timeouts, break IOLoop.instance()
logging.info('Shutdown ...')
# process recursion
terminate()
if options.test:
return run_tests(application)
if options.bootstrap_data or options.wipe_user_data:
username = input("please input username: ")
cursor = User().find_item({'username': username})
for user_data in cursor:
user_id = user_data['id']
logging.info('user_id: ' + user_id)
if options.wipe_user_data:
return wipe_data(user_id)
if options.bootstrap_data:
return bootstrap_data(user_id)
return logging.error('no found user with username: ' + username)
if options.backup:
remove = "rm -rf rethinkdb_dump*"
backup = "rethinkdb dump -e {0}".format(settings['database_name'])
os.system(remove)
return os.system(backup)
if options.dump:
filename = 'static/dump/scq_dump.tar.gz'
remove = "rm static/dump/scq_dump*"
db = settings['database_name']
e_db = ' -e ' + db + '.'
tables = ['Survey', 'Question', 'QuestionResponse', 'SurveyResponse', 'Group']
backup_tables = e_db.join(tables)
backup_tables = e_db + backup_tables
backup = "rethinkdb dump {0} -f {1}".format(backup_tables, filename)
logging.info(backup)
os.system(remove)
return os.system(backup)
if options.debug:
httpserver.listen(settings['site_port'])
signal.signal(signal.SIGINT, sig_handler)
signal.signal(signal.SIGTERM, sig_handler)
else:
httpserver.bind(settings['site_port']) # port
httpserver.start(0)
logging.info("Now serving on http://localhost:{0}".format(settings['site_port']))
tornado.ioloop.IOLoop.instance().start()
logging.info('Exit ...')
def bootstrap_data(user_id):
"""
Creates new course and survey objects, and associates all of this data
"""
user_data = User().get_item(user_id)
if user_data is None:
logging.error("user_id {0} does not correspond to a valid user in the database!".format(user_id))
return
course_id = Course().create_generic_item()
Course().subscribe_user(user_id, course_id)
survey_id = Survey().create_generic_item(user_id, course_id)
logging.info('survey id:\n' + survey_id)
return
def wipe_data(user_id):
"""
Wipes the data associated with a users surveys, classes and courses
Warning: Does not disassociate surveys with courses, user with courses, etc.
It just makes a user fresh and ready for new data
"""
user_data = User().get_item(user_id)
if user_data is None:
logging.error("user_id {0} does not correspond to a valid user in the database!".format(user_id))
return
user_data['courses'] = []
user_data['created_surveys'] = []
user_data['unanswered_surveys'] = []
update_response = User().update_item(user_id, user_data, skip_verify=True)
logging.info(update_response)
return
if __name__ == "__main__":
main()