mirror of
				https://github.com/tiyn/container-critique.git
				synced 2025-10-31 03:01:21 +01:00 
			
		
		
		
	first commit
This commit is contained in:
		
							
								
								
									
										1
									
								
								src/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								src/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| __pycache__/ | ||||
							
								
								
									
										90
									
								
								src/app.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								src/app.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,90 @@ | ||||
| from flask import Flask, flash, make_response, render_template, request, redirect, abort, url_for | ||||
| from flask_login import current_user, login_user, LoginManager | ||||
|  | ||||
| import content as con_gen | ||||
| import config | ||||
|  | ||||
| from flask_wtf import FlaskForm | ||||
| from wtforms import StringField, PasswordField, SubmitField, BooleanField | ||||
| from wtforms.validators import DataRequired | ||||
|  | ||||
| class LoginForm(FlaskForm): | ||||
|     username = StringField('Username', validators=[DataRequired()]) | ||||
|     password = PasswordField('Password', validators=[DataRequired()]) | ||||
|     remember_me = BooleanField('Remember Me') | ||||
|     submit = SubmitField('Sign In') | ||||
|  | ||||
|  | ||||
| app = Flask(__name__) | ||||
| login = LoginManager(app) | ||||
|  | ||||
| TITLE = config.TITLE | ||||
| STYLE = config.STYLE | ||||
| DESCRIPTION = config.DESCRIPTION | ||||
| WEBSITE = config.WEBSITE | ||||
|  | ||||
|  | ||||
| class Config(object): | ||||
|     SECRET_KEY = '123534' | ||||
|  | ||||
| app.config.from_object(Config) | ||||
|  | ||||
|  | ||||
| @app.errorhandler(404) | ||||
| def page_not_found(e): | ||||
|     return render_template('error.html', title=TITLE, errorcode='404', style=STYLE), 404 | ||||
|  | ||||
|  | ||||
| @app.route('/') | ||||
| @app.route('/index.html') | ||||
| def index(): | ||||
|     content = con_gen.gen_index_string() | ||||
|     return render_template('index.html', title=TITLE, content_string=content, style=STYLE) | ||||
|  | ||||
|  | ||||
| @app.route('/archive') | ||||
| @app.route('/archive.html') | ||||
| def blog_archive(): | ||||
|     content = con_gen.gen_arch_string() | ||||
|     return render_template('archive.html', title=TITLE, content_string=content, style=STYLE) | ||||
|  | ||||
|  | ||||
| @app.route('/entry/<path>') | ||||
| def entry(path): | ||||
|     content = con_gen.gen_stand_string(path) | ||||
|     if content != '': | ||||
|         return render_template('standalone.html', title=TITLE, content_string=content, style=STYLE) | ||||
|     abort(404) | ||||
|  | ||||
|  | ||||
| @app.route('/feed.xml') | ||||
| @app.route('/rss.xml') | ||||
| def feed(): | ||||
|     content = con_gen.get_rss_string() | ||||
|     rss_xml = render_template('rss.xml', content_string=content, title=TITLE, | ||||
|                               description=DESCRIPTION, website=WEBSITE) | ||||
|     response = make_response(rss_xml) | ||||
|     response.headers['Content-Type'] = 'application/rss+xml' | ||||
|     return response | ||||
|  | ||||
| @login.user_loader | ||||
| def load_user(id): | ||||
|     return "" | ||||
|  | ||||
| @app.route('/login', methods=['GET', 'POST']) | ||||
| def login(): | ||||
|     if current_user.is_authenticated: | ||||
|         return redirect(url_for('index')) | ||||
|     form = LoginForm() | ||||
|     if form.validate_on_submit(): | ||||
|         user = User.query.filter_by(username=form.username.data).first() | ||||
|         if user is None or not user.check_password(form.password.data): | ||||
|             flash('Invalid username or password') | ||||
|             return redirect(url_for('login')) | ||||
|         login_user(user, remember=form.remember_me.data) | ||||
|         return redirect(url_for('index')) | ||||
|     return render_template('login.html', title='Sign In', form=form) | ||||
|  | ||||
|  | ||||
| if __name__ == '__main__': | ||||
|     app.run(host='0.0.0.0') | ||||
							
								
								
									
										11
									
								
								src/config.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								src/config.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| # Name/title of your blog | ||||
| TITLE = 'Container Critique' | ||||
|  | ||||
| # Description for RSS of your blog | ||||
| DESCRIPTION = 'This is your personal Container Critique.' | ||||
|  | ||||
| # URL for your website: e.g. https://domain.tld | ||||
| WEBSITE = 'localhost:5000' | ||||
|  | ||||
| # Theme for the blog: dark, light | ||||
| STYLE = 'dark' | ||||
							
								
								
									
										45
									
								
								src/content.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								src/content.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,45 @@ | ||||
| ENTRY_DIR = 'templates/entry' | ||||
|  | ||||
| def gen_arch_string(): | ||||
|     """ | ||||
|     Creates and returns a archive string of every file in ENTRY_DIR. | ||||
|  | ||||
|     Returns: | ||||
|     string: html-formatted archive-string | ||||
|     """ | ||||
|     return "" | ||||
|  | ||||
|  | ||||
| def gen_index_string(): | ||||
|     """ | ||||
|     Create and returns a string including every file in the ENTRY_DIR as an index. | ||||
|  | ||||
|     Returns: | ||||
|     string: html-formatted index string | ||||
|     """ | ||||
|     return "" | ||||
|  | ||||
|  | ||||
| def gen_stand_string(path_ex): | ||||
|     """ | ||||
|     Creates a html-string for a file. | ||||
|     If the file is markdown it will convert it. | ||||
|     This functions ensures upscaling for future formats. | ||||
|  | ||||
|     Parameters: | ||||
|     path_ex: path to a file. | ||||
|  | ||||
|     Returns: | ||||
|     string: html-formatted string string equivalent to the file | ||||
|     """ | ||||
|     return "" | ||||
|  | ||||
|  | ||||
| def get_rss_string(): | ||||
|     """ | ||||
|     Create a rss-string of the blog and return it. | ||||
|  | ||||
|     Returns: | ||||
|     string: rss-string of everything that is in the ENTRY_DIR. | ||||
|     """ | ||||
|     return "" | ||||
							
								
								
									
										4
									
								
								src/requirements.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								src/requirements.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| Flask==2.1.2 | ||||
| flask_login==0.6.2 | ||||
| flask_wtf==1.0.1 | ||||
| WTForms==3.0.1 | ||||
							
								
								
									
										83
									
								
								src/static/css/dark.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								src/static/css/dark.css
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,83 @@ | ||||
| @import 'style.css'; | ||||
|  | ||||
| :root { | ||||
|     --bg0: rgb(29,32,33); | ||||
|     --color0: rgb(220,120,0); | ||||
|     --error: rgb(255,0,0); | ||||
|     --footerbg0: rgb(29,32,33); | ||||
|     --link0: rgb(220, 120, 0); | ||||
|     --link1: rgb(255,255,255); | ||||
|     --menulink0: rgb(220, 120, 0); | ||||
|     --menulink1: rgb(255,255,255); | ||||
|     --menubg0: rgb(29,32,33); | ||||
|     --text0: rgb(235,219,178); | ||||
|     --text1: rgb(220, 120, 0); | ||||
| } | ||||
|  | ||||
| a { | ||||
|     color: var(--link0); | ||||
|     transition: var(--transtime); | ||||
| } | ||||
|  | ||||
| a:hover { | ||||
|     color: var(--link1); | ||||
| } | ||||
|  | ||||
| body { | ||||
|     background: var(--bg0); | ||||
| } | ||||
|  | ||||
| footer { | ||||
|     background: var(--footerbg0); | ||||
|     color: var(--text0); | ||||
| } | ||||
|  | ||||
| span { | ||||
|     color: var(--text1); | ||||
| } | ||||
|  | ||||
| .container { | ||||
|     color: var(--text0); | ||||
| } | ||||
|  | ||||
| .container h1, | ||||
| .container h2 { | ||||
|     color: var(--text1); | ||||
| } | ||||
|  | ||||
| .container .flash { | ||||
|     background-color: var(--error); | ||||
| } | ||||
|  | ||||
| .hide-menu:hover, | ||||
| .main-menu a:hover, | ||||
| .show-menu:hover { | ||||
|     color: var(--menulink1); | ||||
| } | ||||
|  | ||||
| .main-menu a { | ||||
|     color: var(--menulink0); | ||||
| } | ||||
|  | ||||
| .main-menu-dropdown { | ||||
|     background: var(--menubg0); | ||||
|     color: var(--menulink0); | ||||
| } | ||||
|  | ||||
| @media screen and (max-width:800px) { | ||||
|  | ||||
|     .main-menu { | ||||
|         background: var(--menubg0); | ||||
|     } | ||||
| } | ||||
|  | ||||
| .entry { | ||||
|     background: var(--bg0); | ||||
|     border-left: 10px solid var(--color0); | ||||
|     color: var(--text0); | ||||
| } | ||||
|  | ||||
| .entry h1, | ||||
| .entry h2 { | ||||
|     color: var(--text1); | ||||
| } | ||||
							
								
								
									
										83
									
								
								src/static/css/light.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								src/static/css/light.css
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,83 @@ | ||||
| @import 'style.css'; | ||||
|  | ||||
| :root { | ||||
|     --bg0: rgb(255,255,255); | ||||
|     --color0: rgb(0,0,120); | ||||
|     --error: rgb(255,0,0); | ||||
|     --footerbg0: rgb(192,192,192); | ||||
|     --link0: rgb(0,0,120); | ||||
|     --link1: rgb(255,255,255); | ||||
|     --menulink0: rgb(0,0,120); | ||||
|     --menulink1: rgb(255,255,255); | ||||
|     --menubg0: rgb(192,192,192); | ||||
|     --text0: rgb(0,0,0); | ||||
|     --text1: rgb(0,0,120); | ||||
| } | ||||
|  | ||||
| a { | ||||
|     color: var(--link0); | ||||
|     transition: var(--transtime); | ||||
| } | ||||
|  | ||||
| a:hover { | ||||
|     color: var(--link1); | ||||
| } | ||||
|  | ||||
| body { | ||||
|     background: var(--bg0); | ||||
| } | ||||
|  | ||||
| footer { | ||||
|     background: var(--footerbg0); | ||||
|     color: var(--text0); | ||||
| } | ||||
|  | ||||
| span { | ||||
|     color: var(--text1); | ||||
| } | ||||
|  | ||||
| .container { | ||||
|     color: var(--text0); | ||||
| } | ||||
|  | ||||
| .container h1, | ||||
| .container h2 { | ||||
|     color: var(--text1); | ||||
| } | ||||
|  | ||||
| .container .flash { | ||||
|     background-color: var(--error); | ||||
| } | ||||
|  | ||||
| .hide-menu:hover, | ||||
| .main-menu a:hover, | ||||
| .show-menu:hover { | ||||
|     color: var(--menulink1); | ||||
| } | ||||
|  | ||||
| .main-menu a { | ||||
|     color: var(--menulink0); | ||||
| } | ||||
|  | ||||
| .main-menu-dropdown { | ||||
|     background: var(--menubg0); | ||||
|     color: var(--menulink0); | ||||
| } | ||||
|  | ||||
| @media screen and (max-width:800px) { | ||||
|  | ||||
|     .main-menu { | ||||
|         background: var(--menubg0); | ||||
|     } | ||||
| } | ||||
|  | ||||
| .entry { | ||||
|     background: var(--bg0); | ||||
|     border-left: 10px solid var(--color0); | ||||
|     color: var(--text0); | ||||
| } | ||||
|  | ||||
| .entry h1, | ||||
| .entry h2 { | ||||
|     color: var(--text1); | ||||
| } | ||||
							
								
								
									
										169
									
								
								src/static/css/style.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										169
									
								
								src/static/css/style.css
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,169 @@ | ||||
| :root { | ||||
|     --error: rgb(255,0,0); | ||||
|     --transtime: 0.7s; | ||||
| } | ||||
|  | ||||
| * { | ||||
|     margin: 0; | ||||
|     padding: 0; | ||||
| } | ||||
|  | ||||
| a { | ||||
|     text-decoration: none; | ||||
|     transition: var(--transtime); | ||||
| } | ||||
|  | ||||
| a:hover { | ||||
|     cursor: pointer; | ||||
| } | ||||
|  | ||||
| body { | ||||
|     margin: 0; | ||||
| } | ||||
|  | ||||
| body, | ||||
| html { | ||||
|     font-family: sans-serif; | ||||
|     height: 100%; | ||||
|     max-width: 100%; | ||||
|     overflow-x: hidden; | ||||
| } | ||||
|  | ||||
| footer { | ||||
|     height: 100px; | ||||
|     padding-top: 20px; | ||||
| } | ||||
|  | ||||
| footer .center { | ||||
|     text-align: center; | ||||
| } | ||||
|  | ||||
| .container { | ||||
|     min-height: 100%; | ||||
|     padding-bottom: 50px; | ||||
|     padding-left: 10%; | ||||
|     padding-right: 10%; | ||||
|     padding-top: 5%; | ||||
| } | ||||
|  | ||||
| .container .flash { | ||||
|     padding: 10px; | ||||
|     width: 400px; | ||||
| } | ||||
|  | ||||
| .hide-menu, | ||||
| .show-menu { | ||||
|     cursor: pointer; | ||||
|     display: none; | ||||
|     font-size: 30px; | ||||
|     transition: var(--transtime); | ||||
| } | ||||
|  | ||||
| .important { | ||||
|     font-size: xx-large; | ||||
|     padding-left: 25vw; | ||||
|     padding-right: 25vw; | ||||
|     padding-top: 30vh; | ||||
|     text-align: left; | ||||
| } | ||||
|  | ||||
| .important span { | ||||
|     font-weight: bold; | ||||
| } | ||||
|  | ||||
| .logo { | ||||
|     height: 80px; | ||||
|     padding-top: 10px; | ||||
| } | ||||
|  | ||||
| .main-menu-dropdown span { | ||||
|     float: left; | ||||
|     font-family: monospace; | ||||
|     font-size: 30px; | ||||
|     font-weight: bold; | ||||
|     line-height: 100px; | ||||
|     padding: 0 10px; | ||||
|     text-decoration: none; | ||||
|     text-transform: uppercase; | ||||
|     transition: 0.7s; | ||||
| } | ||||
|  | ||||
| .main-menu { | ||||
|     float: right; | ||||
|     font-family: monospace; | ||||
|     font-size: 30px; | ||||
|     font-weight: bold; | ||||
|     line-height: 100px; | ||||
| } | ||||
|  | ||||
| .main-menu a { | ||||
|     padding: 0 10px; | ||||
|     text-decoration: none; | ||||
|     text-transform: uppercase; | ||||
|     transition: 0.7s; | ||||
| } | ||||
|  | ||||
| .main-menu-dropdown { | ||||
|     height: 100px; | ||||
|     padding: 0 20px; | ||||
| } | ||||
|  | ||||
| .show-menu { | ||||
|     float: right; | ||||
|     line-height: 100px; | ||||
| } | ||||
|  | ||||
| #main-menu-check { | ||||
|     position: absolute; | ||||
|     visibility: hidden; | ||||
|     z-index: -1111; | ||||
| } | ||||
|  | ||||
| @media screen and (max-width:800px) { | ||||
|     .hide-menu { | ||||
|         position: absolute; | ||||
|         right: 40px; | ||||
|         top: 40px; | ||||
|     } | ||||
|  | ||||
|     .hide-menu, | ||||
|     .show-menu { | ||||
|         display: block; | ||||
|     } | ||||
|  | ||||
|     .main-menu { | ||||
|         height: 100vh; | ||||
|         line-height: normal; | ||||
|         padding: 80px 0; | ||||
|         position: fixed; | ||||
|         right: -100%; | ||||
|         text-align: center; | ||||
|         top: 0; | ||||
|         transition: var(--transtime); | ||||
|         width: 100%; | ||||
|     } | ||||
|     .main-menu a { | ||||
|         display: block; | ||||
|         padding: 20px; | ||||
|     } | ||||
|  | ||||
|     #main-menu-check:checked ~ .main-menu { | ||||
|         right: 0; | ||||
|     } | ||||
| } | ||||
|  | ||||
| .entry { | ||||
|     border-radius: 0 10px 30px 0; | ||||
|     margin-bottom: 20px; | ||||
|     padding: 10px; | ||||
| } | ||||
|  | ||||
| .entry h1, | ||||
| .entry h2 { | ||||
|     margin: 5px auto 2px auto; | ||||
| } | ||||
|  | ||||
| .entry ul { | ||||
|     padding-left: 20; | ||||
| } | ||||
|  | ||||
							
								
								
									
										0
									
								
								src/static/images/logo.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								src/static/images/logo.png
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										11
									
								
								src/templates/archive.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								src/templates/archive.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| {% extends 'template.html' %} | ||||
| {% block content %} | ||||
| <div class="container"> | ||||
|     <div class="blogarchive"> | ||||
| 	<h1>Archive</h1><br> | ||||
|         {% autoescape off %} | ||||
|         {{ content_string }} | ||||
|         {% endautoescape %} | ||||
|     </div> | ||||
| </div> | ||||
| {% endblock %} | ||||
							
								
								
									
										9
									
								
								src/templates/error.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/templates/error.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| {% extends "template.html" %} | ||||
| {% block content %} | ||||
| <div class="container"> | ||||
|     <div class="important"> | ||||
|         Error<br> | ||||
| 	<span>{{ errorcode }}</span> | ||||
|     </div> | ||||
| </div> | ||||
| {% endblock %} | ||||
							
								
								
									
										11
									
								
								src/templates/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								src/templates/index.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| {% extends "template.html" %} | ||||
| {% block content %} | ||||
| <div class="container"> | ||||
|     <div class="blog"> | ||||
|         <h1>Index</h1><br> | ||||
|         {% autoescape off %} | ||||
|         {{ content_string }} | ||||
|         {% endautoescape %} | ||||
|     </div> | ||||
| </div> | ||||
| {% endblock %} | ||||
							
								
								
									
										16
									
								
								src/templates/rss.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/templates/rss.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"> | ||||
|  | ||||
| <channel> | ||||
|     <title>{{ title }}</title> | ||||
|     <description>{{ description }}</description> | ||||
| <language>en-us</language> | ||||
| <link>{{ website }}/feed.xml</link> | ||||
| <atom:link href="/feed.xml" rel="self" type="application/rss+xml" /> | ||||
|  | ||||
| {% autoescape off %} | ||||
| {{ content_string }} | ||||
| {% endautoescape %} | ||||
|  | ||||
| </channel> | ||||
| </rss> | ||||
							
								
								
									
										10
									
								
								src/templates/standalone.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								src/templates/standalone.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| {% extends 'template.html' %} | ||||
| {% block content %} | ||||
| <div class="container"> | ||||
|     <div class="standalone"> | ||||
|         {% autoescape off %} | ||||
|         {{ content_string }} | ||||
|         {% endautoescape %} | ||||
|     </div> | ||||
| </div> | ||||
| {% endblock %} | ||||
							
								
								
									
										32
									
								
								src/templates/template.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								src/templates/template.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | ||||
| <html> | ||||
| <head> | ||||
|     <title>{{ title }}</title> | ||||
|     <link href="{{ url_for('static', filename='css/' + style + '.css') }}" rel="stylesheet" type="text/css"> | ||||
|     <meta charset="utf-8"> | ||||
|     <meta name="viewport" content="width=device-width" initial-scale=1.0> | ||||
| </head> | ||||
| <body> | ||||
|     <!-- Menu --> | ||||
|     <div class="main-menu-dropdown"> | ||||
|         <!-- <img class="logo" src="/static/images/logo.png"> --> | ||||
|         <span>{{ title }}</span> | ||||
|         <input type="checkbox" id="main-menu-check"> | ||||
|         <label for="main-menu-check" class="show-menu">☰</label> | ||||
|         <div class="main-menu"> | ||||
|             <a href="/">Blog</a> | ||||
|             <a href="/archive">Archive</a> | ||||
|             <label for="main-menu-check" class="hide-menu">X</label> | ||||
|         </div> | ||||
|     </div> | ||||
|     <!-- Menu --> | ||||
|     <!-- Content --> | ||||
| 	{% block content %} | ||||
| 	{% endblock %} | ||||
|     <!-- Content --> | ||||
|     <footer> | ||||
|         <div class="center"> | ||||
|             Made with <a href="https://github.com/tiyn/container-critique">Container Critique </a>. | ||||
|         </div> | ||||
|     </footer> | ||||
| </body> | ||||
| </html> | ||||
		Reference in New Issue
	
	Block a user