瀏覽代碼

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. 二進制
      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 查看文件

# Default ignored files # Default ignored files
/workspace.xml /workspace.xml
# Datasource local storage ignored files # Datasource local storage ignored files
/dataSources.local.xml
/dataSources.local.xml
/dataSources/

+ 14
- 0
.idea/dataSources.xml 查看文件

<jdbc-driver>com.mysql.cj.jdbc.Driver</jdbc-driver> <jdbc-driver>com.mysql.cj.jdbc.Driver</jdbc-driver>
<jdbc-url>jdbc:mysql://localhost:3306</jdbc-url> <jdbc-url>jdbc:mysql://localhost:3306</jdbc-url>
</data-source> </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> </component>
</project> </project>

+ 25
- 21
calender/calender.py 查看文件

bp = Blueprint('calender', __name__) bp = Blueprint('calender', __name__)
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'} ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'}


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


@bp.route('/') @bp.route('/')
def index(): def index():
db = get_db() db = get_db()
posts = db.execute( 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' ' FROM post p JOIN user u ON p.author_id = u.id'
' ORDER BY created DESC' ' ORDER BY created DESC'
).fetchall() ).fetchall()
# noinspection PyUnresolvedReferences
return render_template('calender/index.html', posts=posts) return render_template('calender/index.html', posts=posts)




def create(): def create():
if request.method == 'POST': if request.method == 'POST':
title = request.form['title'] title = request.form['title']
nickname = request.form['nickname']
body = request.form['body'] 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 error = None


if not title: if not title:
if error is not None: if error is not None:
flash(error) flash(error)
else: 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): if file and allowed_file(file.filename):
filename = secure_filename(file.filename) filename = secure_filename(file.filename)
file.save(os.path.join(current_app.config['UPLOAD_FOLDER'], 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 redirect(url_for('calender.index'))


return render_template('calender/create.html') return render_template('calender/create.html')


def get_post(id, check_author=True): def get_post(id, check_author=True):
post = get_db().execute( 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' ' FROM post p JOIN user u ON p.author_id = u.id'
' WHERE p.id = ?', ' WHERE p.id = ?',
(id,) (id,)

+ 2
- 0
calender/db.py 查看文件

if db is not None: if db is not None:
db.close() db.close()



def init_db(): def init_db():
db = get_db() db = get_db()


init_db() init_db()
click.echo('Initialized the database.') click.echo('Initialized the database.')



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

二進制
calender/media/memes/bbaum.png 查看文件

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

+ 3
- 1
calender/schema.sql 查看文件

author_id INTEGER NOT NULL, author_id INTEGER NOT NULL,
created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
title TEXT NOT NULL, title TEXT NOT NULL,
nickname TEXT NOT NULL,
body TEXT NOT NULL, body TEXT NOT NULL,
file TEXT NOT NULL,
FOREIGN KEY (author_id) REFERENCES user (id) FOREIGN KEY (author_id) REFERENCES user (id)
);
);

+ 155
- 118
calender/static/calender/style.css 查看文件


body, h1, h2, h3, h4, h5 { body, h1, h2, h3, h4, h5 {
font-family: "Raleway", sans-serif; font-family: "Raleway", sans-serif;
color: black; 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 { .w3-content {
max-width: 800px;
max-width: 800px;
} }
footer{
padding-left: 2px;
position: fixed;
left: 0;
bottom: 0;

video {
width: 100%; 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 { .container {
max-width: 500px; max-width: 500px;
margin: 0 auto; margin: 0 auto;
}
.bgimg-1{
}

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

.button_flash { .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 { .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 { .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 { .rotated-image {
animation: spin_img 1s infinite linear
animation: spin_img 1s infinite linear
} }

.dropbtn { .dropbtn {
padding: 16px; padding: 16px;
font-size: 16px; font-size: 16px;
background-color: #f9f9f9; background-color: #f9f9f9;
min-width: 160px; min-width: 160px;
overflow: auto; 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; z-index: 1;
} }


display: block; display: block;
} }


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


.show {
display: block;
}


@-webkit-keyframes glowing_red { @-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 { @-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 { @-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 { @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 { @-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 { @-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 { @-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 { @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 { @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 查看文件

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 查看文件

</section> </section>
{% block content %} {% block content %}
{% endblock %} {% 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 查看文件

<form method=post enctype=multipart/form-data> <form method=post enctype=multipart/form-data>
<label for="title">Title</label> <label for="title">Title</label>
<input name="title" id="title" value="{{ request.form['title'] }}" required> <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> <label for="body">Body</label>
<textarea name="body" id="body">{{ request.form['body'] }}</textarea> <textarea name="body" id="body">{{ request.form['body'] }}</textarea>
<label for="file">Body</label>
<div> <div>
<p>Choose a mp4, webm, gif , png or jpg file.(max 25MB)</p> <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> </div>
<input type="submit" value=Upload> <input type="submit" value=Upload>
</form> </form>

+ 26
- 19
calender/templates/calender/index.html 查看文件

{% extends 'base.html' %} {% extends 'base.html' %}


{% block header %}



{% block header %}
<div class="container w3-center"> <div class="container w3-center">
<h1>{% block title %}Welcome to the Dankventskalender 2020!{% endblock %}</h1> <h1>{% block title %}Welcome to the Dankventskalender 2020!{% endblock %}</h1>
<div> <div>
{% endif %} {% endif %}
</div> </div>
</div> </div>

{% endblock %} {% endblock %}


{% block content %} {% 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 %} {% 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 查看文件

include_package_data=True, include_package_data=True,
zip_safe=False, zip_safe=False,
install_requires=[ install_requires=[
'flask',
'flask', 'click'
], ],
) )

Loading…
取消
儲存