diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 786190d5ac1f77710269f8042ee99673395ad0e0..016a9241ed05eb582d18ccee352130f2ee2a4481 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -15,6 +15,7 @@ build: #This will be executed on every push. It builds an docker image, which is - master script: - echo "building for branch $CI_COMMIT_REF_NAME, current date:" `date` + - cp VERSION /app - sudo docker image prune -f #Delete old unused images - sudo docker pull python:3 - sudo docker build -t gitlab.jonasled.de/jonasled/url_shorter_docker:$CI_COMMIT_REF_NAME . #Build the image with the name already set to push @@ -33,6 +34,7 @@ build-release: #This will be executed if you push on master, it makes a new rele - git config --global user.email "noreply@jonasled.de" - git tag -a $version -m "$version" #add a tag with the current version - git push --tags -o ci.skip ssh://git@gitlab.jonasled.de:2222/jonasled/url_shorter_docker #Push the tag to the repo ci.skip means don't build the image again. I've configured an ssh key for the runner user,so it can push via ssh. + - cp VERSION /app - sudo docker image prune -f #Delete old unused images - sudo docker pull python:3 - sudo docker build -t gitlab.jonasled.de/jonasled/url_shorter_docker . #Build the image with the name already set to push diff --git a/Dockerfile b/Dockerfile index c9b02677e59f7379d3c2c68fcf4e504c00d1675e..ba41869e627c6ebd4204b7987430b7ea7ae8b7a6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,13 +5,7 @@ EXPOSE 5000 #Copy files to work directory WORKDIR /app -ADD ./static /app/static -ADD ./templates /app/templates -COPY *.py /app/ -COPY export.sh /app/ -COPY import.sh /app/ -COPY VERSION /app/VERSION -COPY requirements.txt /app/requirements.txt +ADD ./app / #Make a complete system update. apt-utils is needed for configuring packages, so we need to install it RUN apt update diff --git a/__main__.py b/app/__main__.py similarity index 100% rename from __main__.py rename to app/__main__.py diff --git a/api.py b/app/api.py similarity index 100% rename from api.py rename to app/api.py diff --git a/deletelink.py b/app/deletelink.py similarity index 100% rename from deletelink.py rename to app/deletelink.py diff --git a/export.sh b/app/export.sh similarity index 100% rename from export.sh rename to app/export.sh diff --git a/githubcallback.py b/app/githubcallback.py similarity index 100% rename from githubcallback.py rename to app/githubcallback.py diff --git a/googlecallback.py b/app/googlecallback.py similarity index 100% rename from googlecallback.py rename to app/googlecallback.py diff --git a/grecaptcha_verify.py b/app/grecaptcha_verify.py similarity index 100% rename from grecaptcha_verify.py rename to app/grecaptcha_verify.py diff --git a/home.py b/app/home.py similarity index 100% rename from home.py rename to app/home.py diff --git a/import.sh b/app/import.sh similarity index 100% rename from import.sh rename to app/import.sh diff --git a/importHelper.py b/app/importHelper.py similarity index 100% rename from importHelper.py rename to app/importHelper.py diff --git a/login.py b/app/login.py similarity index 100% rename from login.py rename to app/login.py diff --git a/main.py b/app/main.py similarity index 97% rename from main.py rename to app/main.py index 012c32c4c17a5dfb9c151173442adac3c410fef4..597a06d99b3649fc3b70da480653877b13775e01 100644 --- a/main.py +++ b/app/main.py @@ -1,222 +1,222 @@ -#!/usr/bin/env python3 -#Import of Libraries -from waitress import serve #Used as webserver (Production) -from flask import Flask, request, redirect, make_response, abort #Used to prepare the dynamic pages -from os import environ #Used for getting the enviorement variables -from itsdangerous import URLSafeSerializer #used for signing the cookies -from random import choice#used for signing the cookies -from string import ascii_lowercase #used for signing the cookies -from requests import get #used to get the current version on the Server - -#Import of shorter specific files -from table_check import table_check #import the table check file -from makeqr import makeQR #Qr code generation tool -from grecaptcha_verify import grecaptcha_verify #Tool to verify the google recaptcha response -from newurl import newurl #Script to add the new urls to the database -from redirectShortenURL import redirectShortenURL #Script to redirect the user to the long site -from login import login #thandles the login -from home import home #returns the main page -from googlecallback import googleCallback #Script to handle the google oauth login -from githubcallback import githubCallback #Script to handle the Github oauth login -from userprofile import userProfile #This script handles the overview of the own links -from deletelink import deleteLink #Script to delete Links of Users, if they want. -from api import apiGet,apiPost #Scripts to handle the API - -domain_to_index = {} - -try: - domain = environ["domains"].split(";") #Get the domains from the enviorement variable. If no enviorement variable is set it will be set to 127.0.0.1:5000 and localhost:5000 (for testing) -except: - domain = ["localhost:5000", "127.0.0.1:5000"] - -try: - if(environ["show_build_date"] == "1"): #If you want to see the builddate you can enable this enviorement variable - builddate = open("builddate.txt", "r").read() - else: - builddate = "" -except: - builddate = "" #If the enviorement Variable is not set also skip the builddate - -try: - if(environ["show_version"] == "1"): #If you want to see the builddate you can enable this enviorement variable - version = open("VERSION", "r").read() - else: - version = "" -except: - version = "" #If the enviorement Variable is not set also skip the version - -try: - recaptchaPrivateKey = environ["recaptcha_private"] #Get the recaptcha keys, if not set set skipRecaptcha to true to skip the check. If the publicKey is not set the user also will not get the code needed for recaptcha delivered in the page. - recaptchaPublicKey = environ["recaptcha_public"] - if(recaptchaPrivateKey != "") and (recaptchaPublicKey != ""): #If the variables are empty also skip the captcha - skipCaptcha = False - else: - skipCaptcha = True - -except: - recaptchaPrivateKey = "" - recaptchaPublicKey = "" - skipCaptcha = True - -try: - if(environ["production"] == "1"): #If you use this in production, please set this to 1, because the Flask Testserver is not very secure (e.g. shows error on Website) - production = True - else: - production = False -except: - production = False - -try: #If you use https with a proxy afterwards you can set this to https and internal redirects will be https not http. This is to prevent bugs with modern browsers, bacause they block http content if the main page is loaded via https. - url_scheme = environ["url_scheme"] -except: - url_scheme = "http" - -try: - host=environ["host"] -except: - host="127.0.0.1" - -try: - if(environ["login"] == "1"): loginEnabled = True - else: loginEnabled = False -except: - loginEnabled = False - -try: - if(environ["passwordToShort"] != ""): - passwordProtected = True - password = environ["passwordToShort"] - else: - passwordProtected = False - password = "" -except: - passwordProtected = False - password = "" - -if(loginEnabled): - try: #Try to get the oauth keys, if it fails, abort and print a message to console - GITHUB_CLIENT_ID = environ['GITHUB_CLIENT_ID'] - GITHUB_CLIENT_SECRET = environ['GITHUB_CLIENT_SECRET'] - GOOGLE_CLIENT_ID = environ['GOOGLE_CLIENT_ID'] - GOOGLE_CLIENT_SECRET = environ['GOOGLE_CLIENT_SECRET'] - except: - print("please set the oauth keys and run again.") - exit() - -try: #check, if admin wants to show a cookie notice to the user. - if(environ["cookieNotice"] == "1"): - cookieNotice = True - else: - cookieNotice = False -except: - cookieNotice = True - -try: #The secret key is used to crypt the auth cookie. There will be a seccond key to make the api key. - secretKey = open("db/secretKey.txt", "r").read() -except: - secretKey = ''.join(choice(ascii_lowercase) for i in range(100)) #If we can't find the secret key(first run) we generate it in this step and write it to a file - print("generated secret Key. Key is: " + secretKey) - f = open("db/secretKey.txt", "w") - f.write(secretKey) - f.close() - secretKey = open("db/secretKey.txt", "r").read() -s = URLSafeSerializer(secretKey) -sAPI = URLSafeSerializer("api_key_" + secretKey) - -index = 0 -domain_prepared = "" -for domains in domain: #Make from every domnain a entry for the select box later - domain_prepared = domain_prepared + '<option value="' + str(domains) + '">' + str(domains) + '</option>' - domain_to_index[domains] = str(index) - index = index + 1 - -if(index > 1): - showDomainSelect=True #Show only domain select, if there are more than one available -else: - showDomainSelect=False - domain_prepared = domain[0] - - - - -app = Flask(__name__) - -@app.route('/', methods=['GET']) -def home_get(): - return home(request, builddate, version, domain_prepared, recaptchaPublicKey, showDomainSelect, cookieNotice, domain_to_index, s, loginEnabled, passwordProtected) - -@app.route('/', methods=['POST']) #This function is used to create a new url -def home_post(): - return newurl(request, skipCaptcha, recaptchaPrivateKey, recaptchaPublicKey, builddate, version, domain_prepared, domain_to_index, showDomainSelect, cookieNotice, s, url_scheme, loginEnabled, passwordProtected, password) - -@app.route('/favicon.ico') #Redirect to the static url of the favicon -def favicon(): - return redirect("/static/favicon.ico", code=301) - -@app.route('/<short_url>') -def redirect_short_url(short_url): - return redirectShortenURL(request, short_url) - - -@app.route('/user/login') -def loginPage(): - if(loginEnabled): return login(request, GITHUB_CLIENT_ID, cookieNotice, GOOGLE_CLIENT_ID, url_scheme, domain) - else: abort(404) - -@app.route("/user/google-callback") -def authorizeGoogle(): - if(loginEnabled): return googleCallback(request, GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, url_scheme, domain, s) - else: abort(404) - -@app.route('/user/github-callback') #Github redirects to this link after the user authenticated. Then we use the Token we get from github and request via the github api the username and the userid -def authorizeGithub(): - if(loginEnabled): return githubCallback(request, GITHUB_CLIENT_SECRET, GITHUB_CLIENT_ID, s) - else: abort(404) - -@app.route('/user/logout') -def logout(): - resp = make_response('<style>\n@media (prefers-color-scheme: dark) {\nbody {\ncolor: #b3b3b3;\nbackground: #151d28;\n}\n}\n</style>\n<h2>Logout successful. Redirecting you back in 2 sec.</h2>\n<script> window.setTimeout(function(){\nwindow.location.href = "/";\n}, 2000);</script>') - resp.set_cookie('userID', "", max_age=0) #Set the max age of the cookies to 0, this means delete the cookies. - resp.set_cookie('username', "", max_age=0) - return resp - -@app.route('/user/links')#This function gives the user the posibility to see and delete his links -def redirectOwnLinks(): - return redirect("/user/links0", code=301) - -@app.route('/user/links<pageNumber>')#This function gives the user the posibility to see and delete his links -def ownLinks(pageNumber): - if(loginEnabled): return userProfile(request, cookieNotice, s, pageNumber, url_scheme) - else: abort(404) - -@app.route('/user/delete', methods=['POST']) #This function is called if a user deletes an entrie -def delete(): - if(loginEnabled): return deleteLink(request, s) - else: abort(404) - -@app.route('/user/makeqr', methods=['POST']) -def makeQrCode(): - link = request.form.get('link') - return "data:image/jpeg;base64," + makeQR(url_scheme + "://" + link) - -@app.route('/user/api', methods=['POST']) -def api(): - return apiPost(request, url_scheme, domain, sAPI, passwordProtected, password) - - -@app.route('/user/api', methods=['GET']) -def apiDocs(): - return apiGet(request, url_scheme, s, sAPI, passwordProtected) - - -def startup(production): - table_check()# This code checks whether database table is created or not - - if production: #Check if production variable is set to true use the waitress webserver, else use the buildin flask webserver, with more debug output - serve(app, host=host, port= 5000, url_scheme=url_scheme) #Start the production Webserver for all users on port 5000 - else: - app.run(host=host, port=5000, debug=True) #Start the Webserver in Debug mode. This means, if the script runs in an error, it will show the error message in Browser. - - return app - +#!/usr/bin/env python3 +#Import of Libraries +from waitress import serve #Used as webserver (Production) +from flask import Flask, request, redirect, make_response, abort #Used to prepare the dynamic pages +from os import environ #Used for getting the enviorement variables +from itsdangerous import URLSafeSerializer #used for signing the cookies +from random import choice#used for signing the cookies +from string import ascii_lowercase #used for signing the cookies +from requests import get #used to get the current version on the Server + +#Import of shorter specific files +from table_check import table_check #import the table check file +from makeqr import makeQR #Qr code generation tool +from grecaptcha_verify import grecaptcha_verify #Tool to verify the google recaptcha response +from newurl import newurl #Script to add the new urls to the database +from redirectShortenURL import redirectShortenURL #Script to redirect the user to the long site +from login import login #thandles the login +from home import home #returns the main page +from googlecallback import googleCallback #Script to handle the google oauth login +from githubcallback import githubCallback #Script to handle the Github oauth login +from userprofile import userProfile #This script handles the overview of the own links +from deletelink import deleteLink #Script to delete Links of Users, if they want. +from api import apiGet,apiPost #Scripts to handle the API + +domain_to_index = {} + +try: + domain = environ["domains"].split(";") #Get the domains from the enviorement variable. If no enviorement variable is set it will be set to 127.0.0.1:5000 and localhost:5000 (for testing) +except: + domain = ["localhost:5000", "127.0.0.1:5000"] + +try: + if(environ["show_build_date"] == "1"): #If you want to see the builddate you can enable this enviorement variable + builddate = open("builddate.txt", "r").read() + else: + builddate = "" +except: + builddate = "" #If the enviorement Variable is not set also skip the builddate + +try: + if(environ["show_version"] == "1"): #If you want to see the builddate you can enable this enviorement variable + version = open("VERSION", "r").read() + else: + version = "" +except: + version = "" #If the enviorement Variable is not set also skip the version + +try: + recaptchaPrivateKey = environ["recaptcha_private"] #Get the recaptcha keys, if not set set skipRecaptcha to true to skip the check. If the publicKey is not set the user also will not get the code needed for recaptcha delivered in the page. + recaptchaPublicKey = environ["recaptcha_public"] + if(recaptchaPrivateKey != "") and (recaptchaPublicKey != ""): #If the variables are empty also skip the captcha + skipCaptcha = False + else: + skipCaptcha = True + +except: + recaptchaPrivateKey = "" + recaptchaPublicKey = "" + skipCaptcha = True + +try: + if(environ["production"] == "1"): #If you use this in production, please set this to 1, because the Flask Testserver is not very secure (e.g. shows error on Website) + production = True + else: + production = False +except: + production = False + +try: #If you use https with a proxy afterwards you can set this to https and internal redirects will be https not http. This is to prevent bugs with modern browsers, bacause they block http content if the main page is loaded via https. + url_scheme = environ["url_scheme"] +except: + url_scheme = "http" + +try: + host=environ["host"] +except: + host="127.0.0.1" + +try: + if(environ["login"] == "1"): loginEnabled = True + else: loginEnabled = False +except: + loginEnabled = False + +try: + if(environ["passwordToShort"] != ""): + passwordProtected = True + password = environ["passwordToShort"] + else: + passwordProtected = False + password = "" +except: + passwordProtected = False + password = "" + +if(loginEnabled): + try: #Try to get the oauth keys, if it fails, abort and print a message to console + GITHUB_CLIENT_ID = environ['GITHUB_CLIENT_ID'] + GITHUB_CLIENT_SECRET = environ['GITHUB_CLIENT_SECRET'] + GOOGLE_CLIENT_ID = environ['GOOGLE_CLIENT_ID'] + GOOGLE_CLIENT_SECRET = environ['GOOGLE_CLIENT_SECRET'] + except: + print("please set the oauth keys and run again.") + exit() + +try: #check, if admin wants to show a cookie notice to the user. + if(environ["cookieNotice"] == "1"): + cookieNotice = True + else: + cookieNotice = False +except: + cookieNotice = True + +try: #The secret key is used to crypt the auth cookie. There will be a seccond key to make the api key. + secretKey = open("db/secretKey.txt", "r").read() +except: + secretKey = ''.join(choice(ascii_lowercase) for i in range(100)) #If we can't find the secret key(first run) we generate it in this step and write it to a file + print("generated secret Key. Key is: " + secretKey) + f = open("db/secretKey.txt", "w") + f.write(secretKey) + f.close() + secretKey = open("db/secretKey.txt", "r").read() +s = URLSafeSerializer(secretKey) +sAPI = URLSafeSerializer("api_key_" + secretKey) + +index = 0 +domain_prepared = "" +for domains in domain: #Make from every domnain a entry for the select box later + domain_prepared = domain_prepared + '<option value="' + str(domains) + '">' + str(domains) + '</option>' + domain_to_index[domains] = str(index) + index = index + 1 + +if(index > 1): + showDomainSelect=True #Show only domain select, if there are more than one available +else: + showDomainSelect=False + domain_prepared = domain[0] + + + + +app = Flask(__name__) + +@app.route('/', methods=['GET']) +def home_get(): + return home(request, builddate, version, domain_prepared, recaptchaPublicKey, showDomainSelect, cookieNotice, domain_to_index, s, loginEnabled, passwordProtected) + +@app.route('/', methods=['POST']) #This function is used to create a new url +def home_post(): + return newurl(request, skipCaptcha, recaptchaPrivateKey, recaptchaPublicKey, builddate, version, domain_prepared, domain_to_index, showDomainSelect, cookieNotice, s, url_scheme, loginEnabled, passwordProtected, password) + +@app.route('/favicon.ico') #Redirect to the static url of the favicon +def favicon(): + return redirect("/static/favicon.ico", code=301) + +@app.route('/<short_url>') +def redirect_short_url(short_url): + return redirectShortenURL(request, short_url) + + +@app.route('/user/login') +def loginPage(): + if(loginEnabled): return login(request, GITHUB_CLIENT_ID, cookieNotice, GOOGLE_CLIENT_ID, url_scheme, domain) + else: abort(404) + +@app.route("/user/google-callback") +def authorizeGoogle(): + if(loginEnabled): return googleCallback(request, GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, url_scheme, domain, s) + else: abort(404) + +@app.route('/user/github-callback') #Github redirects to this link after the user authenticated. Then we use the Token we get from github and request via the github api the username and the userid +def authorizeGithub(): + if(loginEnabled): return githubCallback(request, GITHUB_CLIENT_SECRET, GITHUB_CLIENT_ID, s) + else: abort(404) + +@app.route('/user/logout') +def logout(): + resp = make_response('<style>\n@media (prefers-color-scheme: dark) {\nbody {\ncolor: #b3b3b3;\nbackground: #151d28;\n}\n}\n</style>\n<h2>Logout successful. Redirecting you back in 2 sec.</h2>\n<script> window.setTimeout(function(){\nwindow.location.href = "/";\n}, 2000);</script>') + resp.set_cookie('userID', "", max_age=0) #Set the max age of the cookies to 0, this means delete the cookies. + resp.set_cookie('username', "", max_age=0) + return resp + +@app.route('/user/links')#This function gives the user the posibility to see and delete his links +def redirectOwnLinks(): + return redirect("/user/links0", code=301) + +@app.route('/user/links<pageNumber>')#This function gives the user the posibility to see and delete his links +def ownLinks(pageNumber): + if(loginEnabled): return userProfile(request, cookieNotice, s, pageNumber, url_scheme) + else: abort(404) + +@app.route('/user/delete', methods=['POST']) #This function is called if a user deletes an entrie +def delete(): + if(loginEnabled): return deleteLink(request, s) + else: abort(404) + +@app.route('/user/makeqr', methods=['POST']) +def makeQrCode(): + link = request.form.get('link') + return "data:image/jpeg;base64," + makeQR(url_scheme + "://" + link) + +@app.route('/user/api', methods=['POST']) +def api(): + return apiPost(request, url_scheme, domain, sAPI, passwordProtected, password) + + +@app.route('/user/api', methods=['GET']) +def apiDocs(): + return apiGet(request, url_scheme, s, sAPI, passwordProtected) + + +def startup(production): + table_check()# This code checks whether database table is created or not + + if production: #Check if production variable is set to true use the waitress webserver, else use the buildin flask webserver, with more debug output + serve(app, host=host, port= 5000, url_scheme=url_scheme) #Start the production Webserver for all users on port 5000 + else: + app.run(host=host, port=5000, debug=True) #Start the Webserver in Debug mode. This means, if the script runs in an error, it will show the error message in Browser. + + return app + if (__name__ == "__main__"): startup(production) #Only run the startup script, if this file is directly called. \ No newline at end of file diff --git a/makeqr.py b/app/makeqr.py similarity index 100% rename from makeqr.py rename to app/makeqr.py diff --git a/newurl.py b/app/newurl.py similarity index 100% rename from newurl.py rename to app/newurl.py diff --git a/redirectShortenURL.py b/app/redirectShortenURL.py similarity index 100% rename from redirectShortenURL.py rename to app/redirectShortenURL.py diff --git a/requirements.txt b/app/requirements.txt similarity index 100% rename from requirements.txt rename to app/requirements.txt diff --git a/static/cookie.js b/app/static/cookie.js similarity index 96% rename from static/cookie.js rename to app/static/cookie.js index 68a84f3b8dcaa5943bb2502627ffe579f5cf558a..c0081d3b5f71646e11f3a9e1a32f601e58541ba9 100644 --- a/static/cookie.js +++ b/app/static/cookie.js @@ -1,23 +1,23 @@ -function acceptCookie(){ - document.cookie = "cookieMessageHide=1"; - checkHide(); -} - -function getCookie(name){ - var nameEQ = name + "="; - var ca = document.cookie.split(";"); - for (var i=0; i < ca.length; i++) { - var c = ca[i]; - while(c.charAt(0) == " ") c = c.substr(1, c.length); - if(c.indexOf(nameEQ) == 0) return c.substr(nameEQ.length, c.length) - } - return null -} - -function checkHide(){ - if (getCookie("cookieMessageHide") == "1"){ - $(".cookieinfo").hide(); - } else { - $(".cookieinfo").show(); - } +function acceptCookie(){ + document.cookie = "cookieMessageHide=1"; + checkHide(); +} + +function getCookie(name){ + var nameEQ = name + "="; + var ca = document.cookie.split(";"); + for (var i=0; i < ca.length; i++) { + var c = ca[i]; + while(c.charAt(0) == " ") c = c.substr(1, c.length); + if(c.indexOf(nameEQ) == 0) return c.substr(nameEQ.length, c.length) + } + return null +} + +function checkHide(){ + if (getCookie("cookieMessageHide") == "1"){ + $(".cookieinfo").hide(); + } else { + $(".cookieinfo").show(); + } } \ No newline at end of file diff --git a/static/darkmode.css b/app/static/darkmode.css similarity index 96% rename from static/darkmode.css rename to app/static/darkmode.css index 0377f63a27f7e3c23f7e1c64d00f820b54fdabd6..9e448639bd00be6cac4922edc61725a44e4fdf0b 100644 --- a/static/darkmode.css +++ b/app/static/darkmode.css @@ -1,72 +1,72 @@ -@media (prefers-color-scheme: dark) { /* Settings for darkmode */ - body { /* background of the main page */ - background: #151d28; - } - .form{ /* background and text color of the "window" in the center */ - background: #1a2332; - color: #b3b3b3; - } - .form input{ /* style of the text input box (same color as form, but a brighter border) */ - background: #1a2332; - border: solid #212a39; - color: #b3b3b3; - } - - .form select{ /* style of the domain select box (same color as form, but a brighter border) */ - background: #1a2332; - border: solid; - border-color: #212a39; - color: #b3b3b3; - } - - .form button{ /* color of the big button */ - background: #1cb09a; - color: #fff; - } - .form button:hover,.form button:active,.form button:focus { /* color of the button, if its hovered */ - background: #189684; - color: #b3b3b3; - } - - a { /* color of hyperlinks */ - color: #1cb09a; - text-decoration: none; - } - #loginbar { /* loginbar style (background and text color) */ - background-color: #1a2332; - color: #b3b3b3; - } - #loginbar a{ /* hyperlinks in login bar are not marked special */ - color: #b3b3b3; - } - - #snackbar { /* style options of the snackbar (bottom left) */ - background-color: #1a2332; - color: #b3b3b3; - } - - table#t01 th { /*text color configuration of the table */ - color: #b3b3b3; - } - table#t01 tr:nth-child(even) { /* background color of the table entries (alternately bright and dark) */ - background-color: #151c29; - color: #b3b3b3; - } - table#t01 tr:nth-child(odd) { - background-color: #10151f; - color: #b3b3b3; - } - - .cookieinfo{ - background: #1a2332; - color: #b3b3b3; - } - - .cookieinfo-link{ - color: #1cb09a; - } - - .cookieinfo-close{ - background: #1cb09a; - } +@media (prefers-color-scheme: dark) { /* Settings for darkmode */ + body { /* background of the main page */ + background: #151d28; + } + .form{ /* background and text color of the "window" in the center */ + background: #1a2332; + color: #b3b3b3; + } + .form input{ /* style of the text input box (same color as form, but a brighter border) */ + background: #1a2332; + border: solid #212a39; + color: #b3b3b3; + } + + .form select{ /* style of the domain select box (same color as form, but a brighter border) */ + background: #1a2332; + border: solid; + border-color: #212a39; + color: #b3b3b3; + } + + .form button{ /* color of the big button */ + background: #1cb09a; + color: #fff; + } + .form button:hover,.form button:active,.form button:focus { /* color of the button, if its hovered */ + background: #189684; + color: #b3b3b3; + } + + a { /* color of hyperlinks */ + color: #1cb09a; + text-decoration: none; + } + #loginbar { /* loginbar style (background and text color) */ + background-color: #1a2332; + color: #b3b3b3; + } + #loginbar a{ /* hyperlinks in login bar are not marked special */ + color: #b3b3b3; + } + + #snackbar { /* style options of the snackbar (bottom left) */ + background-color: #1a2332; + color: #b3b3b3; + } + + table#t01 th { /*text color configuration of the table */ + color: #b3b3b3; + } + table#t01 tr:nth-child(even) { /* background color of the table entries (alternately bright and dark) */ + background-color: #151c29; + color: #b3b3b3; + } + table#t01 tr:nth-child(odd) { + background-color: #10151f; + color: #b3b3b3; + } + + .cookieinfo{ + background: #1a2332; + color: #b3b3b3; + } + + .cookieinfo-link{ + color: #1cb09a; + } + + .cookieinfo-close{ + background: #1cb09a; + } } \ No newline at end of file diff --git a/static/external/jquery/jquery.js b/app/static/external/jquery/jquery.js similarity index 100% rename from static/external/jquery/jquery.js rename to app/static/external/jquery/jquery.js diff --git a/static/favicon.ico b/app/static/favicon.ico similarity index 100% rename from static/favicon.ico rename to app/static/favicon.ico diff --git a/static/font.css b/app/static/font.css similarity index 97% rename from static/font.css rename to app/static/font.css index 7c90b7faf20375f810e5f5587a3a393d93bcc44a..9dfa0c6ce6f7e62742150fc0f1d006d4b536a002 100644 --- a/static/font.css +++ b/app/static/font.css @@ -1,56 +1,56 @@ -/* cyrillic-ext */ -@font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 300; - src: local('Roboto Light'), local('Roboto-Light'), url(/static/roboto-light.woff2) format('woff2'); - unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; - } - /* cyrillic */ - @font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 300; - src: local('Roboto Light'), local('Roboto-Light'), url(/static/roboto-light.woff2) format('woff2'); - unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; - } - /* greek-ext */ - @font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 300; - src: local('Roboto Light'), local('Roboto-Light'), url(/static/roboto-light.woff2) format('woff2'); - unicode-range: U+1F00-1FFF; - } - /* greek */ - @font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 300; - src: local('Roboto Light'), local('Roboto-Light'), url(/static/roboto-light.woff2) format('woff2'); - unicode-range: U+0370-03FF; - } - /* vietnamese */ - @font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 300; - src: local('Roboto Light'), local('Roboto-Light'), url(/static/roboto-light.woff2) format('woff2'); - unicode-range: U+0102-0103, U+0110-0111, U+1EA0-1EF9, U+20AB; - } - /* latin-ext */ - @font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 300; - src: local('Roboto Light'), local('Roboto-Light'), url(/static/roboto-light.woff2) format('woff2'); - unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; - } - /* latin */ - @font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 300; - src: local('Roboto Light'), local('Roboto-Light'), url(/static/roboto-light.woff2) format('woff2'); - unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +/* cyrillic-ext */ +@font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 300; + src: local('Roboto Light'), local('Roboto-Light'), url(/static/roboto-light.woff2) format('woff2'); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; + } + /* cyrillic */ + @font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 300; + src: local('Roboto Light'), local('Roboto-Light'), url(/static/roboto-light.woff2) format('woff2'); + unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; + } + /* greek-ext */ + @font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 300; + src: local('Roboto Light'), local('Roboto-Light'), url(/static/roboto-light.woff2) format('woff2'); + unicode-range: U+1F00-1FFF; + } + /* greek */ + @font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 300; + src: local('Roboto Light'), local('Roboto-Light'), url(/static/roboto-light.woff2) format('woff2'); + unicode-range: U+0370-03FF; + } + /* vietnamese */ + @font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 300; + src: local('Roboto Light'), local('Roboto-Light'), url(/static/roboto-light.woff2) format('woff2'); + unicode-range: U+0102-0103, U+0110-0111, U+1EA0-1EF9, U+20AB; + } + /* latin-ext */ + @font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 300; + src: local('Roboto Light'), local('Roboto-Light'), url(/static/roboto-light.woff2) format('woff2'); + unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; + } + /* latin */ + @font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 300; + src: local('Roboto Light'), local('Roboto-Light'), url(/static/roboto-light.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; } \ No newline at end of file diff --git a/static/images/ui-bg_glass_55_fcf0ba_1x400.png b/app/static/images/ui-bg_glass_55_fcf0ba_1x400.png similarity index 100% rename from static/images/ui-bg_glass_55_fcf0ba_1x400.png rename to app/static/images/ui-bg_glass_55_fcf0ba_1x400.png diff --git a/static/images/ui-bg_gloss-wave_100_ece8da_500x100.png b/app/static/images/ui-bg_gloss-wave_100_ece8da_500x100.png similarity index 100% rename from static/images/ui-bg_gloss-wave_100_ece8da_500x100.png rename to app/static/images/ui-bg_gloss-wave_100_ece8da_500x100.png diff --git a/static/images/ui-bg_highlight-hard_100_f5f3e5_1x100.png b/app/static/images/ui-bg_highlight-hard_100_f5f3e5_1x100.png similarity index 100% rename from static/images/ui-bg_highlight-hard_100_f5f3e5_1x100.png rename to app/static/images/ui-bg_highlight-hard_100_f5f3e5_1x100.png diff --git a/static/images/ui-bg_highlight-hard_100_fafaf4_1x100.png b/app/static/images/ui-bg_highlight-hard_100_fafaf4_1x100.png similarity index 100% rename from static/images/ui-bg_highlight-hard_100_fafaf4_1x100.png rename to app/static/images/ui-bg_highlight-hard_100_fafaf4_1x100.png diff --git a/static/images/ui-bg_highlight-hard_15_459e00_1x100.png b/app/static/images/ui-bg_highlight-hard_15_459e00_1x100.png similarity index 100% rename from static/images/ui-bg_highlight-hard_15_459e00_1x100.png rename to app/static/images/ui-bg_highlight-hard_15_459e00_1x100.png diff --git a/static/images/ui-bg_highlight-hard_95_cccccc_1x100.png b/app/static/images/ui-bg_highlight-hard_95_cccccc_1x100.png similarity index 100% rename from static/images/ui-bg_highlight-hard_95_cccccc_1x100.png rename to app/static/images/ui-bg_highlight-hard_95_cccccc_1x100.png diff --git a/static/images/ui-bg_highlight-soft_25_67b021_1x100.png b/app/static/images/ui-bg_highlight-soft_25_67b021_1x100.png similarity index 100% rename from static/images/ui-bg_highlight-soft_25_67b021_1x100.png rename to app/static/images/ui-bg_highlight-soft_25_67b021_1x100.png diff --git a/static/images/ui-bg_highlight-soft_95_ffedad_1x100.png b/app/static/images/ui-bg_highlight-soft_95_ffedad_1x100.png similarity index 100% rename from static/images/ui-bg_highlight-soft_95_ffedad_1x100.png rename to app/static/images/ui-bg_highlight-soft_95_ffedad_1x100.png diff --git a/static/images/ui-bg_inset-soft_15_2b2922_1x100.png b/app/static/images/ui-bg_inset-soft_15_2b2922_1x100.png similarity index 100% rename from static/images/ui-bg_inset-soft_15_2b2922_1x100.png rename to app/static/images/ui-bg_inset-soft_15_2b2922_1x100.png diff --git a/static/images/ui-icons_808080_256x240.png b/app/static/images/ui-icons_808080_256x240.png similarity index 100% rename from static/images/ui-icons_808080_256x240.png rename to app/static/images/ui-icons_808080_256x240.png diff --git a/static/images/ui-icons_847e71_256x240.png b/app/static/images/ui-icons_847e71_256x240.png similarity index 100% rename from static/images/ui-icons_847e71_256x240.png rename to app/static/images/ui-icons_847e71_256x240.png diff --git a/static/images/ui-icons_8DC262_256x240.png b/app/static/images/ui-icons_8DC262_256x240.png similarity index 100% rename from static/images/ui-icons_8DC262_256x240.png rename to app/static/images/ui-icons_8DC262_256x240.png diff --git a/static/images/ui-icons_cd0a0a_256x240.png b/app/static/images/ui-icons_cd0a0a_256x240.png similarity index 100% rename from static/images/ui-icons_cd0a0a_256x240.png rename to app/static/images/ui-icons_cd0a0a_256x240.png diff --git a/static/images/ui-icons_eeeeee_256x240.png b/app/static/images/ui-icons_eeeeee_256x240.png similarity index 100% rename from static/images/ui-icons_eeeeee_256x240.png rename to app/static/images/ui-icons_eeeeee_256x240.png diff --git a/static/images/ui-icons_ffffff_256x240.png b/app/static/images/ui-icons_ffffff_256x240.png similarity index 100% rename from static/images/ui-icons_ffffff_256x240.png rename to app/static/images/ui-icons_ffffff_256x240.png diff --git a/static/jquery-ui.css b/app/static/jquery-ui.css similarity index 100% rename from static/jquery-ui.css rename to app/static/jquery-ui.css diff --git a/static/jquery-ui.js b/app/static/jquery-ui.js similarity index 100% rename from static/jquery-ui.js rename to app/static/jquery-ui.js diff --git a/static/jquery-ui.min.css b/app/static/jquery-ui.min.css similarity index 100% rename from static/jquery-ui.min.css rename to app/static/jquery-ui.min.css diff --git a/static/jquery-ui.min.js b/app/static/jquery-ui.min.js similarity index 100% rename from static/jquery-ui.min.js rename to app/static/jquery-ui.min.js diff --git a/static/jquery-ui.structure.css b/app/static/jquery-ui.structure.css similarity index 100% rename from static/jquery-ui.structure.css rename to app/static/jquery-ui.structure.css diff --git a/static/jquery-ui.structure.min.css b/app/static/jquery-ui.structure.min.css similarity index 100% rename from static/jquery-ui.structure.min.css rename to app/static/jquery-ui.structure.min.css diff --git a/static/jquery-ui.theme.css b/app/static/jquery-ui.theme.css similarity index 100% rename from static/jquery-ui.theme.css rename to app/static/jquery-ui.theme.css diff --git a/static/jquery-ui.theme.min.css b/app/static/jquery-ui.theme.min.css similarity index 100% rename from static/jquery-ui.theme.min.css rename to app/static/jquery-ui.theme.min.css diff --git a/static/roboto-light.woff2 b/app/static/roboto-light.woff2 similarity index 100% rename from static/roboto-light.woff2 rename to app/static/roboto-light.woff2 diff --git a/static/socialSignin/css/buttons-si.css b/app/static/socialSignin/css/buttons-si.css similarity index 100% rename from static/socialSignin/css/buttons-si.css rename to app/static/socialSignin/css/buttons-si.css diff --git a/static/socialSignin/img/github.svg b/app/static/socialSignin/img/github.svg similarity index 100% rename from static/socialSignin/img/github.svg rename to app/static/socialSignin/img/github.svg diff --git a/static/socialSignin/img/google.svg b/app/static/socialSignin/img/google.svg similarity index 100% rename from static/socialSignin/img/google.svg rename to app/static/socialSignin/img/google.svg diff --git a/static/style.css b/app/static/style.css similarity index 94% rename from static/style.css rename to app/static/style.css index 3aef430b45a16590d4d600985e1a6e7317b318c9..d17d337d53cd722dc07846787800e9f4938f13e8 100644 --- a/static/style.css +++ b/app/static/style.css @@ -1,219 +1,219 @@ -.login-page { -width: 999px; -padding: 8% 0 0; -margin: auto; -} -.form { -position: relative; -z-index: 1; -background: #FFFFFF; -margin: 0 auto 100px; -padding: 45px; -text-align: center; -box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.2), 0 5px 5px 0 rgba(0, 0, 0, 0.24); -display: table; -} -.form input { -font-family: "Roboto", sans-serif; -outline: 0; -width: 100%; -margin: 0 0 15px; -padding: 15px; -box-sizing: border-box; -font-size: 14px; -border: solid #b3b3b3; -} -.form button { -font-family: "Roboto", sans-serif; -text-transform: uppercase; -outline: 0; -background: #4CAF50; -width: 100%; -border: 0; -padding: 15px; -color: #FFFFFF; -font-size: 14px; --webkit-transition: all 0.3 ease; -transition: all 0.3 ease; -cursor: pointer; -} -.form button:hover,.form button:active,.form button:focus { -background: #43A047; -} -.form .message { -margin: 15px 0 0; -color: #b3b3b3; -font-size: 12px; -} -a { -color: #4CAF50; -text-decoration: none; -} -.form .register-form { -display: none; -} -.container { -position: relative; -z-index: 1; -max-width: 300px; -margin: 0 auto; -} -.container:before, .container:after { -content: ""; -display: block; -clear: both; -} -.container .info { -margin: 50px auto; -text-align: center; -} -.container .info h1 { -margin: 0 0 15px; -padding: 0; -font-size: 36px; -font-weight: 300; -color: #1a1a1a; -} -.container .info span { -color: #4d4d4d; -font-size: 12px; -} -.container .info span a { -color: #000000; -text-decoration: none; -} -.container .info span .fa { -color: #EF3B3A; -} -body { -background: #76b852; -font-family: "Roboto", sans-serif; --webkit-font-smoothing: antialiased; --moz-osx-font-smoothing: grayscale; -} - -#snackbar { -visibility: hidden; -min-width: 250px; -background-color: #333; -color: #fff; -text-align: center; -border-radius: 2px; -padding: 16px; -position: fixed; -z-index: 1; -margin-left: auto; -margin-right: auto; -bottom: 30px; -font-size: 17px; -} - -#snackbar.show { -visibility: visible; --webkit-animation: fadein 0.5s, fadeout 0.5s 9.5s; -animation: fadein 0.5s, fadeout 0.5s 9.5s; -} - -#loginbar { - min-width: 250px; - background-color: #333; - color: #fff; - text-align: center; - border-radius: 2px; - padding: 16px; - position: fixed; - z-index: 1; - top: 30px; - right: 16px; - font-size: 17px; - } - #loginbar a{ - color: #fff; - } - -table, th, td { - border: 1px solid black; - border-collapse: collapse; -} -th, td { - padding: 15px; - text-align: left; -} -table#t01 tr:nth-child(even) { - background-color: #eee; -} -table#t01 tr:nth-child(odd) { - background-color: #fff; -} -table#t01 th { - background-color: black; - color: white; -} -a#red { - color: red; -} - -button#small { - width: 30%; -} - -.cookieinfo{ - position: fixed; - left: 0px; - right: 0px; - height: auto; - min-height: 21px; - z-index: 2147483647; - background: #fff; - color: #000; - line-height: 21px; - padding: 8px 18px; - font-family: verdana, arial, sans-serif; - font-size: 14px; - text-align: center; - bottom: 0px; - opacity: 1; -} - -.cookieinfo-close{ - float: right; - display: block; - padding: 5px 8px; - min-width: 100px; - margin-left: 5px; - border-radius: 5px; - cursor: pointer; - color: #FFFFFF; - background: #4caf50; - text-align: center; -} - -.cookieinfo-text { - display:block; - padding:5px 0 5px 0; -} - -.cookieinfo-link{ - text-decoration: none; - color: #4caf50; -} - -@-webkit-keyframes fadein { -from {bottom: 0; opacity: 0;} -to {bottom: 30px; opacity: 1;} -} - -@keyframes fadein { -from {bottom: 0; opacity: 0;} -to {bottom: 30px; opacity: 1;} -} - -@-webkit-keyframes fadeout { -from {bottom: 30px; opacity: 1;} -to {bottom: 0; opacity: 0;} -} - -@keyframes fadeout { -from {bottom: 30px; opacity: 1;} -to {bottom: 0; opacity: 0;} +.login-page { +width: 999px; +padding: 8% 0 0; +margin: auto; +} +.form { +position: relative; +z-index: 1; +background: #FFFFFF; +margin: 0 auto 100px; +padding: 45px; +text-align: center; +box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.2), 0 5px 5px 0 rgba(0, 0, 0, 0.24); +display: table; +} +.form input { +font-family: "Roboto", sans-serif; +outline: 0; +width: 100%; +margin: 0 0 15px; +padding: 15px; +box-sizing: border-box; +font-size: 14px; +border: solid #b3b3b3; +} +.form button { +font-family: "Roboto", sans-serif; +text-transform: uppercase; +outline: 0; +background: #4CAF50; +width: 100%; +border: 0; +padding: 15px; +color: #FFFFFF; +font-size: 14px; +-webkit-transition: all 0.3 ease; +transition: all 0.3 ease; +cursor: pointer; +} +.form button:hover,.form button:active,.form button:focus { +background: #43A047; +} +.form .message { +margin: 15px 0 0; +color: #b3b3b3; +font-size: 12px; +} +a { +color: #4CAF50; +text-decoration: none; +} +.form .register-form { +display: none; +} +.container { +position: relative; +z-index: 1; +max-width: 300px; +margin: 0 auto; +} +.container:before, .container:after { +content: ""; +display: block; +clear: both; +} +.container .info { +margin: 50px auto; +text-align: center; +} +.container .info h1 { +margin: 0 0 15px; +padding: 0; +font-size: 36px; +font-weight: 300; +color: #1a1a1a; +} +.container .info span { +color: #4d4d4d; +font-size: 12px; +} +.container .info span a { +color: #000000; +text-decoration: none; +} +.container .info span .fa { +color: #EF3B3A; +} +body { +background: #76b852; +font-family: "Roboto", sans-serif; +-webkit-font-smoothing: antialiased; +-moz-osx-font-smoothing: grayscale; +} + +#snackbar { +visibility: hidden; +min-width: 250px; +background-color: #333; +color: #fff; +text-align: center; +border-radius: 2px; +padding: 16px; +position: fixed; +z-index: 1; +margin-left: auto; +margin-right: auto; +bottom: 30px; +font-size: 17px; +} + +#snackbar.show { +visibility: visible; +-webkit-animation: fadein 0.5s, fadeout 0.5s 9.5s; +animation: fadein 0.5s, fadeout 0.5s 9.5s; +} + +#loginbar { + min-width: 250px; + background-color: #333; + color: #fff; + text-align: center; + border-radius: 2px; + padding: 16px; + position: fixed; + z-index: 1; + top: 30px; + right: 16px; + font-size: 17px; + } + #loginbar a{ + color: #fff; + } + +table, th, td { + border: 1px solid black; + border-collapse: collapse; +} +th, td { + padding: 15px; + text-align: left; +} +table#t01 tr:nth-child(even) { + background-color: #eee; +} +table#t01 tr:nth-child(odd) { + background-color: #fff; +} +table#t01 th { + background-color: black; + color: white; +} +a#red { + color: red; +} + +button#small { + width: 30%; +} + +.cookieinfo{ + position: fixed; + left: 0px; + right: 0px; + height: auto; + min-height: 21px; + z-index: 2147483647; + background: #fff; + color: #000; + line-height: 21px; + padding: 8px 18px; + font-family: verdana, arial, sans-serif; + font-size: 14px; + text-align: center; + bottom: 0px; + opacity: 1; +} + +.cookieinfo-close{ + float: right; + display: block; + padding: 5px 8px; + min-width: 100px; + margin-left: 5px; + border-radius: 5px; + cursor: pointer; + color: #FFFFFF; + background: #4caf50; + text-align: center; +} + +.cookieinfo-text { + display:block; + padding:5px 0 5px 0; +} + +.cookieinfo-link{ + text-decoration: none; + color: #4caf50; +} + +@-webkit-keyframes fadein { +from {bottom: 0; opacity: 0;} +to {bottom: 30px; opacity: 1;} +} + +@keyframes fadein { +from {bottom: 0; opacity: 0;} +to {bottom: 30px; opacity: 1;} +} + +@-webkit-keyframes fadeout { +from {bottom: 30px; opacity: 1;} +to {bottom: 0; opacity: 0;} +} + +@keyframes fadeout { +from {bottom: 30px; opacity: 1;} +to {bottom: 0; opacity: 0;} } \ No newline at end of file diff --git a/table_check.py b/app/table_check.py similarity index 100% rename from table_check.py rename to app/table_check.py diff --git a/templates/apiDocs.html b/app/templates/apiDocs.html similarity index 100% rename from templates/apiDocs.html rename to app/templates/apiDocs.html diff --git a/templates/editEntries.html b/app/templates/editEntries.html similarity index 100% rename from templates/editEntries.html rename to app/templates/editEntries.html diff --git a/templates/home.html b/app/templates/home.html similarity index 97% rename from templates/home.html rename to app/templates/home.html index 9103a713c5d685684cd0e63a349dbe2ab10eafab..939677c5d71c702eec4b1367d1691a380c6bc8ce 100644 --- a/templates/home.html +++ b/app/templates/home.html @@ -1,119 +1,119 @@ -<!DOCTYPE html> -<html lang="en"> - <head> - <link href="/static/jquery-ui.css" rel="stylesheet"> - <link href="/static/style.css" rel="stylesheet"> - <link href="/static/font.css" rel="stylesheet"> - <link href="/static/darkmode.css" rel="stylesheet"> - <link href="/static/socialSignin/css/buttons-si.css" rel="stylesheet"> - <title>URL shorter</title> - <script src="/static/external/jquery/jquery.js"></script> - <script src="/static/jquery-ui.js"></script> - {% if cookieNotice %} - <script src="/static/cookie.js"></script> - {% endif %} - {% if recaptchaPublicKey %} - <script src="https://www.google.com/recaptcha/api.js" async defer></script> - <script> - function onSubmit(token) { - document.getElementById("form").submit(); - } - </script> - {% endif %} - </head> - - <body> - {% if loginEnabled %} - <div id="loginbar">{{loginbar | safe}}</div> - {% endif %} - <div class="login-page"> - <div class="form"> - {% if not short_url %} - <form method="post" id= "form" class="login-form" action=""> - <input id="url" name="url" type="url" placeholder="long url" value="{{long_url_prefilled}}"/> - {% if showDomainSelect %} - Domain: <select name="domain" id="domain"> - {{domain | safe}} - </select> - <br><p> </p> - {% else %} - <input type="hidden" name="domain" id="domain" value={{domain}}> - {% endif %} - <input id="short" name="short" type="text" placeholder="short name" value="{{short_url_prefilled}}"/> - {% if passwordProtected %} - <input id="password" name="password" type="password" placeholder="Password"/> - {% endif %} - - {% if recaptchaPublicKey %} - <button class="g-recaptcha" data-sitekey="{{recaptchaPublicKey}}" data-callback='onSubmit'>short</button> - {% else %} - <button>short</button> - {% endif %} - </form> - {% else %} - <h3>Your shortened URL is: <a href="http://{{short_url}}"> {{short_url}}</a></h3> - <img src="data:image/jpeg;base64,{{qrcode}}"> - <p><a href="/">create another link</a></p> - {% endif %} - <p class="message">© Made by <a href="https://jonasled.de">jonasled</a><br> - Sourcecode is available <a href="https://gitlab.jonasled.de/jonasled/url_shorter_docker">here</a><br> - {% if builddate %} - Builddate: {{builddate}}<br> - {% endif %} - {% if version %} - Version: {{version}} - {% endif %} - </p> - </div> - </div> - <div id="snackbar">{{snackbar}}</div> - <!-- ui-dialog --> - <div id="dialog" title="login"> - <div class="box box-a"> - <ul id="noDot"> - </ul> - </div> - </div> - {% if cookieNotice %} - <div class="cookieinfo"> - <div class="cookieinfo-close" onclick="acceptCookie()"> - ✖ - </div> - <span class="cookieinfo-text"> - We use cookies to enhance your experience. By continuing to visit this site you agree to our use of cookies. <a class="cookieinfo-link" href="http://wikipedia.org/wiki/HTTP_cookie">More info</a> - </span> - </div> - <script> - checkHide(); - </script> - {% endif %} - - - - {% if snackbar %} - <script> - document.getElementById("snackbar").className = "show"; - setTimeout(function(){ document.getElementById("snackbar").className = x.className.replace("show", ""); }, 10000); - </script> - {% endif %} - - {% if domain_prefilled %} - <script> - var x = document.getElementById("domain"); - x.selectedIndex = {{domain_prefilled}}; - </script> - {% endif %} - <script> - $( "#dialog" ).dialog({ - autoOpen: false, - width: 400 - }); - - function showLogin(){ - $( "#dialog" ).dialog( "open" ); - } - - document.getElementById("noDot").innerHTML = '<li><a class="btn-si btn-si-a btn-github" style="color: white;" href="/user/login?service=github">Sign in with GitHub </a></li>\n<li><a class="btn-si btn-si-a btn-google" style="color: white;"href="/user/login?service=google">Sign in with Google</a></li>' - </script> - </body> +<!DOCTYPE html> +<html lang="en"> + <head> + <link href="/static/jquery-ui.css" rel="stylesheet"> + <link href="/static/style.css" rel="stylesheet"> + <link href="/static/font.css" rel="stylesheet"> + <link href="/static/darkmode.css" rel="stylesheet"> + <link href="/static/socialSignin/css/buttons-si.css" rel="stylesheet"> + <title>URL shorter</title> + <script src="/static/external/jquery/jquery.js"></script> + <script src="/static/jquery-ui.js"></script> + {% if cookieNotice %} + <script src="/static/cookie.js"></script> + {% endif %} + {% if recaptchaPublicKey %} + <script src="https://www.google.com/recaptcha/api.js" async defer></script> + <script> + function onSubmit(token) { + document.getElementById("form").submit(); + } + </script> + {% endif %} + </head> + + <body> + {% if loginEnabled %} + <div id="loginbar">{{loginbar | safe}}</div> + {% endif %} + <div class="login-page"> + <div class="form"> + {% if not short_url %} + <form method="post" id= "form" class="login-form" action=""> + <input id="url" name="url" type="url" placeholder="long url" value="{{long_url_prefilled}}"/> + {% if showDomainSelect %} + Domain: <select name="domain" id="domain"> + {{domain | safe}} + </select> + <br><p> </p> + {% else %} + <input type="hidden" name="domain" id="domain" value={{domain}}> + {% endif %} + <input id="short" name="short" type="text" placeholder="short name" value="{{short_url_prefilled}}"/> + {% if passwordProtected %} + <input id="password" name="password" type="password" placeholder="Password"/> + {% endif %} + + {% if recaptchaPublicKey %} + <button class="g-recaptcha" data-sitekey="{{recaptchaPublicKey}}" data-callback='onSubmit'>short</button> + {% else %} + <button>short</button> + {% endif %} + </form> + {% else %} + <h3>Your shortened URL is: <a href="http://{{short_url}}"> {{short_url}}</a></h3> + <img src="data:image/jpeg;base64,{{qrcode}}"> + <p><a href="/">create another link</a></p> + {% endif %} + <p class="message">© Made by <a href="https://jonasled.de">jonasled</a><br> + Sourcecode is available <a href="https://gitlab.jonasled.de/jonasled/url_shorter_docker">here</a><br> + {% if builddate %} + Builddate: {{builddate}}<br> + {% endif %} + {% if version %} + Version: {{version}} + {% endif %} + </p> + </div> + </div> + <div id="snackbar">{{snackbar}}</div> + <!-- ui-dialog --> + <div id="dialog" title="login"> + <div class="box box-a"> + <ul id="noDot"> + </ul> + </div> + </div> + {% if cookieNotice %} + <div class="cookieinfo"> + <div class="cookieinfo-close" onclick="acceptCookie()"> + ✖ + </div> + <span class="cookieinfo-text"> + We use cookies to enhance your experience. By continuing to visit this site you agree to our use of cookies. <a class="cookieinfo-link" href="http://wikipedia.org/wiki/HTTP_cookie">More info</a> + </span> + </div> + <script> + checkHide(); + </script> + {% endif %} + + + + {% if snackbar %} + <script> + document.getElementById("snackbar").className = "show"; + setTimeout(function(){ document.getElementById("snackbar").className = x.className.replace("show", ""); }, 10000); + </script> + {% endif %} + + {% if domain_prefilled %} + <script> + var x = document.getElementById("domain"); + x.selectedIndex = {{domain_prefilled}}; + </script> + {% endif %} + <script> + $( "#dialog" ).dialog({ + autoOpen: false, + width: 400 + }); + + function showLogin(){ + $( "#dialog" ).dialog( "open" ); + } + + document.getElementById("noDot").innerHTML = '<li><a class="btn-si btn-si-a btn-github" style="color: white;" href="/user/login?service=github">Sign in with GitHub </a></li>\n<li><a class="btn-si btn-si-a btn-google" style="color: white;"href="/user/login?service=google">Sign in with Google</a></li>' + </script> + </body> </html> \ No newline at end of file diff --git a/templates/login.html b/app/templates/login.html similarity index 100% rename from templates/login.html rename to app/templates/login.html diff --git a/userprofile.py b/app/userprofile.py similarity index 100% rename from userprofile.py rename to app/userprofile.py