| # 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/ |
| <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> |
| 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,) |
| 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) |
| 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) | ||||
| ); | |||||
| ); |
| 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; | |||||
| } |
| 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; } |
| </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><3</strong> </footer> |
| <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> |
| {% 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 %} |
| include_package_data=True, | include_package_data=True, | ||||
| zip_safe=False, | zip_safe=False, | ||||
| install_requires=[ | install_requires=[ | ||||
| 'flask', | |||||
| 'flask', 'click' | |||||
| ], | ], | ||||
| ) | ) |