123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 |
- # encoding=utf-8
- import json
- import logging
- from tornado.web import HTTPError
- import tornado.websocket
- from terroroftinytown.tracker.base import BaseHandler
- from terroroftinytown.tracker.errors import (NoItemAvailable, UserIsBanned,
- InvalidClaim, FullClaim, UpdateClient, NoResourcesAvailable)
- from terroroftinytown.tracker.model import Project
- from terroroftinytown.tracker.stats import Stats, stats_bus
- from terroroftinytown.util.jsonutil import NativeStringJSONDecoder
- logger = logging.getLogger(__name__)
- class ProjectSettingsHandler(BaseHandler):
- def get(self):
- name = self.get_argument('name')
- project = Project.get_plain(name)
- if project:
- self.write(project.to_dict())
- else:
- raise HTTPError(404, reason='Project not found')
- class LiveStatsHandler(tornado.websocket.WebSocketHandler):
- def open(self):
- global stats_bus
- self.write_message({
- 'live': Stats.instance.get_live(),
- 'lifetime': Stats.instance.get_lifetime(),
- 'global': Stats.instance.get_global(),
- 'project': Stats.instance.get_project()
- })
- stats_bus += self.on_stats
- def on_stats(self, **stats):
- self.write_message({
- 'live_new': stats
- })
- def on_close(self):
- stats_bus.clear_handlers(self)
- class UserStatsHandler(BaseHandler):
- def get(self, username):
- stats = Stats.instance.get_user_lifetime(username)
- self.write({'stats': stats})
- class GetHandler(BaseHandler):
- def post(self):
- ip_address = self.request.remote_ip
- version = int(self.get_argument('version'))
- client_version = int(self.get_argument('client_version'))
- username = self.get_argument('username')
- user_agent = self.request.headers.get('User-Agent')
- try:
- claim = self.application.checkout_item(
- username, ip_address=ip_address, version=version,
- client_version=client_version
- )
- except NoItemAvailable:
- raise HTTPError(
- 404,
- reason='No free items available currently. '
- 'Don\'t worry; this is normal. '
- 'You will be assigned items soon.'
- )
- except UserIsBanned:
- raise HTTPError(
- 403,
- reason='You are banned. Please contact an administrator.'
- )
- except FullClaim:
- raise HTTPError(
- 429,
- reason=(
- 'No more items available for %s. '
- 'Don\'t worry; We limit 1 IP address per shortener. '
- 'Try again later.'
- % (ip_address)
- )
- )
- except UpdateClient as e:
- raise HTTPError(
- 412,
- reason=(
- 'Client needs update. '
- 'Library version: %s, min %s; '
- 'Pipeline version: %s, min %s. '
- 'Please restart Warrior.'
- % (
- e.version, e.current_version,
- e.client_version, e.current_client_version
- )
- )
- )
- except NoResourcesAvailable as e:
- raise HTTPError(
- 507,
- reason='The tracker needs an operator for manual maintenance. '
- 'Try again later.'
- )
- else:
- logger.info(
- 'User request: ip=%s user=%s '
- 'ver=%s client_ver=%s user_agent=%s',
- ip_address, repr(username),
- version, client_version, repr(user_agent)
- )
- logger.info('Checked out claim %s', claim)
- self.write(claim)
- class DoneHandler(BaseHandler):
- def post(self):
- claim_id = self.get_argument('claim_id')
- tamper_key = self.get_argument('tamper_key')
- results_str = self.get_argument('results')
- results = json.loads(results_str, cls=NativeStringJSONDecoder)
- try:
- stats = self.application.checkin_item(claim_id, tamper_key, results)
- except InvalidClaim:
- raise HTTPError(
- 409,
- reason='The item is invalid or '
- 'may have been already done by someone else.'
- )
- else:
- time_diff = stats['finished'] - stats['started']
- logger.info('Checked in claim %s. Len=%d, Time_diff=%d',
- claim_id,
- len(results),
- time_diff
- )
- self.write({'status': 'OK'})
- class ErrorHandler(BaseHandler):
- def post(self):
- claim_id = self.get_argument('claim_id')
- tamper_key = self.get_argument('tamper_key')
- message = self.get_argument('message')
- try:
- self.application.report_error(claim_id, tamper_key, message)
- except InvalidClaim:
- raise HTTPError(409, reason='Invalid item claimed')
- else:
- logger.info('Error reported for claim %s', claim_id)
- self.write({'status': 'OK'})
- class HealthHandler(BaseHandler):
- def _show_maintenance_page(self):
- self.set_status(512, 'export_in_progress')
- def get(self):
- status = self.application.get_project_status()
- if self.application.is_deadman_safety_tripped():
- self.set_status(507, 'deadman_safety_tripped')
- self.write({
- 'http_status_code': self._status_code,
- 'http_status_message': self._reason,
- 'git_hash': str(status.git_hash),
- 'projects': [project.name for project in status.projects],
- 'project_stats': status.project_stats
- })
|