from flask import jsonify, abort, make_response, request, url_for, redirect, session from requests_oauthlib import OAuth2Session from datetime import datetime from app import app, db, models import json def make_public_ticket(ticket): new_ticket = ticket.copy() new_ticket['uri'] = url_for('get_ticket', ticket_id=ticket['id'], _external=True) return new_ticket def ticket_to_dict(ticket): nt = {} nt['id'] = ticket.id nt['summary'] = ticket.summary nt['body'] = ticket.body nt['opened_at'] = ticket.opened_at.strftime('%Y-%m-%dT%H:%M:%S') if ticket.updated_at: nt['updated_at'] = ticket.updated_at.strftime('%Y-%m-%dT%H:%M:%S') else: nt['updated_at'] = None nt['status'] = ticket.status nt['reason'] = ticket.reason if ticket.opened_by: nt['opened_by'] = { 'id': ticket.opened_by.id, 'nickname': ticket.opened_by.nickname, 'email': ticket.opened_by.email, } else: nt['opened_by'] = {'id': None, 'nickname': None, 'email': None} return nt @app.route('/authorized') def authorized_callback(): github = OAuth2Session(app.config['GITHUB_CLIENT_ID'], state=session['oauth_state']) token = github.fetch_token(app.config['TOKEN_URL'], client_secret=app.config['GITHUB_CLIENT_SECRET'], authorization_response=request.url) session['oauth_token'] = token user_data = github.get('https://api.github.com/user') if user_data.status_code == 401: abort(401) json_data = user_data.json() user = models.User.query.filter(models.User.id == json_data['id']).first() if not user: user = models.User( id = json_data['id'], nickname = json_data['login'], email = json_data['email'] ) db.session.add(user) db.session.commit() return "Your access token is: {}".format(token['access_token']) @app.route('/login') def login(): github = OAuth2Session(app.config['GITHUB_CLIENT_ID']) authorization_url, state = github.authorization_url(app.config['AUTHORIZATION_BASE_URL']) session['oauth_state'] = state return redirect(authorization_url) @app.route('/tbt/api/1.0/tickets', methods=['GET']) def get_tickets(): ts = models.Ticket.query.all() tickets = map(ticket_to_dict, ts) return jsonify({'tickets': list(map(make_public_ticket, tickets))}) @app.route('/tbt/api/1.0/ticket', methods=['POST']) def create_ticket(): if not request.json or not ('summary' and 'body' and 'token') in request.json: abort(400) token = {"scope": [""], "access_token": request.json['token'], "token_type": "bearer"} github = OAuth2Session(app.config['GITHUB_CLIENT_ID'], token=token) user_data = github.get('https://api.github.com/user') if user_data.status_code == 401: abort(401) user = models.User.query.get(user_data.json()['id']) ticket = models.Ticket(summary=request.json['summary'], body=request.json['body'], opened_by=user, opened_at=datetime.utcnow()) db.session.add(ticket) db.session.commit() td = ticket_to_dict(ticket) return jsonify({'ticket': make_public_ticket(td)}), 201 @app.route('/tbt/api/1.0/ticket/', methods=['GET']) def get_ticket(ticket_id): ticket = models.Ticket.query.get(ticket_id) if not ticket: abort(404) return jsonify({'ticket': make_public_ticket(ticket_to_dict(ticket))}) @app.route('/tbt/api/1.0/ticket/', methods=['PUT']) def update_ticket(ticket_id): ticket = next((t for t in tickets if t['id'] == ticket_id), None) if not ticket: abort(404) if not request.json: abort(400) ticket['summary'] = request.json.get('summary', ticket['summary']) ticket['body'] = request.json.get('body', ticket['body']) ticket['status'] = request.json.get('status', ticket['status']) ticket['reason'] = request.json.get('reason', ticket['reason']) return jsonify({'ticket': make_public_ticket(ticket)}) @app.route('/tbt/api/1.0/ticket/', methods=['DELETE']) def delete_ticket(ticket_id): ticket = models.Ticket.query.get(ticket_id) if not ticket: abort(404) db.session.delete(ticket) db.session.commit() return jsonify({'result': True}) @app.errorhandler(404) def not_found(error): return make_response(jsonify({'error': 'Not found'}), 404)