diff --git a/config.example.py b/config.example.py index b68422a..d9519f0 100644 --- a/config.example.py +++ b/config.example.py @@ -34,6 +34,11 @@ blah TWITTER_CONSUMER_KEY='vdsvdsvds' TWITTER_CONSUMER_SECRET='hjklhjklhjkl' +""" +blablabl +""" +SERVER_NAME="localhost:5000" + """ you can also use any config variable that flask expects here, such as """ diff --git a/createdb.py b/createdb.py new file mode 100644 index 0000000..cc5c501 --- /dev/null +++ b/createdb.py @@ -0,0 +1,5 @@ +import forget + +from app import db + +db.create_all() diff --git a/lib/__init__.py b/lib/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/lib/twitter.py b/lib/twitter.py new file mode 100644 index 0000000..6fdfd57 --- /dev/null +++ b/lib/twitter.py @@ -0,0 +1,40 @@ +from twitter import Twitter, OAuth +from werkzeug.urls import url_decode +from model import OAuthToken, Account +from app import db + +def get_login_url(callback='oob', consumer_key=None, consumer_secret=None): + twitter = Twitter( + auth=OAuth('', '', consumer_key, consumer_secret), + format='', api_version=None) + resp = url_decode(twitter.oauth.request_token(oauth_callback=callback)) + oauth_token = resp['oauth_token'] + oauth_token_secret = resp['oauth_token_secret'] + + token = OAuthToken(token = oauth_token, token_secret = oauth_token_secret) + db.session.merge(token) + db.session.commit() + + return "https://api.twitter.com/oauth/authenticate?oauth_token=%s" % (oauth_token,) + +def receive_verifier(oauth_token, oauth_verifier, consumer_key=None, consumer_secret=None): + temp_token = OAuthToken.query.get(oauth_token) + if not temp_token: + raise Exception("OAuth token has expired") + twitter = Twitter( + auth=OAuth(temp_token.token, temp_token.token_secret, consumer_key, consumer_secret), + format='', api_version=None) + resp = url_decode(twitter.oauth.access_token(oauth_verifier = oauth_verifier)) + db.session.delete(temp_token) + new_token = OAuthToken(token = resp['oauth_token'], token_secret = resp['oauth_token_secret']) + new_token = db.session.merge(new_token) + new_twitter = Twitter( + auth=OAuth(new_token.token, new_token.token_secret, consumer_key, consumer_secret)) + remote_acct = new_twitter.account.verify_credentials() + acct = Account(remote_id = remote_acct['id_str']) + acct = db.session.merge(acct) + acct.remote_display_name = remote_acct['name'] + acct.remote_avatar_url = remote_acct['profile_image_url_https'] + new_token.account = acct + db.session.commit() + return new_token diff --git a/model.py b/model.py index fdc9fc0..971e8e7 100644 --- a/model.py +++ b/model.py @@ -2,30 +2,35 @@ from datetime import datetime from app import db +from twitter import Twitter, OAuth + class TimestampMixin(object): created_at = db.Column(db.DateTime, server_default=db.func.now()) updated_at = db.Column(db.DateTime, server_default=db.func.now(), onupdate=db.func.now()) -class User(db.Model, TimestampMixin): - __tablename__ = 'users' + def touch(self): + self.updated_at=db.func.now() - display_name = db.Column(db.String) - id = db.Column(db.Integer, primary_key=True) class Account(db.Model, TimestampMixin): - - user = db.relationship(User) - user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False) - - service = db.Column( - db.Enum("twitter", name="enum_services") - , primary_key=True) + __tablename__ = 'accounts' remote_id = db.Column(db.String, primary_key=True) - credentials = db.Column(db.JSON) + # policy_enabled = db.Column(db.Boolean, server_default='FALSE', nullable=False) + # policy_keep_younger = db.Column(db.Interval) + # policy_keep_latest = db.Column(db.Integer) + # policy_delete_every = db.Column(db.Interval) + # policy_ignore_favourites = db.Column(db.Boolean, server_default='TRUE') + + remote_display_name = db.Column(db.String) + remote_avatar_url = db.Column(db.String) + +class OAuthToken(db.Model, TimestampMixin): + __tablename__ = 'oauth_tokens' + + token = db.Column(db.String, primary_key=True) + token_secret = db.Column(db.String, nullable=False) + + remote_id = db.Column(db.String, db.ForeignKey('accounts.remote_id')) + account = db.relationship(Account) - policy_enabled = db.Column(db.Boolean, server_default='FALSE', nullable=False) - policy_keep_younger = db.Column(db.Interval) - policy_keep_latest = db.Column(db.Integer) - policy_delete_every = db.Column(db.Interval) - policy_ignore_favourites = db.Column(db.Boolean, server_default='TRUE') diff --git a/routes.py b/routes.py index b4596dc..509fb56 100644 --- a/routes.py +++ b/routes.py @@ -1,15 +1,32 @@ from app import app -from flask import render_template, session, url_for, redirect +from flask import render_template, session, url_for, redirect, request from datetime import datetime +import lib.twitter +from model import Account +from app import db @app.route('/') def index(): - return render_template('index.html') + viewer = None + if 'remote_id' in session: + viewer = Account.query.get(session['remote_id']) + viewer.touch() + db.session.commit() + return render_template('index.html', viewer = viewer) @app.route('/login/twitter') -def debug_login(): - session['display_name'] = 'codl' - session['created_at'] = datetime.now() +def twitter_login_step1(): + return redirect(lib.twitter.get_login_url( + callback = url_for('twitter_login_step2', _external=True), + **app.config.get_namespace("TWITTER_") + )) + +@app.route('/login/twitter/callback') +def twitter_login_step2(): + oauth_token = request.args['oauth_token'] + oauth_verifier = request.args['oauth_verifier'] + token = lib.twitter.receive_verifier(oauth_token, oauth_verifier, **app.config.get_namespace("TWITTER_")) + session['remote_id'] = token.remote_id return redirect(url_for('index')) @app.route('/logout') diff --git a/templates/index.html b/templates/index.html index a2d1e00..7c9ab64 100644 --- a/templates/index.html +++ b/templates/index.html @@ -1,6 +1,9 @@ -{% if session %} -

Hello, {{session['display_name']}}! Log out

+{% if viewer %} +

Hello, + +{{viewer.remote_display_name}}! Log out

{{session}}

+

{{viewer}}

{% else %}

Hello, stranger! Log in with Twitter

{% endif %}