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>
|
||
|
'''
|