fetch of categories and front end fix

master
grgr 2 years ago
parent 40ebc31f5e
commit 4da31e0699

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2021 Tom Bulled
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

@ -0,0 +1,83 @@
Metadata-Version: 2.1
Name: export
Version: 0.2.0
Summary: Control module exports
Home-page: https://github.com/tombulled/export
License: MIT
Keywords: python,export,public,private
Author: Tom Bulled
Author-email: 26026015+tombulled@users.noreply.github.com
Requires-Python: >=3.8,<4.0
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Project-URL: Documentation, https://github.com/tombulled/export
Project-URL: Repository, https://github.com/tombulled/export
Description-Content-Type: text/markdown
# export
Control module exports
## About
This library dynamically generates an `__all__` attribute for modules
## Usage
### Private by Default
*Does* export objects marked **public**, *doesn't* export everything else
```python
# lib.py
import export
export.init(default=export.PRIVATE)
@export.public
def foo():
pass
def bar():
pass
def baz():
pass
```
```python
>>> import lib
>>>
>>> lib.__all__
['foo']
```
### Public by Default
*Doesn't* export objects marked **private**, *does* export everything else
```python
# lib.py
import export
export.init(default=export.PUBLIC)
def foo():
pass
@export.private
def bar():
pass
@export.private
def baz():
pass
```
```python
>>> import lib
>>>
>>> lib.__all__
['export', 'foo']
```

@ -0,0 +1,14 @@
export-0.2.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
export-0.2.0.dist-info/LICENSE,sha256=GnW03-0adM_f-nbemR0-poxBk-zJQWQB3t8yAMMFMhY,1067
export-0.2.0.dist-info/METADATA,sha256=DtgARxtzqpdsOa2n2X7MCqeAm5oWFqFY44UuL0UR50U,1472
export-0.2.0.dist-info/RECORD,,
export-0.2.0.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
export-0.2.0.dist-info/WHEEL,sha256=y3eDiaFVSNTPbgzfNn0nYn5tEn1cX6WrdetDlQM4xWw,83
export/__init__.py,sha256=Q_CTsi3EXrwEvUx1vaRfOdyCClh212K0UH3CF8MJsxw,148
export/__pycache__/__init__.cpython-310.pyc,,
export/__pycache__/api.cpython-310.pyc,,
export/__pycache__/enums.cpython-310.pyc,,
export/__pycache__/models.cpython-310.pyc,,
export/api.py,sha256=11G7-4dXNQMlUcyG91Ct3MVKeB3Q9JIhZYLNDR3yOyg,1208
export/enums.py,sha256=P2ywq5fVliFyv4XdW-LGi8GDrYoGSQG3baaA0hUhnVY,176
export/models.py,sha256=q292OojIkSLSBKjo-5WUQWbnAONe_X5nk7vbenuknDA,280

@ -0,0 +1,4 @@
Wheel-Version: 1.0
Generator: poetry 1.0.7
Root-Is-Purelib: true
Tag: py3-none-any

@ -0,0 +1,5 @@
from .api import init, public, private
from . import enums
PUBLIC: enums.Access = enums.Access.PUBLIC
PRIVATE: enums.Access = enums.Access.PRIVATE

@ -0,0 +1,46 @@
import inspect
import sys
import types
import typing
from . import enums, models
def init(*, default: enums.Access = enums.Access.PRIVATE) -> None:
module: types.ModuleType = inspect.getmodule(inspect.stack()[1][0])
class Module(types.ModuleType):
_scope: models.Scope = models.Scope(default=default)
@property
def __all__(self) -> typing.List[str]:
attributes: typing.Set[str] = {
key for key in dir(self) if not key.startswith("_")
}
if self._scope.default == enums.Access.PUBLIC:
return sorted(attributes - self._scope.private)
return sorted(self._scope.public)
module.__class__ = Module
def public(obj: typing.T) -> typing.T:
return _export(obj, access=enums.Access.PUBLIC)
def private(obj: typing.T) -> typing.T:
return _export(obj, access=enums.Access.PRIVATE)
def _export(obj: typing.T, access: enums.Access) -> typing.T:
module: types.ModuleType = sys.modules[obj.__module__]
collection: typing.Set[str] = (
module._scope.public if access is enums.Access.PUBLIC else module._scope.private
)
collection.add(obj.__name__)
return obj

@ -0,0 +1,9 @@
import enum
class Access(enum.Enum):
PUBLIC = enum.auto()
PRIVATE = enum.auto()
def __repr__(self) -> str:
return f"<{type(self).__name__}.{self.name}>"

@ -0,0 +1,11 @@
import dataclasses
import typing
from . import enums
@dataclasses.dataclass
class Scope:
default: enums.Access = enums.Access.PRIVATE
public: typing.Set[str] = dataclasses.field(default_factory=set)
private: typing.Set[str] = dataclasses.field(default_factory=set)

Binary file not shown.

@ -1,6 +1,7 @@
# THE LIBRARY #
from itertools import groupby # to handle complex iterations
from itertools import groupby # to handle complex iterations
import os
import sqlite3
@ -16,7 +17,6 @@ def get_db_connection():
# Added row_factory attribute to the sqlite connection, in this way you can have name-based access to columns; this means that the database connection will return rows that behave like regular Python dictionaries.
# ----- FLASK ----- #
class PrefixMiddleware(object):
@ -41,19 +41,23 @@ app = Flask(__name__)
app.wsgi_app = PrefixMiddleware(app.wsgi_app, prefix='/soupboat/library')
@app.route("/", methods=['GET', 'POST'])
@app.route("/")
def home():
conn = get_db_connection()
todos = conn.execute('SELECT c.content, cat.title FROM cards c JOIN categories cat \
ON c.category_id = cat.id ORDER BY c.created').fetchall()
ON c.category_id = cat.id ORDER BY cat.title').fetchall()
categories = {}
# for each category and group of cards for each cat in groupby() grouper object
for k, g in groupby(todos, key=lambda t: t['title']):
categories[k] = list(g)
print(categories[k])
for cat, cards in categories.items(): # ♥ .items is a build in attribute of the dictionary(?)
print(cat)
for card in cards:
print(' ', card['content'])
# if request.method == 'POST':
# title = request.form.get('title')
# author = request.form.get('author')
@ -64,26 +68,25 @@ def home():
return render_template('home.html', categories=categories)
# @app.route("/add", methods=['GET', 'POST'])
# def create():
# # the goal here is to choose from a list of parameters what you want to add
# # 1- ogni blocco del form dovrebbe essere una tabella a parte
# if request.method == 'POST':
# title = request.form.get('title')
# author = request.form.get('author')
# description = request.form.get('description')
# add_book(author, title, description)
# # if author:
# # return url_for('add_new_author')
# return redirect(url_for('home'))
# return render_template('add_new.html')
@app.route("/add", methods=['GET', 'POST'])
def create():
# the goal here is to choose from a list of parameters what you want to add
# 1- ogni blocco del form dovrebbe essere una tabella a parte
if request.method == 'POST':
title = request.form.get('title')
author = request.form.get('author')
description = request.form.get('description')
add_book(author, title, description)
# if author:
# return url_for('add_new_author')
return redirect(url_for('home'))
return render_template('add_new.html')
app.run(port=3148)
# app.run(port=3148)
# TODO:
# - list the cards
# - put its category inside
# - put its category inside

@ -8,8 +8,16 @@ with open('schema.sql') as f:
cur = connection.cursor()
cur.execute("INSERT INTO categories (title) VALUES (?)", ('Reading',))
cur.execute("INSERT INTO categories (title) VALUES (?)", ('Note',))
cur.execute("INSERT INTO categories (title) VALUES (?)", ('Question',))
cur.execute("INSERT INTO cards (category_id, content) VALUES (?,?)",
(1, 'Oltre Eboli'))
cur.execute("INSERT INTO cards (category_id, content) VALUES (?,?)",
(1, 'This is not an Atlas'))
# close conenction
connection.commit()
connection.close()
connection.close()

Binary file not shown.

@ -2,12 +2,12 @@
<html lang="en">
<head>
<meta charset="utf-8" />
<title>library</title>
<link rel="stylesheet" href="{{url_for('static', filename='style_default.css')}}">
<script src="{{url_for('static', filename='addnew_panel.js')}}"></script>
<title>{% block title %} {% endblock %}</title>
<!-- <link rel="stylesheet" href="{{url_for('static', filename='style_default.css')}}"> -->
<!-- <script src="{{url_for('static', filename='addnew_panel.js')}}"></script> -->
</head>
<body>
<!-- <a class="nav-link" href="{{ url_for('create') }}">New</a> -->
<!--{# <a class="nav-link" href="{{ url_for('create') }}">New</a> #}-->
{% block content %} {% endblock %}
</body>
</html>

@ -2,20 +2,20 @@
{% block content %}
<h1>{% block title %} Welcome to FlaskTodo {% endblock %}</h1>
{% for category, cards in categories.cards() %}
{% for category, cards in categories.items() %}
<div class="card" style="width: 18rem; margin-bottom: 50px;">
<div class="card-header">
<h3>{{ category }}</h3>
</div>
<ul class="list-group list-group-flush">
{% for card in cards %}
<li class="list-group-item">{{ cards['content'] }}</li>
<li class="list-group-item">{{ card['content'] }}</li>
{% endfor %}
</ul>
</div>
{% endfor %}
{% endblock %}
<!-- <!DOCTYPE html>
<!-- {#<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
@ -47,4 +47,4 @@
</div>
</body>
</html> -->
</html> #}-->

Loading…
Cancel
Save