From 2415834c72934a530f0036733f43497fa8833f91 Mon Sep 17 00:00:00 2001
From: flifloo
Date: Mon, 29 Apr 2019 15:53:18 +0200
Subject: [PATCH] End of rework
---
app/forms.py | 38 ++++++---
app/models.py | 27 ++++++-
app/routes.py | 148 ++++++++++++++++++-----------------
app/templates/dashboard.html | 22 +++++-
app/templates/login.html | 6 ++
app/templates/settings.html | 17 ++--
database.py | 68 ----------------
tr.py | 5 --
tw.py | 18 -----
9 files changed, 168 insertions(+), 181 deletions(-)
delete mode 100644 database.py
delete mode 100644 tr.py
delete mode 100644 tw.py
diff --git a/app/forms.py b/app/forms.py
index 4afddfd..84cb7f8 100644
--- a/app/forms.py
+++ b/app/forms.py
@@ -1,28 +1,48 @@
from flask_wtf import FlaskForm
-from wtforms import StringField, PasswordField, BooleanField, SubmitField
+from wtforms import StringField, PasswordField, BooleanField, SubmitField, RadioField, IntegerField
from wtforms.validators import ValidationError, DataRequired, Email, EqualTo
from app.models import User
+import trello, trello_credentials
class LoginForm(FlaskForm):
- username = StringField("Username", validators=[DataRequired()])
- password = PasswordField("Password", validators=[DataRequired()])
+ username = StringField("Username", validators = [DataRequired()])
+ password = PasswordField("Password", validators = [DataRequired()])
remember_me = BooleanField("Remember Me")
submit = SubmitField("Sign In")
+ def validate_username(self, username):
+ if not User.query.filter_by(username = username.data).first():
+ raise ValidationError("Invalid username.")
+
+ def validate_password(self, password):
+ user = User.query.filter_by(username = self.username.data).first()
+ if user and not user.check_password(password.data):
+ raise ValidationError("Invalid password.")
+
class RegistrationForm(FlaskForm):
- username = StringField("Username", validators=[DataRequired()])
- email = StringField("Email", validators=[DataRequired(), Email()])
- password = PasswordField("Password", validators=[DataRequired()])
+ username = StringField("Username", validators = [DataRequired()])
+ email = StringField("Email", validators = [DataRequired(), Email()])
+ password = PasswordField("Password", validators = [DataRequired()])
password2 = PasswordField(
- "Repeat Password", validators=[DataRequired(), EqualTo("password")])
+ "Repeat Password", validators = [DataRequired(), EqualTo("password")])
submit = SubmitField("Register")
def validate_username(self, username):
- user = User.query.filter_by(username=username.data).first()
+ 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()
+ user = User.query.filter_by(email = email.data).first()
if user is not None:
raise ValidationError("Please use a different email address.")
+
+class TrelloAPIForm(FlaskForm):
+ token = StringField("Token", validators = [DataRequired()])
+ submit = SubmitField("Connect")
+
+ def validate_token(self, token):
+ try:
+ trello.TrelloClient(api_key = trello_credentials.api_key, token = token.data).list_boards()
+ except:
+ raise ValidationError("Invalid Trello Token")
diff --git a/app/models.py b/app/models.py
index 24dbecb..42ce835 100644
--- a/app/models.py
+++ b/app/models.py
@@ -2,6 +2,7 @@ from app import db
from werkzeug.security import generate_password_hash, check_password_hash
from flask_login import UserMixin
from app import login
+import tweepy, twitter_credentials, trello, trello_credentials
class User(UserMixin, db.Model):
id = db.Column(db.Integer, primary_key=True, unique=True)
@@ -9,7 +10,9 @@ class User(UserMixin, db.Model):
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")
+ tweets = db.relationship("Tweets", backref="user", lazy="dynamic")
+ trello_api = db.relationship("TrelloAPI", backref="user", lazy="dynamic")
+ boards = db.relationship("Boards", backref="user", lazy="dynamic")
def set_password(self, password):
self.password_hash = generate_password_hash(password)
@@ -26,11 +29,33 @@ class TwitterAPI(db.Model):
access_token = db.Column(db.String(50), unique=True)
access_token_secret = db.Column(db.String(45), unique=True)
+ def api_login(self):
+ auth = tweepy.OAuthHandler(twitter_credentials.consumer_key, twitter_credentials.consumer_secret_key)
+ auth.set_access_token(self.access_token, self.access_token_secret)
+ return tweepy.API(auth)
+
+class Tweets(db.Model):
+ id = db.Column(db.Integer, primary_key=True, unique=True)
+ user_id = db.Column(db.Integer, db.ForeignKey("user.id"))
+ statu_id = db.Column(db.Integer, unique=True)
+ slots = db.Column(db.Integer)
+ slots_max = db.Column(db.Integer)
+ keywords = db.Column(db.String(256))
+
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)
+ def api_login(self):
+ return trello.TrelloClient(api_key = trello_credentials.api_key, token = self.token)
+
+class Boards(db.Model):
+ id = db.Column(db.Integer, primary_key=True, unique=True)
+ user_id = db.Column(db.Integer, db.ForeignKey("user.id"), unique=True)
+ board_id = db.Column(db.String(24))
+ column_id = db.Column(db.String(24))
+
@login.user_loader
def load_user(id):
return User.query.get(int(id))
diff --git a/app/routes.py b/app/routes.py
index 6e60a29..5a5bf77 100644
--- a/app/routes.py
+++ b/app/routes.py
@@ -1,11 +1,10 @@
from app import app, db
-from flask import Flask, request, redirect, session, render_template, flash, url_for
+from flask import Flask, request, redirect, session, render_template, 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 app.forms import LoginForm, RegistrationForm, TrelloAPIForm
+from app.models import User, TwitterAPI, Tweets, TrelloAPI, Boards
from werkzeug.urls import url_parse
-import twitter_credentials, tweepy, tw
-import trello_credentials, trello, tr
+import tweepy, trello, twitter_credentials, trello_credentials
@app.route("/login", methods=["GET", "POST"])
def login():
@@ -13,16 +12,13 @@ def login():
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)
+ user = User.query.filter_by(username = form.username.data).first()
+ 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)
+ return render_template("login.html", form = form)
@app.route("/register", methods=["GET", "POST"])
def register():
@@ -30,11 +26,10 @@ def register():
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)
+ u = User(username=form.username.data, email=form.email.data)
+ u.set_password(form.password.data)
+ db.session.add(u)
db.session.commit()
- flash("Congratulations, you are now a registered user!")
return redirect(url_for("login"))
return render_template("register.html", form=form)
@@ -46,6 +41,8 @@ def logout():
@app.route("/twlogin")
@login_required
def twlogin():
+ if current_user.twitter_api.first():
+ return "Already an api connected."
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")}
@@ -54,8 +51,7 @@ def twlogin():
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.add(TwitterAPI(access_token = auth.access_token, access_token_secret = auth.access_token_secret, user = current_user))
db.session.commit()
elif not TwitterAPI.query.filter_by(user=current_user).first():
return redirect(auth.get_authorization_url())
@@ -73,6 +69,8 @@ def twlogout():
@app.route("/trlogin")
@login_required
def trlogin():
+ if current_user.twitter_api.first():
+ return "Already an api connected."
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")
@@ -91,75 +89,81 @@ def home():
@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)
+ form = TrelloAPIForm()
+ if form.validate_on_submit():
+ if current_user.trello_api.first():
+ return "Already an api connected."
+ db.session.add(TrelloAPI(token = form.token.data, user = current_user))
+ db.session.commit()
+ return render_template("settings.html", form = form)
@app.route("/dashboard", methods = ["POST", "GET"])
+@login_required
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
-
+ twapi = current_user.twitter_api.first()
+ trapi = current_user.trello_api.first()
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})
+ boards = list()
+ columns = list()
- if tr.is_login(session):
- trapi = trello.TrelloClient(api_key = trello_credentials.api_key, token = database.trtoken(twapi.me().id))
- boards = list()
+ if twapi:
+ twapi = twapi.api_login()
+
+ if request.args.get("twrm"):
+ db.session.delete(Tweets.query.filter_by(user = current_user, statu_id = request.args.get("twrm")).first())
+ db.session.commit()
+ 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:
+ db.session.add(Tweets(user = current_user, statu_id = tweet, slots = 0, slots_max = slots, keywords = str(request.form["keywords"].split(","))))
+ db.session.commit()
+ elif "board" in request.form:
+ db.session.add(Boards(user = current_user, board_id = request.form["board"]))
+ db.session.commit()
+ elif "column" in request.form:
+ current_user.boards.first().column_id = request.form["column"]
+ db.session.commit()
+
+ for t in Tweets.query.filter_by(user = current_user):
+ statu = twapi.get_status(t.statu_id)
+ keywords = "|"
+ for text in eval(t.keywords):
+ keywords += f" {text} |"
+ tweets.append({"text": statu.text, "id": t.statu_id, "slots": f"{t.slots}/{t.slots_max}", "keywords": keywords})
+
+ for t in twapi.user_timeline():
+ if not t.in_reply_to_status_id and not t.retweeted and not Tweets.query.filter_by(user = current_user, statu_id = t.id).first():
+ timeline.append({"text": t.text, "id": t.id})
+
+
+ if trapi:
+ trapi = trapi.api_login()
for b in trapi.list_boards():
- boards.append(b.name)
+ select = False
+ if b.id == current_user.boards.first().board_id:
+ select = True
+ boards.append({"text": b.name, "id": b.id, "select": select})
+ if current_user.boards.first() and current_user.boards.first().board_id:
+ for c in trapi.get_board(current_user.boards.first().board_id).list_lists():
+ select = False
+ if c.id == current_user.boards.first().column_id:
+ select = True
+ columns.append({"text": c.name, "id": c.id, "select": select})
- return render_template("dashboard.html", login = True, tweets = tweets, timeline = timeline, boards = boards, columns = None)
+ return render_template("dashboard.html", timeline = timeline, tweets = tweets, boards = boards, columns = columns)
@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")
diff --git a/app/templates/dashboard.html b/app/templates/dashboard.html
index b602dea..48b7935 100644
--- a/app/templates/dashboard.html
+++ b/app/templates/dashboard.html
@@ -12,6 +12,7 @@
Current automatized tweets
+ {% if current_user.twitter_api.first() %}
@@ -33,10 +34,14 @@
{% endfor %}
+ {% else %}
+ Twitter API not connected
+ {% endif %}
Add an automatized tweet
+ {% if current_user.twitter_api.first() %}
+ {% else %}
+ Twitter API not connected
+ {% endif %}
Trello board
+ {% if current_user.trello_api.first() %}
Choose a column
+ {% if columns %}
+ {% else %}
+
No board set yet
+ {% endif %}
+ {% else %}
+ Trello API not connected
+ {% endif %}
diff --git a/app/templates/login.html b/app/templates/login.html
index 1dfec0b..33f5160 100644
--- a/app/templates/login.html
+++ b/app/templates/login.html
@@ -14,10 +14,16 @@
{{ form.username.label }}
{{ form.username(size=32) }}
+ {% for error in form.username.errors %}
+ [{{ error }}]
+ {% endfor %}
{{ form.password.label }}
{{ form.password(size=32) }}
+ {% for error in form.password.errors %}
+ [{{ error }}]
+ {% endfor %}
{{ form.remember_me() }} {{ form.remember_me.label }}
{{ form.submit() }}
diff --git a/app/templates/settings.html b/app/templates/settings.html
index 0f19606..bbb41ed 100644
--- a/app/templates/settings.html
+++ b/app/templates/settings.html
@@ -12,7 +12,7 @@
Connexions
Twitter :
- {% if twlogin %}
+ {% if current_user.twitter_api.first() %}
Connected
Disconnect
{% else %}
@@ -20,15 +20,22 @@
Connect
{% endif %}
Trello :
- {% if trlogin %}
+ {% if current_user.trello_api.first() %}
Connected
Disconnect
{% else %}
Disconnected
Click here and give the token bellow
-
{% endif %}
diff --git a/database.py b/database.py
deleted file mode 100644
index 3bbd5dd..0000000
--- a/database.py
+++ /dev/null
@@ -1,68 +0,0 @@
-import sqlite3
-
-def tradd(id, token):
- with sqlite3.connect('database.db') as db:
- sucess = True
- dbc = db.cursor()
- for u in dbc.execute("SELECT * FROM trello WHERE id=?", (id,)):
- sucess = False
- if sucess:
- dbc.execute("INSERT INTO trello (id, token) VALUES (?, ?)", (id, token,))
- dbc.close()
- db.commit()
- return sucess
-
-def trrm(id):
- with sqlite3.connect('database.db') as db:
- dbc = db.cursor()
- dbc.execute("DELETE FROM trello WHERE id=?", (id,))
- dbc.close()
- db.commit()
-
-def trtoken(id):
- with sqlite3.connect('database.db') as db:
- token = False
- dbc = db.cursor()
- for u in dbc.execute("SELECT * FROM trello WHERE id=?;", (id,)):
- token = u
- dbc.close()
- 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:
- Table = False
- dbc = db.cursor()
- log = False
- iid = None
- for t in dbc.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='trello';"):
- Table = True
- if not Table:
- 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()
- db.commit()
- #register("flifloo", "flifloo@gmail.com", "owo")
diff --git a/tr.py b/tr.py
deleted file mode 100644
index e0cd1fb..0000000
--- a/tr.py
+++ /dev/null
@@ -1,5 +0,0 @@
-import trello
-import tw
-
-def is_trlogin(session):
- return is_twkeys(session) and database.trtoken(tw.api_login(session).me().id)
diff --git a/tw.py b/tw.py
deleted file mode 100644
index 59cebe1..0000000
--- a/tw.py
+++ /dev/null
@@ -1,18 +0,0 @@
-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()