Pyramid Starter project
-404 Page Not Found
+ +Méditation SUNYATA Paris
+404 Page non trouvée
diff --git a/cao_blogr.sqlite b/cao_blogr.sqlite index 4f6e422..220e314 100644 Binary files a/cao_blogr.sqlite and b/cao_blogr.sqlite differ diff --git a/cao_blogr/alembic/env.py b/cao_blogr/alembic/env.py index 9546957..cfbc519 100644 --- a/cao_blogr/alembic/env.py +++ b/cao_blogr/alembic/env.py @@ -3,7 +3,7 @@ from alembic import context from pyramid.paster import get_appsettings, setup_logging from sqlalchemy import engine_from_config -from pyramid_blogr.models.meta import Base +from cao_blogr.models.meta import Base config = context.config diff --git a/cao_blogr/alembic/versions/20220430_85284752d1d5.py b/cao_blogr/alembic/versions/20220430_85284752d1d5.py new file mode 100644 index 0000000..09bb2b7 --- /dev/null +++ b/cao_blogr/alembic/versions/20220430_85284752d1d5.py @@ -0,0 +1,46 @@ +"""init + +Revision ID: 85284752d1d5 +Revises: bbacde35234d +Create Date: 2022-04-30 14:21:08.576738 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '85284752d1d5' +down_revision = 'bbacde35234d' +branch_labels = None +depends_on = None + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.create_table('tags', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('topic', sa.Unicode(length=25), nullable=True), + sa.Column('tag', sa.Unicode(length=25), nullable=True), + sa.Column('title', sa.Unicode(length=25), nullable=False), + sa.PrimaryKeyConstraint('id', name=op.f('pk_tags')), + sa.UniqueConstraint('title', name=op.f('uq_tags_title')) + ) + op.create_index('topic_index', 'tags', ['topic', 'tag'], unique=False) + op.create_table('topics', + sa.Column('topic', sa.Unicode(length=25), nullable=False), + sa.Column('title', sa.Unicode(length=25), nullable=False), + sa.PrimaryKeyConstraint('topic', name=op.f('pk_topics')), + sa.UniqueConstraint('title', name=op.f('uq_topics_title')) + ) + op.create_index(op.f('ix_entries_tag'), 'entries', ['tag'], unique=False) + op.create_index(op.f('ix_entries_topic'), 'entries', ['topic'], unique=False) + # ### end Alembic commands ### + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_index(op.f('ix_entries_topic'), table_name='entries') + op.drop_index(op.f('ix_entries_tag'), table_name='entries') + op.drop_table('topics') + op.drop_index('topic_index', table_name='tags') + op.drop_table('tags') + # ### end Alembic commands ### diff --git a/cao_blogr/alembic/versions/20220501_de7d23a4b139.py b/cao_blogr/alembic/versions/20220501_de7d23a4b139.py new file mode 100644 index 0000000..a57afb6 --- /dev/null +++ b/cao_blogr/alembic/versions/20220501_de7d23a4b139.py @@ -0,0 +1,32 @@ +"""init + +Revision ID: de7d23a4b139 +Revises: 85284752d1d5 +Create Date: 2022-05-01 08:41:03.244262 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = 'de7d23a4b139' +down_revision = '85284752d1d5' +branch_labels = None +depends_on = None + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.add_column('tags', sa.Column('tag_name', sa.Unicode(length=25), nullable=False)) + op.create_unique_constraint(op.f('uq_tags_tag_name'), 'tags', ['tag_name']) + op.add_column('topics', sa.Column('topic_name', sa.Unicode(length=25), nullable=False)) + op.create_unique_constraint(op.f('uq_topics_topic_name'), 'topics', ['topic_name']) + # ### end Alembic commands ### + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_constraint(op.f('uq_topics_topic_name'), 'topics', type_='unique') + op.drop_column('topics', 'topic_name') + op.drop_constraint(op.f('uq_tags_tag_name'), 'tags', type_='unique') + op.drop_column('tags', 'tag_name') + # ### end Alembic commands ### diff --git a/cao_blogr/forms.py b/cao_blogr/forms.py index 8ad68ec..bda9f69 100644 --- a/cao_blogr/forms.py +++ b/cao_blogr/forms.py @@ -1,6 +1,6 @@ -from wtforms import Form, StringField, TextAreaField, validators +from wtforms import Form, StringField, TextAreaField, SelectField from wtforms import IntegerField, PasswordField -from wtforms.validators import InputRequired, Length +from wtforms.validators import InputRequired, DataRequired, Length from wtforms.widgets import HiddenInput strip_filter = lambda x: x.strip() if x else None @@ -10,10 +10,8 @@ class BlogCreateForm(Form): filters=[strip_filter]) body = TextAreaField('Corps du texte', validators=[InputRequired(), Length(min=1)], filters=[strip_filter]) - topic = StringField('Topic', validators=[InputRequired(), Length(min=1, max=255)], - filters=[strip_filter]) - tag = StringField('Tag', validators=[InputRequired(), Length(min=1, max=20)], - filters=[strip_filter]) + tag = SelectField('Tag', validators=[DataRequired()], id='select_tag') + class BlogUpdateForm(BlogCreateForm): id = IntegerField(widget=HiddenInput()) diff --git a/cao_blogr/models/blog_record.py b/cao_blogr/models/blog_record.py index 978306e..675ab1e 100644 --- a/cao_blogr/models/blog_record.py +++ b/cao_blogr/models/blog_record.py @@ -6,6 +6,7 @@ from sqlalchemy import ( Unicode, #<- will provide Unicode field UnicodeText, #<- will provide Unicode text field DateTime, #<- time abstraction field + Index, ) from webhelpers2.text import urlify #<- will generate slugs from webhelpers2.date import distance_of_time_in_words #<- human friendly dates @@ -15,10 +16,10 @@ class BlogRecord(Base): __tablename__ = 'entries' id = Column(Integer, primary_key=True) title = Column(Unicode(255), unique=True, nullable=False) - body = Column(UnicodeText, default=u'') - body_html = Column(UnicodeText, default=u'') - tag = Column(Unicode, default='pyramid') - topic = Column(Unicode, default='blog') + body = Column(UnicodeText, default='') + body_html = Column(UnicodeText, default='') + tag = Column(Unicode(25), index=True) + topic = Column(Unicode(25), index=True) created = Column(DateTime, default=datetime.datetime.utcnow) edited = Column(DateTime, default=datetime.datetime.utcnow) @@ -28,6 +29,19 @@ class BlogRecord(Base): @property def created_in_words(self): - return distance_of_time_in_words(self.created, - datetime.datetime.utcnow()) + return distance_of_time_in_words(self.created, datetime.datetime.utcnow()) + +class Topics(Base): + __tablename__ = 'topics' + topic = Column(Unicode(25), primary_key=True) + topic_name = Column(Unicode(25), nullable=False) + + +class Tags(Base): + __tablename__ = 'tags' + id = Column(Integer, primary_key=True) + topic = Column(Unicode(25)) + tag = Column(Unicode(25)) + tag_name = Column(Unicode(25), nullable=False) + __table_args__ = (Index('topic_index', "topic", "tag"), ) diff --git a/cao_blogr/routes.py b/cao_blogr/routes.py index 5515009..c1cce48 100644 --- a/cao_blogr/routes.py +++ b/cao_blogr/routes.py @@ -7,6 +7,7 @@ def includeme(config): config.add_route('blog_search', '/blog_search') config.add_route('login', '/login') config.add_route('logout', '/logout') + config.add_route('topic', '/topic/{topic}') config.add_route('users', '/users') config.add_route('user_add', '/user_add/{name}') config.add_route('user_pwd', '/user_pwd/{name}') diff --git a/cao_blogr/services/blog_record.py b/cao_blogr/services/blog_record.py index 4afc9d3..aa3423c 100644 --- a/cao_blogr/services/blog_record.py +++ b/cao_blogr/services/blog_record.py @@ -3,16 +3,18 @@ import datetime #<- will be used to set default dates on models from sqlalchemy import or_ from paginate_sqlalchemy import SqlalchemyOrmPage #<- provides pagination -from ..models.blog_record import BlogRecord +from ..models.blog_record import BlogRecord, Topics, Tags from markdown2 import Markdown class BlogRecordService(object): @classmethod - def all(cls, request): - query = request.dbsession.query(BlogRecord) - return query.order_by(sa.desc(BlogRecord.created)) + def by_topic(cls, request, topic): + query = request.dbsession.query(BlogRecord).join(Tags, Tags.topic == BlogRecord.topic, Tags.tag == BlogRecord.tag) + query = query.filter(BlogRecord.topic == topic) + query = query.order_by(BlogRecord.tag, BlogRecord.title).all() + return query @classmethod def by_criteria(cls, request, criteria): @@ -27,18 +29,18 @@ class BlogRecordService(object): return query.get(_id) @classmethod - def get_paginator(cls, request, page=1): + def get_last_five(cls, request): + # gest the last 5 items modified query = request.dbsession.query(BlogRecord) - query = query.order_by(sa.desc(BlogRecord.created)) - query_params = request.GET.mixed() + query = query.order_by(sa.desc(BlogRecord.edited)).limit(5).all() + return query - def url_maker(link_page): - # replace page param with values generated by paginator - query_params['page'] = link_page - return request.current_route_url(_query=query_params) - - return SqlalchemyOrmPage(query, page, items_per_page=5, - url_maker=url_maker) + @classmethod + def get_tags_byTopic(cls, request, topic): + # gest the last 5 items modified + query = request.dbsession.query(Tags).filter(Tags.topic == topic) + query = query.order_by(Tags.tag).all() + return query @classmethod def proc_after_create(cls, request, _id): diff --git a/cao_blogr/static/dao-trang.jpg b/cao_blogr/static/dao-trang.jpg new file mode 100644 index 0000000..50eb7cd Binary files /dev/null and b/cao_blogr/static/dao-trang.jpg differ diff --git a/cao_blogr/static/logo-zoom.jpg b/cao_blogr/static/logo-zoom.jpg new file mode 100644 index 0000000..9ff4a22 Binary files /dev/null and b/cao_blogr/static/logo-zoom.jpg differ diff --git a/cao_blogr/static/theme.css b/cao_blogr/static/theme.css index b7b65b2..e601f8e 100644 --- a/cao_blogr/static/theme.css +++ b/cao_blogr/static/theme.css @@ -5,14 +5,13 @@ body { font: 400 15px/1.8 Lato, sans-serif; color: #666; } -h3, h4 { - margin: 10px 0 30px 0; +h2 { + margin: 30px 0 30px 0; letter-spacing: 10px; - font-size: 20px; color: #111; } .container { - padding: 60px 80px; + padding: 60px 80px 20px 80px; } .person { border: 10px solid transparent; @@ -43,7 +42,7 @@ h3, h4 { background: #bc2131; color: #bdbdbd; } -.bg-1 h3 {color: #fff;} +.bg-1 h2 {color: #fff;} .bg-1 p {font-style: italic;} .list-group-item:first-child { border-top-right-radius: 0; @@ -63,7 +62,7 @@ h3, h4 { color: #555; } -.modal-header, h4, .close { +.modal-header, .close { background-color: #333; color: #fff !important; text-align: center; diff --git a/cao_blogr/templates/404.jinja2 b/cao_blogr/templates/404.jinja2 index aaf1241..1d8e9df 100644 --- a/cao_blogr/templates/404.jinja2 +++ b/cao_blogr/templates/404.jinja2 @@ -1,8 +1,10 @@ {% extends "layout.jinja2" %} {% block content %} -
404 Page Not Found
+ +404 Page non trouvée
[ Retour ] @@ -12,20 +13,8 @@
{{ entry.body_html | safe }}
- Topic : {{ entry.topic }} - | - Tag : {{ entry.tag }} - | - Créé le : {{ entry.created.strftime("%d-%m-%Y - %H:%M") }} - | - Modifié le : {{ entry.edited.strftime("%d-%m-%Y - %H:%M") }} -
- {% else %} -- Créé : {{ entry.created_in_words }} -
- {% endif %} - ++ Publié le : {{ entry.edited.strftime("%d-%m-%Y - %H:%M") }} +
+ {% endblock %} diff --git a/cao_blogr/templates/blog_edit.jinja2 b/cao_blogr/templates/blog_edit.jinja2 index 9256505..3a7cbf6 100644 --- a/cao_blogr/templates/blog_edit.jinja2 +++ b/cao_blogr/templates/blog_edit.jinja2 @@ -1,6 +1,7 @@ {% extends "cao_blogr:templates/layout.jinja2" %} {% block content %} +