Commit 6d729d56 authored by okhin's avatar okhin 🚴

Merge branch '65-improve-coding-style' into 'master'

Resolve "improve coding style"

Closes #65

See merge request !58
parents 0161a2d3 ed14ab70
Pipeline #1027 passed with stage
in 16 seconds
from django.contrib import admin
from bt import models
class CommentInline(admin.TabularInline):
model = models.Comment
max_num = 1
model = models.Comment
max_num = 1
class ViolationAdmin(admin.ModelAdmin):
list_display = ('state', 'country', 'operator', 'contract', 'resource_name', 'media', 'activationid', 'old', 'creation_date')
list_filter = ('state', 'operator_ref', 'contract', 'resource_name', 'media', 'country', 'old')
inlines = [CommentInline, ]
list_display = ('state', 'country', 'operator', 'contract', 'resource_name', 'media', 'activationid', 'old', 'creation_date')
list_filter = ('state', 'operator_ref', 'contract', 'resource_name', 'media', 'country', 'old')
inlines = [CommentInline, ]
admin.site.register(models.Violation, ViolationAdmin)
class CommentAdmin(admin.ModelAdmin):
list_display = ('violation', 'submitter_name', 'comment')
list_filter = ('violation', 'submitter_name')
list_display = ('violation', 'submitter_name', 'comment')
list_filter = ('violation', 'submitter_name')
admin.site.register(models.Comment, CommentAdmin)
class AttachmentAdmin(admin.ModelAdmin):
list_display = ('name', 'comment')
list_display = ('name', 'comment')
admin.site.register(models.Attachment, AttachmentAdmin)
class ConfirmationAdmin(admin.ModelAdmin):
list_display = ('violation', 'key')
list_filter = ('violation__operator_ref', 'violation__contract', 'violation__resource_name', 'violation__media', 'violation__country')
list_display = ('violation', 'key')
list_filter = ('violation__operator_ref', 'violation__contract', 'violation__resource_name', 'violation__media', 'violation__country')
admin.site.register(models.Confirmation, ConfirmationAdmin)
class FeaturedCaseAdmin(admin.ModelAdmin):
pass
admin.site.register(models.FeaturedCase, FeaturedCaseAdmin)
class OperatorAdmin(admin.ModelAdmin):
list_display = ("__unicode__", "reported_violations")
search_fields = ('name', )
pass
admin.site.register(models.Operator, OperatorAdmin)
\ No newline at end of file
list_display = ("__unicode__", "reported_violations")
search_fields = ('name', )
pass
admin.site.register(models.Operator, OperatorAdmin)
#from django.contrib.auth.models import User
from tastypie import fields
from tastypie.authorization import DjangoAuthorization
from tastypie.resources import ModelResource, ALL, ALL_WITH_RELATIONS
from bt.models import Violation, Operator
#class UserResource(ModelResource):
# class UserResource(ModelResource):
# class Meta:
# queryset = User.objects.all()
# resource_name = 'auth/user'
# excludes = ['email', 'password', 'is_superuser']
class OperatorResource(ModelResource):
class OperatorResource(ModelResource):
class Meta:
queryset = Operator.objects.all()
list_allowed_methods = ['get', 'post']
......@@ -27,7 +25,8 @@ class OperatorResource(ModelResource):
class APIResource(ModelResource):
operator = fields.ForeignKey(OperatorResource, 'operator_ref')
# user = fields.ForeignKey(UserResource, 'user')
# user = fields.ForeignKey(UserResource, 'user')
class Meta:
queryset = Violation.objects.all()
......
......@@ -2,6 +2,7 @@ from django.contrib.syndication.views import Feed
from django.utils.feedgenerator import Atom1Feed
from bt.models import Violation
class RssSiteNewsFeed(Feed):
title = "NNMON - Latest NN Infringements"
link = "/"
......@@ -17,7 +18,7 @@ class RssSiteNewsFeed(Feed):
def item_title(self, item):
return "%s (%s) %s" % (item.operator, item.country, item.contract)
class AtomSiteNewsFeed(RssSiteNewsFeed):
feed_type = Atom1Feed
subtitle = RssSiteNewsFeed.description
......@@ -3,27 +3,30 @@ from django.conf import settings
from django.utils.translation import ugettext as _
from haystack.forms import SearchForm
from haystack.query import SearchQuerySet
from bt.models import Violation, COUNTRIES, RESOURCES, TYPES, MEDIA
from bt.models import COUNTRIES, RESOURCES, TYPES, MEDIA
from bt.multifile import MultiFileField
from operator import itemgetter
from captcha.fields import CaptchaField
class AdvancedEditor(forms.Textarea):
class Media:
js = (settings.MEDIA_URL+'/js/tinymce/tiny_mce.js',)
js = (settings.MEDIA_URL + '/js/tinymce/tiny_mce.js', )
def __init__(self, language=None, attrs=None):
self.language = language or settings.LANGUAGE_CODE[:2]
self.attrs = {'class': 'advancededitor'}
if attrs: self.attrs.update(attrs)
if attrs:
self.attrs.update(attrs)
super(AdvancedEditor, self).__init__(attrs)
class AddViolation(forms.Form):
resource_name = forms.CharField(required=True, max_length=4096, label=_('Please describe the discrimination'), help_text=_("What service or site, or person is unavailable or seems artificially slowed down. e.g. VoIP, p2p, filesharing, specific websites, etc."))
country = forms.ChoiceField(required=True, choices=(('',''),)+tuple(sorted(COUNTRIES,key=itemgetter(1))), label=_("Country"), help_text=_('EU member state where the discrimination is reported.'))
country = forms.ChoiceField(required=True, choices=(('', ''), ) + tuple(sorted(COUNTRIES, key=itemgetter(1))), label=_("Country"), help_text=_('EU member state where the discrimination is reported.'))
operator = forms.CharField(required=True, max_length=256, label=_("Operator"), help_text=_('The ISP or operator providing the Internet service.'))
contract = forms.CharField(required=True, max_length=256, label=_("Contract"), help_text=_('The specific contract at the ISP provider. (please be as specific as possible)'))
media = forms.ChoiceField(required=True, choices=tuple(sorted(MEDIA,key=itemgetter(1))), label=_('Is the Internet connection over mobile or fixed line?'))
media = forms.ChoiceField(required=True, choices=tuple(sorted(MEDIA, key=itemgetter(1))), label=_('Is the Internet connection over mobile or fixed line?'))
comment = forms.CharField(required=True, widget=AdvancedEditor(), label=_('Please describe the symptoms you are experiencing.'))
email = forms.EmailField(required=True, label=_('Email (set this to enable saving)'), help_text=_("We need your email to validate your report. Your email address is obligatory, but we will never use your personal data for anything else than checking the submission. (see next for an optional exception)"))
consent = forms.BooleanField(required=False, label=_("I want to help further"), help_text=_("We need your consent to contact you for clarifications regarding your report. This is optional, but helps us improve the quality of the reports. Thanks!"))
......@@ -37,11 +40,12 @@ class AddViolation(forms.Form):
type = forms.ChoiceField(required=True, choices=tuple(TYPES), label=_('How would you describe the discrimination?'))
captcha = CaptchaField(label=_("In order to protect against spam, please fill in the result of the following calculation. (note the + and the * are somewhat confusing)"))
class SearchViolation(SearchForm):
country = forms.ChoiceField(required=False, choices=(('',''),)+tuple(sorted(COUNTRIES,key=itemgetter(1))), label=_("Country"), help_text=_('EU member state where the discrimination is reported.'))
country = forms.ChoiceField(required=False, choices=(('', ''),) + tuple(sorted(COUNTRIES, key=itemgetter(1))), label=_("Country"), help_text=_('EU member state where the discrimination is reported.'))
operator = forms.CharField(required=False, max_length=256, label=_("Operator"), help_text=_('The ISP or operator providing the Internet service.'))
contract = forms.CharField(required=False, max_length=256, label=_("Contract"), help_text=_('The specific contract at the ISP provider. (please be as specific as possible)'))
media = forms.ChoiceField(required=False, choices=(('',''),)+tuple(sorted(MEDIA,key=itemgetter(1))), label=_('Is the Internet connection over mobile or fixed line?'))
media = forms.ChoiceField(required=False, choices=(('', ''), ) + tuple(sorted(MEDIA, key=itemgetter(1))), label=_('Is the Internet connection over mobile or fixed line?'))
def search(self):
# By default, the search field is q. So let's check if it's empty
......@@ -67,5 +71,6 @@ class SearchViolation(SearchForm):
return sqs
class QuickSearchViolation(forms.Form):
query = forms.CharField(required='True', max_length=256, label=_("Search"), help_text=_('Search for an existing violation'))
......@@ -36,7 +36,7 @@ COUNTRIES = (
('FI', _('Finland')),
('SE', _('Sweden')),
('UK', _('United Kingdom')),
)
)
RESOURCES = (
('other', _('other')),
('port', _('port')),
......@@ -48,7 +48,7 @@ RESOURCES = (
('video', _('video streaming')),
('audio', _('audio streaming')),
('class', _('class of application or contraint')),
)
)
TYPES = (
('zerorating', _('Zero Rating')),
('specialised', _('Specialised Service')),
......@@ -56,11 +56,11 @@ TYPES = (
('throttling', _('Throttling')),
('prioritisation', _('Prioritisation')),
('other', _('Other'))
)
)
MEDIA = (
('fixed', _('Fixed')),
('mobile', _('Mobile')),
)
)
STATUS = (
('moreinfo', _('Need more info')),
('new', _('New')),
......@@ -69,7 +69,8 @@ STATUS = (
('ooscope', _('Out of scope')),
('resolved', _('Resolved')),
('closed', _('Closed')),
)
)
class Operator(models.Model):
"""
......@@ -85,6 +86,7 @@ class Operator(models.Model):
def __unicode__(self):
return self.name
class Violation(models.Model):
country = models.CharField(max_length=2, choices=COUNTRIES)
operator_ref = models.ForeignKey(Operator, related_name="violations")
......@@ -92,12 +94,12 @@ class Violation(models.Model):
resource = models.CharField(max_length=20, choices=RESOURCES, blank=True)
resource_name = models.CharField(max_length=4096, blank=True)
type = models.CharField(max_length=20, choices=TYPES, blank=True)
media = models.CharField( max_length=20, choices=MEDIA, blank=True)
temporary = models.BooleanField( )
media = models.CharField(max_length=20, choices=MEDIA, blank=True)
temporary = models.BooleanField()
contractual = models.BooleanField()
contract_excerpt = models.TextField(null=True, blank=True)
loophole = models.BooleanField()
activationid= models.CharField(max_length=128, null=True, blank=True)
activationid = models.CharField(max_length=128, null=True, blank=True)
state = models.CharField(max_length=20, choices=STATUS, default='new', blank=True)
editorial = models.TextField(null=True, blank=True)
old = models.BooleanField(default="False")
......@@ -131,7 +133,7 @@ class Violation(models.Model):
class Comment(models.Model):
submitter_email = models.EmailField()
submitter_name = models.CharField(max_length=20)
consent = models.BooleanField( )
consent = models.BooleanField()
comment = models.TextField()
timestamp = models.DateTimeField()
violation = models.ForeignKey(Violation)
......@@ -142,10 +144,11 @@ class Comment(models.Model):
def __unicode__(self):
return _("Comment #%s") % (self.pk)
class Attachment(models.Model):
storage = models.FileField(upload_to='static')
name= models.CharField(max_length=512)
type= models.CharField(max_length=512)
name = models.CharField(max_length=512)
type = models.CharField(max_length=512)
comment = models.ForeignKey(Comment)
class Admin:
......@@ -154,23 +157,28 @@ class Attachment(models.Model):
def __unicode__(self):
return self.name
class Confirmation(models.Model):
key=models.CharField(max_length=64, blank=True)
email=models.EmailField()
key = models.CharField(max_length=64, blank=True)
email = models.EmailField()
violation = models.ForeignKey(Violation)
class Admin:
pass
class ViolationModerator(CommentModerator):
email_notification = True
moderate_after = 0
moderate_after = 0
def moderate(self, comment, content_object, request):
return True
if Violation not in moderator._registry:
moderator.register(Violation, ViolationModerator)
class FeaturedCase(models.Model):
case = models.OneToOneField(Violation)
......
......@@ -5,17 +5,14 @@ Created by Edward Dale (www.scompt.com)
Released into the Public Domain
"""
from django.utils.encoding import force_unicode
from django.utils.datastructures import MultiValueDict, MergeDict
from django.utils.translation import ugettext
from django.forms.fields import Field, EMPTY_VALUES
from django.core.files.uploadedfile import UploadedFile
from django.forms.widgets import Input, FILE_INPUT_CONTRADICTION
from django.forms.util import ErrorList, ValidationError, flatatt
from django.utils.safestring import mark_safe
from django.forms.util import ValidationError
FILE_INPUT_EMPTY_VALUE = object()
class MultiFileInput(Input):
"""
A widget to be used by the MultiFileField to allow the user to upload
......@@ -57,6 +54,7 @@ class MultiFileInput(Input):
return id_
id_for_label = classmethod(id_for_label)
class MultiFileField(Field):
"""
A field allowing users to upload multiple files at once.
......
from haystack import indexes
from models import Operator, Violation
from models import Violation
class ViolationIndexes(indexes.SearchIndex, indexes.Indexable):
text = indexes.CharField(document=True, use_template=True)
......
......@@ -2,13 +2,13 @@
import os
os.environ['DJANGO_SETTINGS_MODULE'] = "nnmon.settings"
from django.conf import settings
from bt.models import Violation
from django.db.models import Count
import odslib
from django.utils.html import strip_tags
import re, htmlentitydefs
import re
import htmlentitydefs
##
# Removes HTML or XML character references and entities from a text string.
#
......@@ -16,8 +16,10 @@ import re, htmlentitydefs
# @return The plain text, as a Unicode string, if necessary.
# source: http://effbot.org/zone/re-sub.htm
def unescape(text):
text=strip_tags(text)
text = strip_tags(text)
def fixup(m):
text = m.group(0)
if text[:2] == "&#":
......@@ -35,48 +37,50 @@ def unescape(text):
text = unichr(htmlentitydefs.name2codepoint[text[1:-1]])
except KeyError:
pass
return text # leave as is
return text # leave as is
return re.sub("&#?\w+;", fixup, text)
def save_ods():
# Create your document
doc = ooolib.Calc()
col=1
row=2
col = 1
row = 2
doc.set_cell_property('bold', True)
doc.set_row_property(row, 'height', '16.5pt')
for heading, width in [('Country', '73pt'),
('Operator', '77pt'),
('Type of measure*','355pt'),
('','355pt'),
('Type of measure*', '355pt'),
('', '355pt'),
('Description of the measure', '148pt'),
('Objective',''),
('Method of implementation (if applicable)',''),
('Number of subscribers having a subscription where this measure is implemented',''),
('How is the user informed?','148pt'),
('Objective', ''),
('Method of implementation (if applicable)', ''),
('Number of subscribers having a subscription where this measure is implemented', ''),
('How is the user informed?', '148pt'),
('Can the user activate/deactivate the measure? How?', '148pt'),
('Protection of business secret','239pt')]:
if width: doc.set_column_property(col, 'width', width)
('Protection of business secret', '239pt')]:
if width:
doc.set_column_property(col, 'width', width)
doc.set_cell_value(col, row, "string", heading)
col+=1
col += 1
doc.set_cell_property('bold', False)
row=3
row = 3
for v in Violation.objects.filter(activationid='').exclude(state__in=['closed', 'ooscope', 'duplicate']).annotate(total=Count('confirmation')):
if v.total>0 or v.state=='verified':
if v.total > 0 or v.state == 'verified':
doc.set_row_property(row, 'height', '16.5pt')
doc.set_cell_property('wrap-option', 'wrap')
doc.set_cell_value(1, row, "string", v.country)
doc.set_cell_value(2, row, "string", v.operator)
doc.set_cell_value(3, row, "string", "%s %s" % (v.type, v.resource_name))
doc.set_cell_value(5, row, "string", "%s\n\n%s" % ( v.editorial, unescape(v.comment_set.get().comment)))
doc.set_cell_value(5, row, "string", "%s\n\n%s" % (v.editorial, unescape(v.comment_set.get().comment)))
doc.set_cell_value(9, row, "string", "%s %s" % ("Contractual" if v.contractual else "", unescape(v.contract_excerpt)))
doc.set_cell_value(10, row, "string", "can update to a different dataplan" if v.loophole else "")
doc.set_cell_value(12, row, "string", v.media)
row+=1
#(v.state, v.country, v.operator, v.contract, v.resource, v.resource_name, v.type, v.media, v.temporary, v.contractual, v.contract_excerpt, v.loophole, v.editorial,v.comment_set.get().comment)
row += 1
# (v.state, v.country, v.operator, v.contract, v.resource, v.resource_name, v.type, v.media, v.temporary, v.contractual, v.contract_excerpt, v.loophole, v.editorial,v.comment_set.get().comment)
# Save the document to the file you want to create
doc.save("/tmp/ec_berec_tm_questionnaire.ods")
from django.template import Library, Variable
from django.template import Library
from django.conf import settings
from django import template
import random
from ..models import COUNTRIES, STATUS, TYPES, MEDIA
register = Library()
@register.simple_tag
def root_url():
return settings.ROOT_URL
@register.simple_tag
def media_url():
return settings.MEDIA_URL
country_map=dict(COUNTRIES)
country_map = dict(COUNTRIES)
@register.filter(name='country')
def country(code):
return country_map[code]
status_map=dict(STATUS)
status_map = dict(STATUS)
@register.filter(name='status')
def status(code):
try:
return status_map[code]
except:
except Exception:
return code
type_map=dict(TYPES)
type_map = dict(TYPES)
@register.filter(name='type')
def type(code):
try:
return type_map[code]
except:
except Exception:
return code
media_map=dict(MEDIA)
media_map = dict(MEDIA)
@register.filter(name='media')
def media(code):
try:
return media_map[code]
except:
except Exception:
return code
......@@ -6,6 +6,7 @@ import json
register = Library()
@register.filter(name='jsonify')
def jsonify(object):
if isinstance(object, QuerySet):
......
This diff is collapsed.
......@@ -13,82 +13,82 @@ operator_api_resource = OperatorResource()
admin.autodiscover()
urlpatterns = patterns('',
url(r'^$',
view=bt.AddForm.as_view(),
name="homepage"),
url(r'^list/$',
view=bt.ViolationsList.as_view(),
name="list_violations"),
url(r'^list/(?P<country>\w+)/$',
view=bt.ViolationsList.as_view(),
name="filter_country"),
url(r'^list/(?P<country>\w+)/(?P<operator>\w+)/$',
view=bt.ViolationsList.as_view(),
name="filter_operator"),
# violation cannonical url and redirections
url(r'^(?P<id>[0-9]*)$',
RedirectView.as_view(url='/view/%(id)s')),
url(r'^view/(?P<id>[0-9]*)$',
view=bt.ViolationView.as_view(),
name="violation_url"),
url(r'^attach/(?P<id>[0-9]*)$',
view=bt.get_attach,
name="attach"),
# different data outputs
url(r'^csv$',
view=bt.ViolationCsvList.as_view(),
name="csv_output"),
url(r'^ods$',
view=bt.asods,
name="ods_output"),
url(r'^rss/$',
view=RssSiteNewsFeed(),
name="rss_output"),
url(r'^atom/$',
view=AtomSiteNewsFeed(),
name="atom_output"),
url(r'^activate/$',
view=bt.activate,
name="activate"),
url(r'^confirm/(?P<id>[0-9a-z]*)$',
view=bt.confirm,
name="confirm"),
url(r'^confirm/(?P<id>[0-9]*)/(?P<name>.*)$',
view=bt.confirm,
name="confirm_full"),
url(r'^moderate/$',
view=bt.moderate,
name="moderate"),
url(r'^lookup/',
view=bt.LookupView.as_view(template_name='search/lookup.json'),
name="lookup"),
url(r'^accounts/logout$',
'django.contrib.auth.views.logout', {'next_page': '/'}),
url(r'^accounts/',
include('registration.backends.hmac.urls')),
url(r'^comments/',
include('django_comments.urls')),
url(r'^about/$',
TemplateView.as_view(template_name='nn.html')),
url(r'^start/$',
TemplateView.as_view(template_name='start.html')),
url(r'^captcha/',
include('captcha.urls')),
url(r'^admin/',
include(admin.site.urls)),
url(r'^api/',
include(api_resource.urls)),
url(r'^api/',
include(operator_api_resource.urls)),
url(r'^search/',
bt.ViolationSearchView.as_view(template_name='search/search.html')),
# Language switch
url(r'^i18n/', include('django.conf.urls.i18n')),
)
url(r'^$',
view=bt.AddForm.as_view(),
name="homepage"),
url(r'^list/$',
view=bt.ViolationsList.as_view(),
name="list_violations"),
url(r'^list/(?P<country>\w+)/$',
view=bt.ViolationsList.as_view(),
name="filter_country"),
url(r'^list/(?P<country>\w+)/(?P<operator>\w+)/$',
view=bt.ViolationsList.as_view(),
name="filter_operator"),
# violation cannonical url and redirections
url(r'^(?P<id>[0-9]*)$',
RedirectView.as_view(url='/view/%(id)s')),
url(r'^view/(?P<id>[0-9]*)$',
view=bt.ViolationView.as_view(),
name="violation_url"),
url(r'^attach/(?P<id>[0-9]*)$',
view=bt.get_attach,
name="attach"),
# different data outputs
url(r'^csv$',
view=bt.ViolationCsvList.as_view(),
name="csv_output"),
url(r'^ods$',
view=bt.asods,
name="ods_output"),
url(r'^rss/$',
view=RssSiteNewsFeed(),
name="rss_output"),
url(r'^atom/$',
view=AtomSiteNewsFeed(),
name="atom_output"),
url(r'^activate/$',
view=bt.activate,
name="activate"),
url(r'^confirm/(?P<id>[0-9a-z]*)$',
view=bt.confirm,
name="confirm"),
url(r'^confirm/(?P<id>[0-9]*)/(?P<name>.*)$',
view=bt.confirm,
name="confirm_full"),
url(r'^moderate/$',
view=bt.moderate,
name="moderate"),
url(r'^lookup/',
view=bt.LookupView.as_view(template_name='search/lookup.json'),
name="lookup"),
url(r'^accounts/logout$',
'django.contrib.auth.views.logout', {'next_page': '/'}),
url(r'^accounts/',
include('registration.backends.hmac.urls')),
url(r'^comments/',
include('django_comments.urls')),
url(r'^about/$',
TemplateView.as_view(template_name='nn.html')),
url(r'^start/$',
TemplateView.as_view(template_name='start.html')),
url(r'^captcha/',
include('captcha.urls')),
url(r'^admin/',
include(admin.site.urls)),
url(r'^api/',
include(api_resource.urls)),
url(r'^api/',
include(operator_api_resource.urls)),
url(r'^search/',
bt.ViolationSearchView.as_view(template_name='search/search.html')),
# Language switch
url(r'^i18n/', include('django.conf.urls.i18n')),
)
if settings.DEV_SERVER == True:
if settings.DEV_SERVER is True:
urlpatterns += patterns('',
(r'^site_media/(?P<path>.*)$',
'django.views.static.serve',
{'document_root': settings.MEDIA_PATH}),
)
\ No newline at end of file
(r'^site_media/(?P<path>.*)$',
'django.views.static.serve',
{'document_root': settings.MEDIA_PATH}),
)
[flake8]
count = True
exclude = .git ,migrations
max-line-length = 160
ignore=E501,E128
from spamlesscomment.forms import CommentFormWithCaptcha
def get_form():
return CommentFormWithCaptcha
from django.contrib import admin
from django.contrib import admin # noqa
# Register your models here.
from django.db import models
from django.db import models # noqa
# Create your models here.
from django.test import TestCase
from django.test import TestCase # noqa
# Create your tests here.
from django.shortcuts import render
from django.shortcuts import render # noqa
# Create your views here.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment