diff --git a/.gitpod.Dockerfile b/.gitpod.Dockerfile new file mode 100644 index 0000000..5a44b5c --- /dev/null +++ b/.gitpod.Dockerfile @@ -0,0 +1,14 @@ +FROM gitpod/workspace-full + +# Install Redis. +RUN sudo apt-get update \ + && sudo apt-get install -y \ + redis-server mongodb \ + && sudo rm -rf /var/lib/apt/lists/* + EXPOSE 80 + EXPOSE 443 +# Install custom tools, runtimes, etc. +# For example "bastet", a command-line tetris clone: +# RUN brew install bastet +# +# More information: https://www.gitpod.io/docs/config-docker/ diff --git a/.gitpod.yml b/.gitpod.yml new file mode 100644 index 0000000..44bd2e7 --- /dev/null +++ b/.gitpod.yml @@ -0,0 +1,5 @@ +image: + file: .gitpod.Dockerfile + +tasks: + - init: pip install -r ./requirements.txt diff --git a/requirements.txt b/requirements.txt index 63dc48b..c5216da 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,9 +1,11 @@ flask +flask-session +redis Pillow pycrypto asn1crypto==0.24.0 certifi==2018.4.16 -cffi==1.11.5 +dnspython chardet==3.0.4 ConfigArgParse==0.13.0 configobj==5.0.6 diff --git a/server.py b/server.py index 2b0ddc6..9dc4143 100644 --- a/server.py +++ b/server.py @@ -1,13 +1,9 @@ -import datetime -import hashlib -import os -import secrets -import traceback -from os.path import splitext +import datetime import hashlib import os import secrets import traceback from os.path import splitext from +werkzeug.utils import secure_filename import pymongo from PIL import Image -from flask import Flask, request, json, jsonify, render_template, session, redirect +from flask import Flask, request, json, jsonify, render_template, session, redirect, send_from_directory from flask_session import Session from pymongo import MongoClient @@ -86,6 +82,12 @@ def create_new_user(uid: int, name: str): def datefromunix(s): return datetime.datetime.fromtimestamp(int(s) / 1000).strftime("%Y-%m-%d %H:%M") +@app.route('/favicon.ico') +def favicon(): + return send_from_directory(os.path.join(app.root_path, 'static'), + 'favicon.ico', mimetype='image/vnd.microsoft.icon') + + @app.route('/') def index(): @@ -121,7 +123,11 @@ def my_portal(): activity = _db.images.find({"user_uid": session.get("logged_in")}).sort('created', pymongo.DESCENDING).limit(5) activity = [x for x in activity] return render_template("my_portal.html", domains=allowed_domains, total=total, images=activity) - +@app.route('/i/') +def return_pic(filename): + """ Show just the image specified. + """ + return send_from_directory( _config['storage_dir'], secure_filename(filename)) @app.route('/my/files', methods=['GET', 'POST']) def my_files(): @@ -193,6 +199,96 @@ def print_stats(): "files": _db.images.count(), "domains": len(allowed_domains) }) +@app.route('/nl/') +def index-nl(): + return render_template("home.html", domains=allowed_domains) + + +@app.route('/nl/login', methods=['GET', 'POST']) +def login-nl(): + if request.method == "POST": + usr = check_user(request.form.get("username", "unknown"), request.form.get("password", "unknown")) + if usr is None: + return render_template('login.html', is_error=True) + next_url = request.args.get("next", "/") + if session.get("logged_in"): + return redirect(next_url) + session['logged_in'] = usr.uid + return redirect(next_url) + + else: + return render_template('nl/login.html', is_error=False) + + +@app.route('/nl/my/ip', methods=['GET']) +def my_ip-nl(): + return jsonify({"ip": get_client_ip()}) + + +@app.route('/nl/my', methods=['GET']) +def my_portal-nl(): + if session.get("logged_in", None) is None: + return redirect("/login?next=/nl/my") + total = _db.images.find({"user_uid": session.get("logged_in")}).count() + activity = _db.images.find({"user_uid": session.get("logged_in")}).sort('created', pymongo.DESCENDING).limit(5) + activity = [x for x in activity] + return render_template("nl/my_portal.html", domains=allowed_domains, total=total, images=activity) + + +@app.route('/nl/my/files', methods=['GET', 'POST']) +def my_files-nl(): + if session.get("logged_in", None) is None: + return redirect("/nl/login?next=/nl/my/files") + + if request.method == "POST": + action = request.form.get("action") + if action == "delete_all": + total = _db.images.find({"user_uid": session.get("logged_in")}) + for image in total: + fpath = "{}/{}{}".format(storage_folder, image['name'], image['extension']) + if os.path.exists(fpath): + os.remove(fpath) + else: + print("This file does not exist:", fpath) + _db.images.delete_many({"user_uid": session.get("logged_in")}) + elif action == "delete_one": + name = request.form.get("name") + image = _db.images.find_one({"user_uid": session.get("logged_in"), "name": name}) + if image: + fpath = "{}/{}{}".format(storage_folder, image['name'], image['extension']) + if os.path.exists(fpath): + os.remove(fpath) + else: + print("This file does not exist:", fpath) + return jsonify({"success": False}) + _db.images.delete_one({"user_uid": session.get("logged_in"), "name": image['name']}) + return jsonify({"success": True}) + + def get_page(page_size, page_num): + skips = page_size * (page_num - 1) + cursor = _db.images.find({"user_uid": session.get("logged_in")}) \ + .skip(skips) \ + .limit(page_size) \ + .sort('created', pymongo.DESCENDING) + return [x for x in cursor] + + page = int(request.args.get("page", 1)) + images = get_page(50, page) + next_page = bool(get_page(50, page + 1)) + next_page_num = page + 1 + prev_page = page != 1 + prev_page_num = page - 1 + + return render_template("nl/my_files.html", images=images, page=page, next_page=next_page, prev_page=prev_page, + next_page_num=next_page_num, prev_page_num=prev_page_num) + + +@app.route('/nl/my/config', methods=['GET']) +def my_config-nl(): + if session.get("logged_in", None) is None: + return redirect("/nl/login?next=/nl/my/config") + usr = _db.users.find_one({"uid": session.get("logged_in")}) + return render_template("nl/my_config.html", **{"domains": allowed_domains, "token": usr['token']}) @app.route('/upload', methods=['POST']) @@ -234,7 +330,7 @@ def upload(): @app.route('/add-user', methods=['POST']) def add_user(): - token = request.headers.get("Authorization", "unknown") + token = request.form['Authorization'] if token != secret_key: return "Not authorized", 403 if request.method == 'POST': diff --git a/static/favicon.ico b/static/favicon.ico new file mode 100644 index 0000000..0dec7f1 Binary files /dev/null and b/static/favicon.ico differ diff --git a/templates/nl/home.html b/templates/nl/home.html new file mode 100644 index 0000000..84ac8be --- /dev/null +++ b/templates/nl/home.html @@ -0,0 +1,64 @@ + + + + + + ksoft.si :: Foto host + + + + + + + +
+

ksoft.si - Image host

+

Je persoonlijke geen bullshit foto host.

+
+ Mijn account + geef mijn config +
+
+

List van domeinen:

+

+ {% for d in domains %} + {{ d }}
+ {% endfor %} +

+
+ Don't email us about account creation.| . + +

+ english? + +
+
+ +
+ + diff --git a/templates/nl/login.html b/templates/nl/login.html new file mode 100644 index 0000000..2c0c9be --- /dev/null +++ b/templates/nl/login.html @@ -0,0 +1,53 @@ + + + + + + Ksoft.Si :: Login + + + + + + +
+

Login

+ {% if is_error %} +

Wrong username or password.

+ {% endif %} +
+
+ + + +
+
+ Don't email us about account creation. | support@ksoft.si. + + +
+ + diff --git a/templates/nl/my_config.html b/templates/nl/my_config.html new file mode 100644 index 0000000..391b76f --- /dev/null +++ b/templates/nl/my_config.html @@ -0,0 +1,96 @@ + + + + + + Ksoft.Si :: Sharex Config + + + + + + +
+

Jouw config:

+ + +
+
+ Back +
+
+ +
+
+
{
+  "Name": "ksoft-sharex",
+  "DestinationType": "ImageUploader",
+  "RequestURL": "https://i.ksoft.si/upload",
+  "FileFormName": "image",
+  "Headers": {
+    "Authorization": "{{ token }}"
+  },
+  "URL": "https://i.ksoft.si/i/$json:filename$$json:extension$"
+}
+
+ + + + + diff --git a/templates/nl/my_files.html b/templates/nl/my_files.html new file mode 100644 index 0000000..b3d5b8f --- /dev/null +++ b/templates/nl/my_files.html @@ -0,0 +1,257 @@ + + + + + + Ksoft.Si :: Mijn bestanden + + + + + + + + + +
+

Your files:

+
+ +
+ + + +
+
+
+
+
+ +
+
{{ page }}
+
+
+ next page +
+
+
+ + + + + + + + + + {% for i in images %} + + + + + + {% else %} + + + + {% endfor %} + +
naamgecreeerdActies
+ {{ i.name }}{{ i.extension }}{{ i.created | getdate }} +
+ + + +
+
je hebt nog geen bestanden :(.
+
+ + + + + + diff --git a/templates/nl/my_portal.html b/templates/nl/my_portal.html new file mode 100644 index 0000000..ac3195f --- /dev/null +++ b/templates/nl/my_portal.html @@ -0,0 +1,61 @@ + + + + + + Ksoft.Si :: mijn account + + + + + + + +
+

Mijn Account

+

Je persoonlijke geen bullshit foto host.

+
+ Mijn config + Mijn bestanden +
+
+

Activiteit:

+

Totaal aantal bestanden: {{ total }}

+ + {% for f in images %} + + {% else %} + + {% endfor %} +
{{ f.name }}{{ f.extension }}
geen recente activiteit.
+
+ Ksoft.Si team © 2021 | Discord: NANI#0001 + +
+ +