1
0
Fork 0

End of rework

This commit is contained in:
Ethanell 2019-04-29 15:53:18 +02:00
parent 6beb1bb246
commit 2415834c72
9 changed files with 168 additions and 181 deletions

View file

@ -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")

View file

@ -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))

View file

@ -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")

View file

@ -12,6 +12,7 @@
<h3>Current automatized tweets</h3>
<hr />
{% if current_user.twitter_api.first() %}
<table>
<thead>
<tr>
@ -33,10 +34,14 @@
{% endfor %}
</tbody>
</table>
{% else %}
<h4>Twitter API not connected</h4>
{% endif %}
<hr />
<h3>Add an automatized tweet</h3>
<hr />
{% if current_user.twitter_api.first() %}
<form action = "https://cyberplanificateur.flifloo.fr/dashboard" method = "POST">
<section>
<div class="row">
@ -54,12 +59,16 @@
</div>
</div>
</section>
<input type="submit" value="Connect" class="button primary">
<input type="submit" value="Select" class="button primary">
</form>
{% else %}
<h4>Twitter API not connected</h4>
{% endif %}
<hr />
<h3>Trello board</h3>
<hr />
{% if current_user.trello_api.first() %}
<section>
<div class="row">
<div class="col-6 col-12-medium">
@ -67,7 +76,7 @@
<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'] }}">
<input type="radio" id="{{ b['id'] }}" name="board" value="{{ b['id'] }}" {% if b['select'] %} checked="checked" {% endif %}>
<label for="{{ b['id'] }}">{{ b['text'] }}</label>
</div>
{% endfor %}
@ -76,18 +85,25 @@
</div>
<div class="col-6 col-12-medium">
<h4>Choose a column</h4>
{% if columns %}
<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'] }}">
<input type="radio" id="{{ c['id'] }}" name="column" value="{{ c['id'] }}" {% if c['select'] %} checked="checked" {% endif %}>
<label for="{{ c['id'] }}">{{ c['text'] }}</label>
</div>
{% endfor %}
<input type="submit" value="Select" class="button primary">
</form>
{% else %}
<p>No board set yet</p>
{% endif %}
</div>
</div>
</section>
{% else %}
<h4>Trello API not connected</h4>
{% endif %}
<hr />
</div>
</section>

View file

@ -14,10 +14,16 @@
<p>
{{ form.username.label }}<br>
{{ form.username(size=32) }}
{% for error in form.username.errors %}
<span style="color: red;">[{{ error }}]</span>
{% endfor %}
</p>
<p>
{{ form.password.label }}<br>
{{ form.password(size=32) }}
{% for error in form.password.errors %}
<span style="color: red;">[{{ error }}]</span>
{% endfor %}
</p>
<p>{{ form.remember_me() }} {{ form.remember_me.label }}</p>
<p>{{ form.submit() }}</p>

View file

@ -12,7 +12,7 @@
<h3>Connexions</h3>
<p>Twitter :
{% if twlogin %}
{% if current_user.twitter_api.first() %}
<font color="green">Connected</font></p>
<a href="{{ url_for('twlogout') }}" class="button">Disconnect</a>
{% else %}
@ -20,15 +20,22 @@
<a href="{{ url_for('twlogin') }}" class="button primary">Connect</a>
{% endif %}
<p>Trello :
{% if trlogin %}
{% if current_user.trello_api.first() %}
<font color="green">Connected</font></p>
<a href="{{ url_for('trlogout') }}" class="button">Disconnect</a>
{% else %}
<font color="red">Disconnected</font></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">
<input type="text" name="trtoken" placeholder="Trello token" />
<input type="submit" value="Connect" class="button primary">
<form action = "" method = "POST" novalidate>
{{ form.hidden_tag() }}
<p>
{{ form.token.label }}
{{ form.token(size=64) }}
{% for error in form.token.errors %}
<span style="color: red;">[{{ error }}]</span>
{% endfor %}
</p>
<p>{{ form.submit() }}</p>
</form>
{% endif %}

View file

@ -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")

5
tr.py
View file

@ -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)

18
tw.py
View file

@ -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()