Browse Source

Little model refactoring + lorem & nuke commands

lorem = feeds database with random placeholders
nuke = drop database
Jeremie W 1 year ago
parent
commit
087065d94c

+ 4
- 0
.gitignore View File

@@ -2,6 +2,10 @@
2 2
 */*/__pycache__
3 3
 */*/*/__pycache__
4 4
 *.pyc
5
+.DS_Store
6
+*/.DS_Store
7
+*/*/.DS_Store
8
+*/*/*/.DS_Store
5 9
 app/uploads/*
6 10
 venv/*
7 11
 doc/_build/

+ 1
- 3
app/__init__.py View File

@@ -9,13 +9,11 @@ from glob import glob
9 9
 from config import config, __APP_NAME__
10 10
 import os.path as op
11 11
 
12
-
13 12
 mail = Mail()
14 13
 db = SQLAlchemy()
15 14
 moment = Moment()
16 15
 admin = Admin(name = __APP_NAME__ + ' Admin', template_mode="bootstrap3")
17
-path = op.join(op.dirname(__file__), 'static/podcasts')
18
-admin.add_view(FileAdmin(path, '/static/podcasts/', name='Files'))
16
+base_path = op.dirname(__file__)
19 17
 
20 18
 def create_app(config_name):
21 19
     app = Flask(__name__)

+ 68
- 0
app/commands.py View File

@@ -0,0 +1,68 @@
1
+import contextlib
2
+from operator import itemgetter
3
+from flask import url_for
4
+from flask_script import Command
5
+from . import db
6
+
7
+from app.models.podcast import Podcast
8
+from app.models.contributor import *
9
+from app.models.blog import *
10
+from app.models.event import *
11
+from app.models.label import *
12
+from app.models.tag import *
13
+from app.models.section import *
14
+from app.models.page import *
15
+
16
+
17
+class RoutesCommand(Command):
18
+    """List registered routes"""
19
+
20
+    def __init__(self, app):
21
+        self.app = app
22
+
23
+    def run(self):
24
+        from urllib.parse import unquote
25
+        output = []
26
+        for rule in self.app.url_map.iter_rules():
27
+
28
+            options = {}
29
+            for arg in rule.arguments:
30
+                options[arg] = "[{0}]".format(arg)
31
+
32
+            methods = ','.join(rule.methods)
33
+            url = url_for(rule.endpoint, **options)
34
+            line = unquote("{:35s} {:35s} {}"
35
+                           .format(rule.endpoint, methods, url))
36
+            output.append((line, url))
37
+
38
+        # Sort output by url not name
39
+        for (line, _) in sorted(output, key=itemgetter(1)):
40
+            print(line)
41
+
42
+
43
+class NukeCommand(Command):
44
+    """Nuke the database (except the platform table)"""
45
+
46
+    def __init__(self, db):
47
+        self.db = db
48
+
49
+    def run(self):
50
+        self.db.drop_all()
51
+        self.db.create_all()
52
+        self.db.session.commit()
53
+
54
+class LoremCommand(Command):
55
+    """Feed database with placeholders"""
56
+
57
+    def __init__(self, db):
58
+        self.db = db
59
+
60
+    def run(self):
61
+        BlogPost.fake_feed()
62
+        Contributor.fake_feed()
63
+        Event.fake_feed()
64
+        Label.fake_feed()
65
+        Podcast.fake_feed()
66
+        Section.fake_feed()
67
+        Tag.fake_feed()
68
+        Page.fake_feed()

+ 10
- 0
app/main/views.py View File

@@ -12,6 +12,15 @@ import json
12 12
 from uuid import uuid4
13 13
 app = Flask(__name__)
14 14
 
15
+from app.models.podcast import Podcast
16
+from app.models.contributor import *
17
+from app.models.blog import *
18
+from app.models.event import *
19
+from app.models.label import *
20
+from app.models.tag import *
21
+from app.models.section import *
22
+from app.models.page import *
23
+
15 24
 
16 25
 #########################
17 26
 #  Main pages           #
@@ -31,6 +40,7 @@ def index(specificContent=None):
31 40
 def about():
32 41
     return render_template( 'about.html',
33 42
                             styles = getStyles(),
43
+                            page = Page.query.filter_by(title='À propos').first(),
34 44
                             scripts = getScripts(), )
35 45
 
36 46
 @main.route('/maintenance', methods=['GET', 'POST'])

+ 45
- 35
app/models/admin.py View File

@@ -1,27 +1,44 @@
1 1
 from flask_admin.contrib.sqla import ModelView
2 2
 from flask_admin.contrib.fileadmin import FileAdmin
3
+from flask_admin.form.upload import FileUploadInput
3 4
 from wtforms import TextAreaField
4 5
 from wtforms.widgets import TextArea
5
-from .. import db, admin, path
6
+from .. import db, admin, base_path
7
+import os.path as op
8
+
6 9
 from .podcast import Podcast
7
-from .author import *
10
+from .contributor import *
8 11
 from .blog import *
9 12
 from .event import *
10
-from .meta import *
13
+from .label import *
14
+from .tag import *
11 15
 from .section import *
16
+from .page import *
17
+
12 18
 
19
+podcastPath = op.join(base_path, 'static/podcasts/')
13 20
 
14 21
 # Admin views
15
-''' Fixme : add localization (http://flask-admin.readthedocs.io/en/latest/advanced/#localization-with-flask-babelex)'''
22
+# FIXME : add localization (http://flask-admin.readthedocs.io/en/latest/advanced/#localization-with-flask-babelex)"""
16 23
 
17
-''' Fixme : file field for podcast
18
-class PodcastFileWidget(FileAdmin):
19
-    def __call__(self, base_path, *args, **kwargs):
20
-        storage = LocalFileStorage(base_path)
21
-        return super(FileAdmin, self).__init__(*args, storage=storage, **kwargs)
24
+# FIXME : Inline file admin
25
+'''
26
+class FileAdminWidget(FileAdmin):
27
+    def __call__(self, **kwargs):
28
+        if kwargs.get('class'):
29
+            kwargs['class'] += ' fileAdmin'
30
+        else:
31
+            kwargs.setdefault('class', 'fileAdmin')
32
+        if not kwargs.get['path']:
33
+            kwargs.setdefault('path', base_path)
34
+        if not kwargs.get['url']:
35
+            kwargs.setdefault('url', '/static/')
36
+        if not kwargs.get('name'):
37
+            kwargs.setdefault('name', 'setdefault')
38
+        return super(FileAdmin, self).__call__(field, **kwargs)
22 39
 
23
-class PodcastFileField(PodcastFileWidget):
24
-    widget = PodcastFileWidget()
40
+class FileAdminField(FileAdminWidget):
41
+    widget = FileAdminWidget(base_path=podcastPath, url='/static/podcasts/', name='Files')
25 42
 '''
26 43
 
27 44
 class CKTextAreaWidget(TextArea):
@@ -38,11 +55,17 @@ class CKTextAreaField(TextAreaField):
38 55
 class ModalView(ModelView):
39 56
     create_modal = True
40 57
 
41
-class PodcastView(ModelView):
58
+class PageView(ModelView):
42 59
     extra_js = ['//cdn.ckeditor.com/4.6.0/standard/ckeditor.js']
60
+    form_overrides = {
61
+        'desc': CKTextAreaField
62
+    }
63
+
64
+
65
+class PodcastView(PageView):
43 66
     form_columns = ('title',
44 67
         'label',
45
-        'authors',
68
+        'contributors',
46 69
         'desc',
47 70
         'mood',
48 71
         'type',
@@ -62,7 +85,7 @@ class PodcastView(ModelView):
62 85
     }
63 86
     column_labels = dict(
64 87
         title='Titre',
65
-        authors='Auteurs',
88
+        contributors='Auteurs',
66 89
         type='Musical',
67 90
         desc='Description',
68 91
         mood='Ambiance',
@@ -73,38 +96,25 @@ class PodcastView(ModelView):
73 96
             'default': False
74 97
         }
75 98
     }
76
-    inline_models = (Tag, )
77
-    form_overrides = {
78
-        'desc': CKTextAreaField
79
-    }
80
-#    form_overrides = {
81
-# Fixme : uncomment when PodcastFileField is fixed
82
-#        'link': PodcastFileField
83
-#     }
84 99
 
85
-class SectionView(ModelView):
100
+    inline_models = (Tag, Section, )
101
+
102
+class SectionView(PageView):
86 103
     form_excluded_columns = ['timestamp']
87
-    extra_js = ['//cdn.ckeditor.com/4.6.0/standard/ckeditor.js']
88
-    form_overrides = {
89
-        'desc': CKTextAreaField
90
-    }
91 104
 
92
-class AuthorView(ModalView):
105
+class ContributorView(ModalView):
93 106
     form_excluded_columns = ['podcasts']
94 107
 
95 108
 class LabelView(ModalView):
96 109
     form_excluded_columns = ['podcasts', 'sections']
97 110
 
98
-class BlogView(ModelView):
111
+class BlogView(PageView):
99 112
     form_excluded_columns = ['timestamp']
100
-    extra_js = ['//cdn.ckeditor.com/4.6.0/standard/ckeditor.js']
101
-    form_overrides = {
102
-        'content': CKTextAreaField
103
-    }
104 113
 
105 114
 admin.add_view(PodcastView(Podcast, db.session))
115
+admin.add_view(FileAdmin(podcastPath, '/static/podcasts/', name='Anciens podcasts'))
106 116
 admin.add_view(BlogView(BlogPost, db.session))
107
-admin.add_view(AuthorView(Author, db.session))
117
+admin.add_view(ContributorView(Contributor, db.session))
108 118
 admin.add_view(ModelView(Event, db.session))
109 119
 admin.add_view(LabelView(Label, db.session))
110
-admin.add_view(SectionView(Section, db.session))
120
+admin.add_view(PageView(Page, db.session))

+ 0
- 13
app/models/author.py View File

@@ -1,13 +0,0 @@
1
-from .. import db
2
-
3
-class Author(db.Model):
4
-    __tablename__ = 'authors'
5
-    id = db.Column(db.Integer, primary_key=True)
6
-    name = db.Column(db.String(128))
7
-    status = db.Column(db.String(128))
8
-    bio = db.Column(db.Text)
9
-    podcasts = db.relationship('Podcast',
10
-                secondary='publications')
11
-
12
-    def __str__(self):
13
-        return self.name

+ 29
- 1
app/models/blog.py View File

@@ -3,9 +3,37 @@ from .. import db
3 3
 from datetime import datetime
4 4
 
5 5
 class BlogPost(db.Model):
6
+    """ Blog posts """
6 7
     __tablename__ = 'blog_posts'
7 8
     id = db.Column(db.Integer, primary_key=True)
8 9
     title = db.Column(db.String(256))
10
+    """ Title of the podcast """
9 11
     date = db.Column(db.Date, default=datetime.utcnow)
10
-    content = db.Column(db.Text)
12
+    """ Date of recording """
13
+    desc = db.Column(db.Text)
14
+    """ Description """
11 15
     label_id = db.Column(db.Integer, db.ForeignKey('labels.id'))
16
+    """ Label """
17
+    contributor_id = db.Column(db.Integer, db.ForeignKey('contributors.id'))
18
+    """ Contributor """
19
+
20
+    @staticmethod
21
+    def fake_feed(count=10):
22
+        """ Randomly feeds the database """
23
+        from sqlalchemy.exc import IntegrityError
24
+        from random import seed, randint
25
+        import forgery_py
26
+
27
+        seed()
28
+        for i in range(count):
29
+            bp = BlogPost(
30
+                title = forgery_py.lorem_ipsum.title(),
31
+                desc = forgery_py.lorem_ipsum.paragraph(),
32
+                label_id = randint(0, 10),
33
+                contributor_id = randint(0, 10)
34
+            )
35
+            db.session.add(bp)
36
+        try:
37
+            db.session.commit()
38
+        except IntegrityError:
39
+            db.session.rollback()

+ 32
- 0
app/models/contributor.py View File

@@ -0,0 +1,32 @@
1
+from .. import db
2
+
3
+class Contributor(db.Model):
4
+    __tablename__ = 'contributors'
5
+    id = db.Column(db.Integer, primary_key=True)
6
+    name = db.Column(db.String(128))
7
+    status = db.Column(db.String(128))
8
+    bio = db.Column(db.Text)
9
+    podcasts = db.relationship('Podcast',
10
+                secondary='publications')
11
+
12
+    def __str__(self):
13
+        return self.name
14
+
15
+    @staticmethod
16
+    def fake_feed(count=10):
17
+        """ Randomly feeds the database """
18
+        from sqlalchemy.exc import IntegrityError
19
+        from random import seed
20
+        import forgery_py
21
+
22
+        seed()
23
+        for i in range(count):
24
+            c = Contributor(
25
+                name = forgery_py.name.full_name(),
26
+                status = forgery_py.lorem_ipsum.word(),
27
+                bio = forgery_py.lorem_ipsum.sentence())
28
+            db.session.add(c)
29
+        try:
30
+            db.session.commit()
31
+        except IntegrityError:
32
+            db.session.rollback()

+ 31
- 0
app/models/event.py View File

@@ -2,10 +2,41 @@ from .. import db
2 2
 from datetime import datetime
3 3
 
4 4
 class Event(db.Model):
5
+    """ An agenda item """
6
+
5 7
     __tablename__ = 'events'
6 8
     id = db.Column(db.Integer, primary_key=True)
7 9
     title = db.Column(db.String(256))
10
+    """ Event's title """
8 11
     place = db.Column(db.String(128))
12
+    """ Location """
9 13
     begin = db.Column(db.DateTime)
14
+    """ Date of the event's beggining """
10 15
     end = db.Column(db.DateTime)
16
+    """ Date of the event's ending """
11 17
     desc = db.Column(db.Text)
18
+    """ Description of the event """
19
+    label_id = db.Column(db.Integer, db.ForeignKey('labels.id'))
20
+    """ Label of the event """
21
+
22
+    @staticmethod
23
+    def fake_feed(count=10):
24
+        """ Randomly feeds the database """
25
+        from sqlalchemy.exc import IntegrityError
26
+        from random import seed
27
+        import forgery_py
28
+
29
+        seed()
30
+        for i in range(count):
31
+            e = Event(
32
+                title = forgery_py.lorem_ipsum.title(),
33
+                place = forgery_py.address.street_address(),
34
+                begin = forgery_py.date.date(),
35
+                end = forgery_py.date.date(),
36
+                desc = forgery_py.lorem_ipsum.paragraph()
37
+            )
38
+            db.session.add(e)
39
+        try:
40
+            db.session.commit()
41
+        except IntegrityError:
42
+            db.session.rollback()

+ 33
- 0
app/models/label.py View File

@@ -0,0 +1,33 @@
1
+from .. import db
2
+
3
+class Label(db.Model):
4
+    """ Collectives and broadcasts """
5
+    __tablename__ = "labels"
6
+    id = db.Column(db.Integer, primary_key=True)
7
+    name = db.Column(db.String(128))
8
+    desc = db.Column(db.Text)
9
+    #label_id = db.relationship('Label', backref='label', lazy=True)
10
+    podcasts = db.relationship('Podcast', backref='label', lazy=True)
11
+    sections = db.relationship('Section', backref='label', lazy=True)
12
+    blogPosts = db.relationship('BlogPost', backref ='label', lazy=True)
13
+
14
+    def __str__(self):
15
+        return self.name
16
+
17
+    @staticmethod
18
+    def fake_feed(count=10):
19
+        from sqlalchemy.exc import IntegrityError
20
+        from random import seed
21
+        import forgery_py
22
+
23
+        seed()
24
+        for i in range(count):
25
+            l = Label(
26
+                name = forgery_py.lorem_ipsum.title(),
27
+                desc = forgery_py.lorem_ipsum.paragraph()
28
+            )
29
+            db.session.add(l)
30
+        try:
31
+            db.session.commit()
32
+        except IntegrityError:
33
+            db.session.rollback()

+ 0
- 20
app/models/meta.py View File

@@ -1,20 +0,0 @@
1
-from .. import db
2
-
3
-class Label(db.Model):
4
-    __tablename__ = "labels"
5
-    id = db.Column(db.Integer, primary_key=True)
6
-    name = db.Column(db.String(128))
7
-    desc = db.Column(db.Text)
8
-    podcasts = db.relationship('Podcast', backref='label', lazy=True)
9
-    sections = db.relationship('Section', backref='label', lazy=True)
10
-    blogPosts = db.relationship('BlogPost', backref ='label', lazy=True)
11
-
12
-    def __str__(self):
13
-        return self.name
14
-
15
-class Tag(db.Model):
16
-    __tablename__ = "tags"
17
-    id = db.Column(db.Integer, primary_key=True)
18
-    name = db.Column(db.String(128))
19
-    podcast_id = db.Column(db.Integer, db.ForeignKey('podcasts.id'))
20
-    section_id = db.Column(db.Integer, db.ForeignKey('sections.id'))

+ 34
- 0
app/models/page.py View File

@@ -0,0 +1,34 @@
1
+from .. import db
2
+
3
+class Page(db.Model):
4
+    """ Pages """
5
+    __tablename__ = 'pages'
6
+    id = db.Column(db.Integer, primary_key=True)
7
+    title = db.Column(db.String(256))
8
+    desc = db.Column(db.Text)
9
+    label_id = db.Column(db.Integer, db.ForeignKey('labels.id'))
10
+
11
+    @staticmethod
12
+    def fake_feed(count=10):
13
+        """ Randomly feeds the database """
14
+        from sqlalchemy.exc import IntegrityError
15
+        from random import seed, randint
16
+        import forgery_py
17
+
18
+        seed()
19
+        about = Page(
20
+            title = "À propos",
21
+            desc = forgery_py.lorem_ipsum.paragraphs(quantity=10)
22
+        )
23
+        db.session.add(about)
24
+        for i in range(count):
25
+            p = Page(
26
+                title = forgery_py.lorem_ipsum.title(),
27
+                desc = forgery_py.lorem_ipsum.paragraphs(quantity=9),
28
+                label_id = randint(0, 10),
29
+            )
30
+            db.session.add(p)
31
+        try:
32
+            db.session.commit()
33
+        except IntegrityError:
34
+            db.session.rollback()

+ 44
- 5
app/models/podcast.py View File

@@ -1,32 +1,71 @@
1 1
 from .. import db
2 2
 from datetime import datetime
3
-from .author import Author
3
+from .contributor import Contributor
4 4
 from .section import Section
5
-from .meta import Label, Tag
5
+from .label import *
6
+from .tag import *
6 7
 
8
+""" Taxonomy table """
7 9
 publications = db.Table('publications',
8 10
     db.Column('podcast_id', db.Integer, db.ForeignKey('podcasts.id'), primary_key=True),
9
-    db.Column('author_id', db.Integer, db.ForeignKey('authors.id'), primary_key=True))
11
+    db.Column('contributor_id', db.Integer, db.ForeignKey('contributors.id'), primary_key=True))
10 12
 
13
+""" Podcasts class and table """
11 14
 class Podcast(db.Model):
12 15
     __tablename__ = 'podcasts'
13 16
     id = db.Column(db.Integer, primary_key=True)
17
+    """ Title of the podcast """
14 18
     title = db.Column(db.String(256))
15
-    authors = db.relationship('Author',
19
+    """ Contibutors authoring the podcast """
20
+    contributors = db.relationship('Contributor',
16 21
                 secondary='publications',
17 22
                 lazy='select',
18 23
                 back_populates='podcasts')
24
+    """ Sections of the podcast """
19 25
     sections = db.relationship('Section',
20 26
                 backref=db.backref('podcast', lazy='select'),
21 27
                 lazy='select')
28
+    """ Description of the podcast """
22 29
     desc = db.Column(db.Text)
30
+    """ Label of the podcast """
23 31
     label_id = db.Column(db.Integer, db.ForeignKey('labels.id'))
32
+    """ Date of publication """
24 33
     date = db.Column(db.Date, default=datetime.utcnow)
34
+    """ Mood of the podcast """
25 35
     mood = db.Column(db.SmallInteger)
36
+    """ Link to the audio file """
26 37
     link = db.Column(db.String(256))
38
+    """ Type : musical or non-musical """
27 39
     type = db.Column(db.Boolean())
40
+    """ Tags of the podcasts """
28 41
     tags = db.relationship('Tag',
29 42
                 backref=db.backref('podcasts', lazy='select'),
30 43
                 lazy='select')
31
-    timestamp = db.Column(db.DateTime, default=datetime.utcnow)
44
+    """ Datetime of publication """
45
+    timestamp = db.Column(db.DateTime, primary_key=True, default=datetime.utcnow)
46
+    """ State of te publication """
32 47
     public = db.Column(db.Boolean())
48
+
49
+    @staticmethod
50
+    def fake_feed(count=100):
51
+        """ Randomly feed the database """
52
+        from sqlalchemy.exc import IntegrityError
53
+        from random import seed, randint, choice
54
+        import forgery_py
55
+
56
+        seed()
57
+        for i in range(count):
58
+            p = Podcast(
59
+                title = forgery_py.lorem_ipsum.title(),
60
+                desc = forgery_py.lorem_ipsum.paragraph(),
61
+                label_id = randint(0, 10),
62
+                mood = choice(['slow', 'medium', 'fast']),
63
+                link = choice([
64
+                    'http://podcast.radiorhino.eu/Émissions/Cachemire%20Darbuqqa/Cachemire%20épisode%201.mp3',
65
+                    'http://podcast.radiorhino.eu/Émissions/Cachemire%20Darbuqqa/Cachemire%20épisode%202.mp3',
66
+                    'http://podcast.radiorhino.eu/Émissions/Cachemire%20Darbuqqa/Cachemire%20épisode%205.mp3',
67
+                    'http://podcast.radiorhino.eu/Émissions/Cachemire%20Darbuqqa/Cachmire%20épisode%206-1.mp3',
68
+                    'http://podcast.radiorhino.eu/Émissions/Cachemire%20Darbuqqa/cachemire%20darbuqqa%2012-1%20fausse%20stéréo.mp3']),
69
+                type = choice([True, False]),
70
+                public = True
71
+            )

+ 29
- 1
app/models/section.py View File

@@ -2,13 +2,41 @@ from .. import db
2 2
 from datetime import datetime
3 3
 
4 4
 class Section(db.Model):
5
+    """ Podcast sections """
5 6
     __tablename__ = "sections"
6 7
     id = db.Column(db.Integer, primary_key=True)
7 8
     title = db.Column(db.String(256))
9
+    """ Title of the section """
8 10
     desc = db.Column(db.Text)
9
-    author_id = db.Column(db.Integer, db.ForeignKey('authors.id'))
11
+    """ Description """
12
+    contributor_id = db.Column(db.Integer, db.ForeignKey('contributors.id'))
13
+    """ Contributor's ID """
10 14
     podcast_id = db.Column(db.Integer, db.ForeignKey('podcasts.id'))
15
+    """ Podcast's ID """
11 16
     label_id = db.Column(db.Integer, db.ForeignKey('labels.id'))
17
+    """ Label's ID"""
12 18
     begin = db.Column(db.Time)
19
+    """ Beginning of the section """
13 20
     end = db.Column(db.Time)
21
+    """ Ending of the section """
14 22
     timestamp = db.Column(db.DateTime, default=datetime.utcnow)
23
+    """ Date and time of creation """
24
+
25
+    @staticmethod
26
+    def fake_feed(count=10):
27
+        """ Randomly feeds the database """
28
+        from sqlalchemy.exc import IntegrityError
29
+        from random import seed, randint
30
+        import forgery_py
31
+
32
+        seed()
33
+        for i in range(count):
34
+            s = Section(
35
+                title = forgery_py.lorem_ipsum.title(),
36
+                desc = forgery_py.lorem_ipsum.paragraph()
37
+            )
38
+            db.session.add(s)
39
+        try:
40
+            db.session.commit()
41
+        except IntegrityError:
42
+            db.session.rollback()

+ 31
- 0
app/models/tag.py View File

@@ -0,0 +1,31 @@
1
+from .. import db
2
+
3
+class Tag(db.Model):
4
+    """ Tags of the podcasts """
5
+    __tablename__ = "tags"
6
+    id = db.Column(db.Integer, primary_key=True)
7
+    name = db.Column(db.String(128))
8
+    """ Name of the tag """
9
+    podcast_id = db.Column(db.Integer, db.ForeignKey('podcasts.id'))
10
+    """ Podcast """
11
+    section_id = db.Column(db.Integer, db.ForeignKey('sections.id'))
12
+    """ Section """
13
+
14
+    @staticmethod
15
+    def fake_feed(count=10):
16
+        """ Randomly feeds the database """
17
+        from sqlalchemy.exc import IntegrityError
18
+        from random import seed, randint
19
+        import forgery_py
20
+
21
+        seed()
22
+        for i in range(count):
23
+            t = Tag(
24
+                name = forgery_py.lorem_ipsum.word(),
25
+                podcast_id = randint(0,100)
26
+            )
27
+            db.session.add(t)
28
+        try:
29
+            db.session.commit()
30
+        except IntegrityError:
31
+            db.session.rollback()

+ 3
- 2
app/templates/about.html View File

@@ -2,6 +2,7 @@
2 2
 
3 3
 {% block main %}
4 4
 
5
-<h2>Radio Rhino c'est des gens qui parlent et qui écoutent de la musique</h2>
5
+<h2>{{ page.title }}</h2>
6
+{{ page.desc }}
6 7
 
7
-{% endblock %}
8
+{% endblock %}

BIN
data-dev.sqlite View File


+ 6
- 6
doc/conf.py View File

@@ -53,7 +53,7 @@ master_doc = 'index'
53 53
 # General information about the project.
54 54
 project = 'Rhino CMS'
55 55
 copyright = '2017, Hackstub'
56
-author = 'Hackstub'
56
+contributor = 'Hackstub'
57 57
 
58 58
 # The version info for the project you're documenting, acts as replacement for
59 59
 # |version| and |release|, also used in various other places throughout the
@@ -142,7 +142,7 @@ latex_elements = {
142 142
 
143 143
 # Grouping the document tree into LaTeX files. List of tuples
144 144
 # (source start file, target name, title,
145
-#  author, documentclass [howto, manual, or own class]).
145
+#  contributor, documentclass [howto, manual, or own class]).
146 146
 latex_documents = [
147 147
     (master_doc, 'RhinoCMS.tex', 'Rhino CMS Documentation',
148 148
      'Hackstub', 'manual'),
@@ -152,21 +152,21 @@ latex_documents = [
152 152
 # -- Options for manual page output ---------------------------------------
153 153
 
154 154
 # One entry per manual page. List of tuples
155
-# (source start file, name, description, authors, manual section).
155
+# (source start file, name, description, contributors, manual section).
156 156
 man_pages = [
157 157
     (master_doc, 'rhinocms', 'Rhino CMS Documentation',
158
-     [author], 1)
158
+     [contributor], 1)
159 159
 ]
160 160
 
161 161
 
162 162
 # -- Options for Texinfo output -------------------------------------------
163 163
 
164 164
 # Grouping the document tree into Texinfo files. List of tuples
165
-# (source start file, target name, title, author,
165
+# (source start file, target name, title, contributor,
166 166
 #  dir menu entry, description, category)
167 167
 texinfo_documents = [
168 168
     (master_doc, 'RhinoCMS', 'Rhino CMS Documentation',
169
-     author, 'RhinoCMS', 'One line description of project.',
169
+     contributor, 'RhinoCMS', 'One line description of project.',
170 170
      'Miscellaneous'),
171 171
 ]
172 172
 

+ 3
- 1
manage.py View File

@@ -2,17 +2,19 @@ import os
2 2
 from app import create_app, db
3 3
 from flask_script import Manager, Shell
4 4
 from flask_migrate import Migrate, MigrateCommand
5
+from app.commands import *
5 6
 
6 7
 app = create_app(os.getenv('FLASK_CONFIG') or 'default')
7 8
 manager = Manager(app)
8 9
 
9
-
10 10
 def make_shell_context():
11 11
     return dict(app=app, db=db)
12 12
 
13 13
 migrate = Migrate(app, db)
14 14
 manager.add_command('db', MigrateCommand)
15 15
 manager.add_command('shell', Shell(make_context=make_shell_context))
16
+manager.add_command('nuke', NukeCommand(db))
17
+manager.add_command('lorem', LoremCommand(db))
16 18
 
17 19
 if __name__ == '__main__':
18 20
     manager.run()

Loading…
Cancel
Save