...
 
Commits (79)
......@@ -9,63 +9,63 @@ from operator import itemgetter
from captcha.fields import CaptchaField
class AdvancedEditor(forms.Textarea):
class Media:
js = (settings.MEDIA_URL+'/js/tinymce/tiny_mce.js',)
class Media:
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)
super(AdvancedEditor, self).__init__(attrs)
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)
super(AdvancedEditor, self).__init__(attrs)
class AddViolation(forms.Form):
resource_name = forms.CharField(required=True, max_length=4096, label=_('Please specify the affected resource'), 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 restriction 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?'))
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!"))
nick = forms.CharField(required=False, label=_("Name or nickname"), help_text=_("We need some name to display that instead of an email address."))
attachments = MultiFileField(required=False, label=_("Attach screenshot, document or any other relevant information."))
resource = forms.ChoiceField(required=False, choices=(('',''),)+tuple(sorted(RESOURCES,key=itemgetter(1))), label=_('What is the affected resource type. (optional)'))
type = forms.ChoiceField(required=False, choices=(('',''),)+tuple(sorted(TYPES,key=itemgetter(1))), label=_('Is the Resource Blocked or otherwise discrimated? (optional)'))
temporary = forms.BooleanField(required=False, label=_('Is the restriction only temporary, e.g. due to network overload? (optional)'))
loophole = forms.BooleanField(required=False, label=_('Is there another offer provided by this Operator which removes this restriction? (optional)'))
contractual = forms.BooleanField(required=False, label=_('Is the restriction described in the subscribers contract? (optional)'))
contract_excerpt = forms.CharField(required=False, widget=AdvancedEditor(), label=_('Please copy the relevant section describing the restriction from the user contract. (optional)'))
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)"))
resource_name = forms.CharField(required=True, max_length=4096, label=_('Please specify the affected resource'), 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 restriction 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?'))
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!"))
nick = forms.CharField(required=False, label=_("Name or nickname"), help_text=_("We need some name to display that instead of an email address."))
attachments = MultiFileField(required=False, label=_("Attach screenshot, document or any other relevant information."))
resource = forms.ChoiceField(required=False, choices=tuple(sorted(RESOURCES,key=itemgetter(1))), label=_('What is the affected resource type. (optional)'))
type = forms.ChoiceField(required=True, choices=tuple(sorted(TYPES,key=itemgetter(1))), label=_('What types of resctriction happens in this case?'))
temporary = forms.BooleanField(required=False, label=_('Is the restriction only temporary, e.g. due to network overload? (optional)'))
loophole = forms.BooleanField(required=False, label=_('Is there another offer provided by this Operator which removes this restriction? (optional)'))
contractual = forms.BooleanField(required=False, label=_('The restriction is described in the subscribers contract.'))
contract_excerpt = forms.CharField(required=False, widget=AdvancedEditor(), label=_('Please copy the relevant section describing the restriction from the user contract. (optional)'))
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=True, choices=(('',''),)+tuple(sorted(COUNTRIES,key=itemgetter(1))), label=_("Country"), help_text=_('EU member state where the restriction 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?'))
country = forms.ChoiceField(required=False, choices=(('',''),)+tuple(sorted(COUNTRIES,key=itemgetter(1))), label=_("Country"), help_text=_('EU member state where the restriction 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?'))
def search(self):
# By default, teh search field is q. So let's check if it's empty
if not self.cleaned_data['q']:
sqs = SearchQuerySet().all()
else:
sqs = super(SearchViolation, self).search()
def search(self):
# By default, the search field is q. So let's check if it's empty
if not self.cleaned_data['q']:
sqs = SearchQuerySet().all().exclude(old=True)
else:
sqs = super(SearchViolation, self).search().exclude(old=True)
if not self.is_valid():
return self.no_query_found()
if not self.is_valid():
return self.no_query_found()
if self.cleaned_data['operator']:
sqs = sqs.filter(operator=self.cleaned_data['operator'])
if self.cleaned_data['operator']:
sqs = sqs.filter(operator__icontains=self.cleaned_data['operator'])
if self.cleaned_data['contract']:
sqs = sqs.filter(contract=self.cleaned_data['contract'])
if self.cleaned_data['contract']:
sqs = sqs.filter(contract__icontains=self.cleaned_data['contract'])
if self.cleaned_data['media']:
sqs = sqs.filter(media=self.cleaned_data['media'])
if self.cleaned_data['media']:
sqs = sqs.filter(media=self.cleaned_data['media'])
if self.cleaned_data['country']:
sqs = sqs.filter(country=self.cleaned_data['country'])
if self.cleaned_data['country']:
sqs = sqs.filter(country=self.cleaned_data['country'])
return sqs
return sqs
class QuickSearchViolation(forms.Form):
query = forms.CharField(required='True', max_length=256, label=_("Search"), help_text=_('Search for an existing violation'))
......@@ -64,11 +64,11 @@ class Migration(migrations.Migration):
('media', models.CharField(blank=True, max_length=20, choices=[(b'fixed', 'Fixed'), (b'mobile', 'Mobile')])),
('temporary', models.BooleanField()),
('contractual', models.BooleanField()),
('contract_excerpt', models.TextField(blank=True)),
('contract_excerpt', models.TextField(null=True, blank=True)),
('loophole', models.BooleanField()),
('activationid', models.CharField(max_length=128, blank=True)),
('state', models.CharField(default=b'new', max_length=20, blank=True, choices=[(b'moreinfo', 'Need more info'), (b'new', 'New'), (b'verified', 'Verified'), (b'duplicate', 'Duplicate'), (b'ooscope', 'Out of scope'), (b'closed', 'Closed')])),
('editorial', models.TextField(blank=True)),
('editorial', models.TextField(null=True, blank=True)),
('operator_ref', models.ForeignKey(related_name='violations', to='bt.Operator')),
],
),
......
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('bt', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='violation',
name='old',
field=models.BooleanField(default=b'False'),
),
]
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
def archive_old(apps, schema_editor):
Violation = apps.get_model("bt", "Violation")
for violation in Violation.objects.all():
violation.old = True
violation.save()
class Migration(migrations.Migration):
dependencies = [
('bt', '0002_violation_old'),
]
operations = [
migrations.RunPython(archive_old),
]
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('bt', '0003_auto_20160301_2032'),
]
operations = [
migrations.AlterField(
model_name='violation',
name='activationid',
field=models.CharField(max_length=128, null=True, blank=True),
),
]
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('bt', '0004_auto_20160301_2103'),
]
operations = [
migrations.AlterField(
model_name='violation',
name='country',
field=models.CharField(max_length=2, choices=[(b'BE', 'Belgium'), (b'BG', 'Bulgaria'), (b'CH', 'Switzerland'), (b'CZ', 'Czech Republic'), (b'DK', 'Denmark'), (b'DE', 'Germany'), (b'EE', 'Estonia'), (b'IE', 'Ireland'), (b'EL', 'Greece'), (b'ES', 'Spain'), (b'FR', 'France'), (b'IC', 'Iceland'), (b'IS', 'Iceland'), (b'IT', 'Italy'), (b'CY', 'Cyprus'), (b'LI', 'Liechtenstein'), (b'LV', 'Latvia'), (b'LT', 'Lithuania'), (b'LU', 'Luxembourg'), (b'HU', 'Hungary'), (b'MT', 'Malta'), (b'NL', 'Netherlands'), (b'NO', 'Norway'), (b'AT', 'Austria'), (b'PL', 'Poland'), (b'PT', 'Portugal'), (b'RO', 'Romania'), (b'SI', 'Slovenia'), (b'SK', 'Slovakia'), (b'FI', 'Finland'), (b'SE', 'Sweden'), (b'UK', 'United Kingdom')]),
),
migrations.AlterField(
model_name='violation',
name='resource',
field=models.CharField(blank=True, max_length=20, choices=[(b'port', 'port'), (b'protocol', 'protocol'), (b'service', 'service'), (b'site', 'website'), (b'user', 'user'), (b'ip', 'ip'), (b'video', 'video streaming'), (b'audio', 'audio streaming'), (b'class', 'class of application or contraint'), (b'other', 'other')]),
),
migrations.AlterField(
model_name='violation',
name='type',
field=models.CharField(blank=True, max_length=20, choices=[(b'zerorating', 'Zero Rating'), (b'blocking', 'Blocking'), (b'throttling', 'Throttling'), (b'prioritisation', 'Prioritisation'), (b'specialised', 'Specialised Service'), (b'other', 'Other')]),
),
]
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
import datetime
class Migration(migrations.Migration):
dependencies = [
('bt', '0005_auto_20160302_1202'),
]
operations = [
migrations.AddField(
model_name='violation',
name='creation_date',
field=models.DateField(default=datetime.datetime(2016, 3, 2, 12, 14, 23, 907012), auto_now_add=True),
preserve_default=False,
),
]
......@@ -5,6 +5,7 @@ from django_comments.moderation import CommentModerator, moderator
COUNTRIES = (
('BE', _('Belgium')),
('BG', _('Bulgaria')),
('CH', _('Switzerland')),
('CZ', _('Czech Republic')),
('DK', _('Denmark')),
('DE', _('Germany')),
......@@ -13,9 +14,11 @@ COUNTRIES = (
('EL', _('Greece')),
('ES', _('Spain')),
('FR', _('France')),
('IC', _('Iceland')),
('IS', _('Iceland')),
('IT', _('Italy')),
('CY', _('Cyprus')),
('LI', _('Liechtenstein')),
('LV', _('Latvia')),
('LT', _('Lithuania')),
('LU', _('Luxembourg')),
......@@ -38,13 +41,21 @@ RESOURCES = (
('port', _('port')),
('protocol', _('protocol')),
('service', _('service')),
('site', _('site')),
('site', _('website')),
('user', _('user')),
('ip', _('ip')),
('video', _('video streaming')),
('audio', _('audio streaming')),
('class', _('class of application or contraint')),
('other', _('other'))
)
TYPES = (
('zerorating', _('Zero Rating')),
('blocking', _('Blocking')),
('throttling', _('Throttling')),
('prioritisation', _('Prioritisation')),
('specialised', _('Specialised Service')),
('other', _('Other'))
)
MEDIA = (
('fixed', _('Fixed')),
......@@ -73,7 +84,6 @@ 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")
......@@ -84,11 +94,13 @@ class Violation(models.Model):
media = models.CharField( max_length=20, choices=MEDIA, blank=True)
temporary = models.BooleanField( )
contractual = models.BooleanField()
contract_excerpt = models.TextField(blank=True)
contract_excerpt = models.TextField(null=True, blank=True)
loophole = models.BooleanField()
activationid= models.CharField(max_length=128, 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(blank=True)
editorial = models.TextField(null=True, blank=True)
old = models.BooleanField(default="False")
creation_date = models.DateField(auto_now_add=True)
def confirmations(self):
return self.confirmation_set.filter(key='').count()
......@@ -108,7 +120,6 @@ class Violation(models.Model):
def __unicode__(self):
return "#%s %s/%s" % (self.pk, self.country, self.operator)
class Comment(models.Model):
submitter_email = models.EmailField()
submitter_name = models.CharField(max_length=20)
......
......@@ -5,9 +5,12 @@ class ViolationIndexes(indexes.SearchIndex, indexes.Indexable):
text = indexes.CharField(document=True, use_template=True)
operator = indexes.CharField(model_attr="operator_ref")
country = indexes.CharField(model_attr="country")
contract = indexes.CharField(model_attr="contract_excerpt")
type = indexes.BooleanField(model_attr="contractual")
contract = indexes.CharField(model_attr="contract")
type = indexes.CharField(model_attr="contractual")
media = indexes.CharField(model_attr="media")
operator_name = indexes.CharField()
state = indexes.NgramField(model_attr="state")
old = indexes.BooleanField(model_attr="old")
def get_model(self):
return Violation
......
from django.core.serializers import serialize
from django.db.models.query import QuerySet
from django.template import Library
from haystack.models import SearchResult
import json
register = Library()
@register.filter(name='jsonify')
def jsonify(object):
if isinstance(object, QuerySet):
return serialize('json', object)
elif object == []:
return json.dumps(object)
elif isinstance(object[0], SearchResult):
return serialize('json', [x.object for x in object])
else:
return json.dumps(object)
......@@ -6,6 +6,7 @@ from django.shortcuts import render_to_response, get_object_or_404, redirect
from django.template import RequestContext, loader, Context
from django.core.files import File
from django.core.servers.basehttp import FileWrapper
from django.core import serializers
from django.conf import settings
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.core.exceptions import ObjectDoesNotExist
......@@ -15,7 +16,8 @@ from django.contrib.auth.models import User
from django.utils.translation import ugettext_lazy as _
from django.db.models import Count
from haystack.generic_views import SearchView
from models import Violation, Attachment, Comment, Confirmation, COUNTRIES, STATUS, Operator
from haystack.query import SearchQuerySet
from models import Violation, Attachment, Comment, Confirmation, COUNTRIES, STATUS, Operator, FeaturedCase
from tempfile import mkstemp
from datetime import datetime
import hashlib, os, re, json
......@@ -142,20 +144,10 @@ def sendverifymail(service,to,body):
return actid
class JSONMixin(object):
def get(self, request, *args, **kwargs):
qs = self.get_queryset()
if qs.count():
return HttpResponse(json.dumps(sorted([(x.id, x.resource_name) for x in qs])))
else:
return HttpResponse('')
class AddForm(FormView):
model = Violation
template_name = 'index.html'
form_class = AddViolation
success_url = '/'
context_object_name = 'violations'
def form_valid(self, form):
msg=_("Thank you for submitting a new report. To finalize your submission please confirm using your validation key.\nYour verification key is %s/%s%s\nPlease note that reports are moderated, it might take some time before your report appears online. Thank you for your patience.")
......@@ -173,7 +165,8 @@ class AddForm(FormView):
contractual = form.cleaned_data['contractual'],
contract_excerpt = sanitizeHtml(form.cleaned_data['contract_excerpt']),
loophole = form.cleaned_data['loophole'],
activationid = actid
activationid = actid,
old = False
)
v.save()
#c=Confirmation(key='', email=form.cleaned_data['email'], violation=v)
......@@ -187,7 +180,7 @@ class AddForm(FormView):
violation=v,
)
c.save()
for f in request.FILES.getlist('attachments[]'):
for f in self.request.FILES.getlist('attachments[]'):
a=Attachment(comment=c, name=f.name, type=f.content_type)
m = hashlib.sha256()
for chunk in f.chunks():
......@@ -195,27 +188,25 @@ class AddForm(FormView):
sname=m.hexdigest()
a.storage.save(sname,f)
a.save()
messages.add_message(request, messages.INFO, _('Thank you for submitting this report, you will receive a verification email immediately, if not check your spam folder.'))
messages.add_message(self.request, messages.INFO, _('Thank you for submitting this report, you will receive a verification email immediately, if not check your spam folder.'))
return super(AddForm, self).form_valid(form)
def get_queryset(self):
return Violation.objects.filter(activationid='',featuredcase__isnull=False).order_by('id').reverse()[:3]
def get_context_data(self, **kwargs):
context = super(AddForm, self).get_context_data(**kwargs)
reports = sorted([(i['total'],i['id'])
for i in Violation.objects.values('id').filter(activationid='').exclude(state__in=['closed', 'ooscope', 'duplicate']).annotate(total=Count('confirmation'))],
for i in Violation.objects.values('id').filter(activationid='').exclude(state__in=['closed', 'ooscope', 'duplicate']).exclude(old=True).annotate(total=Count('confirmation'))],
reverse=True)
confirms = sorted([(i['total'],i['country'])
for i in Violation.objects.values('country').filter(activationid='').exclude(state__in=['closed', 'ooscope', 'duplicate']).annotate(total=Count('confirmation'))],
for i in Violation.objects.values('country').filter(activationid='').exclude(state__in=['closed', 'ooscope', 'duplicate']).exclude(old=True).annotate(total=Count('confirmation'))],
reverse=True)
operators = sorted([(i['total'],i['operator_ref__name'])
for i in Violation.objects.values('operator_ref__name').filter(activationid='').exclude(state__in=['closed', 'ooscope', 'duplicate']).annotate(total=Count('confirmation'))],
for i in Violation.objects.values('operator_ref__name').filter(activationid='').exclude(state__in=['closed', 'ooscope', 'duplicate']).exclude(old=True).annotate(total=Count('confirmation'))],
reverse=True)
context['stats'] = [
(_('Total confirmed reports'), len([i for i,z in reports if i>0])),
(_('Countries with some confirmed reports'), len([i for i,z in confirms if i>0])),
(_('Operators with some confirmed reports'), len([i for i,z in operators if i>0]))]
context['violations'] = [fc.case for fc in FeaturedCase.objects.all() if not fc.case.old][:3]
return context
class ViolationsList(ListView):
......@@ -223,17 +214,17 @@ class ViolationsList(ListView):
context_object_name = 'violations'
def get_queryset(self):
queryset = Violation.objects.filter(activationid='')
queryset = Violation.objects.filter(activationid='').exclude(old=True)
if 'operator' in self.kwargs:
# If i Have operator I have a country
queryset = Violation.objects.filter(activationid='',
country=self.kwargs['country'],
operator_ref__name=self.kwargs['operator'])
operator_ref__name=self.kwargs['operator']).exclude(old=True)
if 'country' in self.kwargs:
queryset = Violation.objects.filter(activationid='',
country=self.kwargs['country'])
country=self.kwargs['country']).exclude(old=True)
if 'all' not in self.request.GET:
queryset = queryset.filter(activationid='').exclude(state__in=['duplicate', 'closed'])
queryset = queryset.filter(activationid='').exclude(state__in=['duplicate', 'closed']).exclude(old=False)
return queryset
def get_context_data(self, **kwargs):
......@@ -243,7 +234,7 @@ class ViolationsList(ListView):
context['country'] = self.kwargs['country']
else:
countries = sorted([(i['total'], i['country'])
for i in Violation.objects.values('country').filter(activationid='').exclude(state__in=['duplicate', 'closed']).annotate(total=Count('country'))],
for i in Violation.objects.values('country').filter(activationid='').exclude(state__in=['duplicate', 'closed']).exclude(old=True).annotate(total=Count('country'))],
reverse=True)
countryweights=json.dumps([{'iso2': y, 'w': x} for x, y in countries])
context['countries'] = countries
......@@ -262,11 +253,26 @@ class ViolationView(DetailView):
raise Http404
return object
class LookupView(JSONMixin, SearchView):
queryset = Violation.objects.filter(activationid='')
class LookupView(SearchView):
searchqueryset = SearchQuerySet().exclude(old=True)
form_class = SearchViolation
def get_queryset(self):
return super(LookupView, self).get_queryset().exclude(old=True)
def get_context_data(self, *args, **kwargs):
context = super(LookupView, self).get_context_data(*args, **kwargs)
if 'object_list' in context:
context['object_list'] = [obj for obj in context['object_list'] if not obj.object.old]
return context
class ViolationSearchView(SearchView):
searchqueryset = SearchQuerySet().exclude(old=True)
form_class = SearchViolation
def get_queryset(self):
return super(ViolationSearchView, self).get_queryset().exclude(old=True)
def get_context_data(self, *args, **kwargs):
context = super(ViolationSearchView, self).get_context_data(*args, **kwargs)
countries = sorted([(k, len(list(g)),) for k, g in groupby(sorted([i['country'] for i in self.queryset.values('country')]))])
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -4,13 +4,15 @@ BeautifulSoup==3.2.1
defusedxml==0.4.1
Django==1.8.6
django-ajax-selects==1.4.1
django-bootstrap3==7.0.0
django-contrib-comments==1.6.1
django-debug-toolbar==1.4
django-haystack==2.4.1
django-registration==2.0.3
django-simple-captcha==0.4.6
django-tastypie==0.12.2
django-tinymce==2.0.6
flup==1.0.3.dev20110405
flup
httplib2==0.9.2
lxml==3.5.0
oauth2==1.9.0.post1
......@@ -24,5 +26,6 @@ pytz==2015.7
simplejson==3.8.1
six==1.10.0
South==1.0.2
sqlparse==0.1.18
wheel==0.24.0
Whoosh==2.7.0
......@@ -145,6 +145,8 @@ INSTALLED_APPS = (
'haystack',
# Debugging bar
'debug_toolbar',
# Let's have fun with bootstrap
'bootstrap3',
)
TEMPLATE_CONTEXT_PROCESSORS = ("django.contrib.auth.context_processors.auth",
......
This diff is collapsed.
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
body { border: 0; padding: 0; font-family: Verdana,Arial,Helvetica,sans-serif; }
img { border: 0; vertical-align: middle; }
h1, h2, h3, h4, div, ul { padding: 0; margin: 0; }
li { list-style: none; }
h1, h2, h3, h4, div { padding: 0; margin: 0; }
.fieldWrapper { width: 100%; position: relative; }
.fieldWrapper label { display: inline-block; }
......@@ -49,7 +48,8 @@ li { list-style: none; }
#addForm .fieldWrapper label { display: inline-block; min-width: 6em; }
#addForm.index .help_text { font-size: 0.7em; width: 30%; position: relative; float: right; left: 0; }
.index #add_attach { cursor: pointer; }
#id_captcha_1 { width: 2em; }
img.captcha {float: left; }
#id_captcha_1 { width: auto; }
.innerfield { display: inline-block; margin-top: 0.5em;}
.align-right { text-align: right;}
dd.text { width: 50%; display: block !important; }
......@@ -76,10 +76,10 @@ p label { width: 7em; display: inline-block; }
#footer {
text-align: center;
max-width: 960px;
clear: both;
margin: auto;
background-color: #f9f9f9;
padding-bottom:30px;
}
.errorlist { font-size: .8em; color: red; }
......@@ -237,26 +237,28 @@ blockquote {
}
#header {
background: #f9f9f9;
padding:3%
}
#header a {
color: #222;
color: white;
text-decoration: none;
}
h1 {
margin: 25px 0 0 0; padding: 30px 0;
margin: 25px 0 0 0;
padding: 3%;
font-family: 'DroidSansBold', Helvetica, Arial, "Liberation Sans", FreeSans, sans-serif;
font-size: 35px;
line-height: 1;
font-weight: normal;
font-weight: bold;
text-shadow:1px 2px 1px rgba(0, 0, 0, 0.4);
}
h1 span {
display: block;
font-family: 'DroidSansRegular', Helvetica, Arial, "Liberation Sans", FreeSans, sans-serif;
font-size: .8em;
font-weight: normal;
color: orange;
font-weight: bold;
}
/* User */
......@@ -279,7 +281,6 @@ h1 span {
}
#user p {
width: 960px;
margin: 0 auto;
text-align: right;
}
......@@ -288,61 +289,51 @@ h1 span {
color: orange;
}
/* Navigation menu */
#nav {
height: 36px;
margin: 0; padding: 0;
list-style-type: none;
border-bottom: 1px solid #ddd;
}
#nav li {
display: inline-block;
}
#nav #current {
color: #231f20;
background: #fff;
border: 1px solid #ddd;
border-bottom: 1px solid #fff;
}
#nav #current:hover, #nav #current:active, #nav #current:focus {
color: orange;
}
#nav a {
display: block;
height: 19px;
padding: 8px 1em;
text-decoration: none;
color: #ccc;
border: 1px solid #f0f0f0;
border-bottom-color: #ddd;
-moz-border-radius: 2px 2px 0 0;
-webkit-border-radius: 2px 2px 0 0;
-o-border-radius: 2px 2px 0 0;
border-radius: 2px 2px 0 0;
}
#nav a:hover, #nav a:active, #nav a:focus {
color: #231f20;
background: #fff;
border: 1px solid #ddd;
border-bottom-color: #fff;
outline: none;
}
/* Content layout
---------------------------*/
#global {
position: relative;
width: 960px;
margin: 25px auto 50px auto;
}
/* Content */
#content {
width: 610px;
width: 60%;
}
#add-case{
width: 40%;
}
#header{
background: rgba(11,145,194,1);
background: -moz-linear-gradient(left, rgba(11,145,194,1) 0%, rgba(4,220,227,1) 100%);
background: -webkit-gradient(left top, right top, color-stop(0%, rgba(11,145,194,1)), color-stop(100%, rgba(4,220,227,1)));
background: -webkit-linear-gradient(left, rgba(11,145,194,1) 0%, rgba(4,220,227,1) 100%);
background: -o-linear-gradient(left, rgba(11,145,194,1) 0%, rgba(4,220,227,1) 100%);
background: -ms-linear-gradient(left, rgba(11,145,194,1) 0%, rgba(4,220,227,1) 100%);
background: linear-gradient(to right, rgba(11,145,194,1) 0%, rgba(4,220,227,1) 100%);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#0b91c2', endColorstr='#04dce3', GradientType=1 );
background-image: url("images/net-neutrality.png"), -moz-linear-gradient(left, rgba(11,145,194,1) 0%, rgba(4,220,227,1) 100%);
background-image: url("images/net-neutrality.png"), -webkit-gradient(left top, right top, color-stop(0%, rgba(11,145,194,1)), color-stop(100%, rgba(4,220,227,1)));
background-image: url("images/net-neutrality.png"), -webkit-linear-gradient(left, rgba(11,145,194,1) 0%, rgba(4,220,227,1) 100%);
background-image: url("images/net-neutrality.png"), -o-linear-gradient(left, rgba(11,145,194,1) 0%, rgba(4,220,227,1) 100%);
background-image: url("images/net-neutrality.png"), -ms-linear-gradient(left, rgba(11,145,194,1) 0%, rgba(4,220,227,1) 100%);
background-image: url("images/net-neutrality.png"), linear-gradient(to right, rgba(11,145,194,1) 0%, rgba(4,220,227,1) 100%);
}
h2{
margin: 1.5em 0 1em 0;
}
h2:first-child{
margin: 0.5em 0 1em 0;
}
#global h2:first-child {
margin-top: 0;
}
......@@ -373,6 +364,27 @@ h1 span {
margin-top: 1em;
}
.navbar-default {
background: #333;
border: none !important;
border-radius: 0;
}
.navbar-default .active a {
color:#555 !important;
}
.navbar-default a{
color:white !important;
}
.navbar-default li:hover{
background:#444 !important;
}
.navbar-default li.active{
background:#555 !important;
}
/* View page */
......@@ -455,7 +467,7 @@ div.comment {
input[type=submit], input[type=button], .button, input[type="text"], textarea, select {
font: 14.4px Helvetica, Arial, "Liberation Sans", FreeSans, sans-serif;
background: #fff;
border: 1px solid #ccc;
/*border: 1px solid #ccc;*/
-moz-border-radius: 2px;
-webkit-border-radius: 2px;
-o-border-radius: 2px;
......@@ -693,7 +705,7 @@ ul.messages {
#map { float: right; }
.logo-org { display: inline-block; margin: 15px; text-align: center; vertical-align: top; background-color: #f9f9f9; }
.logo-org img { height: 80px; }
.logo-org img { height: 80px; margin-bottom:10px}
.dark { background-color: #212121; }
tr.duplicate-status td { background: #aaa !important; }
......@@ -722,6 +734,32 @@ input[type="text"], input[type="textarea"] {
#push { clear: both; }
#wrapper {
max-width: 960px;
margin: auto;
}
#table {
clear: both;
}
@media screen and (max-width: 700px) {
h1{font-size:30px}
h2{font-size:24px}
h1 span{font-size:16px}
}
@media screen and (max-width: 500px) {
#add-case {
width:100%;
}
#content {
width:100%;
}
}
@media screen and (max-width: 870px) {
.navbar-right input[type="text"]{
width:100px;
}
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -24,12 +24,15 @@ function empty(node) {
// This fucntiosn check the first four forms
function check1st4() {
console.log('Check 1st4');
var resource=$('#id_resource_name').val();
var country=$('#id_country').val();
var op=$('#id_operator').val();
var contract=$('#id_contract').val();
var media=$('#id_media').val();
var contractual=$('#id_contractual').val();
var div=$('#similar_cases');
if(country && op && contract && media) {
if(country && op && contract && media && contractual && resource) {
$.getJSON('/lookup/?country='+country+'&contract='+contract+'&operator='+op+'&media='+media, function(data) {
if (data.length>0) {
div.parent().removeClass('hidden');
......@@ -40,6 +43,7 @@ function check1st4() {
var val=data.pop();
div.append('<li><a href="/view/'+val[0]+'">'+(val[1] || "no resource given")+'</a></li>');
};
console.log("Lookup : " + data);
});
$('#id_comment').parent().parent().show().focus();
$('#id_comment_ifr').focus();
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
{% extends "base.html" %}
{% load bt %}
{% load i18n %}
{% block active_tab_about %}id="current"{% endblock %}
{% block active_tab_about %}class="active"{% endblock %}
{% block content %}
<div id='global'>
<h3>{% trans "On the Internet, <strong>you</strong> decide what you do, right? <em>Not anymore!</em>" %}</h3>
<p>{% trans "Large telecommunication providers want to control what you do online. They want to restrict access to internet telephony in order to force you to use their telephone services. They want to charge you for viewing of videos. They want to prohibit the use of specific software on their networks, or throttle innovative applications such as peer-to-peer filesharing." %}</p>
<p>{% trans "This must stop. We want to ensure that your freedom online is protected and that you decide which content you access, and which applications and services you use. Net neutrality is about your freedom online." %}</p>
<p>{% trans "Violations on Net Neutrality are bad for freedom of communication, freedom of choice, innovation and communication costs. They lead to a situation where the provider can decide what you do online, not you, and this restricts your freedom. It becomes more difficult for innovative companies to offer their services via the internet, because they may be blocked or slowed down by providers. And it leads to higher communication costs because you may have to pay extra to use cheap services such as internet telephony." %}</p>
<p>{% trans "We need to ensure that the Internet remains free, open and accessible for all. This is what Net Neutrality is about. The European Commission and national regulators need to prohibit providers from restricting your online traffic and do so before it is too late. In order to convince them about the urgency of this problem, we aim to create a comprehensive report of Net Neutrality violations in Europe. This website is the way to report these violations." %}</p>
<h3>{% trans "On the Internet, <strong>you</strong> decide what you do, right? <em>Maybe not!</em>" %}</h3>
<p>{% trans "Online companies and telecommunication providers want to control what you do online. For example, they want to restrict access to Internet telephony in order to force you to use the telephone service that they want you to use. They want to charge you extra for watching videos or listening to music, if you choose a service that they are not promoting. They want to prohibit the use of specific software on their networks or throttle innovative applications such as peer-to-peer filesharing. They want people to pay to access your blog." %}</p>
<p>{% trans "This must stop. We want to ensure that your rights and freedoms online are protected and that you decide which content you access and which applications and services you use." %}</p>
<p>{% trans "Net Neutrality violations harm freedom of expression, freedom of information, freedom of choice, innovation, competition, privacy and increase communication costs. " %}</p>
<p>{% trans "We need to ensure that the Internet remains free, open and accessible for all. This is what net neutrality is about. The European Commission and national regulators need to prohibit providers from restricting your online traffic and do so before it is too late. In order to convince them about the urgency of this problem, we aim to create a comprehensive data set of Net Neutrality violations in Europe. " %}</p>
<h3>{% trans "Guidelines for reporting cases" %}</h3>
<p>{% trans "In reporting violations of Net Neutrality on RespectMyNet.eu, please describe only connection issues that are related to traffic discrimination, that is to say cases where Internet access providers discriminate traffic according to the source, destination, type or actual content of the data transmitted over the network (i.e. if your provider blocks traffic coming from YouTube or slows down Usenet traffic). If possible, please verify whether indeed the provider can be blamed: sometimes it is just the server itself which is not working (i.e. if a website is down, this is obviously not the fault of the internet access provider)." %}</p>
<p>{% trans "Internet providers can abuse their control over their network in several ways. For example, they can discriminate between individual applications by throttling, blocking or prioritising them - this is called &ldquo;technical discrimination&rdquo;. They can also discriminate between individual applications by excluding them from your monthly data cap - this is called &ldquo;economic discrimination&rdquo;, which is commonly known as &ldquo;zero-rating&rdquo;. A mixture of both types of discrimination is usually encountered in the provision of abusive &ldquo;Specialised Services&rdquo;, which can turn into paid-fast lanes." %}</p>
<p>{% trans "When reporting economic net neutrality violations through RespectMyNet.eu, please provide us with a description of the practice of your ISP. We need to know what services are not counted towards your monthly data cap and what happens with your Internet connection if your data cap is exceeded. By providing links to the relevant offerings, advertisement material and terms-of-service of the product, you are providing us with crucial evidence to present to the regulators. If you are not sure on how to classify a violation that you encounter, just leave the relevant fields empty. Submissions can be discussed and modified once they are in the system." %}</p>
<p>{% trans "When reporting technical net neutrality violations through RespectMyNet.eu, please describe only connection issues that are related to traffic discrimination, that is to say cases where Internet access providers discriminate between traffic according to the source, destination, type or actual content of the data transmitted over the network (i.e. if your provider blocks traffic coming from YouTube or slows down Usenet traffic). If possible, please verify whether the provider is the one to be blamed: sometimes it is just the server itself which is not working (i.e. if a website is down, this is obviously not the fault of the Internet access provider)." %}</p>
<p>{% trans "Sample of common ISP issues that DO NOT require a formal complaint (from: <a href='http://www.ispreview.co.uk/new/complain/complain.shtml'>http://www.ispreview.co.uk/new/complain/complain.shtml</a>)" %}</p>
<ul class="with-disc">
<li>
<p>{% trans "<b>Brief and Uncommon Critical Service (Email, Website Browsing etc.) Outages.</b>" %}</p>
<p>{% trans "Sadly, ISPs experience occasional problems with online services, such as email access. These are usually resolved after a few minutes or hours, an only very occasionally will they last longer than a day. Don't get too frustrated, inform them of your problem and allow some time for it to be resolved." %}</p>
<p>{% trans "Unfortunately, ISPs experience occasional problems with online services, such as email access. These are usually resolved after a few minutes or hours, and only very occasionally will they last longer than a day. Don't get too frustrated, inform them of your problem and allow some time for it to be resolved." %}</p>
</li>
<li>
<p>{% trans "<b>General Fluctuations in Broadband Speed.</b>" %}</p>
<p>{% trans 'Broadband is a so-called "best efforts" service, which means it is shared between many users and open to fluctuations in performance (often more so in dense urban areas). For example, if you have an 8Mbps package but your line is only rated to cope with 2Mbps then you should not be surprised to see speeds vary from around 1 to 1.5Mbps (potentially lower during peak periods). Few get the advertised or even best estimated speed for their line.' %}</p>
<p>{% trans "Broadband is a so-called &ldquo;best effort&rdquo; service, which means it is shared between many users and open to fluctuations in performance (especially in dense urban areas). For example, if you have an 8Mbps package but your line is only rated to cope with 2Mbps, you should not be surprised to see speeds vary from around 1 to 1.5Mbps (or even lower during peak periods). Very few providers provide information about broadband speed. This should change after the entry in operation of the new European net neutrality rules. Your ISP has to provide you with information about the traffic management that affects you, as well as included details in your contract regarding the minimum, maximum and average bandwidth speed of your Internet connection." %}</p>
</li>
<li>
<p>{% trans "<b>Short and Uncommon Broadband Connection Problems.</b>" %}</p>
<p>{% trans "Once again, connections do sometimes go down and fail to connect/reconnect, though usually for no more than one day at most. These issues should be very rare and 9 times out of 10 they will be fixed within a few minutes or hours." %}</p>
<p>{% trans "Once again, connections do sometimes go down and fail to connect/reconnect, though usually for no more than one day at most. These issues should be very rare and are usually fixed within a few minutes or hours." %}</p>
</li>
</ul>
</div>
......
{% load json_filters %}
{{ object_list|jsonify|safe }}
This diff is collapsed.
{% extends "base.html" %}
{% load bt %}
{% load i18n %}
{% block active_tab_start %}id="current"{% endblock %}
{% block active_tab_start %}class="active"{% endblock %}
{% block content %}
<div id='global'>
<p>{% trans "Do you want to check whether your access provider is manipulating your internet traffic? Great!" %}</p>
<p> {% trans "There are a lot of tools which make life easier for you. Here is a short selection." %}</p>
<p> {% trans "There are a lot of tools which make life easier for you. You can find very much more information about this subject on the website of <a href=\"http://www.measurementlab.net/tests\">measurementlab</a>. Here is a short selection." %}</p>
<h3>{% trans "Recommended tools" %}</h3>
<p>{% trans "These tools are probably the most helpful when it comes to tracking traffic discrimination." %}</p>
<ul class="with-disc">
<li><h4><a href="http://www.neubot.org/">neubot</a></h4>
<p>{% trans "<em>Available for Mac OS X, Ubuntu (GNU/Linux) and Windows.</em>" %}</p>
<p>{% trans "Neubot is a research project on network neutrality of the NEXA Center for Internet & Society at Politecnico di Torino. The project is based on a lightweight open-source program that interested users can download and install on their computers. The program runs in background and periodically performs transmission tests with some test servers and with other instances of the program itself. These transmission tests probe the Internet using various application level protocols. The program saves tests results locally and uploads them on the project servers. The collected dataset contains samples from various Providers and allows to monitor network neutrality." %}</p>
<p>{% trans "Neubot is a research project on network neutrality of the NEXA Center for Internet & Society at Politecnico di Torino. The project is based on a lightweight open-source programme that interested users can download and install on their computers. The programme runs in background and periodically performs transmission tests with some test servers and with other instances of the programme itself. These transmission tests probe the Internet using various application level protocols. The program saves tests results locally and uploads them on the project servers. The collected dataset contains samples from various Providers and allows to monitor network neutrality." %}</p>
</li>
<li><h4><a href="http://www.measurementlab.net/tools/glasnost">Glasnost test</a></h4>
<p>{% trans "<em>In-browser Java.</em>" %}</p>
......@@ -37,11 +37,6 @@
<p>{% trans "<em>Runs on Mac OS X, GNU/Linux and Windows</em>" %}</p>
<p>{% trans 'Determine whether an ISP is performing traffic shaping. ShaperProbe detects whether your ISP performs "traffic shaping". Traffic shaping means that your ISP automatically drops your access rate after you have downloaded or uploaded a certain number of bytes. ShaperProbe detects whether traffic shaping is used in either the upload or download directions, and in that case that it is used, ShaperProbe reports the shaping rate and the "maximum burst size" before shaping begins.' %}</p>
</li>
<li><h4><a href="http://gtnoise.net/nano/">NANO</a></h4>
<p>{% trans "<em>Runs on GNU/Linux only for now, Mac OS X and Windows versions to come.</em>" %}
<p>{% trans "Passive monitoring by NANO-agent: NANO-agent monitors the number of packets transferred for each active flow per unit time, as well as tracks for unexpected events like packet loss, and TCP RST packets. NANO-agent coallates each flow with the application that owns the flow. NANO agent also monitors the load on the client computer. All these statistics are reported to collection servers located at Georgia Tech. You may visualize your data by visiting this page." %}</p>
<p>{% trans "<em>Privacy:</em> NANO will monitor all of your Internet traffic and send back limited statistics, but does not collect data on what is being sent." %}</p>
</li>
<li><h4><a href="http://aqualab.cs.northwestern.edu/projects/NEWS.html">NEWS</a></h4>
<p>{% trans "Torrent-protocol based sensor plugin for Vuze/Azureus BitTorrent client using a crowd approach sharing data with peers." %}</p>
</li>
......
......@@ -2,7 +2,7 @@
{% load bt %}
{% load i18n %}
{% load comments %}
{% block active_tab_cases %}id="current"{% endblock %}
{% block active_tab_cases %}class="active"{% endblock %}
{% block styles %}
{% endblock %}
{% block adminext %}
......
......@@ -59,8 +59,8 @@ urlpatterns = patterns('',
url(r'^moderate/$',
view=bt.moderate,
name="moderate"),
url(r'^lookup/$',
view=bt.LookupView.as_view(),
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': '/'}),
......