mastodon-BDSM/BDSM/views.py

288 lines
9.2 KiB
Python
Raw Permalink Normal View History

2022-09-18 05:23:33 +02:00
#!/usr/bin/env python3
import os
import pytz
2022-11-15 11:08:03 +01:00
import json
2022-09-18 05:23:33 +02:00
from flask import render_template, request, url_for, redirect, flash, abort
from flask_sqlalchemy import Pagination
2023-03-25 18:52:04 +01:00
from sqlalchemy import or_
2022-09-18 05:23:33 +02:00
from BDSM import app, db
2023-03-25 18:52:04 +01:00
from BDSM.models import Media, Poll, Settings, Toot, Emoji
from BDSM.toot import app_login, app_register, archive_toot, get_context
2022-09-18 05:23:33 +02:00
from mastodon import Mastodon
2022-09-19 11:39:30 +02:00
from types import SimpleNamespace
from datetime import timezone
2023-05-24 08:05:05 +02:00
from typing import Any
2023-05-09 11:34:28 +02:00
2022-09-22 17:57:43 +02:00
# @app.context_processor
# def inject_setting():
# settings = Settings.query.first()
# return settings.__dict__
2022-09-18 05:23:33 +02:00
2023-05-09 11:34:28 +02:00
2022-09-18 05:23:33 +02:00
@app.route('/', methods=['GET', 'POST'])
def index():
2022-09-22 17:57:43 +02:00
settings = Settings.query.first()
if settings == None:
return redirect(url_for('settings'))
else:
page = request.args.get('page', 1, type=int)
2023-03-25 18:52:04 +01:00
toots_ = Toot.query.order_by(Toot.created_at.desc()).filter(or_(Toot.acct==settings.account, Toot.reblog_id!=None)).paginate(page=page, per_page=50)
2022-09-22 17:57:43 +02:00
toots = process_toot(toots_)
path=SimpleNamespace()
path.path = "index"
path.args = {}
2022-09-18 15:56:48 +02:00
2022-09-22 17:57:43 +02:00
return render_template('view.html', toots=toots, pagination=toots_, path=path)
2022-09-19 11:39:30 +02:00
2023-05-09 11:34:28 +02:00
2023-03-25 18:52:04 +01:00
@app.route('/favourited', methods=['GET', 'POST'])
def favourited():
settings = Settings.query.first()
if settings == None:
return redirect(url_for('settings'))
else:
page = request.args.get('page', 1, type=int)
toots_ = Toot.query.order_by(Toot.created_at.desc()).filter_by(favourited=True).paginate(page=page, per_page=50)
toots = process_toot(toots_)
path=SimpleNamespace()
path.path = "favourited"
path.args = {}
return render_template('view.html', toots=toots, pagination=toots_, path=path)
2023-05-09 11:34:28 +02:00
2023-03-25 18:52:04 +01:00
@app.route('/bookmarked', methods=['GET', 'POST'])
def bookmarked():
settings = Settings.query.first()
if settings == None:
return redirect(url_for('settings'))
else:
page = request.args.get('page', 1, type=int)
toots_ = Toot.query.order_by(Toot.created_at.desc()).filter_by(bookmarked=True).paginate(page=page, per_page=50)
toots = process_toot(toots_)
path=SimpleNamespace()
path.path = "bookmarked"
path.args = {}
return render_template('view.html', toots=toots, pagination=toots_, path=path)
2023-05-09 11:34:28 +02:00
@app.route('/search', methods=['GET', 'POST'])
def search():
if request.method == 'POST':
query = request.form['query']
return redirect(url_for('search',query=query))
2022-09-19 11:39:30 +02:00
query = request.args.get('query', "", type=str)
page = request.args.get('page', 1, type=int)
2022-11-08 19:21:50 +01:00
toots_ = Toot.query.order_by(Toot.created_at.desc()).filter(Toot.content.like("%"+query+"%")).paginate(
page=page, per_page=50)
toots = process_toot(toots_)
path=SimpleNamespace()
# Rule: /serch
path.path = str(request.url_rule)[1:] #FIXME
path.args = {}
path.args["query"] = query
return render_template('view.html', toots=toots, pagination=toots_, path=path)
2022-09-18 05:23:33 +02:00
2022-09-22 17:57:43 +02:00
@app.route('/context/<int:toot_id>', methods=['GET', 'POST'])
def context(toot_id):
def get_reply(reply_id):
toots = Toot.query.order_by(Toot.created_at.desc()).filter_by(in_reply_to_id=reply_id).all()
for i in toots:
if i.in_reply_to_id != None:
i.reply = get_reply(i.id)
return toots
2022-09-23 17:22:18 +02:00
toots = []
toot_ = Toot.query.get(toot_id)
if toot_ == None:
2023-03-25 18:52:04 +01:00
abort(404)
toots.append(toot_)
2022-09-23 17:22:18 +02:00
toots = process_toot(toots)
toots[0].reply = get_reply(toot_id)
in_reply_to_id = toots[0].in_reply_to_id
while(in_reply_to_id != None):
toot = []
toot_ = Toot.query.get(toots[0].in_reply_to_id)
if toot_ == None:
2023-03-25 18:52:04 +01:00
break
2022-09-23 17:22:18 +02:00
toot.append(toot_)
toot = process_toot(toot)
toots.insert(0,toot[0])
in_reply_to_id = toot[0].in_reply_to_id
return render_template('view.html', toots=toots,)
2022-09-22 17:57:43 +02:00
2023-05-09 11:34:28 +02:00
2022-11-07 19:25:06 +01:00
@app.route('/grab/<int:toot_id>', methods=['GET', 'POST'])
def grab(toot_id):
settings = Settings.query.first()
2023-03-25 18:52:04 +01:00
domain = settings.domain
2022-11-07 19:25:06 +01:00
url = "https://" + domain
get_context(url, toot_id)
flash('抓取完成……大概!')
return redirect(url_for('context',toot_id=toot_id))
2023-05-09 11:34:28 +02:00
2022-09-18 05:23:33 +02:00
@app.route('/settings', methods=['GET', 'POST'])
def settings():
if request.method == 'POST':
timezone = request.form['timezone']
settings = Settings.query.first()
if settings == None:
2023-03-25 18:52:04 +01:00
domain = request.form['domain']
if not domain or len(domain) > 50:
flash('无效输入')
return redirect(url_for('settings'))
settings = Settings(domain=domain, timezone=timezone)
2022-09-18 05:23:33 +02:00
db.session.add(settings)
else:
settings.timezone = timezone
db.session.commit()
flash('设置已修改')
return redirect(url_for('settings'))
settings = Settings.query.first()
2023-05-24 08:05:05 +02:00
app_init = os.path.isfile("data/pyBDSM_clientcred.secret") and os.path.isfile("data/user.secret")
2022-09-18 15:56:48 +02:00
if settings == None:
flash('请输入相关设置!')
2022-09-18 05:23:33 +02:00
return render_template('settings.html',settings=settings, app_init=app_init)
2023-05-09 11:34:28 +02:00
2023-05-24 08:05:05 +02:00
@app.route("/register", methods=["GET", "POST"])
def register() -> Any:
2022-09-18 05:23:33 +02:00
settings = Settings.query.first()
if settings == None:
2023-03-25 18:52:04 +01:00
flash('请先输入站点地址!')
2022-09-18 05:23:33 +02:00
return redirect(url_for('settings'))
else:
2023-05-24 08:05:05 +02:00
if os.path.isfile("data/user.secret"):
flash('应用已授权!')
return redirect(url_for("settings"))
2023-03-25 18:52:04 +01:00
domain = settings.domain
2022-09-18 05:23:33 +02:00
url = "https://" + domain
2023-05-24 08:05:05 +02:00
if not os.path.isfile("data/pyBDSM_clientcred.secret"):
app_register(url)
2023-03-25 18:52:04 +01:00
2022-09-18 05:23:33 +02:00
if request.method == 'POST':
token = request.form['token'].rstrip()
2023-05-24 08:05:05 +02:00
mastodon = Mastodon(client_id="data/pyBDSM_clientcred.secret", api_base_url=url)
print("test")
mastodon.log_in(code=token, to_file="data/user.secret", scopes=['read'])
2022-09-18 05:23:33 +02:00
2023-05-24 08:05:05 +02:00
if not os.path.isfile("data/user.secret"):
mastodon = Mastodon(client_id="data/pyBDSM_clientcred.secret", api_base_url=url)
url = mastodon.auth_request_url(client_id="data/pyBDSM_clientcred.secret", scopes=['read'])
return render_template("register.html",url=url)
2022-09-18 05:23:33 +02:00
2023-05-24 08:05:05 +02:00
mastodon, _ = app_login(url)
account = mastodon.me().acct
settings.account = account
db.session.commit()
2022-09-18 05:23:33 +02:00
2023-07-16 23:02:12 +02:00
flash('应用授权成功!')
return redirect(url_for("settings"))
2023-05-09 11:34:28 +02:00
2022-09-18 05:23:33 +02:00
@app.route('/archive', methods=['GET', 'POST'])
def archive():
settings = Settings.query.first()
2022-11-08 19:21:50 +01:00
if request.method == 'POST':
archive_match = request.form.getlist("archive_match")
2023-03-25 18:52:04 +01:00
domain = settings.domain
2022-09-18 05:23:33 +02:00
url = "https://" + domain
2022-11-08 19:21:50 +01:00
archive_toot(url, archive_match)
2022-09-18 05:23:33 +02:00
2022-11-08 19:21:50 +01:00
flash('存档完成……大概!')
return redirect(url_for('index'))
2022-09-18 05:23:33 +02:00
2022-11-08 19:21:50 +01:00
if settings == None:
return redirect(url_for('settings'))
else:
return render_template('archive.html')
2023-05-09 11:34:28 +02:00
def process_toot(toots_):
toots = []
settings = Settings.query.first()
user_timezone = pytz.timezone(settings.timezone)
fmt = '%Y-%m-%d %H:%M:%S'
2022-09-22 17:57:43 +02:00
if hasattr(toots_, 'items'):
toots_ = toots_.items
for toot_ in toots_:
toot = SimpleNamespace(**toot_.__dict__)
toot.created_at = toot.created_at.replace(tzinfo=timezone.utc)
toot.created_at = toot.created_at.astimezone(user_timezone).strftime(fmt)
2023-03-25 18:52:04 +01:00
if toot.acct == settings.account:
2022-11-07 19:25:06 +01:00
toot.is_myself = True
else:
toot.is_myself = False
2023-03-25 18:52:04 +01:00
if toot.reblog_id != None:
toot = Toot.query.get(toot.reblog_id)
toot = SimpleNamespace(**toot.__dict__)
toot.is_reblog = True
if toot.media_list != "":
toot.medias = []
#media_list "1111,2222,333,"
media_list = toot.media_list[:-1].split(",")
for media_id in media_list:
media = Media.query.get(int(media_id))
if media != None:
toot.medias.append(media)
if toot.emoji_list != "":
toot.emojis = []
#emoji_list "blobfoxaaa,blobcatwww,fox_think,"
emoji_list = toot.emoji_list[:-1].split(",")
for emoji_shortcode in emoji_list:
emoji = Emoji.query.filter_by(shortcode=emoji_shortcode, acct=toot.acct).first()
if emoji != None:
emoji_shortcode = ':' + emoji_shortcode + ':'
2023-05-09 11:34:28 +02:00
# emoji_url = emoji.url
emoji_html = f'''
<img class="emojione custom-emoji" alt="{emoji_shortcode}" title="{emoji_shortcode}" src="{emoji.url}" >
'''
toot.content = toot.content.replace(emoji_shortcode, emoji_html)
2022-11-15 11:08:03 +01:00
if toot.poll_id != None:
poll = Poll.query.get(toot.poll_id)
poll_options = json.loads(poll.options.replace("\'", "\""))
poll_count = str(poll.votes_count)
poll_content = '<strong>总票数: ' + poll_count + '</strong><br>'
for i in poll_options:
poll_content += i['title'] + " / " + str(i['votes_count']) + '<br>'
toot.content += poll_content
toots.append(toot)
2023-05-09 11:34:28 +02:00
return toots