109 lines
3.2 KiB
Python
109 lines
3.2 KiB
Python
|
|
import json
|
|
import sqlite3
|
|
import contextlib
|
|
from flask import Flask, Response, request
|
|
|
|
app = Flask(__name__)
|
|
|
|
@app.route('/main.js')
|
|
def main_js():
|
|
with open('disstuff.js', 'r') as f:
|
|
return Response(
|
|
f.read(),
|
|
mimetype='application/javascript',
|
|
)
|
|
|
|
@app.route('/repos.json')
|
|
def repos():
|
|
with (
|
|
contextlib.closing(sqlite3.connect('disrepos.db', isolation_level=None)) as db,
|
|
contextlib.closing(db.cursor()) as cursor,
|
|
):
|
|
cursor.execute('''
|
|
SELECT `rowid`, `owner`, `name`, `stars`, `forks`, `desc`, `lang`, `flag`
|
|
FROM `repos`
|
|
ORDER BY `rowid` ASC
|
|
''')
|
|
keys = 'rowid owner name stars forks desc lang flag'.split(' ')
|
|
return Response(
|
|
json.dumps([dict(zip(keys, row)) for row in cursor]),
|
|
mimetype='text/json',
|
|
)
|
|
|
|
@app.route('/badusers.json')
|
|
def badusers():
|
|
with (
|
|
contextlib.closing(sqlite3.connect('disrepos.db', isolation_level=None)) as db,
|
|
contextlib.closing(db.cursor()) as cursor,
|
|
):
|
|
cursor.execute('''
|
|
SELECT DISTINCT `owner`
|
|
FROM `repos`
|
|
WHERE `owner` IN (
|
|
SELECT `owner`
|
|
FROM `repos`
|
|
WHERE `flag`='spam')
|
|
''')
|
|
return Response(
|
|
json.dumps([row[0] for row in cursor]),
|
|
mimetype='text/json',
|
|
)
|
|
|
|
@app.route('/flag', methods=['POST'])
|
|
def flag():
|
|
with (
|
|
contextlib.closing(sqlite3.connect('disrepos.db', isolation_level=None)) as db,
|
|
contextlib.closing(db.cursor()) as cursor,
|
|
):
|
|
rowid = int(request.form['rowid'])
|
|
flag = request.form['flag']
|
|
if flag == '':
|
|
flag = None
|
|
cursor.execute('''
|
|
UPDATE `repos`
|
|
SET `flag`=?
|
|
WHERE `rowid`=?
|
|
''', (flag, rowid))
|
|
assert cursor.rowcount == 1
|
|
return ''
|
|
|
|
|
|
@app.route('/')
|
|
def index():
|
|
return '''
|
|
<!doctype html>
|
|
<style>
|
|
html {
|
|
font-size: smaller;
|
|
background: gainsboro;
|
|
}
|
|
form {
|
|
display: inline-block;
|
|
}
|
|
th {
|
|
position: sticky;
|
|
top: 0;
|
|
background: gainsboro; /* sorry dark theme users */
|
|
}
|
|
tr:hover { background-color: mistyrose; }
|
|
tr[data-active-row] {
|
|
background-color: yellow;
|
|
}
|
|
[data-flag=spam] td:first-of-type { background: red; }
|
|
td[data-bad-user] { background: red; }
|
|
[data-flag=notSpam] td:first-of-type { background: green; }
|
|
</style>
|
|
Filter: <form onsubmit="update(); return false"><input list="filters" type="text" id="filter" style="width: 400px;"> <input type="submit" value="Update"></form> <span id="filterstatus"></span>
|
|
<datalist id="filters">
|
|
<option value="!stars&&!forks&&!lang&&desc"></option>
|
|
<option value="desc&&!lang"></option>
|
|
<option value="desc&&/viagra/i.test(desc)"></option>
|
|
<option value="desc&&/<a href="(?![^"]*(github\.com|\\bgit\.))/i.test(desc)"></option>
|
|
<option value="desc&&/buy|cashapp|erectile|escort|essay|support|viagra|wholesale/i.test(desc)"></option>
|
|
</datalist>
|
|
<hr>
|
|
<div id="main"></div>
|
|
<script src="/main.js"></script>
|
|
'''
|