1
0
Fork 0
mirror of https://github.com/Lynnesbian/FediBooks/ synced 2024-11-25 16:48:58 +00:00

Compare commits

...

24 commits

Author SHA1 Message Date
1c67016fa6
emphasise that you need to add accounts to learn from 2020-01-20 15:30:01 +10:00
dc7787d296
more stable code with better error handling 2020-01-20 15:21:46 +10:00
fe01416134
add missing db connection 2020-01-20 14:40:59 +10:00
8cab227531
remove debug code 2020-01-20 14:39:42 +10:00
4b6e563f76
fixed yet another silly issue 2020-01-20 14:38:55 +10:00
07670c4a74
handle running out of posts gracefully 2020-01-20 14:37:39 +10:00
f1a4811094
new generic image 2020-01-20 14:35:58 +10:00
570c62a779
remove commented out stuff 2020-01-20 14:08:41 +10:00
39178dff9c
fix incorrect link 2020-01-20 14:08:30 +10:00
d8dc54f802
only keep 50 most recent messages, disable input box while waiting for a reply 2020-01-20 14:06:39 +10:00
e9cdbf7de2
actually display the error message when there's an error 2020-01-20 13:49:16 +10:00
3d0cdbc5e5
chat UI improvements 2020-01-20 13:46:30 +10:00
d48eb9264f
added a note about JS to the footer 2020-01-20 13:23:40 +10:00
5f089f4040
basic chat functionality 2020-01-20 13:18:59 +10:00
60728c0b35
message generation for bot chat 2020-01-20 13:01:56 +10:00
170a666496
fixed a silly 2020-01-20 12:56:24 +10:00
898f2f7aae
seperated text generation and posting into their own functions 2020-01-20 12:53:11 +10:00
841098cc18
less logspam 2020-01-20 12:52:38 +10:00
34622230b0
allow sending messages in bot chat 2020-01-20 12:43:25 +10:00
11197eb7e7
better englische 2020-01-20 12:22:07 +10:00
9830eeda6b
less log spam 2020-01-20 12:18:17 +10:00
6cfa9ef35f
temporary print statement for debugging 2020-01-20 12:15:27 +10:00
fa60a6569d
less error spam 2020-01-20 12:12:53 +10:00
d06f89ed3f
better mysql instructions 2020-01-20 12:02:22 +10:00
13 changed files with 201 additions and 76 deletions

View file

@ -27,8 +27,7 @@ If this doesn't work, try using ``pip`` instead. If it still doesn't work, you m
``` ```
CREATE DATABASE `fedibooks`; CREATE DATABASE `fedibooks`;
CREATE USER 'myuser' IDENTIFIED BY 'mypassword'; CREATE USER 'myuser' IDENTIFIED BY 'mypassword';
GRANT USAGE ON *.* TO 'myuser'@localhost IDENTIFIED BY 'mypassword'; GRANT ALL PRIVILEGES ON `fedibooks`.* TO 'myuser';
GRANT ALL privileges ON `fedibooks`.* TO 'myuser'@localhost;
FLUSH PRIVILEGES; FLUSH PRIVILEGES;
exit exit
``` ```

View file

@ -34,24 +34,18 @@ def extract_post(post):
text = text.rstrip("\n") # remove trailing newline(s) text = text.rstrip("\n") # remove trailing newline(s)
return text return text
def make_post(args): def generate_output(handle):
id = None
acct = None
if len(args) > 1:
id = args[1]
acct = args[3]
handle = args[0]
db = MySQLdb.connect( db = MySQLdb.connect(
host = cfg['db_host'], host = cfg['db_host'],
user=cfg['db_user'], user=cfg['db_user'],
passwd=cfg['db_pass'], passwd=cfg['db_pass'],
db=cfg['db_name'] db=cfg['db_name']
) )
print("Generating post for {}".format(handle)) # print("Generating post for {}".format(handle))
dc = db.cursor(MySQLdb.cursors.DictCursor) dc = db.cursor(MySQLdb.cursors.DictCursor)
c = db.cursor() c = db.cursor()
dc.execute(""" dc.execute("""
SELECT SELECT
learn_from_cw, learn_from_cw,
length, length,
fake_mentions, fake_mentions,
@ -64,17 +58,11 @@ def make_post(args):
FROM FROM
bots, credentials bots, credentials
WHERE WHERE
bots.handle = %s bots.handle = %s
AND bots.credentials_id = credentials.id AND bots.credentials_id = credentials.id
""", (handle,)) """, (handle,))
bot = dc.fetchone() bot = dc.fetchone()
client = Mastodon(
client_id = bot['client_id'],
client_secret = bot['client_secret'],
access_token = bot['secret'],
api_base_url = "https://{}".format(handle.split("@")[2])
)
# by default, only select posts that don't have CWs. # by default, only select posts that don't have CWs.
# if learn_from_cw, then also select posts with CWs # if learn_from_cw, then also select posts with CWs
@ -92,7 +80,7 @@ def make_post(args):
# 4. join the list into a string separated by newlines # 4. join the list into a string separated by newlines
posts = "\n".join(list(sum(c.fetchall(), ()))) posts = "\n".join(list(sum(c.fetchall(), ())))
if len(posts) == 0: if len(posts) == 0:
print("No posts to learn from.") print("{} - No posts to learn from.".format(handle))
return return
if bot['fake_mentions'] == 'never': if bot['fake_mentions'] == 'never':
@ -124,30 +112,64 @@ def make_post(args):
if bot['fake_mentions_full']: if bot['fake_mentions_full']:
post = re.sub(r"@(\w+)@([\w.]+)", r"@{}\1@{}\2".format(zws, zws), post) post = re.sub(r"@(\w+)@([\w.]+)", r"@{}\1@{}\2".format(zws, zws), post)
else: else:
post = re.sub(r"@(\w+)@([\w.]+)", r"@{}\1".format(zws), post) post = re.sub(r"@(\w+)@([\w.]+)", r"@{}\1".format(zws), post)
# also format handles without instances, e.g. @user instead of @user@instan.ce # also format handles without instances, e.g. @user instead of @user@instan.ce
post = re.sub(r"(?<!\S)@(\w+)", r"@{}\1".format(zws), post) post = re.sub(r"(?<!\S)@(\w+)", r"@{}\1".format(zws), post)
print(post) return bot, post
visibility = bot['post_privacy'] if len(args) == 1 else args[2]
visibilities = ['public', 'unlisted', 'private']
if visibilities.index(visibility) < visibilities.index(bot['post_privacy']):
# if post_privacy is set to a more restricted level than the visibility of the post we're replying to, use the user's setting
visibility = bot['post_privacy']
if acct is not None:
post = "{} {}".format(acct, post)
# ensure post isn't longer than bot['length']
post = post[:bot['length']] def make_post(args):
# send toot!! id = None
try: acct = None
client.status_post(post, id, visibility = visibility, spoiler_text = bot['content_warning']) if len(args) > 1:
except MastodonUnauthorizedError: id = args[1]
# user has revoked the token given to the bot acct = args[3]
# this needs to be dealt with properly later on, but for now, we'll just disable the bot handle = args[0]
c.execute("UPDATE bots SET enabled = FALSE WHERE handle = %s", (handle,))
# print("Generating post for {}".format(handle))
bot, post = generate_output(handle)
client = Mastodon(
client_id = bot['client_id'],
client_secret = bot['client_secret'],
access_token = bot['secret'],
api_base_url = "https://{}".format(handle.split("@")[2])
)
db = MySQLdb.connect(
host = cfg['db_host'],
user=cfg['db_user'],
passwd=cfg['db_pass'],
db=cfg['db_name']
)
c = db.cursor()
# print(post)
visibility = bot['post_privacy'] if len(args) == 1 else args[2]
visibilities = ['public', 'unlisted', 'private']
if visibilities.index(visibility) < visibilities.index(bot['post_privacy']):
# if post_privacy is set to a more restricted level than the visibility of the post we're replying to, use the user's setting
visibility = bot['post_privacy']
if acct is not None:
post = "{} {}".format(acct, post)
# ensure post isn't longer than bot['length']
# TODO: ehhhhhhhhh
post = post[:bot['length']]
# send toot!!
try:
client.status_post(post, id, visibility = visibility, spoiler_text = bot['content_warning'])
except MastodonUnauthorizedError:
# user has revoked the token given to the bot
# this needs to be dealt with properly later on, but for now, we'll just disable the bot
c.execute("UPDATE bots SET enabled = FALSE WHERE handle = %s", (handle,))
except:
print("Failed to create post for {}".format(handle))
if id == None: if id == None:
# this wasn't a reply, it was a regular post, so update the last post date # this wasn't a reply, it was a regular post, so update the last post date
c.execute("UPDATE bots SET last_post = CURRENT_TIMESTAMP() WHERE handle = %s", (handle,)) c.execute("UPDATE bots SET last_post = CURRENT_TIMESTAMP() WHERE handle = %s", (handle,))
db.commit() db.commit()
c.close()

View file

@ -47,7 +47,7 @@ def bot_accounts_add(mysql, cfg):
else: else:
session['instance_type'] = "Mastodon" session['instance_type'] = "Mastodon"
session['step'] += 1 session['step'] += 1
else: else:
error = "Unsupported instance type. Misskey support is planned." error = "Unsupported instance type. Misskey support is planned."
return render_template("bot/accounts_add.html", error = error) return render_template("bot/accounts_add.html", error = error)
@ -81,12 +81,13 @@ def bot_accounts_add(mysql, cfg):
username = client.account_verify_credentials()['username'] username = client.account_verify_credentials()['username']
if username != session['username']: if username != session['username']:
error = "Please authenticate as {}.".format(session['username']) error = "Please authenticate as {}.".format(session['username'])
print("Auth error - {} is not {}".format(session['username'], username))
return render_template("bot/accounts_add.html", error = error) return render_template("bot/accounts_add.html", error = error)
except: except:
session['step'] = 1 session['step'] = 1
error = "Authentication failed." error = "Authentication failed."
return render_template("bot/accounts_add.html", error = error) return render_template("bot/accounts_add.html", error = error)
# 1. download host-meta to find webfinger URL # 1. download host-meta to find webfinger URL
r = requests.get("https://{}/.well-known/host-meta".format(session['instance']), timeout=10) r = requests.get("https://{}/.well-known/host-meta".format(session['instance']), timeout=10)
if r.status_code != 200: if r.status_code != 200:

View file

@ -19,7 +19,7 @@ def scrape_posts(account):
) )
handle = account[0] handle = account[0]
outbox = account[1] outbox = account[1]
print("Scraping {}".format(handle)) # print("Scraping {}".format(handle))
c = db.cursor() c = db.cursor()
last_post = 0 last_post = 0
c.execute("SELECT COUNT(*) FROM `posts` WHERE `fedi_id` = %s", (handle,)) c.execute("SELECT COUNT(*) FROM `posts` WHERE `fedi_id` = %s", (handle,))
@ -80,9 +80,15 @@ def scrape_posts(account):
if not done: if not done:
if pleroma: if pleroma:
r = requests.get(j['next'], timeout = 10) if 'next' in j:
r = requests.get(j['next'], timeout = 10)
else:
done = True
else: else:
r = requests.get(j['prev'], timeout = 10) if 'prev' in j:
r = requests.get(j['prev'], timeout = 10)
else:
done = True
if r.status_code == 429: if r.status_code == 429:
# we are now being ratelimited, move on to the next user # we are now being ratelimited, move on to the next user
@ -94,7 +100,7 @@ def scrape_posts(account):
db.commit() db.commit()
db.commit() db.commit()
print("Finished scraping {}".format(handle)) # print("Finished scraping {}".format(handle))
print("Establishing DB connection") print("Establishing DB connection")
db = MySQLdb.connect( db = MySQLdb.connect(

View file

@ -2,33 +2,55 @@
import MySQLdb import MySQLdb
from mastodon import Mastodon from mastodon import Mastodon
from multiprocessing import Pool from multiprocessing import Pool
import requests
import json import json
import functions import functions
cfg = json.load(open('config.json')) cfg = json.load(open('config.json'))
def update_icon(bot): def update_icon(bot):
db = MySQLdb.connect( try:
host = cfg['db_host'], db = MySQLdb.connect(
user=cfg['db_user'], host = cfg['db_host'],
passwd=cfg['db_pass'], user=cfg['db_user'],
db=cfg['db_name'], passwd=cfg['db_pass'],
use_unicode=True, db=cfg['db_name'],
charset="utf8mb4" use_unicode=True,
) charset="utf8mb4"
)
except:
print("Failed to connect to database.")
return
url = "https://{}".format(bot['handle'].split("@")[2])
try:
r = requests.head(url, timeout=10, allow_redirects = True)
if r.status_code != 200:
raise
except:
print("{} is down.".format(url))
return
print("Updating cached icon for {}".format(bot['handle']))
client = Mastodon( client = Mastodon(
client_id = bot['client_id'], client_id = bot['client_id'],
client_secret = bot['client_secret'], client_secret = bot['client_secret'],
access_token = bot['secret'], access_token = bot['secret'],
api_base_url = "https://{}".format(bot['handle'].split("@")[2]) api_base_url = url
) )
avatar = client.account_verify_credentials()['avatar']
c = db.cursor() c = db.cursor()
try:
avatar = client.account_verify_credentials()['avatar']
except:
c.execute("UPDATE bots SET icon_update_time = CURRENT_TIMESTAMP() WHERE handle = %s", (bot['handle'],))
db.commit()
c.close()
return
c.execute("UPDATE bots SET icon = %s, icon_update_time = CURRENT_TIMESTAMP() WHERE handle = %s", (avatar, bot['handle'])) c.execute("UPDATE bots SET icon = %s, icon_update_time = CURRENT_TIMESTAMP() WHERE handle = %s", (avatar, bot['handle']))
db.commit() db.commit()
c.close()
print("Establishing DB connection") print("Establishing DB connection")
db = MySQLdb.connect( db = MySQLdb.connect(
@ -48,6 +70,7 @@ db.commit()
print("Generating posts") print("Generating posts")
cursor.execute("SELECT handle FROM bots WHERE enabled = TRUE AND TIMESTAMPDIFF(MINUTE, last_post, CURRENT_TIMESTAMP()) >= post_frequency") cursor.execute("SELECT handle FROM bots WHERE enabled = TRUE AND TIMESTAMPDIFF(MINUTE, last_post, CURRENT_TIMESTAMP()) >= post_frequency")
# cursor.execute("SELECT handle FROM bots WHERE enabled = TRUE")
bots = cursor.fetchall() bots = cursor.fetchall()
with Pool(cfg['service_threads']) as p: with Pool(cfg['service_threads']) as p:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 8.9 KiB

44
app/static/script.js Normal file
View file

@ -0,0 +1,44 @@
var chatlog = [];
function sendMessage() {
let id = window.location.href.split("/").slice(-1)[0]
message = document.getElementById("chatbox-input-box").value
document.getElementById("chatbox-input-box").value = ''
document.getElementById("chatbox-input-box").disabled = true;
chatlog.push(["user", message])
renderChatlog();
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4) {
if (this.status == 200) {
message = this.responseText.replace("\n", "<br>");
} else {
message = "Encountered an error while trying to get a response.";
}
chatlog.push(["bot", message]);
renderChatlog();
document.getElementById("chatbox-input-box").disabled = false;
}
};
xhttp.open("GET", `/bot/chat/${id}/message`, true);
xhttp.send();
return false;
}
function renderChatlog() {
let chatbox = document.getElementById("chatbox");
let out = "";
if (chatlog.length > 50) {
chatlog.shift(); //only keep the 50 most recent messages to avoid slowdown
}
chatlog.forEach(function(item, i) {
if (item[0] == "user") {
out += `<div class="message-container user"><div class="message user">${item[1]}</div></div>`;
} else {
out += `<div class="message-container bot"><div class="bot-icon"></div><div class="message bot">${item[1]}</div></div>`;
}
})
chatbox.innerHTML = out;
chatbox.scrollTop = chatbox.scrollHeight;
}

View file

@ -217,21 +217,29 @@ form .row {
height: 90vh; height: 90vh;
background-color: #3d4353; background-color: #3d4353;
padding: 10px; padding: 10px;
overflow-y: scroll;
} }
#chatbox-input, #chatbox-input input{ #chatbox-input, #chatbox-input input{
width: 100%; width: 100%;
} }
#chatbox, #chatbox-input {
max-width: 600px;
margin: 0 auto;
}
#chatbox-input {
display: block;
}
.message { .message {
display: inline-block; display: inline-block;
padding: 5px; padding: 5px;
min-height: 30px; min-height: 30px;
max-width: 60%; max-width: 60%;
margin-bottom: 5px;
} }
.message-container.user { .message-container.user {
text-align: right; text-align: right;
} }
.message-container .bot-icon { .message-container .bot-icon {
background: center / contain url("https://lynnesbian.space/img/bune.png") no-repeat;
height: 30px; height: 30px;
width: 30px; width: 30px;
display: inline-block; display: inline-block;

View file

@ -4,6 +4,17 @@
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>FediBooks</title> <title>FediBooks</title>
{% include 'imports.html' %} {% include 'imports.html' %}
<style>
.bot-icon {
background: center / contain url("{{icon}}") no-repeat;
}
</style>
<script>
window.onload = function() {
document.getElementById("chatbox-input-box").focus();
document.getElementById("chatbox-input").onsubmit = sendMessage;
}
</script>
</head> </head>
<body> <body>
@ -11,7 +22,7 @@
<h1 class="thin centred">Chat</h1> <h1 class="thin centred">Chat</h1>
<p class="centred">Talking to {{ bot }}</p> <p class="centred">Talking to {{ bot }}</p>
<p class="centred" style="margin: 20px 0;"> <p class="centred" style="margin: 20px 0;">
<a class="button btn-primary" href="/bot/accounts/add" role="button"><i class="fas fa-home"></i> Home</a> <a class="button btn-primary" href="/" role="button"><i class="fas fa-home"></i> Home</a>
</p> </p>
</div> </div>
@ -23,17 +34,11 @@
<div class="container"> <div class="container">
<div id="chatbox"> <div id="chatbox">
<div class="message-container user">
<div class="message user">Henlo</div>
</div>
<div class="message-container bot">
<div class="bot-icon"></div>
<div class="message bot">Henlo human uwu<br>How are you</div>
</div>
</div> </div>
<form id="chatbox-input"> <form id="chatbox-input">
<input name="message" placeholder="Press enter to send"> <input id="chatbox-input-box" autocomplete="off" required name="message" placeholder="Press enter to send">
</form> </form>
</div> </div>

View file

@ -12,7 +12,7 @@
</div> </div>
{% include 'error.html' %} {% include 'error.html' %}
<div class="container centred"> <div class="container centred">
<form method="POST"> <form method="POST">
{% if session['step'] == 1 %} {% if session['step'] == 1 %}
@ -26,12 +26,12 @@
{% elif session['step'] == 3 %} {% elif session['step'] == 3 %}
<p>You now need to give your bot access to the {{ session['instance'] }} account you have created for it. If you have not yet created an account on {{ session['instance'] }} for your bot to use, please do so now.</p> <p>You now need to give your bot access to the {{ session['instance'] }} account you have created for it. If you have not yet created an account on {{ session['instance'] }} for your bot to use, please do so now.</p>
<p>Sign in to the {{ session['instance'] }} account you want your bot to use, then click next to begin the authorisation process.</p> <p>In another tab, sign in to the {{ session['instance'] }} account you want your bot to use. Once that's done, click next to begin the authorisation process.</p>
{% elif session['step'] == 4 %} {% elif session['step'] == 4 %}
<h2 class="thin centred">Congratulations!</h2> <h2 class="thin centred">Congratulations!</h2>
<p>FediBooks has successfully authenticated with your instance, and your bot is ready to be configured. Click finish to return to the bot management screen.</p> <p>FediBooks has successfully authenticated with your instance, and your bot is ready to be configured. Click finish to return to the bot management screen.</p>
<p>To get your bot working, you need to add at least one account for it to learn from. You can do so by clicking the <i class="fas fa-users"></i> button. To configure settings such as posting frequency and content warnings, click the <i class="fas fa-cog"></i> button.</p> <p><strong>Important:</strong> To get your bot working, you need to add at least one account for it to learn from. You can do so by clicking the <i class="fas fa-users"></i> button. To configure settings such as posting frequency and content warnings, click the <i class="fas fa-cog"></i> button.</p>
{% else %} {% else %}
<h2 class="thin centred">Error</h2> <h2 class="thin centred">Error</h2>

View file

@ -2,6 +2,7 @@
<div class='subtle small'> <div class='subtle small'>
<p>FediBooks is beta software. It might behave unexpectedly. You can learn more about FediBooks <a href="/about">here</a>. <br> <p>FediBooks is beta software. It might behave unexpectedly. You can learn more about FediBooks <a href="/about">here</a>. <br>
Website design and FediBooks software by <a href='https://fedi.lynnesbian.space/@LynnearSoftware'>Lynne</a>. This site uses <a href="https://fontawesome.com">Font Awesome</a>. <br> Website design and FediBooks software by <a href='https://fedi.lynnesbian.space/@LynnearSoftware'>Lynne</a>. This site uses <a href="https://fontawesome.com">Font Awesome</a>. <br>
Some of FediBooks' functionality requires JavaScript to be enabled, although the core functions such as bot configuration do not. <br>
FediBooks uses a cookie to keep you logged in. Deleting this cookie will log you out, and your bots will still work. You can also sign out <a href="/do/signout">here</a>. <br> FediBooks uses a cookie to keep you logged in. Deleting this cookie will log you out, and your bots will still work. You can also sign out <a href="/do/signout">here</a>. <br>
Source code is available <a href="https://github.com/Lynnesbian/Fedibooks">here</a> under the AGPLv3 license.</p> Source code is available <a href="https://github.com/Lynnesbian/Fedibooks">here</a> under the AGPLv3 license.</p>
</div> </div>

View file

@ -1,4 +1,5 @@
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="https://kit-free.fontawesome.com/releases/latest/css/free.min.css"> <link rel="stylesheet" href="https://kit-free.fontawesome.com/releases/latest/css/free.min.css">
<link rel='stylesheet' type='text/css' href="{{ url_for('static', filename='style.css') }}" /> <link rel='stylesheet' type='text/css' href="{{ url_for('static', filename='style.css') }}" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,700&display=swap"> <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,700&display=swap">
<script src="{{ url_for('static', filename='script.js') }}"></script>

View file

@ -76,7 +76,7 @@ def render_delete():
# should never happen ;) # should never happen ;)
session['error'] = "An unknown error occurred." session['error'] = "An unknown error occurred."
return redirect(url_for("render_delete"), 303) return redirect(url_for("render_delete"), 303)
if bcrypt.checkpw(pw_hashed, data['password']): if bcrypt.checkpw(pw_hashed, data['password']):
# passwords match, delete the account # passwords match, delete the account
session['error'] = "succ ess" session['error'] = "succ ess"
@ -106,7 +106,7 @@ def render_delete():
c.close() c.close()
mysql.connection.commit() mysql.connection.commit()
# TODO: show a "deletion successful" message or something # TODO: show a "deletion successful" message or something
return redirect(url_for("do_signout"), 303) return redirect(url_for("do_signout"), 303)
@ -159,8 +159,20 @@ def bot_toggle(id):
@app.route("/bot/chat/<id>") @app.route("/bot/chat/<id>")
def bot_chat(id): def bot_chat(id):
return render_template("coming_soon.html") # return render_template("coming_soon.html")
# return render_template("/bot/chat.html", bot = id) if bot_check(id):
c = mysql.connection.cursor()
c.execute("SELECT icon FROM `bots` WHERE handle = %s", (id,))
icon = c.fetchone()[0]
if icon is None:
icon = "/img/bot_generic.png"
return render_template("/bot/chat.html", bot = id, icon = icon)
@app.route("/bot/chat/<id>/message")
def bot_chat_message(id):
if bot_check(id):
_, message = functions.generate_output(id)
return message
@app.route("/bot/blacklist/<id>") @app.route("/bot/blacklist/<id>")
def bot_blacklist(id): def bot_blacklist(id):
@ -258,9 +270,12 @@ def push(id):
'privkey': int(bot[0].rstrip("\0")), 'privkey': int(bot[0].rstrip("\0")),
'auth': bot[1] 'auth': bot[1]
} }
push_object = client.push_subscription_decrypt_push(request.data, params, request.headers['Encryption'], request.headers['Crypto-Key']) try:
notification = client.notifications(id = push_object['notification_id']) push_object = client.push_subscription_decrypt_push(request.data, params, request.headers['Encryption'], request.headers['Crypto-Key'])
me = client.account_verify_credentials()['id'] notification = client.notifications(id = push_object['notification_id'])
me = client.account_verify_credentials()['id']
except:
return "Push failed - do we still have access to {}?".format(id)
# first, check how many times the bot has posted in this thread. # first, check how many times the bot has posted in this thread.
# if it's over 15, don't reply. # if it's over 15, don't reply.
@ -329,7 +344,7 @@ def do_login():
if data == None: if data == None:
session['error'] = "Incorrect login information." session['error'] = "Incorrect login information."
return redirect(url_for("show_login_page"), 303) return redirect(url_for("show_login_page"), 303)
if bcrypt.checkpw(pw_hashed, data['password']): if bcrypt.checkpw(pw_hashed, data['password']):
session['user_id'] = data['id'] session['user_id'] = data['id']
return redirect(url_for("render_home")) return redirect(url_for("render_home"))