1
0
Fork 0

Big rework of Flask and database with new login system

This commit is contained in:
Ethanell 2019-04-29 01:49:40 +02:00
parent 7de70b423c
commit 6beb1bb246
51 changed files with 500 additions and 174 deletions

14
app/__init__.py Normal file
View file

@ -0,0 +1,14 @@
from flask import Flask
from config import Config
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_login import LoginManager
app = Flask(__name__)
app.config.from_object(Config)
db = SQLAlchemy(app)
migrate = Migrate(app, db)
login = LoginManager(app)
login.login_view = "login"
from app import routes, models

28
app/forms.py Normal file
View file

@ -0,0 +1,28 @@
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, BooleanField, SubmitField
from wtforms.validators import ValidationError, DataRequired, Email, EqualTo
from app.models import User
class LoginForm(FlaskForm):
username = StringField("Username", validators=[DataRequired()])
password = PasswordField("Password", validators=[DataRequired()])
remember_me = BooleanField("Remember Me")
submit = SubmitField("Sign In")
class RegistrationForm(FlaskForm):
username = StringField("Username", validators=[DataRequired()])
email = StringField("Email", validators=[DataRequired(), Email()])
password = PasswordField("Password", validators=[DataRequired()])
password2 = PasswordField(
"Repeat Password", validators=[DataRequired(), EqualTo("password")])
submit = SubmitField("Register")
def validate_username(self, username):
user = User.query.filter_by(username=username.data).first()
if user is not None:
raise ValidationError("Please use a different username.")
def validate_email(self, email):
user = User.query.filter_by(email=email.data).first()
if user is not None:
raise ValidationError("Please use a different email address.")

36
app/models.py Normal file
View file

@ -0,0 +1,36 @@
from app import db
from werkzeug.security import generate_password_hash, check_password_hash
from flask_login import UserMixin
from app import login
class User(UserMixin, db.Model):
id = db.Column(db.Integer, primary_key=True, unique=True)
username = db.Column(db.String(64), index=True, unique=True)
email = db.Column(db.String(120), index=True, unique=True)
password_hash = db.Column(db.String(128))
twitter_api = db.relationship("TwitterAPI", backref="user", lazy="dynamic")
trello_api = db.relationship('TrelloAPI', backref="user", lazy="dynamic")
def set_password(self, password):
self.password_hash = generate_password_hash(password)
def check_password(self, password):
return check_password_hash(self.password_hash, password)
def __repr__(self):
return f"<User {self.username}>"
class TwitterAPI(db.Model):
id = db.Column(db.Integer, primary_key=True, unique=True)
user_id = db.Column(db.Integer, db.ForeignKey("user.id"), unique=True)
access_token = db.Column(db.String(50), unique=True)
access_token_secret = db.Column(db.String(45), unique=True)
class TrelloAPI(db.Model):
id = db.Column(db.Integer, primary_key=True, unique=True)
user_id = db.Column(db.Integer, db.ForeignKey("user.id"), unique=True)
token = db.Column(db.String(64), unique=True)
@login.user_loader
def load_user(id):
return User.query.get(int(id))

165
app/routes.py Normal file
View file

@ -0,0 +1,165 @@
from app import app, db
from flask import Flask, request, redirect, session, render_template, flash, url_for
from flask_login import current_user, login_user, logout_user, login_required
from app.forms import LoginForm, RegistrationForm
from app.models import User, TwitterAPI, TrelloAPI
from werkzeug.urls import url_parse
import twitter_credentials, tweepy, tw
import trello_credentials, trello, tr
@app.route("/login", methods=["GET", "POST"])
def login():
if current_user.is_authenticated:
return redirect(url_for("home"))
form = LoginForm()
if form.validate_on_submit():
user = User.query.filter_by(username=form.username.data).first()
if user is None or not user.check_password(form.password.data):
flash("Invalid username or password")
return redirect(url_for("login"))
login_user(user, remember=form.remember_me.data)
next_page = request.args.get("next")
if not next_page or url_parse(next_page).netloc != "":
next_page = url_for("home")
return redirect(next_page)
return render_template("login.html", form=form)
@app.route("/register", methods=["GET", "POST"])
def register():
if current_user.is_authenticated:
return redirect(url_for("index"))
form = RegistrationForm()
if form.validate_on_submit():
user = User(username=form.username.data, email=form.email.data)
user.set_password(form.password.data)
db.session.add(user)
db.session.commit()
flash("Congratulations, you are now a registered user!")
return redirect(url_for("login"))
return render_template("register.html", form=form)
@app.route("/logout")
def logout():
logout_user()
return redirect(url_for("home"))
@app.route("/twlogin")
@login_required
def twlogin():
auth = tweepy.OAuthHandler(twitter_credentials.consumer_key, twitter_credentials.consumer_secret_key, "https://cyberplanificateur.flifloo.fr/twlogin")
if request.args.get("oauth_token") and request.args.get("oauth_verifier"):
auth.request_token = {"oauth_token" : request.args.get("oauth_token"), "oauth_token_secret" : request.args.get("oauth_verifier")}
try:
auth.get_access_token(request.args.get("oauth_verifier"))
except:
return "Error ! Failed to get access token"
else:
twapi = TwitterAPI(access_token = auth.access_token, access_token_secret = auth.access_token_secret, user = current_user)
db.session.add(twapi)
db.session.commit()
elif not TwitterAPI.query.filter_by(user=current_user).first():
return redirect(auth.get_authorization_url())
return redirect(url_for("settings"))
@app.route("/twlogout")
@login_required
def twlogout():
twapi = TwitterAPI.query.filter_by(user=current_user).first()
if twapi:
db.session.delete(twapi)
db.session.commit()
return redirect(url_for("settings"))
@app.route("/trlogin")
@login_required
def trlogin():
return redirect(f"https://trello.com/1/authorize?expiration=never&name=Cyberplanificateur&scope=read,write&response_type=token&key={trello_credentials.api_key}&return_url=https://cyberplanificateur.flifloo.fr/settings")
@app.route("/trlogout")
@login_required
def trlogout():
trapi = TrelloAPI.query.filter_by(user=current_user).first()
if trapi:
db.session.delete(trapi)
db.session.commit()
return redirect(url_for("settings"))
@app.route("/")
def home():
return render_template("index.html")
@app.route("/settings", methods = ["POST", "GET"])
@login_required
def settings():
trloginfail = False
if "trtoken" in request.form:
try:
trello.TrelloClient(api_key = trello_credentials.api_key, token = request.form["trtoken"]).list_boards()
except:
trloginfail = True
else:
trapi = TrelloAPI(token = request.form["trtoken"], user = current_user)
db.session.add(trapi)
db.session.commit()
return render_template("settings.html", twlogin = TwitterAPI.query.filter_by(user=current_user).first(), trlogin = TrelloAPI.query.filter_by(user=current_user).first(), trloginfail = trloginfail)
@app.route("/dashboard", methods = ["POST", "GET"])
def dashboard():
if not tw.is_login(session):
return redirect("/")
twapi = tw.api_login(session)
if request.args.get("twrm"):
database.twrm(request.args.get("twrm"))
if request.args.get("delet"):
twapi.destroy_status(request.args.get["twrm"])
elif "tweet" in request.form and "slots" in request.form and "keywords" in request.form:
try:
slots = int(request.form["slots"])
tweet = int(request.form["tweet"])
except:
formerror = True
else:
database.twadd(twapi.me().id, tweet, slots, str(request.form["keywords"].split(",")))
formerror = False
tweets = list()
idtake = list()
for t in database.twlist(twapi.me().id):
tw = twapi.get_status(t["id"])
keywords = "|"
for te in eval(t["keywords"]):
keywords += f" {te} |"
tweets.append({"text": tw.text, "id": tw.id, "slots": f"{t['slots']}/{t['maxslots']}", "keywords": keywords})
idtake.append(tw.id)
timeline = list()
for t in twapi.user_timeline():
if not t.in_reply_to_status_id and not t.retweeted and t.id not in idtake:
timeline.append({"text": t.text, "id": t.id})
if tr.is_login(session):
trapi = trello.TrelloClient(api_key = trello_credentials.api_key, token = database.trtoken(twapi.me().id))
boards = list()
for b in trapi.list_boards():
boards.append(b.name)
return render_template("dashboard.html", login = True, tweets = tweets, timeline = timeline, boards = boards, columns = None)
@app.route("/twtoken")
def twtoken():
return f"{session['access_token']} -- {session['access_secret_token']}"
@app.route("/twpost")
def twpost():
if tw.is_login(session):
api = twapi_login(session)
api.update_status("bloup")
return "Send !"
else:
return "Not login !"
@app.route("/test")
def test():
return render_template("elements.html")

View file

Before

Width:  |  Height:  |  Size: 401 B

After

Width:  |  Height:  |  Size: 401 B

View file

Before

Width:  |  Height:  |  Size: 396 B

After

Width:  |  Height:  |  Size: 396 B

View file

Before

Width:  |  Height:  |  Size: 357 B

After

Width:  |  Height:  |  Size: 357 B

View file

Before

Width:  |  Height:  |  Size: 434 KiB

After

Width:  |  Height:  |  Size: 434 KiB

View file

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 52 KiB

View file

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View file

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

View file

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View file

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View file

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View file

@ -0,0 +1,96 @@
{% extends "template.html" %}
{% block content %}
<!-- Main -->
<article id="main">
<header>
<h2>Dashboard</h2>
<p>Your personal dashboard</p>
</header>
<section class="wrapper style5">
<div class="inner">
<h3>Current automatized tweets</h3>
<hr />
<table>
<thead>
<tr>
<th class="align-center">Tweet</th>
<th class="align-center">Slots</th>
<th class="align-center">Keywords</th>
<th class="align-center">Actions</th>
</tr>
</thead>
<tbody>
{% for t in tweets %}
<tr>
<td><blockquote>{{ t['text'] }}</blockquote></td>
<td class="align-center">{{ t['slots'] }}</td>
<td class="align-center">{{ t['keywords'] }}</td>
<td class="align-right"><a href="https://cyberplanificateur.flifloo.fr/dashboard?twrm={{ t['id']}}" class="button primary">Disable</a>
<a href="https://cyberplanificateur.flifloo.fr/dashboard?twrm={{ t['id']}}&delet=True" class="button">Delet</a></td>
</tr>
{% endfor %}
</tbody>
</table>
<hr />
<h3>Add an automatized tweet</h3>
<hr />
<form action = "https://cyberplanificateur.flifloo.fr/dashboard" method = "POST">
<section>
<div class="row">
<div class="col-6 col-12-medium">
{% for t in timeline %}
<div class="col-4 col-12-small">
<input type="radio" id="{{ t['id'] }}" name="tweet" value="{{ t['id'] }}">
<label for="{{ t['id'] }}">{{ t['text'] }}</label>
</div>
{% endfor %}
</div>
<div class="col-6 col-12-medium">
<input type="text" name="slots" placeholder="Slots number" />
<input type="text" name="keywords" placeholder="Keywords (separate with a comma)" />
</div>
</div>
</section>
<input type="submit" value="Connect" class="button primary">
</form>
<hr />
<h3>Trello board</h3>
<hr />
<section>
<div class="row">
<div class="col-6 col-12-medium">
<h4>Choose a board</h4>
<form action="https://cyberplanificateur.flifloo.fr/dashboard" method="POST">
{% for b in boards %}
<div class="col-4 col-12-small">
<input type="radio" id="{{ b['id'] }}" name="board" value="{{ b['id'] }}">
<label for="{{ b['id'] }}">{{ b['text'] }}</label>
</div>
{% endfor %}
<input type="submit" value="Select" class="button primary">
</form>
</div>
<div class="col-6 col-12-medium">
<h4>Choose a column</h4>
<form action="https://cyberplanificateur.flifloo.fr/dashboard" method="POST">
{% for c in columns %}
<div class="col-4 col-12-small">
<input type="radio" id="{{ c['id'] }}" name="column" value="{{ c['id'] }}">
<label for="{{ c['id'] }}">{{ c['text'] }}</label>
</div>
{% endfor %}
<input type="submit" value="Select" class="button primary">
</form>
</div>
</div>
</section>
<hr />
</div>
</section>
</article>
{% endblock %}

View file

@ -7,10 +7,10 @@
<h2>Cyberplanificateur</h2> <h2>Cyberplanificateur</h2>
<p>Manage your commissions was never so easy with with the Cyberplanificateur</p> <p>Manage your commissions was never so easy with with the Cyberplanificateur</p>
<ul class="actions special"> <ul class="actions special">
{% if login %} {% if current_user.is_authenticated %}
<li><a href="{{ url_for('dashboard') }}" class="button primary">Dashboard</a></li> <li><a href="{{ url_for('dashboard') }}" class="button primary">Dashboard</a></li>
{% else %} {% else %}
<li><a href="{{ url_for('twlogin') }}" class="button primary">Login !</a></li> <li><a href="{{ url_for('login') }}" class="button primary">Login !</a></li>
{% endif %} {% endif %}
</ul> </ul>
</div> </div>

31
app/templates/login.html Normal file
View file

@ -0,0 +1,31 @@
{% extends "template.html" %}
{% block content %}
<!-- Main -->
<article id="main">
<header>
<h2>Sign In</h2>
</header>
<section class="wrapper style5">
<div class="inner">
<form action="" method="post" novalidate>
{{ form.hidden_tag() }}
<p>
{{ form.username.label }}<br>
{{ form.username(size=32) }}
</p>
<p>
{{ form.password.label }}<br>
{{ form.password(size=32) }}
</p>
<p>{{ form.remember_me() }} {{ form.remember_me.label }}</p>
<p>{{ form.submit() }}</p>
</form>
<p>New User? <a href="{{ url_for('register') }}">Click to Register!</a></p>
</div>
</section>
</article>
{% endblock %}

View file

@ -0,0 +1,49 @@
{% extends "template.html" %}
{% block content %}
<!-- Main -->
<article id="main">
<header>
<h2>Register</h2>
</header>
<section class="wrapper style5">
<div class="inner">
<form action="" method="post">
{{ form.hidden_tag() }}
<p>
{{ form.username.label }}<br>
{{ form.username(size=32) }}<br>
{% for error in form.username.errors %}
<span style="color: red;">[{{ error }}]</span>
{% endfor %}
</p>
<p>
{{ form.email.label }}<br>
{{ form.email(size=64) }}<br>
{% for error in form.email.errors %}
<span style="color: red;">[{{ error }}]</span>
{% endfor %}
</p>
<p>
{{ form.password.label }}<br>
{{ form.password(size=32) }}<br>
{% for error in form.password.errors %}
<span style="color: red;">[{{ error }}]</span>
{% endfor %}
</p>
<p>
{{ form.password2.label }}<br>
{{ form.password2(size=32) }}<br>
{% for error in form.password2.errors %}
<span style="color: red;">[{{ error }}]</span>
{% endfor %}
</p>
<p>{{ form.submit() }}</p>
</form>
</div>
</section>
</article>
{% endblock %}

View file

@ -11,8 +11,13 @@
<div class="inner"> <div class="inner">
<h3>Connexions</h3> <h3>Connexions</h3>
{% if trloginfail and not trlogin %} <p>Twitter :
<h4><font color="red">Invalid Trello token !</font></h4> {% if twlogin %}
<font color="green">Connected</font></p>
<a href="{{ url_for('twlogout') }}" class="button">Disconnect</a>
{% else %}
<font color="red">Disconnected</font></p>
<a href="{{ url_for('twlogin') }}" class="button primary">Connect</a>
{% endif %} {% endif %}
<p>Trello : <p>Trello :
{% if trlogin %} {% if trlogin %}
@ -20,7 +25,7 @@
<a href="{{ url_for('trlogout') }}" class="button">Disconnect</a> <a href="{{ url_for('trlogout') }}" class="button">Disconnect</a>
{% else %} {% else %}
<font color="red">Disconnected</font></p> <font color="red">Disconnected</font></p>
<p><a href="https://trello.com/1/authorize?expiration=never&name=Cyberplanificateur&scope=read,write&response_type=token&key=4b9aa97a8ec693574d819aeaf9e0eefa&return_url=https://cyberplanificateur.flifloo.fr/settings">Click here</a> and give the token bellow</p> <p><a href="{{ url_for('trlogin') }}">Click here</a> and give the token bellow</p>
<form action = "https://cyberplanificateur.flifloo.fr/settings" method = "POST"> <form action = "https://cyberplanificateur.flifloo.fr/settings" method = "POST">
<input type="text" name="trtoken" placeholder="Trello token" /> <input type="text" name="trtoken" placeholder="Trello token" />
<input type="submit" value="Connect" class="button primary"> <input type="submit" value="Connect" class="button primary">

View file

@ -27,12 +27,12 @@
<div id="menu"> <div id="menu">
<ul> <ul>
<li><a href="{{ url_for('home') }}">Home</a></li> <li><a href="{{ url_for('home') }}">Home</a></li>
{% if login %} {% if current_user.is_authenticated %}
<li><a href="{{ url_for('dashboard') }}">Dashboard</a></li> <li><a href="{{ url_for('dashboard') }}">Dashboard</a></li>
<li><a href="{{ url_for('settings')}}">Settings</a></li> <li><a href="{{ url_for('settings')}}">Settings</a></li>
<li><a href="{{ url_for('twlogout')}}">Log Out</a></li> <li><a href="{{ url_for('logout')}}">Log Out</a></li>
{% else %} {% else %}
<li><a href="{{ url_for('twlogin')}}">Log In</a></li> <li><a href="{{ url_for('login')}}">Log In</a></li>
{% endif %} {% endif %}
</ul> </ul>
</div> </div>

7
config.py Normal file
View file

@ -0,0 +1,7 @@
import os
basedir = os.path.abspath(os.path.dirname(__file__))
class Config(object):
SECRET_KEY = "*i9uld6u@t!kxl9%o+byxqf14&a&&@y@q=l$!lg4m%b-a*^o(a"
SQLALCHEMY_DATABASE_URI = "sqlite:///" + os.path.join(basedir, "database.db")
SQLALCHEMY_TRACK_MODIFICATIONS = False

9
cyberplanificateur.py Normal file
View file

@ -0,0 +1,9 @@
from app import app
from app.models import User, TwitterAPI, TrelloAPI
@app.shell_context_processor
def make_shell_context():
return {"db": db, "User": User, "TwitterAPI": TwitterAPI, "TrelloAPI": TrelloAPI}
if __name__ == "__main__":
app.run(debug=True, port=5000, host="0.0.0.0")

View file

@ -7,7 +7,7 @@ def tradd(id, token):
for u in dbc.execute("SELECT * FROM trello WHERE id=?", (id,)): for u in dbc.execute("SELECT * FROM trello WHERE id=?", (id,)):
sucess = False sucess = False
if sucess: if sucess:
dbc.execute("INSERT INTO trello (id, token) VALUES (?, ?)", (id, token)) dbc.execute("INSERT INTO trello (id, token) VALUES (?, ?)", (id, token,))
dbc.close() dbc.close()
db.commit() db.commit()
return sucess return sucess
@ -28,6 +28,31 @@ def trtoken(id):
dbc.close() dbc.close()
return token return token
def twadd(user, id, maxslots, keywords):
with sqlite3.connect('database.db') as db:
dbc = db.cursor()
dbc.execute("INSERT INTO tweets (user, id, slots, maxslots, keywords) VALUES (?, ?, ?, ?, ?)", (user, id, 0, maxslots, keywords,))
dbc.close()
db.commit()
def twrm(id):
with sqlite3.connect('database.db') as db:
dbc = db.cursor()
dbc.execute("DELETE FROM tweets WHERE id=?", (id,))
dbc.close()
db.commit()
def twlist(user):
with sqlite3.connect('database.db') as db:
dbc = db.cursor()
tweets = list()
for u in dbc.execute("SELECT * FROM tweets WHERE user=?", (user,)):
tweets.append({"id": u[1], "slots": u[2], "maxslots": u[3], "keywords": u[4]})
dbc.close()
db.commit()
return tweets
with sqlite3.connect('database.db') as db: with sqlite3.connect('database.db') as db:
Table = False Table = False
dbc = db.cursor() dbc = db.cursor()
@ -36,7 +61,8 @@ with sqlite3.connect('database.db') as db:
for t in dbc.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='trello';"): for t in dbc.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='trello';"):
Table = True Table = True
if not Table: if not Table:
dbc.execute('''CREATE TABLE trello (id text, token text)''') dbc.execute('''CREATE TABLE trello (id int, token text)''')
dbc.execute('''CREATE TABLE tweets (user int, id int, slots int, maxslots int, keywords text)''')
dbc.close() dbc.close()
db.commit() db.commit()
#register("flifloo", "flifloo@gmail.com", "owo") #register("flifloo", "flifloo@gmail.com", "owo")

99
site.py
View file

@ -1,99 +0,0 @@
from flask import Flask, request, redirect, session, render_template
import twitter_credentials, tweepy, database, trello_credentials, trello
app = Flask(__name__)
app.secret_key = "*i9uld6u@t!kxl9%o+byxqf14&a&&@y@q=l$!lg4m%b-a*^o(a"
def is_twkeys(session):
try:
session["access_token"]
session["access_secret_token"]
except:
return False
else:
return True
def twapi_login(session):
auth = tweepy.OAuthHandler(twitter_credentials.consumer_key, twitter_credentials.consumer_secret_key)
auth.set_access_token(session["access_token"], session["access_secret_token"])
return tweepy.API(auth)
def is_twlogin(session):
return is_twkeys(session) and twapi_login(session).verify_credentials()
def is_trlogin(session):
return is_twkeys(session) and database.trtoken(twapi_login(session).me().id)
@app.route("/twlogin")
def twlogin():
auth = tweepy.OAuthHandler(twitter_credentials.consumer_key, twitter_credentials.consumer_secret_key, "https://cyberplanificateur.flifloo.fr/twlogin")
if request.args.get("oauth_token") and request.args.get("oauth_verifier"):
auth.request_token = {"oauth_token" : request.args.get("oauth_token"), "oauth_token_secret" : request.args.get("oauth_verifier")}
try:
auth.get_access_token(request.args.get("oauth_verifier"))
except:
return "Error ! Failed to get access token"
else:
session["access_token"] = auth.access_token
session["access_secret_token"] = auth.access_token_secret
elif not is_twlogin(session):
return redirect(auth.get_authorization_url())
return redirect("/")
@app.route("/twlogout")
def twlogout():
if is_twkeys(session):
session.pop("access_token", None)
session.pop("access_secret_token", None)
return redirect("/")
@app.route("/trlogout")
def trlogout():
if not is_twlogin(session):
return redirect("/")
if is_trlogin(session):
database.trrm(twapi_login(session).me().id)
return redirect("/settings")
@app.route("/")
def home():
return render_template("index.html", login = is_twlogin(session))
@app.route("/settings", methods = ['POST', 'GET'])
def settings():
if not is_twlogin(session):
return redirect("/")
trloginfail = False
if "trtoken" in request.form:
try:
trello.TrelloClient(api_key = trello_credentials.api_key, token = request.form["trtoken"]).list_boards()
except:
trloginfail = True
else:
database.tradd(twapi_login(session).me().id, request.form["trtoken"])
return render_template("settings.html", login = True, trlogin = is_trlogin(session), trloginfail = trloginfail)
@app.route("/dashboard")
def dashboard():
if not is_twlogin(session):
return redirect("/")
return render_template("dashboard.html", login = True, tweets = ["test1", "test2", "test3"], timeline = [{"id": 1, "text": "test1"}, {"id": 2, "text": "test2"}, {"id": 3, "text": "test3"}, {"id": 4, "text": "test4"}])
@app.route("/twpost")
def twpost():
if is_twlogin(session):
api = twapi_login(session)
api.update_status("bloup")
return "Send !"
else:
return "Not login !"
@app.route("/test")
def test():
return render_template("elements.html")
if __name__ == "__main__":
app.run(debug=True, port=5000, host="0.0.0.0")

View file

@ -1,64 +0,0 @@
{% extends "template.html" %}
{% block content %}
<!-- Main -->
<article id="main">
<header>
<h2>Dashboard</h2>
<p>Your personal dashboard</p>
</header>
<section class="wrapper style5">
<div class="inner">
<h3>Current automatized tweets</h3>
<hr />
<table>
{% for t in tweets %}
<tr>
<td><blockquote>{{ t }}</blockquote></td>
<td><a href="#" class="button primary">Disable</a>
<a href="#" class="button">Delet</a></td>
</tr>
{% endfor %}
</table>
<hr />
<h3>Add an automatized tweet</h3>
<hr />
<section>
<div class="row">
<div class="col-6 col-12-medium">
{% for t in timeline %}
<div class="col-4 col-12-small">
<input type="radio" id="{{ t['id'] }}" name="tweet">
<label for="{{ t['id'] }}">{{ t['text'] }}</label>
</div>
{% endfor %}
</div>
<div class="col-6 col-12-medium">
<input type="text" name="slots" placeholder="Slots number" />
<input type="text" name="keywords" placeholder="Keywords (separate with a comma)" />
</div>
</div>
</section>
<input type="submit" value="Connect" class="button primary">
<hr />
<h3>Trello board</h3>
<hr />
<section>
<div class="row">
<div class="col-6 col-12-medium">
<h4>Choose a board</h4>
</div>
<div class="col-6 col-12-medium">
<h4>Choose a columns</h4>
</div>
</div>
</section>
<hr />
</div>
</section>
</article>
{% endblock %}

5
tr.py Normal file
View file

@ -0,0 +1,5 @@
import trello
import tw
def is_trlogin(session):
return is_twkeys(session) and database.trtoken(tw.api_login(session).me().id)

18
tw.py Normal file
View file

@ -0,0 +1,18 @@
import tweepy, twitter_credentials
def api_login(session):
auth = tweepy.OAuthHandler(twitter_credentials.consumer_key, twitter_credentials.consumer_secret_key)
auth.set_access_token(session["access_token"], session["access_secret_token"])
return tweepy.API(auth)
def is_keys(session):
try:
session["access_token"]
session["access_secret_token"]
except:
return False
else:
return True
def is_login(session):
return is_keys(session) and api_login(session).verify_credentials()