Commit 9103196a authored by okhin's avatar okhin

Merge branch 'django-1.8' into 'master'

Django 1.8

Moving all code to django 1.8, updating the javascript library, removng dead dependencies, updating the modules.

Rewrote the full map system with d3 + datamaps instead of Kartograph + Chloro.

See merge request !1
parents c11e56f6 ce5d11ba
nnmon the bugtracker for teh internetz
======================================
# Net Neutrality MONitor
nnmon is the project running [respectmynet.eu](http://respectmynet.eu/).
This django application is used to collect data about net neutrality violation,
to allow a name and shame policy.
Installation
------------
# Setup
You have to clone this branch (django-1.8) to get the latest source code.
The recommended way is to use a virtualenv and to run the app through apache and
uwsgi.
## System dependencies
You need to install some development package to activate al the needed python
modules.
sudo apt-get install libxml2-dev libxslt-dev build-essential python-dev libsqlite3-dev libjpeg-dev zlib1g-dev libapache2-mod-uwsgi libapache2-mod-wsgi uwsgi-plugin-python libfreetype6-dev uwsgi
## Create a virtualenv
The recommended way is to install a python-virtualenv and to run the django
application from there.
virtualenv nnmon-env
source nnmon-env/bin/activate
## Get the source
You need to git clone the repository:
git clone http://git.laquadrature.net/la-quadrature-du-net/respect-my-net.git respect-my-net
## Install the module dependencies
Now, you need to install all the needed python modules, with pip.
pip install --upgrade -r nnmon-requirements.txt
## Configure django
Edit the configuration file for django. Pay special attention to DEBUG, various
path and SECRET_KEY settings. Next you need to setup the database, using the
manage.py tool.
python manage.py migrate
## Set-up uwsgi
You need to create an application for uwsgi. Create a file in
/etc/uwsgi/apps-available with the fllowing content. Adapat to your needs and
read the documentation:
[uwsgi]
plugins = python
uid = www-data
pythonpath = /home/rmn/respect-my-net
module = nnmon.wsgi:application
env = DJANGO_SETTINGS_MODULE=nnmon.settings
chdir = /home/rmn/respect-my-net
home = /home/rmn/nnmon-env
vacuum = True
master = True
max-requests = 5000
pidfile = /run/uwsgi/app/rmn/pid
daemonize = /var/log/uwsgi/rmn.log
socket = /run/uwsgi/app/rmn/socket
PythonPath is where the django app is based (ie: the root of the git
repository), chdir is the same path. Home, is the path of the virtualenv created
above.
Now you need to activate the apps by creating a symoblic link into
/etc/uwsgi/apps-enabled, and to restart uwsgi.
cd /etc/uwsgi/apps-enabled
ln -s ../apps-available/nnmond.conf
service restart uwsgi
## Set-up apache
You need to setup apache (or nginx depending on what you prefer). First, you
need to actvivate the uwsgi module:
a2enmod uwsgi
service apache2 restart
And now you need to create a VirtualHost in
/etc/apache2/sites-availabe/nnmon.conf
<virtualhost *:80>
ServerName rmn.example.com
SetHandler uwsgi-handler
uWSGISocket /run/uwsgi/app/rmn/socket
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %T
%{Host}i" alternc
CustomLog /var/log/apache2/access.log alternc
ErrorLog /var/log/apache2/rmn.error.log
</virtualhost>
You need to activate the website and the to reload apache. Of course, for
production use, you should use a TLS VirtualHost.
a2ensite nnmon
service apache2 reload
See [/docs/SETUP.md](nnmon/blob/master/docs/SETUP.md)
[extractors]
django = babeldjango.extract:extract_django
[django: templates/*.*]
[django: templates/comments/*.*]
[python: bt/**.py]
This diff is collapsed.
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding model 'Operator'
db.create_table('bt_operator', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('name', self.gf('django.db.models.fields.CharField')(max_length=256)),
('logo', self.gf('django.db.models.fields.files.ImageField')(max_length=100, null=True, blank=True)),
))
db.send_create_signal('bt', ['Operator'])
# Adding field 'Violation.operator_ref'
db.add_column('bt_violation', 'operator_ref',
self.gf('django.db.models.fields.related.ForeignKey')(related_name='violations', null=True, to=orm['bt.Operator']),
keep_default=False)
def backwards(self, orm):
# Deleting model 'Operator'
db.delete_table('bt_operator')
# Deleting field 'Violation.operator_ref'
db.delete_column('bt_violation', 'operator_ref_id')
models = {
'bt.attachment': {
'Meta': {'object_name': 'Attachment'},
'comment': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['bt.Comment']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '512'}),
'storage': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
'type': ('django.db.models.fields.CharField', [], {'max_length': '512'})
},
'bt.comment': {
'Meta': {'object_name': 'Comment'},
'comment': ('django.db.models.fields.TextField', [], {}),
'consent': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'submitter_email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}),
'submitter_name': ('django.db.models.fields.CharField', [], {'max_length': '20'}),
'timestamp': ('django.db.models.fields.DateTimeField', [], {}),
'violation': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['bt.Violation']"})
},
'bt.confirmation': {
'Meta': {'object_name': 'Confirmation'},
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'key': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
'violation': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['bt.Violation']"})
},
'bt.featuredcase': {
'Meta': {'object_name': 'FeaturedCase'},
'case': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['bt.Violation']", 'unique': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
},
'bt.operator': {
'Meta': {'object_name': 'Operator'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'logo': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '256'})
},
'bt.violation': {
'Meta': {'object_name': 'Violation'},
'activationid': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}),
'contract': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}),
'contract_excerpt': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'contractual': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'country': ('django.db.models.fields.CharField', [], {'max_length': '2'}),
'editorial': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'loophole': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'media': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}),
'operator': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
'operator_ref': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'violations'", 'null': 'True', 'to': "orm['bt.Operator']"}),
'resource': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}),
'resource_name': ('django.db.models.fields.CharField', [], {'max_length': '4096', 'blank': 'True'}),
'state': ('django.db.models.fields.CharField', [], {'default': "'new'", 'max_length': '20', 'blank': 'True'}),
'temporary': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'type': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'})
}
}
complete_apps = ['bt']
\ No newline at end of file
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import DataMigration
from django.db import models
class Migration(DataMigration):
def forwards(self, orm):
"Populate new operator foreign key field"
for violation in orm['bt.Violation'].objects.all():
operator, created = orm['bt.Operator'].objects.get_or_create(name=violation.operator)
violation.operator_ref = operator
violation.save()
def backwards(self, orm):
"No need for backward pass"
pass
models = {
'bt.attachment': {
'Meta': {'object_name': 'Attachment'},
'comment': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['bt.Comment']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '512'}),
'storage': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
'type': ('django.db.models.fields.CharField', [], {'max_length': '512'})
},
'bt.comment': {
'Meta': {'object_name': 'Comment'},
'comment': ('django.db.models.fields.TextField', [], {}),
'consent': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'submitter_email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}),
'submitter_name': ('django.db.models.fields.CharField', [], {'max_length': '20'}),
'timestamp': ('django.db.models.fields.DateTimeField', [], {}),
'violation': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['bt.Violation']"})
},
'bt.confirmation': {
'Meta': {'object_name': 'Confirmation'},
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'key': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
'violation': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['bt.Violation']"})
},
'bt.featuredcase': {
'Meta': {'object_name': 'FeaturedCase'},
'case': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['bt.Violation']", 'unique': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
},
'bt.operator': {
'Meta': {'object_name': 'Operator'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'logo': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '256'})
},
'bt.violation': {
'Meta': {'object_name': 'Violation'},
'activationid': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}),
'contract': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}),
'contract_excerpt': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'contractual': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'country': ('django.db.models.fields.CharField', [], {'max_length': '2'}),
'editorial': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'loophole': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'media': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}),
'operator': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
'operator_ref': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'violations'", 'null': 'True', 'to': "orm['bt.Operator']"}),
'resource': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}),
'resource_name': ('django.db.models.fields.CharField', [], {'max_length': '4096', 'blank': 'True'}),
'state': ('django.db.models.fields.CharField', [], {'default': "'new'", 'max_length': '20', 'blank': 'True'}),
'temporary': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'type': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'})
}
}
complete_apps = ['bt']
symmetrical = True
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Deleting field 'Violation.operator'
db.delete_column('bt_violation', 'operator')
# Changing field 'Violation.operator_ref'
db.alter_column('bt_violation', 'operator_ref_id', self.gf('django.db.models.fields.related.ForeignKey')(default=0, to=orm['bt.Operator']))
def backwards(self, orm):
# Adding field 'Violation.operator'
db.add_column('bt_violation', 'operator',
self.gf('django.db.models.fields.CharField')(default=0, max_length=256),
keep_default=False)
# Changing field 'Violation.operator_ref'
db.alter_column('bt_violation', 'operator_ref_id', self.gf('django.db.models.fields.related.ForeignKey')(null=True, to=orm['bt.Operator']))
models = {
'bt.attachment': {
'Meta': {'object_name': 'Attachment'},
'comment': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['bt.Comment']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '512'}),
'storage': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
'type': ('django.db.models.fields.CharField', [], {'max_length': '512'})
},
'bt.comment': {
'Meta': {'object_name': 'Comment'},
'comment': ('django.db.models.fields.TextField', [], {}),
'consent': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'submitter_email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}),
'submitter_name': ('django.db.models.fields.CharField', [], {'max_length': '20'}),
'timestamp': ('django.db.models.fields.DateTimeField', [], {}),
'violation': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['bt.Violation']"})
},
'bt.confirmation': {
'Meta': {'object_name': 'Confirmation'},
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'key': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
'violation': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['bt.Violation']"})
},
'bt.featuredcase': {
'Meta': {'object_name': 'FeaturedCase'},
'case': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['bt.Violation']", 'unique': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
},
'bt.operator': {
'Meta': {'object_name': 'Operator'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'logo': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '256'})
},
'bt.violation': {
'Meta': {'object_name': 'Violation'},
'activationid': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}),
'contract': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}),
'contract_excerpt': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'contractual': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'country': ('django.db.models.fields.CharField', [], {'max_length': '2'}),
'editorial': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'loophole': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'media': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}),
'operator_ref': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'violations'", 'to': "orm['bt.Operator']"}),
'resource': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}),
'resource_name': ('django.db.models.fields.CharField', [], {'max_length': '4096', 'blank': 'True'}),
'state': ('django.db.models.fields.CharField', [], {'default': "'new'", 'max_length': '20', 'blank': 'True'}),
'temporary': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'type': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'})
}
}
complete_apps = ['bt']
\ No newline at end of file
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.contrib.comments.moderation import CommentModerator, moderator
from django_comments.moderation import CommentModerator, moderator
COUNTRIES = (
('BE', _('Belgium')),
......
......@@ -6,7 +6,7 @@ from django.conf import settings
from bt.models import Violation
from django.db.models import Count
import ooolib
import odslib
from django.utils.html import strip_tags
import re, htmlentitydefs
##
......
......@@ -2,7 +2,7 @@ from django.template import Library, Variable
from django.conf import settings
from django import template
import random
from nnmon.bt.models import COUNTRIES, STATUS, TYPES, MEDIA
from ..models import COUNTRIES, STATUS, TYPES, MEDIA
register = Library()
......
Reading emails in development mode
==================================
In development mode, emails are written in `/tmp/app-messages/`.
To find the last sent email use your funcky `ls` command: