From 67b485507b4b73983bdc784555d92bcd986b8430 Mon Sep 17 00:00:00 2001 From: Goran Topic Date: Mon, 23 Oct 2017 13:02:32 +0900 Subject: [PATCH 01/83] Bugfix: latest era --- raidar/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/raidar/views.py b/raidar/views.py index 3419f031..0a7f62fc 100644 --- a/raidar/views.py +++ b/raidar/views.py @@ -203,7 +203,7 @@ def global_stats(request, era_id=None, area_id=None, json=None): try: if era_id is None: - era_id = eras[-1]['id'] + era_id = eras[0]['id'] era = Era.objects.get(id=era_id) if area_id is None: raw_data = era.val From 4a8a8b87d4a53649b655d449eed54ff1844c18e7 Mon Sep 17 00:00:00 2001 From: Goran Topic Date: Mon, 23 Oct 2017 14:37:54 +0900 Subject: [PATCH 02/83] Support for django debug toolbar --- gw2raidar/settings.py | 7 +++++++ raidar/urls.py | 9 ++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/gw2raidar/settings.py b/gw2raidar/settings.py index a0fdfcc8..e9481edd 100644 --- a/gw2raidar/settings.py +++ b/gw2raidar/settings.py @@ -37,6 +37,8 @@ # (it can be set in `settings_local.py`) ALLOWED_HOSTS = [] +INTERNAL_IPS = ['127.0.0.1'] + # Application definition @@ -160,3 +162,8 @@ from .settings_local import * except ImportError: pass + +if DEBUG: + if importlib.util.find_spec("debug_toolbar"): + INSTALLED_APPS.append('debug_toolbar') + MIDDLEWARE.append('debug_toolbar.middleware.DebugToolbarMiddleware') diff --git a/raidar/urls.py b/raidar/urls.py index 9926ae41..d1f21fd6 100644 --- a/raidar/urls.py +++ b/raidar/urls.py @@ -1,6 +1,7 @@ from django.conf import settings -from django.conf.urls import url +from django.conf.urls import url, include from django.contrib.auth import views as auth_views +import importlib from . import views @@ -30,3 +31,9 @@ url(r'^$', views.index, name = "index"), url(r'^global_stats(?:/(?P[0-9]+))?(?:/area-(?P[0-9]+))?(?P\.json)?$', views.global_stats, name = "global_stats"), ] + +if settings.DEBUG and importlib.util.find_spec('debug_toolbar'): + import debug_toolbar + urlpatterns = [ + url(r'^__debug__/', include(debug_toolbar.urls)), + ] + urlpatterns From aabb51adcdc0ae326a09ce50a7e2bd064044bf1e Mon Sep 17 00:00:00 2001 From: Goran Topic Date: Mon, 23 Oct 2017 06:29:08 +0000 Subject: [PATCH 03/83] Select related in encounter admin --- raidar/admin.py | 1 + 1 file changed, 1 insertion(+) diff --git a/raidar/admin.py b/raidar/admin.py index 351416f9..72b8718f 100644 --- a/raidar/admin.py +++ b/raidar/admin.py @@ -81,6 +81,7 @@ def url_id_link(self, obj): search_fields = ('=url_id', '=filename', '^area__name', '=characters__name', '^characters__account__name', '=characters__account__user__username', '=tags__name', '=category__name') list_display = ('filename', 'url_id_link', 'area', 'success', 'category', 'started_at', 'duration', 'uploaded_at', 'uploaded_by') + list_select_related = ('category', 'uploaded_by', 'area') inlines = (ParticipationInline,) readonly_fields = ('url_id', 'started_at', 'duration', 'uploaded_at', 'uploaded_by', 'area', 'filename') From 68adb6d2d3f8c9bdbb541b6ac2f0ece822d3dca1 Mon Sep 17 00:00:00 2001 From: Goran Topic Date: Mon, 23 Oct 2017 16:26:18 +0900 Subject: [PATCH 04/83] Make profile graph only plot successes --- raidar/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/raidar/views.py b/raidar/views.py index 0a7f62fc..bb22cb1e 100644 --- a/raidar/views.py +++ b/raidar/views.py @@ -532,7 +532,7 @@ def profile_graph(request): stat = request.POST['stat'] participations = Participation.objects.select_related('encounter').filter( - encounter__era_id=era_id, character__account__user=request.user) + encounter__era_id=era_id, character__account__user=request.user, encounter__success=True) try: if area_id.startswith('All'): From 8781966b5904fc4e086b73a50cfef9dcae4d6652 Mon Sep 17 00:00:00 2001 From: Immortius Date: Mon, 23 Oct 2017 19:39:58 +1100 Subject: [PATCH 05/83] #184 Added mo cm detection --- analyser/analyser.py | 2 +- analyser/bosses.py | 13 ++++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/analyser/analyser.py b/analyser/analyser.py index f202f747..44d26380 100644 --- a/analyser/analyser.py +++ b/analyser/analyser.py @@ -290,7 +290,7 @@ def __init__(self, encounter): encounter_collector.add_data('start_tick', start_time, int) encounter_collector.add_data('end_tick', encounter_end, int) encounter_collector.add_data('duration', (encounter_end - start_time) / 1000, float) - encounter_collector.add_data('cm', self.boss_info.cm_detector(events)) + encounter_collector.add_data('cm', self.boss_info.cm_detector(events, self.boss_instids)) encounter_collector.add_data('phase_order', [name for name,start,end in self.phases]) for phase in self.phases: diff --git a/analyser/bosses.py b/analyser/bosses.py index ebb0adce..3409c8bd 100644 --- a/analyser/bosses.py +++ b/analyser/bosses.py @@ -15,18 +15,21 @@ class Kind(IntEnum): DUMMY = 3 FRACTAL = 4 -def no_cm(events): +def no_cm(events, boss_instids): return False -def yes_cm(events): +def yes_cm(events, boss_instids): return True -def cairn_cm_detector(events): +def cairn_cm_detector(events, boss_instids): return len(events[events.skillid == 38098]) > 0 -def samarog_cm_detector(events): +def samarog_cm_detector(events, boss_instids): return len(events[(events.skillid == 37966)&(events.time - events.time.min() < 10000)]) > 0 +def mo_cm_detector(events, boss_instids): + return len(events[(events.state_change == 12) & (events.dst_agent == 30000000) & (events.src_instid.isin(boss_instids))]) > 0 + class Metric: def __init__(self, name, short_name, data_type, split_by_player = True, split_by_phase = False, desired = DesiredValue.LOW): self.name = name @@ -218,7 +221,7 @@ def find_end_time(self, Metric('Soldiers', 'Soldiers', MetricType.COUNT, False), Metric('Soldier\'s Aura', 'Soldier AOE', MetricType.COUNT), Metric('Enemy Tile', 'Enemy Tile', MetricType.COUNT) - ]), + ], cm_detector = mo_cm_detector), Boss('Samarog', Kind.RAID, [0x4324], phases = [ Phase("Phase 1", True, phase_end_health = 66, phase_end_damage_stop = 10000), Phase("First split", False, phase_end_damage_start = 10000), From d669d3aa4fbd0eb09946b1c18fc0c278fd673c5f Mon Sep 17 00:00:00 2001 From: Immortius Date: Mon, 23 Oct 2017 20:05:49 +1100 Subject: [PATCH 06/83] #184 Deimos cm detection --- analyser/bosses.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/analyser/bosses.py b/analyser/bosses.py index 3409c8bd..2935c3ad 100644 --- a/analyser/bosses.py +++ b/analyser/bosses.py @@ -30,6 +30,9 @@ def samarog_cm_detector(events, boss_instids): def mo_cm_detector(events, boss_instids): return len(events[(events.state_change == 12) & (events.dst_agent == 30000000) & (events.src_instid.isin(boss_instids))]) > 0 +def deimos_cm_detector(events, boss_instids): + return len(events[(events.state_change == 12) & (events.dst_agent == 42000000) & (events.src_instid.isin(boss_instids))]) > 0 + class Metric: def __init__(self, name, short_name, data_type, split_by_player = True, split_by_phase = False, desired = DesiredValue.LOW): self.name = name @@ -252,7 +255,7 @@ def find_end_time(self, Metric('Demonic Shockwave', 'Shockwave', MetricType.COUNT, True, False), Metric('Teleports', 'Teleports', MetricType.COUNT, True, False), Metric('Tear Consumed', 'Tears Consumed', MetricType.COUNT, True, False) - ]), + ], cm_detector = deimos_cm_detector), Boss('Standard Kitty Golem', Kind.DUMMY, [16199]), Boss('Average Kitty Golem', Kind.DUMMY, [16177]), Boss('Vital Kitty Golem', Kind.DUMMY, [16198]), From 191383c52810f61ea757c3315011ed4a273b058a Mon Sep 17 00:00:00 2001 From: Goran Topic Date: Tue, 24 Oct 2017 11:08:38 +0900 Subject: [PATCH 07/83] Fix error being thrown by upload when no `file` --- raidar/views.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/raidar/views.py b/raidar/views.py index bb22cb1e..6469d36f 100644 --- a/raidar/views.py +++ b/raidar/views.py @@ -373,6 +373,7 @@ def initial(request): return JsonResponse(response) +@sensitive_variables('password') def _perform_login(request): username = request.POST.get('username') password = request.POST.get('password') @@ -387,7 +388,6 @@ def _perform_login(request): @require_POST @sensitive_post_parameters('password') -@sensitive_variables('password') def login(request): if request.method == 'GET': return index(request, page={ 'name': 'login' }) @@ -480,10 +480,13 @@ def logout(request): def _perform_upload(request): if (len(request.FILES) != 1): - return _error("Only single file uploads are allowed") + return ("Only single file uploads are allowed", None) filename = next(iter(request.FILES)) - file = request.FILES['file'] + if 'file' in request.FILES: + file = request.FILES['file'] + else: + return ("Missing file attachment named `file`", None) filename = file.name uploaded_at = time() @@ -511,12 +514,15 @@ def upload(request): @csrf_exempt @require_POST +@sensitive_post_parameters('password') def api_upload(request): user = _perform_login(request) if not user: return _error('Could not authenticate') auth_login(request, user) filename, upload = _perform_upload(request) + if not upload: + return _error(filename) return JsonResponse({"filename": filename, "upload_id": upload.id}) From 4139e24be53c457b6b3a3e282695b32ff750b673 Mon Sep 17 00:00:00 2001 From: Goran Topic Date: Tue, 24 Oct 2017 11:22:52 +0900 Subject: [PATCH 08/83] Make erroneous API requests return 4xx status --- raidar/views.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/raidar/views.py b/raidar/views.py index 6469d36f..d2093713 100644 --- a/raidar/views.py +++ b/raidar/views.py @@ -43,9 +43,9 @@ def _safe_get(f, default=None): except (KeyError, TypeError): return default -def _error(msg, **kwargs): +def _error(msg, status=200, **kwargs): kwargs['error'] = str(msg) - return JsonResponse(kwargs) + return JsonResponse(kwargs, status=status) def _userprops(request): @@ -518,11 +518,11 @@ def upload(request): def api_upload(request): user = _perform_login(request) if not user: - return _error('Could not authenticate') + return _error('Could not authenticate', status=401) auth_login(request, user) filename, upload = _perform_upload(request) if not upload: - return _error(filename) + return _error(filename, status=400) return JsonResponse({"filename": filename, "upload_id": upload.id}) From bb2394d483384681a45fcc068e364991f2ecd0fc Mon Sep 17 00:00:00 2001 From: Goran Topic Date: Tue, 24 Oct 2017 16:42:47 +0900 Subject: [PATCH 09/83] Version bump --- gw2raidar/settings.py | 4 ++-- raidar/templates/raidar/info_releasenotes.html | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/gw2raidar/settings.py b/gw2raidar/settings.py index e9481edd..07cc1d5d 100644 --- a/gw2raidar/settings.py +++ b/gw2raidar/settings.py @@ -14,8 +14,8 @@ from dateutil import parser VERSION = { - 'id': '1.0.0', - 'timestamp': 1508725674, # date +%s + 'id': '1.0.1', + 'timestamp': 1508830887, # date +%s } # Build paths inside the project like this: os.path.join(BASE_DIR, ...) diff --git a/raidar/templates/raidar/info_releasenotes.html b/raidar/templates/raidar/info_releasenotes.html index 71512545..e3a3594c 100644 --- a/raidar/templates/raidar/info_releasenotes.html +++ b/raidar/templates/raidar/info_releasenotes.html @@ -5,6 +5,11 @@

released on [[formatDate(data.version.timestamp)]]

+
    +
  • Added code in preparation for detection of Raid Challenge Mode instances
  • +
  • Changed response status code to 4xx for erroneous API upload requests
  • +
+

Version 1.0.0

This major release marks a massive milestone for GW2Raidar. Massive thanks to the community for your support, patience and feedback!