diff options
author | Egor Yurtaev <yurtaev.egor@gmail.com> | 2014-12-04 18:47:21 +0600 |
---|---|---|
committer | Egor Yurtaev <yurtaev.egor@gmail.com> | 2014-12-25 12:56:47 +0600 |
commit | 6494f9adbd021ce60eb8b3e7adcef99bcc91c6a1 (patch) | |
tree | 42ae37420ae96c6f71aa2837e27f53c0cc757d07 | |
parent | cdface5a74454742dd1498a13ee8be0dc4926288 (diff) | |
download | omaha-server-6494f9adbd021ce60eb8b3e7adcef99bcc91c6a1.zip omaha-server-6494f9adbd021ce60eb8b3e7adcef99bcc91c6a1.tar.gz omaha-server-6494f9adbd021ce60eb8b3e7adcef99bcc91c6a1.tar.bz2 |
add 'crash' app
-rw-r--r-- | omaha_server/.coveragerc | 2 | ||||
-rw-r--r-- | omaha_server/crash/__init__.py | 0 | ||||
-rw-r--r-- | omaha_server/crash/admin.py | 30 | ||||
-rw-r--r-- | omaha_server/crash/forms.py | 28 | ||||
-rw-r--r-- | omaha_server/crash/migrations/0001_initial.py | 34 | ||||
-rw-r--r-- | omaha_server/crash/migrations/__init__.py | 0 | ||||
-rw-r--r-- | omaha_server/crash/models.py | 31 | ||||
-rw-r--r-- | omaha_server/crash/tests/__init__.py | 0 | ||||
-rw-r--r-- | omaha_server/crash/tests/test_models.py | 45 | ||||
-rw-r--r-- | omaha_server/crash/tests/test_views.py | 51 | ||||
-rw-r--r-- | omaha_server/crash/urls.py | 28 | ||||
-rw-r--r-- | omaha_server/crash/views.py | 48 | ||||
-rw-r--r-- | omaha_server/omaha_server/settings.py | 2 | ||||
-rw-r--r-- | omaha_server/omaha_server/settings_test.py | 2 | ||||
-rw-r--r-- | omaha_server/omaha_server/urls.py | 1 |
15 files changed, 301 insertions, 1 deletions
diff --git a/omaha_server/.coveragerc b/omaha_server/.coveragerc index 61e020e..0f4ac3c 100644 --- a/omaha_server/.coveragerc +++ b/omaha_server/.coveragerc @@ -6,4 +6,6 @@ omit = omaha/models.py omaha/forms.py omaha/admin.py + crash/admin.py + crash/models.py data_file = ../.coverage
\ No newline at end of file diff --git a/omaha_server/crash/__init__.py b/omaha_server/crash/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/omaha_server/crash/__init__.py diff --git a/omaha_server/crash/admin.py b/omaha_server/crash/admin.py new file mode 100644 index 0000000..d32d5be --- /dev/null +++ b/omaha_server/crash/admin.py @@ -0,0 +1,30 @@ +# coding: utf8 + +""" +This software is licensed under the Apache 2 license, quoted below. + +Copyright 2014 Crystalnix Limited + +Licensed under the Apache License, Version 2.0 (the "License"); you may not +use this file except in compliance with the License. You may obtain a copy of +the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +License for the specific language governing permissions and limitations under +the License. +""" + +from django.contrib import admin +from models import Crash + + +@admin.register(Crash) +class CrashAdmin(admin.ModelAdmin): + list_display = ('app_id', 'user_id', 'created', 'modified',) + list_display_links = ('app_id', 'user_id', 'created', 'modified',) + list_filter = ('created',) + search_fields = ('app_id', 'user_id',) diff --git a/omaha_server/crash/forms.py b/omaha_server/crash/forms.py new file mode 100644 index 0000000..c6e0ee5 --- /dev/null +++ b/omaha_server/crash/forms.py @@ -0,0 +1,28 @@ +# coding: utf8 + +""" +This software is licensed under the Apache 2 license, quoted below. + +Copyright 2014 Crystalnix Limited + +Licensed under the Apache License, Version 2.0 (the "License"); you may not +use this file except in compliance with the License. You may obtain a copy of +the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +License for the specific language governing permissions and limitations under +the License. +""" + +from django import forms +from models import Crash + + +class CrashFrom(forms.ModelForm): + class Meta: + model = Crash + exclude = [] diff --git a/omaha_server/crash/migrations/0001_initial.py b/omaha_server/crash/migrations/0001_initial.py new file mode 100644 index 0000000..f456fc4 --- /dev/null +++ b/omaha_server/crash/migrations/0001_initial.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations +import django.utils.timezone +import jsonfield.fields +import django_extensions.db.fields + + +class Migration(migrations.Migration): + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Crash', + fields=[ + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('created', django_extensions.db.fields.CreationDateTimeField(default=django.utils.timezone.now, verbose_name='created', editable=False, blank=True)), + ('modified', django_extensions.db.fields.ModificationDateTimeField(default=django.utils.timezone.now, verbose_name='modified', editable=False, blank=True)), + ('mini_dump', models.FileField(upload_to=b'minidump/%Y/%m/%d')), + ('app_id', models.CharField(max_length=38, null=True, blank=True)), + ('user_id', models.CharField(max_length=38, null=True, blank=True)), + ('meta', jsonfield.fields.JSONField(help_text=b'JSON format', null=True, verbose_name=b'Meta-information', blank=True)), + ], + options={ + 'ordering': ('-modified', '-created'), + 'abstract': False, + 'get_latest_by': 'modified', + }, + bases=(models.Model,), + ), + ] diff --git a/omaha_server/crash/migrations/__init__.py b/omaha_server/crash/migrations/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/omaha_server/crash/migrations/__init__.py diff --git a/omaha_server/crash/models.py b/omaha_server/crash/models.py new file mode 100644 index 0000000..263ae82 --- /dev/null +++ b/omaha_server/crash/models.py @@ -0,0 +1,31 @@ +# coding: utf8 + +""" +This software is licensed under the Apache 2 license, quoted below. + +Copyright 2014 Crystalnix Limited + +Licensed under the Apache License, Version 2.0 (the "License"); you may not +use this file except in compliance with the License. You may obtain a copy of +the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +License for the specific language governing permissions and limitations under +the License. +""" + +from django.db import models +from django_extensions.db.models import TimeStampedModel + +from jsonfield import JSONField + + +class Crash(TimeStampedModel): + mini_dump = models.FileField(upload_to='minidump/%Y/%m/%d') + app_id = models.CharField(max_length=38, null=True, blank=True) + user_id = models.CharField(max_length=38, null=True, blank=True) + meta = JSONField(verbose_name='Meta-information', help_text='JSON format', null=True, blank=True) diff --git a/omaha_server/crash/tests/__init__.py b/omaha_server/crash/tests/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/omaha_server/crash/tests/__init__.py diff --git a/omaha_server/crash/tests/test_models.py b/omaha_server/crash/tests/test_models.py new file mode 100644 index 0000000..5a3e160 --- /dev/null +++ b/omaha_server/crash/tests/test_models.py @@ -0,0 +1,45 @@ +# coding: utf8 + +""" +This software is licensed under the Apache 2 license, quoted below. + +Copyright 2014 Crystalnix Limited + +Licensed under the Apache License, Version 2.0 (the "License"); you may not +use this file except in compliance with the License. You may obtain a copy of +the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +License for the specific language governing permissions and limitations under +the License. +""" + +from django import test +from django.core.files.uploadedfile import SimpleUploadedFile + +from crash.models import Crash + + +class CrashModelTest(test.TestCase): + def test_model(self): + meta = dict( + lang='en', + version='1.0.0.1', + ) + app_id = '{D0AB2EBC-931B-4013-9FEB-C9C4C2225C8C}', + user_id = '{2882CF9B-D9C2-4edb-9AAF-8ED5FCF366F7}', + obj = Crash.objects.create( + app_id=app_id, + user_id=user_id, + mini_dump=SimpleUploadedFile('./dump.dat', False), + meta=meta, + ) + + self.assertTrue(obj) + self.assertDictEqual(obj.meta, meta) + self.assertEqual(obj.app_id, app_id) + self.assertEqual(obj.user_id, user_id) diff --git a/omaha_server/crash/tests/test_views.py b/omaha_server/crash/tests/test_views.py new file mode 100644 index 0000000..7db7f5b --- /dev/null +++ b/omaha_server/crash/tests/test_views.py @@ -0,0 +1,51 @@ +# coding: utf8 + +""" +This software is licensed under the Apache 2 license, quoted below. + +Copyright 2014 Crystalnix Limited + +Licensed under the Apache License, Version 2.0 (the "License"); you may not +use this file except in compliance with the License. You may obtain a copy of +the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +License for the specific language governing permissions and limitations under +the License. +""" + +from django import test +from django.core.files.uploadedfile import SimpleUploadedFile +from django.core.urlresolvers import reverse + +from crash.models import Crash + + +class CrashViewTest(test.TestCase): + def test_view(self): + meta = dict( + lang='en', + version='1.0.0.1', + ) + mini_dump_file = SimpleUploadedFile("minidump.dat", "content") + form_data = dict( + app_id='{D0AB2EBC-931B-4013-9FEB-C9C4C2225C8C}', + user_id='{2882CF9B-D9C2-4edb-9AAF-8ED5FCF366F7}', + mini_dump=mini_dump_file, + ) + + form_data.update(meta) + + self.assertEqual(Crash.objects.all().count(), 0) + response = self.client.post(reverse('crash'), form_data) + self.assertEqual(response.status_code, 201) + self.assertEqual(Crash.objects.all().count(), 1) + obj = Crash.objects.get() + self.assertEqual(response.content, str(obj.pk)) + self.assertDictEqual(obj.meta, meta) + self.assertEqual(obj.app_id, form_data['app_id']) + self.assertEqual(obj.user_id, form_data['user_id']) diff --git a/omaha_server/crash/urls.py b/omaha_server/crash/urls.py new file mode 100644 index 0000000..1cef528 --- /dev/null +++ b/omaha_server/crash/urls.py @@ -0,0 +1,28 @@ +# coding: utf8 + +""" +This software is licensed under the Apache 2 license, quoted below. + +Copyright 2014 Crystalnix Limited + +Licensed under the Apache License, Version 2.0 (the "License"); you may not +use this file except in compliance with the License. You may obtain a copy of +the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +License for the specific language governing permissions and limitations under +the License. +""" + +from django.conf.urls import patterns, url + +from views import CrashFormView + + +urlpatterns = patterns('', + url(r'^service/crash_report/$', CrashFormView.as_view(), name='crash'), +) diff --git a/omaha_server/crash/views.py b/omaha_server/crash/views.py new file mode 100644 index 0000000..7f86e24 --- /dev/null +++ b/omaha_server/crash/views.py @@ -0,0 +1,48 @@ +# coding: utf8 + +""" +This software is licensed under the Apache 2 license, quoted below. + +Copyright 2014 Crystalnix Limited + +Licensed under the Apache License, Version 2.0 (the "License"); you may not +use this file except in compliance with the License. You may obtain a copy of +the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +License for the specific language governing permissions and limitations under +the License. +""" + +import json + +from django.views.generic import FormView +from django.views.decorators.csrf import csrf_exempt +from django.http import HttpResponse +from forms import CrashFrom + + +class CrashFormView(FormView): + http_method_names = ('post',) + form_class = CrashFrom + + @csrf_exempt + def dispatch(self, *args, **kwargs): + return super(CrashFormView, self).dispatch(*args, **kwargs) + + def form_valid(self, form): + meta = self.request.POST.dict() + meta.pop("app_id", None) + meta.pop("user_id", None) + obj = form.save(commit=False) + if meta: + obj.meta = meta + obj.save() + return HttpResponse(obj.pk, status=201) + + def form_invalid(self, form): + return HttpResponse(json.dumps(form.errors), status=400, content_type='application/json') diff --git a/omaha_server/omaha_server/settings.py b/omaha_server/omaha_server/settings.py index 59d44ed..e8e3362 100644 --- a/omaha_server/omaha_server/settings.py +++ b/omaha_server/omaha_server/settings.py @@ -26,6 +26,7 @@ SUIT_CONFIG = { 'MENU': ( 'sites', {'app': 'omaha', 'label': 'Omaha', 'icon': 'icon-refresh'}, + {'app': 'crash', 'label': 'Crash reports', 'icon': 'icon-fire'}, {'label': 'Statistics', 'url': 'omaha_statistics', 'icon': 'icon-star'}, ), } @@ -68,6 +69,7 @@ INSTALLED_APPS = ( 'django_tables2', 'omaha', + 'crash', ) MIDDLEWARE_CLASSES = ( diff --git a/omaha_server/omaha_server/settings_test.py b/omaha_server/omaha_server/settings_test.py index c1dbc45..7c40832 100644 --- a/omaha_server/omaha_server/settings_test.py +++ b/omaha_server/omaha_server/settings_test.py @@ -13,7 +13,7 @@ TEST_RUNNER = 'django_nose.NoseTestSuiteRunner' NOSE_ARGS = [ '--with-coverage', - '--cover-package=omaha_server,omaha', + '--cover-package=omaha_server,omaha,crash', '--cover-inclusive', '--with-doctest', ] diff --git a/omaha_server/omaha_server/urls.py b/omaha_server/omaha_server/urls.py index e334ef2..abd5ac2 100644 --- a/omaha_server/omaha_server/urls.py +++ b/omaha_server/omaha_server/urls.py @@ -5,6 +5,7 @@ from django.contrib import admin urlpatterns = patterns('', url(r'', include('omaha.urls')), + url(r'', include('crash.urls')), url(r'^admin/', include(admin.site.urls)), ) |