def search(pattern): db = get_db() files = {} patches = set() for file_id in get_db().execute("SELECT id FROM blobs"): for patch_id in patches_for(file_id[0]): files.setdefault(patch_id, set()) files[patch_id].update([file_id[0]]) patches.update([os.path.join(config["BASE_PATH"], binascii.hexlify(patch_id).decode("utf-8"))]) grep = subprocess.Popen(["xzgrep", "-F", "-l", pattern]+list(patches), stdout=subprocess.PIPE) matches, _ = grep.communicate() if grep.returncode > 1: raise Exception("xzgrep failed with %s" % grep.returncode) matches = matches.splitlines() possible_matches = set() for match in map(lambda s: binascii.unhexlify(os.path.basename(s.decode("utf-8"))), matches): possible_matches.update(files[match]) matches = set() for file in possible_matches: for line in rebuild(file): if line.decode("utf-8").find(pattern) >= 0: matches.update([file]) break return matches
def inject_user(): user = verify() if user is None: admin = False else: admin = get_db().execute("SELECT admin FROM users WHERE canonical_name = ?", (user,)).fetchone()[0] return dict(user=user, admin=admin)
def rebuild(rev): if rev is None: return [] c = get_db().execute("SELECT parent, patch FROM blobs WHERE id = ?", (sqlite3.Binary(rev),)) parent, patch_id = c.fetchone() with lzma.open(os.path.join(app.config["BASE_PATH"], binascii.hexlify(patch_id).decode("utf-8")), "rb") as f: patch_ = f.read().splitlines(True) return patch(rebuild(parent), patch_)
def patches_for(rev): if rev is None: return [] c = get_db().execute("SELECT parent, patch FROM blobs WHERE id = ?", (sqlite3.Binary(rev),)) parent, patch_id = c.fetchone() for patch in patches_for(parent): yield patch yield patch_id
def admindelete(): db = get_db() user = verify() if user == None: flask.abort(403) catid = flask.request.form["delete"] db.execute("DELETE FROM files WHERE files.id = ?", (catid,)) db.commit() return flask.redirect("/admin")
def verify(): if "username" not in flask.session: return None name = nameprep(flask.session["username"]) c = get_db().execute("SELECT password FROM users WHERE canonical_name = ?", (name,)) key = c.fetchone() if key == None: return None return name
def deleteuser(): db = get_db() user = verify() if user == None: flask.abort(403) username = flask.request.form["delete"] db.execute("DELETE FROM users WHERE users.name = ?", (username,)) db.commit() return flask.redirect("/users")
def admin(): user = verify() if user is None: flask.abort(403) db = get_db() row = db.execute("SELECT admin FROM users WHERE canonical_name = ?", (user,)).fetchone() if row is None or row[0] == 0: flask.abort(403) c = db.execute("SELECT files.id, files.name, files.revision, blobs.ctime, users.name FROM files INNER JOIN blobs ON blobs.id = files.revision LEFT OUTER JOIN users ON users.id = files.owner") copycats = list(map(lambda row: (row[0], row[1], format_url(row[2]), row[3], row[4]), c)) return flask.render_template("admin.html", active="admin", copycats=copycats)
def users(): user = verify() if user is None: flask.abort(403) db = get_db() row = db.execute("SELECT admin FROM users WHERE canonical_name = ?", (user,)).fetchone() if row is None or row[0] == 0: flask.abort(403) c = db.execute("SELECT COUNT(files.id), users.name, users.email FROM files INNER JOIN users ON users.id = files.owner GROUP BY users.name") userlist = list(map(lambda row: (row[0], row[1], row[2]), c)) return flask.render_template("users.html", active="admin", userlist=userlist)
def register(): name = flask.request.form.get("name") cname = nameprep(name) email = flask.request.form.get("email") password = flask.request.form.get("password") if password != flask.request.form.get("password2"): flask.abort(400) if name is None or cname is None or email is None or password is None: flask.abort(400) password = hash_password(cname, password) try: get_db().execute("INSERT INTO users (name, canonical_name, password, email) VALUES(?, ?, ?, ?)", (name, cname, sqlite3.Binary(password), email)) get_db().commit() except: flask.abort(409) flask.session["username"] = cname return flask.redirect("/")
def raw(file_id): try: rev = decode_rev(file_id) except: flask.abort(404) c = get_db().execute("SELECT revision FROM files WHERE substr(revision, 1, ?) = ?", (len(rev), sqlite3.Binary(rev))) if c is None: flask.abort(404) rev = c.fetchone()[0] response = flask.make_response(b"".join(rebuild(rev))) response.headers["Content-Type"] = "text/plain" return response
def editcat(): url = flask.request.form["url"] file_id = flask.request.form["id"] name = flask.request.form["title"] print("Editing cat: " + file_id) db = get_db() user = verify() if user == None: flask.abort(403) try: rev = decode_rev(url[3::]) except: flask.abort(404) c = get_db().execute("SELECT revision, name FROM files WHERE substr(revision, 1, ?) = ?", (len(rev), sqlite3.Binary(rev))) if c is None: flask.abort(404) rev = c.fetchone()[0] plaincat = b"".join(rebuild(rev)).decode("utf-8") lexers = sorted(map(lambda x: (x[0], x[1][0]), pygments.lexers.get_all_lexers())) return flask.render_template("editcat.html", plaincat=plaincat, lexers=lexers, file_id=file_id, name=name)
def usercats(): user = verify() if user == None: flask.abort(403) c = get_db().execute("SELECT files.id, files.name, files.revision, files.type, blobs.ctime FROM files INNER JOIN blobs ON blobs.id = files.revision LEFT OUTER JOIN users ON users.id = files.owner WHERE users.canonical_name = ?", (user,)) files = list(c) copycats = list(map(lambda row: (row[0], row[1], format_url(row[2]), lexer_name(row[3]), row[4]), files))[::-1] base = BeautifulSoup(flask.render_template("usercats.html", active="usercats", copycats=copycats)) for f in files: fragment = BeautifulSoup(format_rev(f[2], f[3], 10)).body tag = base.find("div", id="file-{}".format(f[0])) tag = tag.find("div", class_="panel-footer") for elem in fragment.children: tag.insert_before(elem) return str(base)
def cooked(file_id): try: rev = decode_rev(file_id) except: flask.abort(404) c = get_db().execute("SELECT files.revision, files.type, files.name, users.name FROM files LEFT OUTER JOIN users ON files.owner = users.id WHERE substr(files.revision, 1, ?) = ?", (len(rev), sqlite3.Binary(rev))) row = c.fetchone() if row is None: flask.abort(404) rev, lexer, name, user = row fragment = BeautifulSoup(format_rev(rev, lexer)).body base = BeautifulSoup(flask.render_template("copycat.html", url=format_url(rev)[3:], name=name, user=user)) for tag in fragment.children: base.find("div", id="copycat").append(tag) return str(base)
def login(): if flask.request.method == "GET": return flask.render_template("login.html", active="login") name = nameprep(flask.request.form.get("name")) password = flask.request.form.get("password") if name is None or password is None: flask.abort(400) password = hash_password(name, password) c = get_db().execute("SELECT canonical_name FROM users WHERE canonical_name = ? AND password = ?", (name, sqlite3.Binary(password))) cname = c.fetchone() if cname is None or cname[0] != name: flask.abort(401) if "remember" in flask.request.form: flask.session.permanent = True flask.session["username"] = cname[0] return flask.redirect("/")
def submit(): value = flask.request.form["button"] print(value) src = flask.request.form["copycat"] kood = flask.request.form["lexer"] if value=="preview": preview(src, kood) return try: lexer = pygments.lexers.get_lexer_by_name(kood).aliases[0] except: lexer = pygments.lexers.guess_lexer(src).aliases[0] patch_ = "".join(diff("", src.splitlines(True))) file_id = blake2b(data=src.encode("utf-8")).digest() patch_id = blake2b(data=patch_.encode("utf-8")).digest() ctime = datetime.datetime.now(datetime.timezone.utc) db = get_db() try: db.execute("INSERT INTO blobs (id, patch, ctime) VALUES (?, ?, ?)", (sqlite3.Binary(file_id), sqlite3.Binary(patch_id), ctime)) except: blob = db.execute("SELECT id FROM blobs WHERE id = ?", (sqlite3.Binary(file_id),)).fetchone() if blob == None or blob[0] != file_id: raise with lzma.open(os.path.join(app.config["BASE_PATH"], binascii.hexlify(patch_id).decode("utf-8")), "w") as f: f.write(patch_.encode("utf-8")) user = verify() if user is None: owner_id = None else: owner_id = db.execute("SELECT id FROM users WHERE canonical_name = ?", (user,)).fetchone()[0] db.execute("INSERT INTO files (owner, name, type, revision) VALUES(?, ?, ?, ?)", (owner_id, flask.request.form["name"], lexer, sqlite3.Binary(file_id))) db.commit() return flask.redirect(format_url(file_id))
import sys sys.path = [".."]+sys.path from copycatbowl import app from copycatbowl.db import get_db from copycatbowl.auth import nameprep with app.app_context(): db = get_db() while True: new_admin = nameprep(input("User to make admin, empty string to stop: ")) if new_admin == "": break if new_admin == None: print("Name contains invalid characters") try: db.execute("UPDATE users SET admin = 1 WHERE canonical_name = ?", (new_admin,)) except Exception as e: print(e) db.commit()