ref: 4060021d8528a01b556152163d80be1824d2359c fanboi2/migration d---------
Add scope column to banwords.
Add banwords (#46)

Merge rule and rule ban into ban (#45)

Closes #43 
Add admin panel (#26)

Massive cleanup in preparation for 0.30 (#25)

* Only use environment variable to configure the application.

  Closes #17

  In order to simplify deployment on containerized or 12-factor centric
  environment (such as Docker or Heroku) where writing configuration
  file is not preferrable.

  We also prefer to have only a single way to configure application,
  which means Pyramid-style ini configurations are now dropped in favor
  for environment variable.

* Refactor post utils into post filters

  Closes #23

  Akismet, DNSBL and proxy checking are now refactored into a 'filter'
  which can be easily extended.

* Replaced Beaker with PyNaCl-based session storage.

  This change switched session storage from Memcached-based session
  storage to a cookie-based session storage with strong encryption
  using PyNaCl.

* Replaced app-specific settings with setting model.

  Application specific settings are now stored in the database instead
  of configuration file as these configurations are not required
  for running the app and may require a bit more complicate data

* Add services layer

  Closes #18

  We've added services layer and successfully migrated the application
  to use services rather than calling components directly. This change
  will make it easier to extend as well as optimizing the application
  in the future.

  This change also allowed us to remove complexity from model, such as
  that post-commit hooks are now done within the services layer.
  Caching is also implemented in some services, such as settings.

* Explicitly setting up routes.

  We will add authentication and authorization, which requires
  flexibility on the routing configuration, which means the helper in
  its current form is no longer preferrable.

* Use Pyramid native CSRF implementation.

  We have now switched to Pyramid's native CSRF implementation instead
  of using home-grown SecureForm. This change resulted in a simplified
  form handling throughout the application.

* Replaced fb2 maintenance scripts.

  As we will have a proper admin interface, these scripts are no
  longer necessary and its usage are discouraged. Due to this, we are
  dropping all the maintenance scripts in favor for a more specific

* Remove PyCharm-style type annotations.

  To be replaced with Python 3.5-style type annotations in order to
  incorporate type checking with MyPy.

* Consolidate assets directory for concerns separation.

  Move all assets-related files into assets/ so it's clear that which
  files are responsible for compiling assets (and thus purgable after
  assets are compiled when building images).

* Convert JsonType field to native JSON field.

  SQLALchemy has since supported the native JSON field in PostgreSQL
  and it is no longer necessary to use our own implementation of JSON
  field that was a wrapper over Text.

* Cleanup migration files

  Styling fixes per Flake8.

* Update dependencies.

  Make sure dependencies are up-to-date.
Allow rule override to be scoped.
Add page model and views.

Allow creation of custom pages that may be use to store static content
such as guidelines or deletion policies. There also exists an
"internal pages" that are used for site customization.

Currently two internal pages are available:

* global_css — custom CSS that applies to every page.
* global_appendix — area that appear on top of footer on every page.

Any number of pages may be created.
Add rules system for evaluating rules based on IP address.

The rules system currently support two type of rules:

* Ban — disallow matched IP address to post in a board.
* Override — override board status for a certain IP address.

Each rule may be trigger on/off and may specify active period.
Allow boards to be restricted, locked and archived.

For moderation purpose. Behavior for each status is as follows:

* open — anyone may create new topic and post.
* restricted — nobody can create new topic but may post.
* locked — nobody may create new topic nor post.
* archived — same as locked, but board is no longer shown in the list.

In summary,

| Status     | Shown in list | New Topic | New Post |
| open       |      Yes      |    Yes    |    Yes   |
| restricted |      Yes      |    No     |    Yes   |
| locked     |      Yes      |    No     |    No    |
| archived   |      No       |    No     |    No    |
Use topic_meta for topic metadata retrieval instead of subquery

Since we now allow posts to be deleted and the post may be restored
later, topic metadata such as post count now need to explicitly tracked
somewhere (since we can no longer reuse post.number).
Index naming convention and schema housekeeping.

This commit breaks ability to migrate from existing application to newer
version due to a change in migration ID format. It is highly recommend
to dump the database with data only and restore it to a database, e.g.

    $ pg_dump -T alembic_version -a -Fc > fanboi2.dump
    $ psql template1 -c "DROP DATABASE fanboi2;"
    $ psql template1 -c "CREATE DATABASE fanboi2;"
    $ alembic upgrade c71cae24d111
    $ pg_restore -O -x -a -d fanboi2 fanboi2.dump
    $ alembic upgrade head
Integrate versioned with existing models.
Project directory restructure.

Move resources out of fanboi2 package into its own "assets" directory
in order to make fanboi2 package consist mostly of Python-related

Sample configuration are also moved to examples/ directory with
a README accordingly.
Merge branch 'feature/sage-post' into develop
Add bumped field to post.

Similar to Topic.posted_at but Topic.bumped_at will query a post that
was last created with Post.bumped flag set to True.
Store user name and display with post.

This name is inherited from board and saved so that when we changed
board settings, old post name don't get changed.
Add topic status, post limit and auto-archiving.

When topic reaches max_posts set within board, its status will now
automatically changed to "archived". When topic is archived, user could
not create any more post on that topic. Two other statuses are "open"
and "locked", the former being default and enables posting and the
latter is like archived, but used when explicitly locked by moderators.
Add script for updating board info.

* Add agreements field to board for displaying posting agreement.
* Add description field for board list.
Add helper functions for datetime handling.

Also make datetime field timezone-aware since we're doing TZ conversion
on display (defaults to Bangkok with UTC as datetime attribute.)
Merge branch 'feature/py3' into develop