Переглянути джерело

post now complete visible, files added to db

master
Johannnes Bürst 5 роки тому
джерело
коміт
de0da705fa
12 змінених файлів з 234 додано та 189 видалено
  1. +2
    -1
      .idea/.gitignore
  2. +14
    -0
      .idea/dataSources.xml
  3. +25
    -21
      calender/calender.py
  4. +2
    -0
      calender/db.py
  5. BIN
      calender/media/memes/bbaum.png
  6. +3
    -1
      calender/schema.sql
  7. +155
    -118
      calender/static/calender/style.css
  8. +0
    -26
      calender/static/style.css
  9. +2
    -1
      calender/templates/base.html
  10. +4
    -1
      calender/templates/calender/create.html
  11. +26
    -19
      calender/templates/calender/index.html
  12. +1
    -1
      setup.py

+ 2
- 1
.idea/.gitignore Переглянути файл

@@ -1,4 +1,5 @@
# Default ignored files
/workspace.xml
# Datasource local storage ignored files
/dataSources.local.xml
/dataSources.local.xml
/dataSources/

+ 14
- 0
.idea/dataSources.xml Переглянути файл

@@ -7,5 +7,19 @@
<jdbc-driver>com.mysql.cj.jdbc.Driver</jdbc-driver>
<jdbc-url>jdbc:mysql://localhost:3306</jdbc-url>
</data-source>
<data-source source="LOCAL" name="calender" uuid="17a463e8-6100-487f-bdd0-6ebd223d5bf6">
<driver-ref>sqlite.xerial</driver-ref>
<synchronize>true</synchronize>
<jdbc-driver>org.sqlite.JDBC</jdbc-driver>
<jdbc-url>jdbc:sqlite:C:\Users\jbuer\PycharmProjects\dankventskalender3.0\instance\calender.sqlite</jdbc-url>
<libraries>
<library>
<url>file://$APPLICATION_CONFIG_DIR$/jdbc-drivers/Xerial SQLiteJDBC/3.25.1/license.txt</url>
</library>
<library>
<url>file://$APPLICATION_CONFIG_DIR$/jdbc-drivers/Xerial SQLiteJDBC/3.25.1/sqlite-jdbc-3.25.1.jar</url>
</library>
</libraries>
</data-source>
</component>
</project>

+ 25
- 21
calender/calender.py Переглянути файл

@@ -11,15 +11,17 @@ from calender.db import get_db
bp = Blueprint('calender', __name__)
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'}

#Todo admin interface for managing submit, comments, submission date

@bp.route('/')
def index():
db = get_db()
posts = db.execute(
'SELECT p.id, title, body, created, author_id, username'
'SELECT p.id, title, body, created, author_id, username, nickname, file'
' FROM post p JOIN user u ON p.author_id = u.id'
' ORDER BY created DESC'
).fetchall()
# noinspection PyUnresolvedReferences
return render_template('calender/index.html', posts=posts)


@@ -28,7 +30,19 @@ def index():
def create():
if request.method == 'POST':
title = request.form['title']
nickname = request.form['nickname']
body = request.form['body']
# check if the post request has the file part
if 'file' not in request.files:
flash('No file part')
return redirect(request.url)
file = request.files['file']
# if user does not select file, browser also
# submit an empty part without filename
if file.filename == '':
flash('No selected file')
return redirect(request.url)

error = None

if not title:
@@ -37,28 +51,18 @@ def create():
if error is not None:
flash(error)
else:
db = get_db()
db.execute(
'INSERT INTO post (title, body, author_id)'
' VALUES (?, ?, ?)',
(title, body, g.user['id'])
)
db.commit()
# check if the post request has the file part
if 'file' not in request.files:
flash('No file part')
return redirect(request.url)
file = request.files['file']
# if user does not select file, browser also
# submit an empty part without filename
if file.filename == '':
flash('No selected file')
return redirect(request.url)
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join(current_app.config['UPLOAD_FOLDER'], filename))
return redirect(url_for('calender.uploaded_file',
filename=filename))
db = get_db()
db.execute(
'INSERT INTO post (title, body, author_id, nickname, file)'
' VALUES (?, ?, ?, ?, ?)',
(title, body, g.user['id'], nickname, url_for('calender.uploaded_file',
filename=filename))
)
db.commit()
# return redirect(url_for('calender.uploaded_file',filename=filename))
return redirect(url_for('calender.index'))

return render_template('calender/create.html')
@@ -66,7 +70,7 @@ def create():

def get_post(id, check_author=True):
post = get_db().execute(
'SELECT p.id, title, body, created, author_id, username'
'SELECT p.id, title, body, created, author_id, username, nickname, file'
' FROM post p JOIN user u ON p.author_id = u.id'
' WHERE p.id = ?',
(id,)

+ 2
- 0
calender/db.py Переглянути файл

@@ -22,6 +22,7 @@ def close_db(e=None):
if db is not None:
db.close()


def init_db():
db = get_db()

@@ -36,6 +37,7 @@ def init_db_command():
init_db()
click.echo('Initialized the database.')


def init_app(app):
app.teardown_appcontext(close_db)
app.cli.add_command(init_db_command)

BIN
calender/media/memes/bbaum.png Переглянути файл

Before After
Width: 1139  |  Height: 634  |  Size: 224KB

+ 3
- 1
calender/schema.sql Переглянути файл

@@ -12,6 +12,8 @@ CREATE TABLE post (
author_id INTEGER NOT NULL,
created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
title TEXT NOT NULL,
nickname TEXT NOT NULL,
body TEXT NOT NULL,
file TEXT NOT NULL,
FOREIGN KEY (author_id) REFERENCES user (id)
);
);

+ 155
- 118
calender/static/calender/style.css Переглянути файл

@@ -1,82 +1,80 @@

body, h1, h2, h3, h4, h5 {
font-family: "Raleway", sans-serif;
color: black;
margin-bottom: 20px;

}
.w3-content .w3-container-display img{
max-width: 100%;

.w3-content .w3-container-display img {
max-width: 100%;
}

.w3-content {
max-width: 800px;
max-width: 800px;
}
footer{
padding-left: 2px;
position: fixed;
left: 0;
bottom: 0;

video {
width: 100%;
max-width: 500px;
height: auto;
}
video {
width:100%;
max-width:500px;
height:auto;
}
iframe{
width:100%;
max-width:500px;

}
img {
width: 100%;

iframe {
width: 100%;
max-width: 500px;

}
textarea{
resize: none;

img {
width: 100%;
}

.container {
max-width: 500px;
margin: 0 auto;
}
.bgimg-1{
}

.bgimg-1 {
background-attachment: fixed;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
background-image: url("horsehead.jpg");
background-image: url("horsehead.jpg");
min-height: 100%;
}

.button_flash {
background-color: #004A7F;
-webkit-border-radius: 10px;
border-radius: 10px;
border: none;
color: #FFFFFF;
cursor: pointer;
display: inline-block;
font-family: Arial;
font-size: 20px;
padding: 5px 10px;
text-align: center;
text-decoration: none;
background-color: #004A7F;
-webkit-border-radius: 10px;
border-radius: 10px;
border: none;
color: #FFFFFF;
cursor: pointer;
display: inline-block;
font-family: Arial;
font-size: 20px;
padding: 5px 10px;
text-align: center;
text-decoration: none;
}

.button_flash {
-webkit-animation: glowing_red 1500ms infinite;
-moz-animation: glowing_red 1500ms infinite;
-o-animation: glowing_red 1500ms infinite;
animation: glowing_red 1500ms infinite;
-webkit-animation: glowing_red 1500ms infinite;
-moz-animation: glowing_red 1500ms infinite;
-o-animation: glowing_red 1500ms infinite;
animation: glowing_red 1500ms infinite;
}

.button_flash_animation {
-webkit-animation: glowing_green 2000ms infinite;
-moz-animation: glowing_green 2000ms infinite;
-o-animation: glowing_green 2000ms infinite;
animation: glowing_green 2000ms infinite;
-webkit-animation: glowing_green 2000ms infinite;
-moz-animation: glowing_green 2000ms infinite;
-o-animation: glowing_green 2000ms infinite;
animation: glowing_green 2000ms infinite;
}

.rotated-image {
animation: spin_img 1s infinite linear
animation: spin_img 1s infinite linear
}

.dropbtn {
padding: 16px;
font-size: 16px;
@@ -99,7 +97,7 @@ textarea{
background-color: #f9f9f9;
min-width: 160px;
overflow: auto;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
z-index: 1;
}

@@ -110,101 +108,140 @@ textarea{
display: block;
}

.dropdown a:hover {background-color: #f1f1f1}
.show {display:block;}
.dropdown a:hover {
background-color: #f1f1f1
}

.show {
display: block;
}

@-webkit-keyframes glowing_red {
0% { background-color: #B20000; -webkit-box-shadow: 0 0 3px #B20000; }
50% { background-color: #FF0000; -webkit-box-shadow: 0 0 40px #FF0000; }
100% { background-color: #B20000; -webkit-box-shadow: 0 0 3px #B20000; }
0% {
background-color: #B20000;
-webkit-box-shadow: 0 0 3px #B20000;
}
50% {
background-color: #FF0000;
-webkit-box-shadow: 0 0 40px #FF0000;
}
100% {
background-color: #B20000;
-webkit-box-shadow: 0 0 3px #B20000;
}
}

@-moz-keyframes glowing_red {
0% { background-color: #B20000; -moz-box-shadow: 0 0 3px #B20000; }
50% { background-color: #FF0000; -moz-box-shadow: 0 0 40px #FF0000; }
100% { background-color: #B20000; -moz-box-shadow: 0 0 3px #B20000; }
0% {
background-color: #B20000;
-moz-box-shadow: 0 0 3px #B20000;
}
50% {
background-color: #FF0000;
-moz-box-shadow: 0 0 40px #FF0000;
}
100% {
background-color: #B20000;
-moz-box-shadow: 0 0 3px #B20000;
}
}

@-o-keyframes glowing_red {
0% { background-color: #B20000; box-shadow: 0 0 3px #B20000; }
50% { background-color: #FF0000; box-shadow: 0 0 40px #FF0000; }
100% { background-color: #B20000; box-shadow: 0 0 3px #B20000; }
0% {
background-color: #B20000;
box-shadow: 0 0 3px #B20000;
}
50% {
background-color: #FF0000;
box-shadow: 0 0 40px #FF0000;
}
100% {
background-color: #B20000;
box-shadow: 0 0 3px #B20000;
}
}

@keyframes glowing_red {
0% { background-color: #B20000; box-shadow: 0 0 3px #B20000; }
50% { background-color: #FF0000; box-shadow: 0 0 40px #FF0000; }
100% { background-color: #B20000; box-shadow: 0 0 3px #B20000; }
0% {
background-color: #B20000;
box-shadow: 0 0 3px #B20000;
}
50% {
background-color: #FF0000;
box-shadow: 0 0 40px #FF0000;
}
100% {
background-color: #B20000;
box-shadow: 0 0 3px #B20000;
}
}

@-webkit-keyframes glowing_green {
0% { background-color: #3fff00; -webkit-box-shadow: 0 0 3px #3fff00; }
50% { background-color: #0ad100; -webkit-box-shadow: 0 0 40px #0ad100; }
100% { background-color: #3fff00; -webkit-box-shadow: 0 0 3px #3fff00; }
0% {
background-color: #3fff00;
-webkit-box-shadow: 0 0 3px #3fff00;
}
50% {
background-color: #0ad100;
-webkit-box-shadow: 0 0 40px #0ad100;
}
100% {
background-color: #3fff00;
-webkit-box-shadow: 0 0 3px #3fff00;
}
}

@-moz-keyframes glowing_green {
0% { background-color: #3fff00; -moz-box-shadow: 0 0 3px #3fff00; }
50% { background-color: #0ad100; -moz-box-shadow: 0 0 40px #0ad100; }
100% { background-color: #3fff00; -moz-box-shadow: 0 0 3px #3fff00; }
0% {
background-color: #3fff00;
-moz-box-shadow: 0 0 3px #3fff00;
}
50% {
background-color: #0ad100;
-moz-box-shadow: 0 0 40px #0ad100;
}
100% {
background-color: #3fff00;
-moz-box-shadow: 0 0 3px #3fff00;
}
}

@-o-keyframes glowing_green {
0% { background-color: #3fff00; box-shadow: 0 0 3px #3fff00; }
50% { background-color: #0ad100; box-shadow: 0 0 40px #0ad100; }
100% { background-color: #3fff00; box-shadow: 0 0 3px #3fff00; }
0% {
background-color: #3fff00;
box-shadow: 0 0 3px #3fff00;
}
50% {
background-color: #0ad100;
box-shadow: 0 0 40px #0ad100;
}
100% {
background-color: #3fff00;
box-shadow: 0 0 3px #3fff00;
}
}

@keyframes glowing_green {
0% { background-color: #3fff00; box-shadow: 0 0 3px #3fff00; }
50% { background-color: #0ad100; box-shadow: 0 0 40px #0ad100; }
100% { background-color: #3fff00; box-shadow: 0 0 3px #3fff00; }
0% {
background-color: #3fff00;
box-shadow: 0 0 3px #3fff00;
}
50% {
background-color: #0ad100;
box-shadow: 0 0 40px #0ad100;
}
100% {
background-color: #3fff00;
box-shadow: 0 0 3px #3fff00;
}
}




@keyframes spin_img {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(-360deg);
}
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(-360deg);
}
}

.button3 {
color: black;
}

.button3:hover {
background-color: #f44336;
color: white;
}

.button span {
cursor: pointer;
display: inline-block;
position: relative;
transition: 0.5s;
}

.button span:after {
content: '\00bb';
position: absolute;
opacity: 0;
top: 0;
right: -20px;
transition: 0.5s;
}

.button:hover span {
padding-right: 25px;
}

.button:hover span:after {
opacity: 1;
right: 0;
}

+ 0
- 26
calender/static/style.css Переглянути файл

@@ -1,26 +0,0 @@
html { font-family: sans-serif; background: #eee; padding: 1rem; }
body { max-width: 960px; margin: 0 auto; background: white; }
h1 { font-family: serif; color: #377ba8; margin: 1rem 0; }
a { color: #377ba8; }
hr { border: none; border-top: 1px solid lightgray; }
nav { background: lightgray; display: flex; align-items: center; padding: 0 0.5rem; }
nav h1 { flex: auto; margin: 0; }
nav h1 a { text-decoration: none; padding: 0.25rem 0.5rem; }
nav ul { display: flex; list-style: none; margin: 0; padding: 0; }
nav ul li a, nav ul li span, header .action { display: block; padding: 0.5rem; }
.content { padding: 0 1rem 1rem; }
.content > header { border-bottom: 1px solid lightgray; display: flex; align-items: flex-end; }
.content > header h1 { flex: auto; margin: 1rem 0 0.25rem 0; }
.flash { margin: 1em 0; padding: 1em; background: #cae6f6; border: 1px solid #377ba8; }
.post > header { display: flex; align-items: flex-end; font-size: 0.85em; }
.post > header > div:first-of-type { flex: auto; }
.post > header h1 { font-size: 1.5em; margin-bottom: 0; }
.post .about { color: slategray; font-style: italic; }
.post .body { white-space: pre-line; }
.content:last-child { margin-bottom: 0; }
.content form { margin: 1em 0; display: flex; flex-direction: column; }
.content label { font-weight: bold; margin-bottom: 0.5em; }
.content input, .content textarea { margin-bottom: 1em; }
.content textarea { min-height: 12em; resize: vertical; }
input.danger { color: #cc2f2e; }
input[type=submit] { align-self: start; min-width: 10em; }

+ 2
- 1
calender/templates/base.html Переглянути файл

@@ -59,4 +59,5 @@
</section>
{% block content %}
{% endblock %}
</body>
</body>
<footer class="w3-highway-red">Special thanks to <strong>Langspielplatte</strong> for hosting this webspace! <strong>&lt;3</strong> </footer>

+ 4
- 1
calender/templates/calender/create.html Переглянути файл

@@ -8,11 +8,14 @@
<form method=post enctype=multipart/form-data>
<label for="title">Title</label>
<input name="title" id="title" value="{{ request.form['title'] }}" required>
<label for="nickname">Nickname</label>
<input name="nickname" id="nickname" value="{{ request.form['nickname'] }}" required>
<label for="body">Body</label>
<textarea name="body" id="body">{{ request.form['body'] }}</textarea>
<label for="file">Body</label>
<div>
<p>Choose a mp4, webm, gif , png or jpg file.(max 25MB)</p>
<input type="file" placeholder="meme" name="file" required>
<input type="file" placeholder="meme" name="file" id="file" required>
</div>
<input type="submit" value=Upload>
</form>

+ 26
- 19
calender/templates/calender/index.html Переглянути файл

@@ -1,7 +1,8 @@
{% extends 'base.html' %}

{% block header %}


{% block header %}
<div class="container w3-center">
<h1>{% block title %}Welcome to the Dankventskalender 2020!{% endblock %}</h1>
<div>
@@ -14,25 +15,31 @@
{% endif %}
</div>
</div>

{% endblock %}

{% block content %}
{% for post in posts %}
<article class="post">
<header>
<div>
<h1>{{ post['title'] }}</h1>
<div class="about">by {{ post['username'] }} on {{ post['created'].strftime('%Y-%m-%d') }}</div>
</div>
{% if g.user['id'] == post['author_id'] %}
<a class="action" href="{{ url_for('calender.update', id=post['id']) }}">Edit</a>
<div class="container w3-center">
{% for post in posts %}
<div class="item">
<article class="post">
<header>
<div>
<h1>{{ post['title'] }}</h1>
<h2>{{ post['nickname'] }}</h2>
<div class="about">by {{ post['username'] }}
on {{ post['created'].strftime('%Y-%m-%d') }}</div>
</div>
{% if g.user['id'] == post['author_id'] %}
<a class="action" href="{{ url_for('calender.update', id=post['id']) }}">Edit</a>
{% endif %}
</header>
<img class="file" src="{{ post['file'] }}">
<p class="body">{{ post['body'] }}</p>
</article>
{% if not loop.last %}
<hr>
{% endif %}
</header>
<p class="body">{{ post['body'] }}</p>
</article>
{% if not loop.last %}
<hr>
{% endif %}
{% endfor %}
{% endblock %}
</div>
{% endfor %}
</div>
{% endblock %}

+ 1
- 1
setup.py Переглянути файл

@@ -7,6 +7,6 @@ setup(
include_package_data=True,
zip_safe=False,
install_requires=[
'flask',
'flask', 'click'
],
)

Завантаження…
Відмінити
Зберегти