1cde5e53b25d — Eddie Barraco 5 years ago
Init
A => .hgignore +1 -0
@@ 0,0 1,1 @@ 
+__pycache__

          
A => cogito2/__init__.py +0 -0

        
A => cogito2/app.py +28 -0
@@ 0,0 1,28 @@ 
+from .database.filerepository import get_file, get_page_files, get_file_count
+from .database.article_factory import build_from_posix_file, build_from_posix_files
+from .database.markdown import get_html
+from math import ceil
+
+from flask import Flask, render_template, abort, request
+app = Flask(__name__)
+
+@app.route("/")
+@app.route("/archive")
+def article_archive():
+    page = request.args.get('page', 0, type=int)
+    item_per_page=2
+    page_count=ceil(get_file_count() / item_per_page)
+
+    files = get_page_files(page=page, items_per_page=item_per_page)
+    articles = build_from_posix_files(files)
+    return render_template('archive.html', articles=articles, page=page, page_count=page_count)
+
+@app.route("/archive/<path:id>")
+def article_show(id):
+    file = get_file(id)
+    try:
+        article = build_from_posix_file(file)
+    except FileNotFoundError:
+        abort(404)
+
+    return render_template('show.html', article=article)

          
A => cogito2/database/article.py +11 -0
@@ 0,0 1,11 @@ 
+class Article:
+    def __init__(self, id, content, created_at):
+        self.id = id
+        self.content = content
+        self.created_at = created_at
+    def get_title(self):
+        return "title"
+    def get_teasing(self):
+        return "teasing"
+    def get_body(self):
+        return self.content

          
A => cogito2/database/article_factory.py +17 -0
@@ 0,0 1,17 @@ 
+from .article import Article
+from pathlib import PosixPath
+from datetime import datetime
+
+def build_from_posix_file(posix_file: PosixPath):
+    return Article(
+            id=str(posix_file),
+            content=posix_file.read_text(),
+            created_at=datetime.fromtimestamp(posix_file.stat().st_ctime)
+            )
+
+def build_from_posix_files(posix_files: list):
+    articles = []
+    for posix_file in posix_files:
+        articles.append(build_from_posix_file(posix_file))
+
+    return articles

          
A => cogito2/database/filerepository.py +22 -0
@@ 0,0 1,22 @@ 
+from pathlib import Path, PosixPath
+import os
+
+file_root_path=os.getenv('DATA_ROOT_DIR', 'data')
+
+def get_file_count():
+    p = Path(file_root_path)
+    return len(list(p.glob('**/*.md')))
+
+def get_file(file_path):
+    return PosixPath(file_path)
+
+def get_page_files(page=0, items_per_page=10):
+    p = Path(file_root_path)
+    items = list(p.glob('**/*.md'))
+    sorted_items = sorted(items, key=lambda item: item.stat().st_mtime, reverse=True)
+
+    print(page);
+    print(items_per_page);
+
+    return sorted_items[page * items_per_page:page * items_per_page + items_per_page]
+

          
A => cogito2/database/markdown.py +4 -0
@@ 0,0 1,4 @@ 
+from markdown import markdown
+
+def get_html(content):
+    return markdown(content)

          
A => cogito2/static/css/blog.css +55 -0
@@ 0,0 1,55 @@ 
+body {
+    font-family: sans-serif;
+}
+
+.icon {
+    display: block;
+    width: 5rem;
+    height: 5rem;
+    object-fit: cover;
+}
+
+.side-bar {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+}
+
+.date {
+    color: #999;
+}
+
+h1 {
+    font-size: 16pt;
+}
+
+h2 {
+    font-size: 12pt;
+}
+
+p {
+    font-size: 12pt;
+}
+
+h2 > span {
+    margin-right: 1rem;
+}
+
+.pagination {
+    margin-top: 1rem;
+    display: flex;
+    justify-content: space-between;
+}
+
+.container {
+    max-width: 960px;
+    margin-left: auto;
+    margin-right: auto;
+}
+
+@media only screen and (min-width: 960px) {
+    .content {
+        display: grid;
+        grid-template-columns: 3fr 1fr;
+    }
+}

          
A => cogito2/static/img/icon.jpg +0 -0

        
A => cogito2/templates/archive.html +36 -0
@@ 0,0 1,36 @@ 
+{% extends "base.html" %}
+
+{% block body %}
+    <div class="posts">
+        {% for article in articles %}
+        <div class="post">
+            <h2>
+                <span class="date">{{ article.created_at.strftime('%Y-%m-%d') }}</span>
+                <span>
+                    <a href="{{ url_for('article_show', id=article.id) }}">{{ article.get_title() }}</a>
+                </span>
+            </h2>
+            {{ article.get_teasing()|safe }}
+        </div>
+        {% endfor %}
+
+        <div class="pagination">
+            {% if 0 < page %}
+            <a href="{{ url_for('article_archive', page=page-1) }}">Page {{ page-1 }}</a>
+            {% else %}
+            <span></span>
+            {% endif %}
+            {% if page + 1 < page_count %}
+            <a href="{{ url_for('article_archive', page=page+1) }}">Page {{ page+1 }}</a>
+            {% else %}
+            <span></span>
+            {% endif %}
+        </div>
+    </div>
+{% endblock %}
+
+{% block sidebar %}
+    <img src="{{ url_for('static', filename='img/icon.jpg') }}" class="icon"/>
+{% endblock %}
+
+

          
A => cogito2/templates/base.html +25 -0
@@ 0,0 1,25 @@ 
+<!DOCTYPE html>
+<html>
+    <head>
+        <meta charset="UTF-8">
+        <title>{% block title %}Welcome!{% endblock %}</title>
+        <link href="{{ url_for('static', filename='css/blog.css') }}" rel="stylesheet"/>
+        {% block stylesheets %}{% endblock %}
+    </head>
+    <body>
+        <div class="container">
+            <div class="page-title">
+                <h1>The Eddie Barraco's blog</h1>
+            </div>
+            <div class="content">
+                <article>
+                    {% block body %}{% endblock %}
+                </article>
+                <div class="side-bar">
+                    {% block sidebar %}{% endblock %}
+                </div>
+            </div>
+        </div>
+    </body>
+</html>
+

          
A => cogito2/templates/show.html +17 -0
@@ 0,0 1,17 @@ 
+{% extends "base.html" %}
+
+{% block body %}
+    <h2><span>{{ article.get_title() }}</span></h2>
+    <p class="date">
+        Published {{ article.created_at.strftime('%Y-%m-%d') }} on <a href="{{ url_for('article_archive') }}">Eddie Barraco's blog</a>
+    </p>
+    <div>
+        {{ article.get_teasing()|safe }}
+        {{ article.get_body()|safe }}
+    </div>
+{% endblock %}
+
+{% block sidebar %}
+    <img src="{{ url_for('static', filename='img/icon.jpg') }}" class="icon"/>
+{% endblock %}
+