Remove SiteEvent models and associated code (#10259)
Remove SiteEvent models and associated code
This commit is contained in:
Родитель
33664eadac
Коммит
dd3dcb00fe
|
@ -430,11 +430,6 @@ def loc(s):
|
||||||
return trim_whitespace(s)
|
return trim_whitespace(s)
|
||||||
|
|
||||||
|
|
||||||
@library.global_function
|
|
||||||
def site_event_type(type):
|
|
||||||
return amo.SITE_EVENT_CHOICES[type]
|
|
||||||
|
|
||||||
|
|
||||||
@library.global_function
|
@library.global_function
|
||||||
@jinja2.contextfunction
|
@jinja2.contextfunction
|
||||||
def remora_url(context, url, lang=None, app=None, prefix=''):
|
def remora_url(context, url, lang=None, app=None, prefix=''):
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
from datetime import datetime
|
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from mock import Mock
|
from mock import Mock
|
||||||
|
|
||||||
|
@ -10,7 +8,7 @@ from olympia.addons.models import Addon
|
||||||
from olympia.amo import models as amo_models
|
from olympia.amo import models as amo_models
|
||||||
from olympia.amo.tests import TestCase
|
from olympia.amo.tests import TestCase
|
||||||
from olympia.users.models import UserProfile
|
from olympia.users.models import UserProfile
|
||||||
from olympia.zadmin.models import SiteEvent
|
from olympia.zadmin.models import Config
|
||||||
|
|
||||||
|
|
||||||
pytestmark = pytest.mark.django_db
|
pytestmark = pytest.mark.django_db
|
||||||
|
@ -197,22 +195,20 @@ class BasePreviewMixin(object):
|
||||||
|
|
||||||
class BaseQuerysetTestCase(TestCase):
|
class BaseQuerysetTestCase(TestCase):
|
||||||
def test_queryset_transform(self):
|
def test_queryset_transform(self):
|
||||||
# We test with the SiteEvent model because it's a simple model
|
# We test with the Config model because it's a simple model
|
||||||
# with no translated fields, no caching or other fancy features.
|
# with no translated fields, no caching or other fancy features.
|
||||||
SiteEvent.objects.create(start=datetime.now(), description='Zero')
|
Config.objects.create(key='a', value='Zero')
|
||||||
first = SiteEvent.objects.create(start=datetime.now(),
|
first = Config.objects.create(key='b', value='First')
|
||||||
description='First')
|
second = Config.objects.create(key='c', value='Second')
|
||||||
second = SiteEvent.objects.create(start=datetime.now(),
|
Config.objects.create(key='d', value='Third')
|
||||||
description='Second')
|
Config.objects.create(key='e', value='')
|
||||||
SiteEvent.objects.create(start=datetime.now(), description='Third')
|
|
||||||
SiteEvent.objects.create(start=datetime.now(), description='')
|
|
||||||
|
|
||||||
seen_by_first_transform = []
|
seen_by_first_transform = []
|
||||||
seen_by_second_transform = []
|
seen_by_second_transform = []
|
||||||
with self.assertNumQueries(0):
|
with self.assertNumQueries(0):
|
||||||
# No database hit yet, everything is still lazy.
|
# No database hit yet, everything is still lazy.
|
||||||
qs = amo_models.BaseQuerySet(SiteEvent)
|
qs = amo_models.BaseQuerySet(Config)
|
||||||
qs = qs.exclude(description='').order_by('id')[1:3]
|
qs = qs.exclude(value='').order_by('key')[1:3]
|
||||||
qs = qs.transform(
|
qs = qs.transform(
|
||||||
lambda items: seen_by_first_transform.extend(list(items)))
|
lambda items: seen_by_first_transform.extend(list(items)))
|
||||||
qs = qs.transform(
|
qs = qs.transform(
|
||||||
|
|
|
@ -390,19 +390,6 @@ VALIDATOR_SKELETON_EXCEPTION_WEBEXT = {
|
||||||
|
|
||||||
VERSION_SEARCH = re.compile(r'\.(\d+)$')
|
VERSION_SEARCH = re.compile(r'\.(\d+)$')
|
||||||
|
|
||||||
# Types of SiteEvent
|
|
||||||
SITE_EVENT_OTHER = 1
|
|
||||||
SITE_EVENT_EXCEPTION = 2
|
|
||||||
SITE_EVENT_RELEASE = 3
|
|
||||||
SITE_EVENT_CHANGE = 4
|
|
||||||
|
|
||||||
SITE_EVENT_CHOICES = {
|
|
||||||
SITE_EVENT_OTHER: _('Other'),
|
|
||||||
SITE_EVENT_EXCEPTION: _('Exception'),
|
|
||||||
SITE_EVENT_RELEASE: _('Release'),
|
|
||||||
SITE_EVENT_CHANGE: _('Change'),
|
|
||||||
}
|
|
||||||
|
|
||||||
# For use in urls.
|
# For use in urls.
|
||||||
ADDON_ID = r"""(?P<addon_id>[^/<>"']+)"""
|
ADDON_ID = r"""(?P<addon_id>[^/<>"']+)"""
|
||||||
ADDON_UUID = r'(?P<uuid>[\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12})'
|
ADDON_UUID = r'(?P<uuid>[\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12})'
|
||||||
|
|
|
@ -12,7 +12,6 @@ from django.conf import settings
|
||||||
from django.core.exceptions import PermissionDenied
|
from django.core.exceptions import PermissionDenied
|
||||||
from django.core.files.storage import get_storage_class
|
from django.core.files.storage import get_storage_class
|
||||||
from django.db import connection
|
from django.db import connection
|
||||||
from django.db.models import Q
|
|
||||||
from django.db.transaction import non_atomic_requests
|
from django.db.transaction import non_atomic_requests
|
||||||
from django.utils.cache import add_never_cache_headers, patch_cache_control
|
from django.utils.cache import add_never_cache_headers, patch_cache_control
|
||||||
|
|
||||||
|
@ -25,11 +24,10 @@ from olympia import amo
|
||||||
from olympia.access import acl
|
from olympia.access import acl
|
||||||
from olympia.stats.decorators import addon_view_stats
|
from olympia.stats.decorators import addon_view_stats
|
||||||
from olympia.lib.cache import memoize
|
from olympia.lib.cache import memoize
|
||||||
from olympia.amo.decorators import allow_cross_site_request, json_view
|
from olympia.amo.decorators import allow_cross_site_request
|
||||||
from olympia.amo.urlresolvers import reverse
|
from olympia.amo.urlresolvers import reverse
|
||||||
from olympia.amo.utils import AMOJSONEncoder, render
|
from olympia.amo.utils import AMOJSONEncoder, render
|
||||||
from olympia.stats.forms import DateForm
|
from olympia.stats.forms import DateForm
|
||||||
from olympia.zadmin.models import SiteEvent
|
|
||||||
|
|
||||||
from .models import DownloadCount, ThemeUserCount, UpdateCount
|
from .models import DownloadCount, ThemeUserCount, UpdateCount
|
||||||
|
|
||||||
|
@ -380,43 +378,6 @@ def get_daterange_or_404(start, end):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@json_view
|
|
||||||
@non_atomic_requests
|
|
||||||
def site_events(request, start, end):
|
|
||||||
"""Return site events in the given timeframe."""
|
|
||||||
start, end = get_daterange_or_404(start, end)
|
|
||||||
qs = SiteEvent.objects.filter(
|
|
||||||
Q(start__gte=start, start__lte=end) |
|
|
||||||
Q(end__gte=start, end__lte=end))
|
|
||||||
|
|
||||||
events = list(site_event_format(request, qs))
|
|
||||||
|
|
||||||
type_pretty = unicode(amo.SITE_EVENT_CHOICES[amo.SITE_EVENT_RELEASE])
|
|
||||||
|
|
||||||
releases = product_details.firefox_history_major_releases
|
|
||||||
|
|
||||||
for version, date_ in releases.items():
|
|
||||||
events.append({
|
|
||||||
'start': date_,
|
|
||||||
'type_pretty': type_pretty,
|
|
||||||
'type': amo.SITE_EVENT_RELEASE,
|
|
||||||
'description': 'Firefox %s released' % version,
|
|
||||||
})
|
|
||||||
return events
|
|
||||||
|
|
||||||
|
|
||||||
def site_event_format(request, events):
|
|
||||||
for e in events:
|
|
||||||
yield {
|
|
||||||
'start': e.start.isoformat(),
|
|
||||||
'end': e.end.isoformat() if e.end else None,
|
|
||||||
'type_pretty': unicode(amo.SITE_EVENT_CHOICES[e.event_type]),
|
|
||||||
'type': e.event_type,
|
|
||||||
'description': e.description,
|
|
||||||
'url': e.more_info_url,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def daterange(start_date, end_date):
|
def daterange(start_date, end_date):
|
||||||
for n in range((end_date - start_date).days):
|
for n in range((end_date - start_date).days):
|
||||||
yield start_date + timedelta(n)
|
yield start_date + timedelta(n)
|
||||||
|
|
|
@ -9,7 +9,6 @@ from django.views.static import serve as serve_static
|
||||||
from olympia.addons import views as addons_views
|
from olympia.addons import views as addons_views
|
||||||
from olympia.amo.urlresolvers import reverse
|
from olympia.amo.urlresolvers import reverse
|
||||||
from olympia.amo.utils import urlparams
|
from olympia.amo.utils import urlparams
|
||||||
from olympia.stats import views as stats_views
|
|
||||||
from olympia.versions import views as version_views
|
from olympia.versions import views as version_views
|
||||||
from olympia.versions.urls import download_patterns
|
from olympia.versions.urls import download_patterns
|
||||||
|
|
||||||
|
@ -85,10 +84,6 @@ urlpatterns = [
|
||||||
# API v3+.
|
# API v3+.
|
||||||
url(r'^api/', include('olympia.api.urls')),
|
url(r'^api/', include('olympia.api.urls')),
|
||||||
|
|
||||||
# Site events data.
|
|
||||||
url(r'^statistics/events-(?P<start>\d{8})-(?P<end>\d{8})\.json$',
|
|
||||||
stats_views.site_events, name='amo.site_events'),
|
|
||||||
|
|
||||||
# Site statistics that we are going to catch, the rest will fall through.
|
# Site statistics that we are going to catch, the rest will fall through.
|
||||||
url(r'^statistics/', include('olympia.stats.urls')),
|
url(r'^statistics/', include('olympia.stats.urls')),
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,6 @@ from olympia.addons.models import Addon
|
||||||
from olympia.bandwagon.models import (
|
from olympia.bandwagon.models import (
|
||||||
Collection, FeaturedCollection, MonthlyPick)
|
Collection, FeaturedCollection, MonthlyPick)
|
||||||
from olympia.files.models import File
|
from olympia.files.models import File
|
||||||
from olympia.zadmin.models import SiteEvent
|
|
||||||
|
|
||||||
|
|
||||||
LOGGER_NAME = 'z.zadmin'
|
LOGGER_NAME = 'z.zadmin'
|
||||||
|
@ -125,10 +124,3 @@ class FileStatusForm(ModelForm):
|
||||||
|
|
||||||
FileFormSet = modelformset_factory(File, form=FileStatusForm,
|
FileFormSet = modelformset_factory(File, form=FileStatusForm,
|
||||||
formset=BaseModelFormSet, extra=0)
|
formset=BaseModelFormSet, extra=0)
|
||||||
|
|
||||||
|
|
||||||
class SiteEventForm(ModelForm):
|
|
||||||
class Meta:
|
|
||||||
model = SiteEvent
|
|
||||||
fields = ('start', 'end', 'event_type', 'description',
|
|
||||||
'more_info_url')
|
|
||||||
|
|
|
@ -185,27 +185,3 @@ class EmailPreview(ModelBase):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
db_table = 'email_preview'
|
db_table = 'email_preview'
|
||||||
|
|
||||||
|
|
||||||
class SiteEvent(models.Model):
|
|
||||||
"""Information records about downtime, releases, and other pertinent
|
|
||||||
events on the site."""
|
|
||||||
|
|
||||||
SITE_EVENT_CHOICES = amo.SITE_EVENT_CHOICES.items()
|
|
||||||
|
|
||||||
start = models.DateField(db_index=True,
|
|
||||||
help_text='The time at which the event began.')
|
|
||||||
end = models.DateField(
|
|
||||||
db_index=True, null=True, blank=True,
|
|
||||||
help_text='If the event was a range, the time at which it ended.')
|
|
||||||
event_type = models.PositiveIntegerField(choices=SITE_EVENT_CHOICES,
|
|
||||||
db_index=True, default=0)
|
|
||||||
description = models.CharField(max_length=255, blank=True, null=True)
|
|
||||||
# An outbound link to an explanatory blog post or bug.
|
|
||||||
more_info_url = models.URLField(max_length=255, blank=True, null=True)
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
db_table = 'zadmin_siteevent'
|
|
||||||
|
|
||||||
def __unicode__(self):
|
|
||||||
return self.description
|
|
||||||
|
|
|
@ -1,46 +0,0 @@
|
||||||
{% extends 'zadmin/base.html' %}
|
|
||||||
|
|
||||||
{% set title = 'Site Events' %}
|
|
||||||
|
|
||||||
{% block title %}{{ page_title(title) }}{% endblock %}
|
|
||||||
|
|
||||||
{% block extrahead %}
|
|
||||||
<link rel="stylesheet"
|
|
||||||
href="{{ static('css/zamboni/jquery-ui/custom-1.7.2.css') }}">
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
<h2>{{ title }}</h2>
|
|
||||||
|
|
||||||
<form method="post">
|
|
||||||
{% csrf_token %}
|
|
||||||
{{ form.as_p() }}
|
|
||||||
<input type="submit" value="Add New Event">
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<table>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>ID
|
|
||||||
<th>Type
|
|
||||||
<th>Start
|
|
||||||
<th>End
|
|
||||||
<th>Description
|
|
||||||
<th>URL
|
|
||||||
<th colspan=2>Actions
|
|
||||||
<tbody>
|
|
||||||
{% for event in events %}
|
|
||||||
<tr>
|
|
||||||
<td>{{ event.id }}
|
|
||||||
<td>{{ site_event_type(event.event_type) }}
|
|
||||||
<td>{{ event.start }}
|
|
||||||
<td>{{ event.end }}
|
|
||||||
<td>{{ event.description }}
|
|
||||||
<td>{{ event.more_info_url }}
|
|
||||||
<td><a href="{{ url('zadmin.site_events', event.id) }}">edit</a>
|
|
||||||
<td><a href="{{ url('zadmin.site_events.delete', event.id) }}">remove</a>
|
|
||||||
{% else %}
|
|
||||||
<tr><td colspan=0>No Records Found.
|
|
||||||
{% endfor %}
|
|
||||||
</table>
|
|
||||||
{% endblock %}
|
|
|
@ -26,7 +26,6 @@ def admin_site_links():
|
||||||
('View site settings', reverse('zadmin.settings')),
|
('View site settings', reverse('zadmin.settings')),
|
||||||
('View request environment', reverse('zadmin.env')),
|
('View request environment', reverse('zadmin.env')),
|
||||||
('Django admin pages', reverse('zadmin.home')),
|
('Django admin pages', reverse('zadmin.home')),
|
||||||
('Site Events', reverse('zadmin.site_events')),
|
|
||||||
],
|
],
|
||||||
'tools': [
|
'tools': [
|
||||||
('Manage elasticsearch', reverse('zadmin.elastic')),
|
('Manage elasticsearch', reverse('zadmin.elastic')),
|
||||||
|
|
|
@ -104,52 +104,6 @@ class TestHomeAndIndex(TestCase):
|
||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
|
|
||||||
|
|
||||||
class TestSiteEvents(TestCase):
|
|
||||||
fixtures = ['base/users', 'zadmin/tests/siteevents']
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
super(TestSiteEvents, self).setUp()
|
|
||||||
self.client.login(email='admin@mozilla.com')
|
|
||||||
|
|
||||||
def test_get(self):
|
|
||||||
url = reverse('zadmin.site_events')
|
|
||||||
response = self.client.get(url)
|
|
||||||
assert response.status_code == 200
|
|
||||||
events = response.context['events']
|
|
||||||
assert len(events) == 1
|
|
||||||
|
|
||||||
def test_add(self):
|
|
||||||
url = reverse('zadmin.site_events')
|
|
||||||
new_event = {
|
|
||||||
'event_type': 2,
|
|
||||||
'start': '2012-01-01',
|
|
||||||
'description': 'foo',
|
|
||||||
}
|
|
||||||
response = self.client.post(url, new_event, follow=True)
|
|
||||||
assert response.status_code == 200
|
|
||||||
events = response.context['events']
|
|
||||||
assert len(events) == 2
|
|
||||||
|
|
||||||
def test_edit(self):
|
|
||||||
url = reverse('zadmin.site_events', args=[1])
|
|
||||||
modified_event = {
|
|
||||||
'event_type': 2,
|
|
||||||
'start': '2012-01-01',
|
|
||||||
'description': 'bar',
|
|
||||||
}
|
|
||||||
response = self.client.post(url, modified_event, follow=True)
|
|
||||||
assert response.status_code == 200
|
|
||||||
events = response.context['events']
|
|
||||||
assert events[0].description == 'bar'
|
|
||||||
|
|
||||||
def test_delete(self):
|
|
||||||
url = reverse('zadmin.site_events.delete', args=[1])
|
|
||||||
response = self.client.get(url, follow=True)
|
|
||||||
assert response.status_code == 200
|
|
||||||
events = response.context['events']
|
|
||||||
assert len(events) == 0
|
|
||||||
|
|
||||||
|
|
||||||
class TestEmailPreview(TestCase):
|
class TestEmailPreview(TestCase):
|
||||||
fixtures = ['base/addon_3615', 'base/users']
|
fixtures = ['base/addon_3615', 'base/users']
|
||||||
|
|
||||||
|
|
|
@ -54,12 +54,6 @@ urlpatterns = [
|
||||||
url(r'^email-devs$', views.email_devs, name='zadmin.email_devs'),
|
url(r'^email-devs$', views.email_devs, name='zadmin.email_devs'),
|
||||||
url(r'^addon-search$', views.addon_search, name='zadmin.addon-search'),
|
url(r'^addon-search$', views.addon_search, name='zadmin.addon-search'),
|
||||||
|
|
||||||
# Site Event admin.
|
|
||||||
url(r'^events/(?P<event_id>\d+)?$', views.site_events,
|
|
||||||
name='zadmin.site_events'),
|
|
||||||
url(r'^events/(?P<event_id>\d+)/delete$', views.delete_site_event,
|
|
||||||
name='zadmin.site_events.delete'),
|
|
||||||
|
|
||||||
# The Django admin.
|
# The Django admin.
|
||||||
url(r'^models/',
|
url(r'^models/',
|
||||||
include((admin.site.get_urls(), 'admin'), namespace=admin.site.name)),
|
include((admin.site.get_urls(), 'admin'), namespace=admin.site.name)),
|
||||||
|
|
|
@ -27,8 +27,6 @@ from olympia.bandwagon.models import Collection
|
||||||
from olympia.files.models import File, FileUpload
|
from olympia.files.models import File, FileUpload
|
||||||
from olympia.stats.search import get_mappings as get_stats_mappings
|
from olympia.stats.search import get_mappings as get_stats_mappings
|
||||||
from olympia.versions.models import Version
|
from olympia.versions.models import Version
|
||||||
from olympia.zadmin.forms import SiteEventForm
|
|
||||||
from olympia.zadmin.models import SiteEvent
|
|
||||||
|
|
||||||
from . import tasks
|
from . import tasks
|
||||||
from .decorators import admin_required
|
from .decorators import admin_required
|
||||||
|
@ -335,29 +333,3 @@ def recalc_hash(request, file_id):
|
||||||
messages.success(request,
|
messages.success(request,
|
||||||
'File hash and size recalculated for file %d.' % file.id)
|
'File hash and size recalculated for file %d.' % file.id)
|
||||||
return {'success': 1}
|
return {'success': 1}
|
||||||
|
|
||||||
|
|
||||||
@admin.site.admin_view
|
|
||||||
def site_events(request, event_id=None):
|
|
||||||
event = get_object_or_404(SiteEvent, pk=event_id) if event_id else None
|
|
||||||
data = request.POST or None
|
|
||||||
|
|
||||||
if event:
|
|
||||||
form = SiteEventForm(data, instance=event)
|
|
||||||
else:
|
|
||||||
form = SiteEventForm(data)
|
|
||||||
|
|
||||||
if request.method == 'POST' and form.is_valid():
|
|
||||||
form.save()
|
|
||||||
return redirect('zadmin.site_events')
|
|
||||||
pager = amo.utils.paginate(request, SiteEvent.objects.all(), 30)
|
|
||||||
events = pager.object_list
|
|
||||||
return render(request, 'zadmin/site_events.html', {
|
|
||||||
'form': form, 'events': events})
|
|
||||||
|
|
||||||
|
|
||||||
@admin.site.admin_view
|
|
||||||
def delete_site_event(request, event_id):
|
|
||||||
event = get_object_or_404(SiteEvent, pk=event_id)
|
|
||||||
event.delete()
|
|
||||||
return redirect('zadmin.site_events')
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче