first commit

watermarks_url_path
Pedro Sá Couto 4 years ago
commit 2d5aaaee8e

3
.gitignore vendored

@ -0,0 +1,3 @@
env/
venv/
venv/*

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -0,0 +1,99 @@
[2020-05-24 00:36:48 +0100] [24579] [DEBUG] Current configuration:
config: None
bind: ['unix:app.sock']
backlog: 2048
workers: 4
worker_class: sync
threads: 1
worker_connections: 1000
max_requests: 0
max_requests_jitter: 0
timeout: 30
graceful_timeout: 30
keepalive: 2
limit_request_line: 4094
limit_request_fields: 100
limit_request_field_size: 8190
reload: False
reload_engine: auto
reload_extra_files: []
spew: False
check_config: False
preload_app: False
sendfile: None
reuse_port: False
chdir: /var/www/TacticalApp
daemon: False
raw_env: []
pidfile: None
worker_tmp_dir: None
user: 1001
group: 33
umask: 7
initgroups: False
tmp_upload_dir: None
secure_scheme_headers: {'X-FORWARDED-PROTOCOL': 'ssl', 'X-FORWARDED-PROTO': 'https', 'X-FORWARDED-SSL': 'on'}
forwarded_allow_ips: ['127.0.0.1']
accesslog: None
disable_redirect_access_to_syslog: False
access_log_format: %(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"
errorlog: /var/www/TacticalApp/app.log
loglevel: debug
capture_output: False
logger_class: gunicorn.glogging.Logger
logconfig: None
logconfig_dict: {}
syslog_addr: udp://localhost:514
syslog: False
syslog_prefix: None
syslog_facility: user
enable_stdio_inheritance: False
statsd_host: None
dogstatsd_tags:
statsd_prefix:
proc_name: None
default_proc_name: app:app
pythonpath: None
paste: None
on_starting: <function OnStarting.on_starting at 0xb5dff420>
on_reload: <function OnReload.on_reload at 0xb5dff4b0>
when_ready: <function WhenReady.when_ready at 0xb5dff540>
pre_fork: <function Prefork.pre_fork at 0xb5dff618>
post_fork: <function Postfork.post_fork at 0xb5dff6a8>
post_worker_init: <function PostWorkerInit.post_worker_init at 0xb5dff780>
worker_int: <function WorkerInt.worker_int at 0xb5dff810>
worker_abort: <function WorkerAbort.worker_abort at 0xb5dff8a0>
pre_exec: <function PreExec.pre_exec at 0xb5dff930>
pre_request: <function PreRequest.pre_request at 0xb5dff9c0>
post_request: <function PostRequest.post_request at 0xb5dffa08>
child_exit: <function ChildExit.child_exit at 0xb5dffae0>
worker_exit: <function WorkerExit.worker_exit at 0xb5dffb70>
nworkers_changed: <function NumWorkersChanged.nworkers_changed at 0xb5dffc00>
on_exit: <function OnExit.on_exit at 0xb5dffc90>
proxy_protocol: False
proxy_allow_ips: ['127.0.0.1']
keyfile: None
certfile: None
ssl_version: 2
cert_reqs: 0
ca_certs: None
suppress_ragged_eofs: True
do_handshake_on_connect: False
ciphers: None
raw_paste_global_conf: []
strip_header_spaces: False
[2020-05-24 00:36:48 +0100] [24579] [INFO] Starting gunicorn 20.0.4
[2020-05-24 00:36:48 +0100] [24579] [DEBUG] Arbiter booted
[2020-05-24 00:36:48 +0100] [24579] [INFO] Listening at: unix:app.sock (24579)
[2020-05-24 00:36:48 +0100] [24579] [INFO] Using worker: sync
[2020-05-24 00:36:48 +0100] [24581] [INFO] Booting worker with pid: 24581
[2020-05-24 00:36:48 +0100] [24582] [INFO] Booting worker with pid: 24582
[2020-05-24 00:36:48 +0100] [24583] [INFO] Booting worker with pid: 24583
[2020-05-24 00:36:48 +0100] [24584] [INFO] Booting worker with pid: 24584
[2020-05-24 00:36:48 +0100] [24579] [DEBUG] 4 workers
[2020-05-24 01:33:11 +0100] [24579] [INFO] Handling signal: term
[2020-05-24 01:33:11 +0100] [24584] [INFO] Worker exiting (pid: 24584)
[2020-05-24 01:33:11 +0100] [24582] [INFO] Worker exiting (pid: 24582)
[2020-05-24 01:33:11 +0100] [24583] [INFO] Worker exiting (pid: 24583)
[2020-05-24 01:33:11 +0100] [24581] [INFO] Worker exiting (pid: 24581)
[2020-05-24 01:33:11 +0100] [24579] [INFO] Shutting down: Master

@ -0,0 +1,11 @@
from flask import Flask
app = Flask(__name__)
if app.config["ENV"] == "production":
app.config.from_object("config.ProductionConfig")
else:
app.config.from_object("config.DevelopmentConfig")
from app import views

Binary file not shown.

After

Width:  |  Height:  |  Size: 300 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 300 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 300 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 300 KiB

Binary file not shown.

Binary file not shown.

@ -0,0 +1,48 @@
/* http://meyerweb.com/eric/tools/css/reset/
v2.0 | 20110126
License: none (public domain)
*/
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}

@ -0,0 +1,358 @@
@font-face {
font-family: "Lyon";
src: url("LyonJeanTrue.ttf");
font-weight: 300;
font-style: normal;}
@font-face {
font-family: "Favorit";
src: url("Favorit_Regular.ttf");
font-weight: 300;
font-style: normal;}
@font-face {
font-family: "Favorit";
src: url("Favorit_Regular-Italic.ttf");
font-weight: 300;
font-style: italic;}
@font-face {
font-family: "Favorit";
src: url("Favorit_Medium.ttf");
font-weight: 400;
font-style: normal;}
@font-face {
font-family: "Favorit";
src: url("Favorit_Medium-Italic.ttf");
font-weight: 400;
font-style: italic;}
body {
background-color: #e6e7e8;
overflow-x: hidden;
width: 100vw;
}
.spaceleft{
margin-left: 15vw;
padding-top: 30px;
padding-left: 15px;
}
h3{
font-weight: 400;
margin-bottom: 20px;
text-transform: uppercase;
transform: scaleX(0.75);
transform-origin: 0 0;
font-size: calc(10px + 0.3vw);
}
h4{
font-weight: 400;
margin-bottom: 20px;
text-transform: uppercase;
transform: scaleX(0.75);
transform-origin: 0 0;
font-size: calc(10px + 0.3vw);
}
a{
color: #000;
text-decoration: none;
display: inline;
}
a:hover{
color: #cfff00;
text-decoration: none;
cursor: pointer;
}
a:visited{
text-decoration: none;
}
/* ASIDE */
aside{
position: fixed;
top: 0;
left: 0;
width: calc(15vw - 30px);
height: 100vh;
z-index: 2;
display: inline-block;
background-color: #cfff00;
font-family: "Favorit", Arial, Helvetica, sans-serif;
font-size: calc(10px + 0.3vw);
font-weight: 400;
font-style: normal;
line-height: 110%;
padding-left: 30px;
padding-top: 30px;
}
li{
transform: scaleX(0.75);
transform-origin: 0 0;
}
h2{
transform: scaleX(0.75);
transform-origin: 0 0;
font-weight: 400;
}
a.mapping:hover{
color: #FFF;
text-decoration: none;
cursor: pointer;
}
/* INDEX */
h1{
color: #FFF;
font-family: "Lyon", Arial, Helvetica, sans-serif;
font-size: calc(15px + 5vw);
text-align: center;
width: 100vw;
padding-bottom: 15px;
}
#indexabout{
padding-top: 20vh;
padding-bottom: 25px;
}
dl{
font-family: "Favorit", Arial, Helvetica, sans-serif;
font-size: calc(12px + 0.3vw);
text-align: center;
width: 100vw;
font-weight: 400;
font-style: italic;
transform: scaleX(0.75);
line-height: 110%;
}
.colorbackground{
margin-top: -5px;
position: absolute;
overflow: hidden;
width: 100vw;
height: 100vh;
z-index: 1;
}
#indexyellowleft{
position: fixed;
left: 0;
top: 0;
display: inline-block;
width: 38vw;
height: 100vh;
background-color: #cfff00;
}
#indexyellowright{
position: fixed;
left: 76vw;
top: 0;
display: inline-block;
height: 100vh;
width: 24vw;
background-color: #cfff00;
}
.indextext{
position: fixed;
z-index: 2;
}
/* HEADER */
header{
position: fixed;
top: 5px;
width: calc(100vw - 15px);
font-size: 12px;
font-family: "Lyon", Arial, Helvetica, sans-serif;
font-weight: 300;
font-style: normal;
z-index: 999;
}
.marquee {
position: relative;
width: calc(100vw - 15px);
max-width: 100%;
overflow-x: hidden;
height: 50px;
}
.track {
position: absolute;
white-space: nowrap;
will-change: transform;
animation: marquee 20s linear infinite;
}
@keyframes marquee {
from { transform: translateX(0); }
to { transform: translateX(-50%); }
}
a.head{
color: #FFF;
text-decoration: none;
display: inline;
}
a.head:hover{
text-decoration: none;
cursor: pointer;
}
a.head:visited{
text-decoration: none;
}
/* BOOKS REQUESTS */
.requestabook{
position: fixed;
top: 0;
left: 80vw;
width: calc(20vw - 30px);
height: 100vh;
z-index: 3;
display: inline-block;
background-color: #cfff00;
font-family: "Favorit", Arial, Helvetica, sans-serif;
font-size: calc(10px + 0.3vw);
font-weight: 300;
font-style: normal;
line-height: 110%;
padding-left: 30px;
padding-top: 30px;
}
.scrollrequests{
overflow: auto;
height: 100%;
}
.booksrequested{
padding-bottom: 15px;
padding-top: 15px;
padding-left: 5px;
}
.info{
transform: scaleX(0.75);
transform-origin: 0 0;
}
a.linktorequest{
text-decoration: none;
font-style: italic;
display: inline;
margin-bottom: 15px;
}
a.linktorequest:hover{
color: #FFF;
text-decoration: none;
cursor: pointer;
}
@keyframes blinker {
50% {
opacity: 0.5;
}
}
.compressed{
animation: blinker 1s linear infinite;
transform: scaleX(0.75);
transform-origin: 0 0;
padding-top: 10px;
padding-bottom: 15px;
}
/* UPLOAD A BOOK */
.watermarkspace{
padding-top: 30px;
}
.uploadspace{
padding-top: 30px;
}
.form-group{
padding-bottom: 15px;
}
.finalbutton{
margin-top: 10px;
}
button{
border-top: 2px solid white;
border-left: 2px solid white;
border-right: 2px solid black;
border-bottom: 2px solid black;
padding-bottom: 1px;
transform-origin: 0 0;
font-family: "Favorit", Arial, Helvetica, sans-serif;
text-transform: uppercase;
}
label {
line-height: 120%;
}
input{
margin-top: 5px;
}
form{
margin-left: 40px;
display: inline-block;
}
.explainspace{
width: 320px;
display: inline-block;
vertical-align:top;
font-style: italic;
}
.secondp{
text-indent: 30px;
}
/* TOR BROWSER */
img{
height: 300px;
}
.cover{
display: inline-block;
vertical-align: top;
}
figcaption{
font-weight: 400;
margin-bottom: 20px;
text-transform: uppercase;
transform: scaleX(0.75);
transform-origin: 0 0;
font-size: calc(7px + 0.3vw);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

File diff suppressed because one or more lines are too long

@ -0,0 +1,20 @@
{% extends "public/templates/main_template.html" %}
{% block title %}404{% endblock %}
{% block main %}
<div class="colorbackground">
<div id="indexyellowleft"></div>
<div id="indexyellowright"></div>
</div>
<div class="indextext">
<dl>
<dt id="indexabout">ov73e3lxezo2klxva2frlzqbb2usiozqbe56xiochvz5lznpkk6kw4ad.onion</dt>
</dl>
<h1>TACTICAL WATERMARKS<br>ON TOR BROWSER!</h1>
</div>
{% endblock %}

@ -0,0 +1,20 @@
{% extends "public/templates/main_template.html" %}
{% block title %}NOT AN ERROR{% endblock %}
{% block main %}
<div class="colorbackground">
<div id="indexyellowleft"></div>
<div id="indexyellowright"></div>
</div>
<div class="indextext">
<dl>
<dt id="indexabout">ov73e3lxezo2klxva2frlzqbb2usiozqbe56xiochvz5lznpkk6kw4ad.onion</dt>
</dl>
<h1>TACTICAL WATERMARKS<br>ON TOR BROWSER!</h1>
</div>
{% endblock %}

@ -0,0 +1,14 @@
{% extends "public/templates/public_template.html" %}
{% block title %}ABOUT TACTICAL WATERMARKS{% endblock %}
{% block main %}
<div class="spaceleft">
<h3>What is Tactical Watermarks</h3>
<h4>The Project</h4>
<h4>Each Step</h4>
<h4>The thesis</h4>
<h4>Why on Tor Browser?</h4>
</div>
{% endblock %}

@ -0,0 +1,24 @@
{% extends "public/templates/public_template.html" %}
{% block title %}Upload book{% endblock %}
{% block main %}
<div class="requestabook">
<h2>Books Requested</h2>
<p class="compressed"><a class="linktorequest" href="/request_form">Fill a form to request a book</a></p>
{% for book in books %}
<div class="booksrequested">
<h4>{{ book['title'] }}</h4>
<p class="info">{{ book['author'] }}</p>
<p class="info">{{ book['publisher'] }}</p>
<p class="info">{{ book['year'] }}</p>
<p class="info">{{ book['extention'] }}</p>
</div>
{% endfor %}
</div>
{% endblock %}

@ -0,0 +1,18 @@
{% extends "public/templates/public_template.html" %}
{% block title %}ABOUT TACTICAL WATERMARKS{% endblock %}
{% block main %}
<div class="spaceleft">
<h3>Republished Titles</h3>
{% for cover in covers %}
<div class="cover">
<img src="{{ url_for('static', filename='covers/' + cover) }}"></img>
<figcaption><a href="{{ url_for('static', filename='covers/' + cover) }}">{{ cover }}</a></figcaption>
</div>
{% endfor %}
</div>
{% endblock %}

@ -0,0 +1,26 @@
{% extends "public/templates/main_template.html" %}
{% block title %}TACTICAL WATERMARKS{% endblock %}
{% block main %}
<div class="colorbackground">
<div id="indexyellowleft"></div>
<div id="indexyellowright"></div>
</div>
<div class="indextext">
<dl>
<dt id="indexabout"><a href="/about">About Tactical Watermarks</a></dt>
</dl>
<h1>TACTICAL WATERMARKS</h1>
<dl>
<dt><a href="/uploadbook">De-watermark and republish a title</a></dt>
<dt><a href="/republish">Republish a new title</a></dt>
<dt><a href="/terms">Read Terms & Conditions</a></dt>
<dt><a href="ov73e3lxezo2klxva2frlzqbb2usiozqbe56xiochvz5lznpkk6kw4ad.onion">Link to Tor Browser</a></dt>
</dl>
</div>
{% endblock %}

@ -0,0 +1,100 @@
{% extends "public/templates/public_template.html" %}
{% block title %}Watermark Form{% endblock %}
{% block main %}
<div class="spaceleft">
<h3>REPUBLISH A TITLE</h3>
<div class="explainspace">
<p>Here you can upload a file that will be republished to Library Genesis. We take care of the whole process of republishing. Your book should not have watermarks. They will not be removed.</p>
<p class="secondp">We will also create a uploaders signature, read more about it <a href="/about">here</a>! Please feel free to leave your remarks on the process of sharing the file. If you want to batch upload, please <a href="mailto:pedrosacouto@protonmail.com">contact me</a> directly!</p>
</div>
<form action="/uploadbook" method="POST" enctype="multipart/form-data">
<h3>UPLOAD THE FILE</h3>
<form action="/uploadbook" method="POST" enctype="multipart/form-data">
<div class="form-group">
<div class="custom-file">
<input oninput="filesize(this);" type="file" name="book" id="book">
</div>
</div>
<div class="watermarkspace">
<h3>WATERMARK</h3>
<form action="/watermark" method="POST">
<div class="form-group">
<label>↘Identify yourself with a name, nickname or pseudonym!</label><br>
<input class="form" type="text" name="name">
</div>
<div class="form-group">
<label>↘Did you digitise the book?</label><br>
<input class="form" type="text" name="scan">
</div>
<div class="form-group">
<label>↘How long did it take you?</label><br>
<input class="form" type="text" name="time">
</div>
<div class="form-group">
<label>↘Where did you find the source?</label><br>
<input class="form" type="text" name="source">
</div>
<div class="form-group">
<label>↘Why are you sharing this file?<br>You can tell a personal anecdote,<br>You can leave a personal message here!</label><br>
<input class="form" type="text" name="anecdote">
</div>
</div>
<div class="uploadspace">
<input type="checkbox" name="match-with-pairs">Agree with the T&C</input><br>
<button type="submit" class="finalbutton"> Upload </button>
</div>
</form>
</div>
<div class="requestabook">
<h2>Books Requested</h2>
<p class="compressed"><a class="linktorequest" href="/request_form">Fill a form to request a book</a></p>
<div class="scrollrequests">
{% for book in books %}
<div class="booksrequested">
<h4>{{ book['title'] }}</h4>
<p class="info">{{ book['author'] }}</p>
<p class="info">{{ book['publisher'] }}</p>
<p class="info">{{ book['year'] }}</p>
<p class="info">{{ book['extention'] }}</p>
</div>
{% endfor %}
</div>
</div>
{% endblock %}
{% block script %}
<script>
function filesize(elem){
document.cookie = `filesize=${elem.files[0].size}`;
}
</script>
{% endblock %}

@ -0,0 +1,31 @@
{% extends "public/templates/public_template.html" %}
{% block title %}Upload book{% endblock %}
{% block main %}
<div class="spaceleft">
<h3>Request a Book</h3>
<form action='/submit' method='post'>
<label for='title'>Title</label>
<input name='title' type='text'></input>
<label for='author'>Author</label>
<input name='author' type='text'></input>
<label for='publisher'>Publisher</label>
<input name='publisher' type='text'></input>
<label for='year'>Year</label>
<input name='year' type='text'></input>
<label for='extention'>Extention</label>
<input name='extention' type='text'></input>
<input type='submit'></input>
</form>
</div>
{% endblock %}

@ -0,0 +1,31 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="icon" href="{{ url_for('static', filename='img/beau.png') }}">
<meta name="date" content="JULY 2020">
<link rel="stylesheet" href="{{ url_for('static', filename='css/reset.css') }}">
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
<script src="{{ url_for('static', filename='js/app.js') }}"></script>
<title>{% block title %}{% endblock %}</title>
</head>
<body>
<header>
<div class="leftmarquee">
<div class="marquee">
<div class="track">
<div class="content"><a class="head" href="/">TACTICAL WATERMARKS TACTICAL WATERMARKS TACTICAL WATERMARKS TACTICAL WATERMARKS TACTICAL WATERMARKS TACTICAL WATERMARKS TACTICAL WATERMARKS TACTICAL WATERMARKS TACTICAL WATERMARKS TACTICAL WATERMARKS TACTICAL WATERMARKS TACTICAL WATERMARKS TACTICAL WATERMARKS TACTICAL WATERMARKS TACTICAL WATERMARKS TACTICAL WATERMARKS TACTICAL WATERMARKS TACTICAL WATERMARKS TACTICAL WATERMARKS TACTICAL WATERMARKS</a></div>
</div>
</div>
</div>
</header>
<main>{% block main %}{% endblock %}</main>
{% block script %}{% endblock %}
</body>
</html>

@ -0,0 +1,45 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="date" content="JULY 2020">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="{{ url_for('static', filename='css/reset.css') }}">
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
<script src="{{ url_for('static', filename='js/app.js') }}"></script>
<link rel="icon" href="{{ url_for('static', filename='img/beau.png') }}">
<title>{% block title %}{% endblock %}</title>
</head>
<body>
<header>
<div class="leftmarquee">
<div class="marquee">
<div class="track">
<div class="content"><a class="head" href="/">TACTICAL WATERMARKS TACTICAL WATERMARKS TACTICAL WATERMARKS TACTICAL WATERMARKS TACTICAL WATERMARKS TACTICAL WATERMARKS TACTICAL WATERMARKS TACTICAL WATERMARKS TACTICAL WATERMARKS TACTICAL WATERMARKS TACTICAL WATERMARKS TACTICAL WATERMARKS TACTICAL WATERMARKS TACTICAL WATERMARKS TACTICAL WATERMARKS TACTICAL WATERMARKS TACTICAL WATERMARKS TACTICAL WATERMARKS TACTICAL WATERMARKS TACTICAL WATERMARKS</a></div>
</div>
</div>
</div>
</header>
<aside>
<h2>Sitemap</h2>
<br>
<ul>
<li><a class="mapping" href="/about">↘About Tactical Watermarks</a></li>
<li><a class="mapping" href="/uploadbook">↘De-watermark and republish</a></li>
<li><a class="mapping" href="/republish">↘Republish</a></li>
<li><a class="mapping" href="/terms">↘Read Terms & Conditions</a></li>
<li><a class="mapping" href="/404">↘Link to Tor Browser</a></li>
</ul>
</aside>
<main>{% block main %}{% endblock %}</main>
{% block script %}{% endblock %}
</body>
</html>

@ -0,0 +1,32 @@
{% extends "public/templates/public_template.html" %}
{% block title %}TERMS AND CONDITIONS{% endblock %}
{% block main %}
<div class="spaceleft">
<h3>TERMS AND CONDITIONS</h3>
<div>
<h4>The Project</h4>
<p>Here you will read the TOS</p>
</div>
<div class="requestabook">
<h2>LEAVE A COMMENT</h2>
<div class="scrollrequests">
<p class="compressed"><a class="linktorequest" href="/write_comment">Leave a comment</a>
<div class="scrollrequests">
{% for comment in comments %}
<div class="booksrequested">
<h4>{{ comment['name'] }}</h4>
<p class="info">{{ comment['commenting'] }}</p>
</div>
{% endfor %}
</div>
</div>
</div>
{% endblock %}

@ -0,0 +1,99 @@
{% extends "public/templates/public_template.html" %}
{% block title %}Upload book{% endblock %}
{% block main %}
<div class="spaceleft">
<h3>DE-WATERMARK A NEW TITLE</h3>
<div class="explainspace">
<p>Here you can upload a watermarked file that will be republished to Library Genesis. I will de-watermark your text and take care of the whole process of republishing. All watermarks will be removed.</p>
<p class="secondp">We will also create a uploaders signature, read more about it <a href="/about">here</a>! Please feel free to leave your remarks on the process of sharing the file. If you want to batch upload, please <a href="mailto:pedrosacouto@protonmail.com">contact me</a> directly!</p>
</div>
<form action="/uploadbook" method="POST" enctype="multipart/form-data">
<h3>UPLOAD THE FILE</h3>
<div class="form-group">
<div class="custom-file">
<input oninput="filesize(this);" type="file" name="book" id="book">
</div>
</div>
<div class="watermarkspace">
<h3>WATERMARK</h3>
<form action="/watermark" method="POST">
<div class="form-group">
<label>↘Identify yourself with a name, nickname or pseudonym!</label><br>
<input class="form" type="text" name="name">
</div>
<div class="form-group">
<label>↘Did you digitise the book?</label><br>
<input class="form" type="text" name="scan">
</div>
<div class="form-group">
<label>↘How long did it take you?</label><br>
<input class="form" type="text" name="time">
</div>
<div class="form-group">
<label>↘Where did you find the source?</label><br>
<input class="form" type="text" name="source">
</div>
<div class="form-group">
<label>↘Why are you sharing this file?<br>You can tell a personal anecdote,<br>You can leave a personal message here!</label><br>
<input class="form" type="text" name="anecdote">
</div>
</div>
<div class="uploadspace">
<input type="checkbox" name="match-with-pairs">Agree with the T&C</input><br>
<button type="submit" class="finalbutton"> Upload </button>
</div>
</form>
</div>
<div class="requestabook">
<h2>Books Requested</h2>
<p class="compressed"><a class="linktorequest" href="/request_form">Fill a form to request a book</a></p>
<div class="scrollrequests">
{% for book in books %}
<div class="booksrequested">
<h4>{{ book['title'] }}</h4>
<p class="info">{{ book['author'] }}</p>
<p class="info">{{ book['publisher'] }}</p>
<p class="info">{{ book['year'] }}</p>
<p class="info">{{ book['extention'] }}</p>
</div>
{% endfor %}
</div>
</div>
{% endblock %}
{% block script %}
<script>
function filesize(elem){
document.cookie = `filesize=${elem.files[0].size}`;
}
</script>
{% endblock %}

@ -0,0 +1,23 @@
{% extends "public/templates/public_template.html" %}
{% block title %}LEAVE A COMMENT{% endblock %}
{% block main %}
<div class="spaceleft">
<h3>LEAVE A COMMENT</h3>
<form action='/submitcomment' method='post'>
<label for='name'>Name</label>
<input name='name' type='text'></input>
<label for='commenting'>Comment</label>
<input name='commenting' type='text'></input>
<input type='submit'></input>
</form>
</div>
{% endblock %}

@ -0,0 +1,255 @@
from app import app
import flask
from flask import Blueprint, render_template, request, redirect, url_for, flash
import datetime
import os
from werkzeug.utils import secure_filename
from werkzeug.datastructures import ImmutableOrderedMultiDict
import collections
from collections import OrderedDict
import dataset
import sys
import time
app.secret_key = 'PiracyIsCool'
now = datetime.datetime.now()
@app.route('/', methods=['GET'])
def index():
return render_template("public/index.html")
@app.route("/about")
def about():
return render_template("public/about.html")
# UPLOAD FILES
# THIS SHOULD BE IN CONFIG
app.config["BOOK_UPLOAD_DEWATERMARK"] = "/var/www/TacticalApp/app/static/dewatermark"
app.config["BOOK_UPLOAD_REPUBLISH"] = "/var/www/TacticalApp/app/static/republish"
app.config["BOOK_REQUEST"] = "/var/www/TacticalApp/app/static/request"
app.config["ALLOWED_BOOK_EXTENSIONS"] = ["PDF", "EPUB"]
app.config["MAX_BOOK_FILESIZE"] = 500000000
def allowed_book(filename):
if not "." in filename:
return False
ext = filename.rsplit(".", 1)[1]
if ext.upper() in app.config["ALLOWED_BOOK_EXTENSIONS"]:
return True
else:
return False
def allowed_book_filesize(filesize):
if int(filesize) <= app.config["MAX_BOOK_FILESIZE"]:
return True
else:
return False
#Request a book
#REQUEST IN DEWATERMARK
# Link database
db = dataset.connect('sqlite:///file.db?check_same_thread=False')
# create table
table = db['requested']
@app.route('/request_form', methods=['GET'])
def request_form():
return render_template('public/request_form.html')
# from GET /bookrequest render request.html
@app.route('/uploadbook', methods=['GET'])
def bookrequest():
books = table.find(order_by='-id')
return render_template('public/upload_book.html', books=books)
# from POST /submit store data in the database and forward to the request
@app.route('/submit', methods=['POST'])
def submit():
book = dict(title=request.form['title'], author=request.form['author'], publisher=request.form['publisher'], year=request.form['year'], extention=request.form['extention'])
table.insert(book)
return redirect(url_for('index'))
#Request a book
#REQUEST IN REPUBLISH
# from GET /bookrequest render request.html
@app.route('/republish', methods=['GET'])
def bookrepublish():
books = table.find(order_by='-id')
return render_template('public/republish.html', books=books)
#Terms & Comment
# create table for comments
table_comment = db['commented']
@app.route('/write_comment', methods=['GET'])
def write_comment():
return render_template('public/write_comment.html')
# from GET /write_comment render terms.html
@app.route('/terms', methods=['GET'])
def terms():
comments = table_comment.find(order_by='-id')
return render_template('public/terms.html', comments=comments)
# from POST /submit store data in the database and forward to the terms
@app.route('/submitcomment', methods=['POST'])
def submitcomment():
comment = dict(name=request.form['name'], commenting=request.form['commenting'])
table_comment.insert(comment)
return redirect(url_for('terms'))
#Route to Upload, Dewatermark, and republish
@app.route("/uploadbook", methods=["GET", "POST"])
def uploadbook():
if request.method == "POST":
if request.files:
#request filesize
if not allowed_book_filesize(request.cookies.get("filesize")):
print("File exceeded maximum size")
return redirect(request.url)
#demand checkbox
if not request.form.get('match-with-pairs'):
print("You should agree with the T&C")
return redirect(request.url)
book = request.files["book"]
# confirm book has a name
if book.filename == "":
print("Book must have a filename")
return redirect(request.url)
# confirm book is the desired format
if not allowed_book(book.filename):
print("That book extention is not allowed")
return redirect(request.url)
#create a new secure filename
else:
filename = secure_filename(book.filename)
basename, ext = os.path.splitext(filename)
folder = os.path.join(app.config["BOOK_UPLOAD_DEWATERMARK"], basename)
try:
os.makedirs(folder)
except FileExistsError:
pass
bookpath = os.path.join(folder, filename)
x=2
while os.path.exists(bookpath):
bookpath = os.path.join(folder, basename + "_" + str(x) + ext)
x+=1
if request.method == "POST":
req = request.form
name = req["name"]
scan = req["scan"]
time = req["time"]
source = req["source"]
anecdote = req["anecdote"]
fieldnames = [name, scan, time, source, anecdote]
print(fieldnames)
with open((os.path.join(folder, basename) + ".txt"), 'w') as f:
f.write(str(fieldnames))
book.save(bookpath)
print("Book saved")
# flash("Book saved")
return redirect(request.url)
return render_template("public/upload_book.html")
#Route to Upload and republish
@app.route("/republish", methods=["GET", "POST"])
def republish():
if request.method == "POST":
if request.files:
#request filesize
if not allowed_book_filesize(request.cookies.get("filesize")):
print("File exceeded maximum size")
return redirect(request.url)
#demand checkbox
if not request.form.get('match-with-pairs'):
print("You should agree with the T&C")
return redirect(request.url)
file = request.files["book"]
# confirm file has a name
if file.filename == "":
print("Book must have a filename")
return redirect(request.url)
# confirm book is the desired format
if not allowed_book(file.filename):
print("That book extention is not allowed")
return redirect(request.url)
#create a new secure filename
else:
filename = secure_filename(file.filename)
basename, ext = os.path.splitext(filename)
folder = os.path.join(app.config["BOOK_UPLOAD_REPUBLISH"], basename)
try:
os.makedirs(folder)
except FileExistsError:
pass
filepath = os.path.join(folder, filename)
x=2
while os.path.exists(filepath):
filepath = os.path.join(folder, basename + "_" + str(x) + ext)
x+=1
if request.method == "POST":
req = request.form
name = req["name"]
scan = req["scan"]
time = req["time"]
source = req["source"]
anecdote = req["anecdote"]
fieldnames = [name, scan, time, source, anecdote]
print(fieldnames)
with open((os.path.join(folder, basename) + ".txt"), 'w') as f:
f.write(str(fieldnames))
file.save(filepath)
print("file saved")
# flash("file saved")
return redirect(request.url)
return render_template("public/republish.html")
@app.errorhandler(404)
def not_found(e):
return render_template("public/404.html")
@app.errorhandler(500)
def not_found(e):
return render_template("public/500.html")
# TOR BROWSER
@app.route("/covers")
def covers():
covers = os.listdir(os.path.join(app.static_folder, "covers"))
return render_template("public/covers.html", covers=covers)

@ -0,0 +1,16 @@
class Config(object):
# SERVER_NAME = 'hub.xpub.nl/watermark'
DEBUG = True
TESTING = False
SESSION_COOKIE_SECURE = True
class ProductionConfig(Config):
pass
class DevelopmentConfig(Config):
DEBUG = True
SESSION_COOKIE_SECURE = False
class TestingConfig(Config):
TESTING = True
SESSION_COOKIE_SECURE = False

Binary file not shown.

@ -0,0 +1 @@
gunicorn --bind 0.0.0.0:5000 wsgi

@ -0,0 +1,21 @@
alembic
click
console-log
dataset
Flask
Flask-SQLAlchemy
gevent
gevent-websocket
greenlet
gunicorn
itsdangerous
Jinja2
Mako
MarkupSafe
python-dateutil
python-editor
setuptools
six
SQLAlchemy
Werkzeug
wsgigzip

@ -0,0 +1,4 @@
from app import app
if __name__ == "__main__":
app.run(host='0.0.0.0')

@ -0,0 +1,4 @@
from app import app as application
if __name__ == "__main__":
application.run()
Loading…
Cancel
Save