2018-11-01 14:25:47 +00:00
#!/usr/bin/env python3
#Curious Greg - Curious Cat to Mastodon crossposter
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
2018-11-02 02:35:40 +00:00
import requests , sqlite3 , json
2018-11-01 14:25:47 +00:00
from mastodon import Mastodon
2018-11-04 23:17:28 +00:00
from flask import Flask , render_template , request , session , redirect , url_for
2018-11-06 10:30:48 +00:00
import bcrypt
2018-11-06 09:11:03 +00:00
import urllib
2018-11-01 14:25:47 +00:00
2018-11-02 02:35:40 +00:00
cfg = json . load ( open ( " meta.json " ) )
2018-11-06 10:30:48 +00:00
db = sqlite3 . connect ( " database.db " ) #TODO: switch to mysql so concurrency is possible
2018-11-01 14:25:47 +00:00
c = db . cursor ( )
2018-11-06 10:30:48 +00:00
c . execute ( " CREATE TABLE IF NOT EXISTS `data` (username TEXT NOT NULL, instance TEXT NOT NULL, secret TEXT NOT NULL, appid TEXT NOT NULL, appsecret TEXT NOT NULL, cc TEXT, latest_post TEXT, latest_timestamp TEXT, time_between_checks INT) " )
2018-11-01 15:17:02 +00:00
2018-11-02 02:59:29 +00:00
app = Flask ( cfg [ ' name ' ] )
2018-11-02 03:13:08 +00:00
app . secret_key = cfg [ ' flask_key ' ]
2018-11-02 02:59:29 +00:00
2018-11-02 03:13:08 +00:00
@app.route ( ' / ' )
def main ( ) :
2018-11-04 23:17:28 +00:00
if ' acct ' not in session :
return render_template ( " landing_page.html " )
else :
return redirect ( url_for ( ' home ' ) )
@app.route ( ' /home ' )
def home ( ) :
2018-11-06 09:11:03 +00:00
if ' acct ' in session :
acct = session [ ' acct ' ]
return render_template ( " home.html " , acct = acct )
else :
return redirect ( url_for ( ' main ' ) )
2018-11-02 02:59:29 +00:00
2018-11-06 11:22:10 +00:00
@app.route ( ' /debug ' ) #TODO: remove this before making the site live ;p
def print_debug_info ( ) :
return json . dumps ( session . _get_current_object ( ) )
@app.route ( ' /login ' )
def log_in ( ) :
if ' acct ' in session :
#user is probably already logged in. if they aren't, home() will handle things and redirect them back here
return redirect ( url_for ( ' home ' ) )
return render_template ( " login.html " )
# return(json.dumps(client_info))
#internal stuff
2018-11-02 02:59:29 +00:00
@app.route ( ' /internal/auth_a ' )
def internal_auth_a ( ) :
2018-11-04 11:36:25 +00:00
2018-11-06 09:11:03 +00:00
session [ ' instance_url ' ] = request . args . get ( ' url ' , default = ' mastodon.social ' , type = str )
if not session [ ' instance_url ' ] . startswith ( " https:// " ) :
session [ ' instance_url ' ] = " https:// {} " . format ( session [ ' instance_url ' ] )
session [ ' client_id ' ] , session [ ' client_secret ' ] = Mastodon . create_app ( cfg [ ' name ' ] ,
api_base_url = session [ ' instance_url ' ] ,
2018-11-06 10:30:48 +00:00
scopes = [ " write:statuses " , " read:accounts " ] ,
2018-11-06 09:11:03 +00:00
website = cfg [ ' website ' ] ,
redirect_uris = [ ' https://cg.lynnesbian.space/internal/auth_b ' ]
2018-11-04 23:17:28 +00:00
)
2018-11-06 09:11:03 +00:00
params = {
" client_id " : session [ ' client_id ' ] ,
" client_secret " : session [ ' client_secret ' ] ,
2018-11-06 10:30:48 +00:00
" scope " : " write:statuses+read:accounts " ,
2018-11-06 09:11:03 +00:00
" redirect_uri " : " https://cg.lynnesbian.space/internal/auth_b " ,
" response_type " : " code " ,
}
2018-11-06 10:30:48 +00:00
2018-11-06 09:11:03 +00:00
url = " {} /oauth/authorize? {} " . format ( session [ ' instance_url ' ] , urllib . parse . urlencode ( params ) )
2018-11-04 23:17:28 +00:00
return url
2018-11-02 07:52:33 +00:00
2018-11-06 09:11:03 +00:00
@app.route ( ' /internal/auth_b ' )
def internal_auth_b ( ) :
session [ ' secret ' ] = request . args . get ( ' code ' )
#write details to DB
2018-11-06 10:30:48 +00:00
client = Mastodon ( access_token = session [ ' secret ' ] , api_base_url = session [ ' instance_url ' ] )
session [ ' username ' ] = client . account_verify_credentials ( ) [ ' username ' ]
session [ ' acct ' ] = " @ {} @ {} " . format ( session [ ' username ' ] , session [ ' instance_url ' ] . replace ( " https:// " , " " ) )
if c . execute ( " SELECT COUNT(*) FROM data WHERE username LIKE ? AND instance LIKE ? " , ( session [ ' username ' ] , session [ ' instance_url ' ] ) ) . fetchone ( ) [ 0 ] > 0 :
#user already has an account with CG
return redirect ( url_for ( ' log_in ' ) )
2018-11-06 11:22:10 +00:00
2018-11-06 10:30:48 +00:00
c . execute ( " INSERT INTO data (username, instance, secret, appid, appsecret) VALUES (?, ?, ?, ?, ?) " , ( session [ ' username ' ] , session [ ' instance_url ' ] , session [ ' secret ' ] , session [ ' client_id ' ] , session [ ' client_secret ' ] ) )
2018-11-06 09:11:03 +00:00
db . commit ( )
2018-11-06 10:30:48 +00:00
return redirect ( url_for ( ' home ' ) )
2018-11-06 09:11:03 +00:00
2018-11-06 11:22:10 +00:00
@app.route ( ' /internal/do_login ' )
def do_login ( ) :
pass
2018-11-06 10:30:48 +00:00
2018-11-06 11:22:10 +00:00
@app.route ( ' /create_password ' )
def create_password ( ) :
return render_template ( " create_password.html " )