- Login
- SQLAlchemy
- OpenID
- Markdown
- Script
- Cache
- Classy
- WTF
- Psycopg2
- Pygments
- Smartypants
- Python-memcached
- Alembic
The current markdown is based on python markdown with many extensions. For a detailed look at the python markdown documentation (http://pythonhosted.org/Markdown)
- extra
- sane_lists
- codehilite
- smartypants
The site design is mainly targeted to the readers. Some research has been made for the legibility of the content. Based on some readings the following are done:
- The font size is set at 16px to make the content more legible.
- discontinued usage of justification, seems it is a bad idea to use it.
- Administrator
- Moderator
- Author
- Member
- Author writes a Content [Draft] and submits for review [Review]
- Mails sent to all reviewers (based on the tags)
- Reviewer approves and article gets published [Published]
If there are no information provided then based on their comments, the reading style etc score will be generated for each topic/tag.
Every author will be a reviewer based on the subject matter expertise they have provided or that has been calculated. Moderators are appointed or auto upgraded based on the karma they have earned. There are no special badges like Stackoverflow, and no role identification in their miniprofile, but a star in their profile page will indicate that they are either moderators or administrators, and their email addresses will be visible to all members of the site, and cannot restrict messages from any user.
More than 500 words of content will automatically get categorized as Article
Short content targeted to supplement/comment an article. Any member can create a new/commentary.
Comments can be added for any content. Meaning comments can be added for a comment itself. That will effectively show up as threads.
The database is designed to have versions of every content in the site. Articles, comments, news, review comments, all have history of edits. The only exception to this is user specific data, like the user’s profile itself and the messages that a user has recieved. This means, when a message has been deleted there is not way to recover it. But, again, technically speaking, the message will not be deleted until both the parties involved “removes” the message from their “view”.
The database used in fossix is postgresql.
The database is designed to review comments, all have history of edits. The only exception to this is have versions of every content in the site. Articles, comments, news, user specific data, like the user’s profile itself and the messages that a user has recieved. This means, when a message has been deleted there is not way to recover it. But, again, technically speaking, the message will not be deleted until both the parties involved “removes” the message from their “view”.
select table_name from information_schema.tables where table_schema='public';
Date default setting could not be made through sql alchemy. The utcnow breaks migration, and sqlalchemy itself doesn’t seem to understand the NOW()/now() string as default in the database side. So we have to manually update if are going to create the tables anytime again.
alter table content_base alter column create_date set default now();
alter table content_versions alter column last_changed set default now();
Content History -> a table which stores history Content -> represents Articles, Comment and News User -> represents users and user profiles on the system Message -> stores messages sent and recieved between users OpenID -> Each user can attach multiple openID’s to his account Keywords -> Tags representing the content, can refer any Content
Column | Type | Modifiers |
---|---|---|
id | integer | not null, auto increment, pk |
version_num | integer | not null, index |
content_id | integer | not null, refers Content table |
content | text | not null |
tags | integer | not null, refers Keywords table |
title | varchar | not null, unique, index |
last_changed | date | not null |
changed by | integer | not null, refers User table |
state | integer | not null, [saved, approved, rejected, pending…] |
The table will have a unique constraint on both version_num and content_id, because it makes sense that there cannot be versions with two different version numbes for the same content.
Column | Type | Modifiers |
---|---|---|
id | integer | not null, auto increment, pk |
current_version | integer | refers history version_num |
create_date | date | not null, default: Today |
created_by | integer | references User table |
like_count | integer | default: 0 |
read_count | integer | default: 0 |
comment_count | integer | default: 0 |
type | integer | not null, [article, news, comment] |
refers_to | integer | refers to Content Table |
Column | Type | Modifiers |
---|---|---|
id | integer | not null, auto increment, pk |
from | integer | refers to User table |
to | integet | refers to User table |
message | varchar(300) | Not null |
Column | Type | Modifiers |
---|---|---|
id | integer | not null, auto increment, pk |
username | varchar(32) | not null, unique |
fullname | varchar(64) | |
varchar(150) | not null, unique | |
date_joined | date | not null |
role | integer | default: user, [user, author, moderator, admin] |
karma | integer | default: 0 |
email_misc | boolean | default: false |
email_alert | boolean | default: false |
status | integer | default: active, [active, blocked] |
Column | Type | Modifiers |
---|---|---|
id | integer | not null, auto increment, pk |
url | varchar(256) | not null |
user_id | integer | not null, refers User table |
Column | Type | Modifiers |
id | interger | not null, auto increment, pk |
keyword | varchar(25) | not null, unique |
Column | Type | Modifiers |
content_id | integer | refers Content Table |
keyword_id | integer | refers Keyword Table |
A content view from both content history table and content table.
Column |
---|
content_id |
version_num |
content |
tags |
last_changed |
changed_by |
state |
create_date |
created_by |
like_count |
read_count |
comment_count |
type |
refers_to |
This view is created manually in the postgresql database. SQLalchemy doesn’t have native support to create views, but can be done as answered in stackoverflow.
CREATE OR REPLACE VIEW content AS
SELECT a.content_id AS id, a.title, a.last_changed, a.changed_by,
a.state, a.version_num, b.read_count, b.like_count, b.comment_count,
b.refers_to from content_versions a, content_base b
where content_id=id and (a.content_id,a.version_num) in
(select content_id, max(version_num) from content_versions group by
content_id);
To open the database in shell, login as the postgres user and type psql fossixdb List all the tables - \dt View the structure of the table - \d TABLENAME
alembic revision -m “Some message regarding the upgrade” Edit the version scripts if needed and then alembic upgrade|downgrade version|head
- /article The last published article will be displayed
- /article/<id>/[<title>]
- /article/edit/<id> (Login required - author/moderator)
- /article/create (login required)
- /account/login
- /account/create
- /account/profile (login required)
- /account/edit[profile] (login required)
- /user/<username>
- /user/following
- /user/followers
- /moderate/comments (login required - moderator)
- /moderate/posts (login required - moderator)
- /moderate/users
- /about
- /about/<id>/<title>
- /sitemap [,.xml]
- /feed.[rss, json, xml]
- /api(?)
- App dispatcher - Combining multiple applications
- Flask Blueprints - Modular applications (new method)
- Lazy Loading - Don’t load all views at startup
- Flask Classy - Class based view, alternative to blueprints(?)