Web app for browsing, rating and commenting contact points of organisations.
Themes are not bundled. Main theme is located at: obshtestvo/signali-theme
Place the default or your theme in the themes
directory and set its name as value for THEME
setting.
If using Debian you can read through a basic debian.sh
edit it to fit you setup and execute it.
The following is not made into a script, because it varies per distribution and it's good for educational purposes
- python3
- postgres
- redis
- image manipulation libraries
- gettext
# depending on distribution you might want to install
# python-dev, python-devel, or python3-devel libpq-dev
# postgresql-devel postgresql-... python3-venv
# for correct mimetypes installing or updating the `mailcap`
# package on a RedHat-based distribution, or `mime-support` on a Debian distribution.
sudo su - postgres
psql
SHOW hba_file;
vim <the path to hba file>
# change `host all all 127.0.0.1/32 ident` to md5
# image manipulation support
# for debian-based: apt-get install libjpeg62 libjpeg62-dev zlib1g-dev
# redis should be smth like: apt-get install redis-server
The following is not made into a script, because it serves educational purposes
cd <project dir>
# create virtualenv (skip if you already have one)
python3 -m venv ./env/.virtualenv
# activate virtual environment (if not already active)
source env/.virtualenv/bin/activate # (or activate.fish)
# install server requirements
pip install -r env/requirements.txt # (if errors appear, try installing only Django first)
# install client requirements
(cd src/signali.bg-theme && bower install)
# create postgres user & database
sudo su - postgres
createuser -S -D -R -P signali
createdb -O signali signali -E utf-8 -l bg_BG.utf8 -T template0
# set local settings
cp env/.django-sample env/.django
<...edit .django to your needs ....>
# include src in PYTHONPATH
export PYTHONPATH=$PWD/src # (or set -x PYTHONPATH $PWD/src for fish shell)
# initialise db
python manage.py migrate
# IF DEVELOPING ON LOCAL: load data seed
bash env/utils/load_dev_fixtures.sh
# run signali
python manage.py runserver
# go to http://127.0.0.1:8000/
cd signali
export PYTHONPATH=$PWD/src # (or set -x PYTHONPATH $PWD/src )
source env/.virtualenv/bin/activate # (or activate.fish)
python manage.py runserver
# go to http://127.0.0.1:8000/
You must have a cloned version of the repo on your deployment server and exported sensitive settings as environment variables or
defined as env/.django
entries.
Execute the command in the previous "Usual development start" section and then:
cd env
fab debloy:live,static # or fab deploy:live
### Architecture decisions
#### Conventions
- This project tries to follow most of the [12factor](http://12factor.net/) specs with addition of some
**REST**ful conventions provided by the [django-restful](https://github.com/obshtestvo-utilities/django-restful) package.
Other common good practices are also followed.
Example conventions followed:
- not in the way, only use what you want from the conventions, i.e. it can work as standard django install
- handle all errors in one place
- all requests and all calls should be as stateless as possible, pass what you need
- all http methods should be simulatable, be careful to use original `POST` values when dealing with sensitive request data
- response format should be extracted from http header but should also be simulatable
- template names can be auto-detected based on Controller name and request method, so they should
- developers should have full control of data transformation in the template for any format
- DRY, use single codebase where possible
- always think modular, extract logic in topical modules, not simply `/common`
- if requesting html (*commonly web browsers*) always redirect after anything other than 'GET'
- let html be html, don't use framework-specific or package-specific html generators (like form-element generators)
#### Specificity
- Sensitive settings and those specific to deployment are retrieved from ENV variables or `.django` file in the `env`
directory
- If you are simply making a deployment you shouldn't have to modify the `src` directory. The `env` directory holds
all environment-specific settings. If this is not the case please open an issue or submit a pull request. Changing
things in `src` should only happen when you want to change the functionality of the project
- `env` directory holds settings specific to deployment environment:
- server settings - debian install script, nginx sample, uwsgi sample,
- project dependencies descriptor
- environment-specific project settings
- the downloaded project dependencies
- `src` directory is not "*just API*". It holds all sorts server-code and non-html templates
- `themes` directory is where you can place your themes. Deployment procedure expects `build.sh` script to exist
in each theme root directory. This script is responsible for compiling assets in the `build` directory of the theme.
- The `user` and `security` apps has similar purposes
- The main difference between `user` app and `security` app is that `user` app includes the more project-specific
user things (like prepping pages and forms for login, profile editing, and making use of `security` app ).
The `security` app also includes user-related stuff but it limits itself to more generic and security-related
logic (auth, validation, tokens, logout).
- The logic for the data checkpoint in the signup process is in `user` app instead of `security` app. The logic is closer to
the security app because it handles required data before the user is allowed to register, **but** that data usually changes
from project to project which goes against keeping `security` app the more reusable one
- To read more about how auth was implemented look into [`python-social-auth` developer intro](https://github.com/omab/python-social-auth/blob/master/docs/developer_intro.rst)
### Common scenarios
#### Handling success or error, in a django view:
Example 1:
```python
failure = VerboseException("Error occurred") # prepare for failure
# ... error happens
failure.add_error('password', "Password too long")
failure.add_error('email', "Not a valid email")
raise failure
# ...
The code above will render a error/get
template, (or other defined by the RESTFUL_ERROR_TEMPLATE
setting) and
pass all errors to it.
Example 2:
failure = VerboseHtmlOnlyRedirectException("Error occurred").set_redirect('route-name')
# ...
failure.add_error('password', "Password too long")
failure.add_error('email', "Not a valid email")
raise failure
# ...
The code above will behave the same as "Example 1" unless the client requests data in html format (or doesn't specify format),
which is the common case for browsers.
If the client requests html response the code above will put all errors in a session variable
and redirect to route-name
. Useful when you want to show errors in the same form the input originated from.
Example 1:
return {
'result': "Successfully created a new user",
'user_id': 2,
}
The code above will render a template named the same as the method, located in a directory named the same as the class.
I.e.: Rendering users/post.html
.
Note: The file extension is automatically added based on the "Accepted-Type" header.
Example 2:
return HtmlOnlyRedirectSuccessDict({
'result': "Successfully created a new user",
'user_id': 2,
}).set_redirect('route-name')
The code above will behave the same as "Example 1" unless the client requests html response.
If the client requests html response the code above will put all data in a session variable and
redirect to route-name
. Useful when you want to redirect users to the page they originated from.
It's recommended to have pyinotify
installed on your system for more performant dev server reloading
If you're not familiar with Postgres but you are with Mysql this article could be useful.
The following will read a .ini
-like file and export each definition as environment variables.
export $(cat ./env/.django | xargs)
- Login as another user: impersonate or hijack
- Security checkup: https://github.com/carljm/django-secure