From 7de1d81f7d4a39f6bc3a634e8c191b3705da8b60 Mon Sep 17 00:00:00 2001 From: Joey Chatelain Date: Wed, 17 Nov 2021 17:04:24 -0800 Subject: [PATCH 01/23] paginate lc summary --- .../core/templates/core/data_summary.html | 16 +++++++++++++--- neoexchange/core/templatetags/basic_tags.py | 5 +++++ neoexchange/core/views.py | 14 ++++++-------- 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/neoexchange/core/templates/core/data_summary.html b/neoexchange/core/templates/core/data_summary.html index c73ae1139..33f60386c 100644 --- a/neoexchange/core/templates/core/data_summary.html +++ b/neoexchange/core/templates/core/data_summary.html @@ -46,6 +46,9 @@

LCO Light Curves

Target Name + + Period + {% endif %} @@ -57,7 +60,7 @@

LCO Light Curves

{{block.when_observed|date:"Y-m-d"}} - {{block.body.current_name}} + {{block.body.full_name}} {{block.superblock.id}}
@@ -67,8 +70,15 @@

LCO Light Curves

{{body.current_name}} + {% with datum as body %} + {{body.full_name}} + + {% with body|get_period as periods %} + {% for p in periods %} + {{p.value}} + {% endfor %} + {% endwith %} + {% endwith %} {% endif %} {% endif %} diff --git a/neoexchange/core/templatetags/basic_tags.py b/neoexchange/core/templatetags/basic_tags.py index 2f3b3921a..aad1ca82a 100644 --- a/neoexchange/core/templatetags/basic_tags.py +++ b/neoexchange/core/templatetags/basic_tags.py @@ -110,6 +110,11 @@ def format_mpc_line_catcode(measure): return measure.format_mpc_line(include_catcode=True) +@register.filter(is_safe=False) +def get_period(body): + return body.get_physical_parameters('P', False) + + @register.inclusion_tag('partials/block_row.html') def build_block_row(superblock): return { diff --git a/neoexchange/core/views.py b/neoexchange/core/views.py index ef9b6b45f..bb2624a14 100644 --- a/neoexchange/core/views.py +++ b/neoexchange/core/views.py @@ -1804,19 +1804,17 @@ def get_context_data(self, **kwargs): class LCDataListView(ListView): model = Body template_name = 'core/data_summary.html' + alcdefs_blocks = DataProduct.content.sblock().filter(filetype=DataProduct.ALCDEF_TXT).select_related('content_type') + block_ids = [x.object_id for x in alcdefs_blocks] + queryset = Body.objects.filter(superblock__pk__in=block_ids).distinct().prefetch_related('physicalparameters_set') + context_object_name = "data_list" paginate_by = 20 def get_context_data(self, **kwargs): - context = {'data_list': self.find_lc(), 'data_type': 'LC'} + context = super(LCDataListView, self).get_context_data(**kwargs) + context['data_type'] = 'LC' return context - def find_lc(self): - alcdefs_blocks = DataProduct.content.sblock().filter(filetype=DataProduct.ALCDEF_TXT).select_related('content_type') - block_ids = [x.object_id for x in alcdefs_blocks] - alcdef_bodies = Body.objects.filter(superblock__pk__in=block_ids).distinct() - - return alcdef_bodies - def ranking(request): From 416911ed4dc22d2141bea3c6f2ea85cb872a08d4 Mon Sep 17 00:00:00 2001 From: Joey Chatelain Date: Tue, 30 Nov 2021 14:48:26 -0800 Subject: [PATCH 02/23] set period attribute --- neoexchange/core/templates/core/data_summary.html | 2 +- neoexchange/core/templatetags/basic_tags.py | 5 ----- neoexchange/core/views.py | 5 ++++- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/neoexchange/core/templates/core/data_summary.html b/neoexchange/core/templates/core/data_summary.html index 33f60386c..c498a15a2 100644 --- a/neoexchange/core/templates/core/data_summary.html +++ b/neoexchange/core/templates/core/data_summary.html @@ -73,7 +73,7 @@

LCO Light Curves

{{body.full_name}} - {% with body|get_period as periods %} + {% with body.rot_period as periods %} {% for p in periods %} {{p.value}} {% endfor %} diff --git a/neoexchange/core/templatetags/basic_tags.py b/neoexchange/core/templatetags/basic_tags.py index aad1ca82a..2f3b3921a 100644 --- a/neoexchange/core/templatetags/basic_tags.py +++ b/neoexchange/core/templatetags/basic_tags.py @@ -110,11 +110,6 @@ def format_mpc_line_catcode(measure): return measure.format_mpc_line(include_catcode=True) -@register.filter(is_safe=False) -def get_period(body): - return body.get_physical_parameters('P', False) - - @register.inclusion_tag('partials/block_row.html') def build_block_row(superblock): return { diff --git a/neoexchange/core/views.py b/neoexchange/core/views.py index bb2624a14..8e33f235c 100644 --- a/neoexchange/core/views.py +++ b/neoexchange/core/views.py @@ -1806,7 +1806,10 @@ class LCDataListView(ListView): template_name = 'core/data_summary.html' alcdefs_blocks = DataProduct.content.sblock().filter(filetype=DataProduct.ALCDEF_TXT).select_related('content_type') block_ids = [x.object_id for x in alcdefs_blocks] - queryset = Body.objects.filter(superblock__pk__in=block_ids).distinct().prefetch_related('physicalparameters_set') + period_info = PhysicalParameters.objects.filter(parameter_type='P', preferred=True) + prefetch_period = Prefetch('physicalparameters_set', queryset=period_info, to_attr='rot_period') + queryset = Body.objects.filter(superblock__pk__in=block_ids).distinct().prefetch_related(prefetch_period) + param_list = [body.rot_period for body in queryset] context_object_name = "data_list" paginate_by = 20 From fd6f17584c46ee104dc4141daea770ce0e95bfa9 Mon Sep 17 00:00:00 2001 From: Joey Chatelain Date: Wed, 1 Dec 2021 14:38:11 -0800 Subject: [PATCH 03/23] add period table to lc_plot --- .../core/templates/core/block_list.html | 2 +- neoexchange/core/templates/core/plot_lc.html | 38 +++++++++++++++++-- neoexchange/core/views.py | 9 +++-- 3 files changed, 40 insertions(+), 9 deletions(-) diff --git a/neoexchange/core/templates/core/block_list.html b/neoexchange/core/templates/core/block_list.html index eb72ee8b6..6f7388cfe 100644 --- a/neoexchange/core/templates/core/block_list.html +++ b/neoexchange/core/templates/core/block_list.html @@ -35,7 +35,7 @@

Observing Blocks

Obs. Details - Cadence? + Cadence? Active? diff --git a/neoexchange/core/templates/core/plot_lc.html b/neoexchange/core/templates/core/plot_lc.html index 769adb9cc..2d7f26b02 100644 --- a/neoexchange/core/templates/core/plot_lc.html +++ b/neoexchange/core/templates/core/plot_lc.html @@ -31,9 +31,39 @@

Object: {{body.current_name}}

{% block graphic %} {{ lc_div|safe }} {% endblock %} - - {% for alcdef in alcdef_dps %} - {{ alcdef.product.name }} - {% endfor %} +
+
+ + + + + + + + + + + + {% for period in period_list|dictsort:"update_time"%} + + + + + + + + {% endfor %} + +
+ + + Period(h) + + Source + + Notes + + Date +
{{forloop.counter}}{{period.value}}{{period.reference}}{{period.notes}}{{period.update_time}}
{% endblock %} \ No newline at end of file diff --git a/neoexchange/core/views.py b/neoexchange/core/views.py index 8e33f235c..e6138634f 100644 --- a/neoexchange/core/views.py +++ b/neoexchange/core/views.py @@ -3887,15 +3887,16 @@ class LCPlot(LookUpBodyMixin, FormView): template_name = 'core/plot_lc.html' def get(self, request, *args, **kwargs): - best_period = self.body.get_physical_parameters('P', False) + period_list = PhysicalParameters.objects.filter(body=self.body, parameter_type='P') + best_period = period_list.filter(preferred=True) if best_period: - period = best_period[0].get('value', None) + period = best_period[0].value else: period = None script, div, meta_list = get_lc_plot(self.body, {'period': period}) - alcdef_dps = DataProduct.content.fullbody(bodyid=self.body.id).filter(filetype=DataProduct.ALCDEF_TXT) - return self.render_to_response(self.get_context_data(body=self.body, script=script, div=div, meta_list=meta_list)) + return self.render_to_response(self.get_context_data(body=self.body, script=script, div=div, + meta_list=meta_list, period_list=period_list)) def get_context_data(self, **kwargs): params = kwargs From c499a4933f103e102391cb518258630c3c9a41cc Mon Sep 17 00:00:00 2001 From: Joey Chatelain Date: Wed, 1 Dec 2021 15:59:44 -0800 Subject: [PATCH 04/23] allow for overflow in datatables --- neoexchange/core/static/core/css/styles.css | 2 +- neoexchange/core/templates/core/plot_lc.html | 11 +++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/neoexchange/core/static/core/css/styles.css b/neoexchange/core/static/core/css/styles.css index d654861ae..53ef19800 100755 --- a/neoexchange/core/static/core/css/styles.css +++ b/neoexchange/core/static/core/css/styles.css @@ -26,7 +26,7 @@ table { border-collapse: collapse; } table.datatable { margin: 0px; padding: 0px; background-color: white; width: 100%!important; border-collapse: collapse; table-layout: fixed; color:#555;} table.datatable th, table.datatable td { text-align: left; padding: 8px; border: 0px; font-weight: normal; } table.datatable th { padding: 16px 8px; font-weight: bold; border-bottom: 1px solid #aaa;} -table.datatable td { border-bottom: 1px solid #e6e6e6; color: #202020; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } +table.datatable td { border-bottom: 1px solid #e6e6e6; color: #202020; white-space: nowrap; overflow: auto; text-overflow: unset; } table.datatable td a { display: block; } table.datatable .wider { width: 12%; } diff --git a/neoexchange/core/templates/core/plot_lc.html b/neoexchange/core/templates/core/plot_lc.html index 2d7f26b02..ba89179c2 100644 --- a/neoexchange/core/templates/core/plot_lc.html +++ b/neoexchange/core/templates/core/plot_lc.html @@ -40,7 +40,7 @@

Object: {{body.current_name}}

- Period(h) + Period [hours] Source @@ -57,7 +57,14 @@

Object: {{body.current_name}}

{% for period in period_list|dictsort:"update_time"%} {{forloop.counter}} - {{period.value}} + {{period.value}} + {% if period.error %} + ±{{period.error}} + {% endif %} + {% if period.quality %} + ({{period.quality}}) + {% endif %} + {{period.reference}} {{period.notes}} {{period.update_time}} From 253c0292cb06a1b27e4448b1abae8ca14624059d Mon Sep 17 00:00:00 2001 From: Joey Chatelain Date: Wed, 8 Dec 2021 00:05:38 -0800 Subject: [PATCH 05/23] add period form --- neoexchange/core/forms.py | 18 ++++++ neoexchange/core/static/core/css/styles.css | 14 +++++ neoexchange/core/templates/core/plot_lc.html | 61 +++++++++++++++++--- neoexchange/core/views.py | 44 ++++++++++++-- 4 files changed, 124 insertions(+), 13 deletions(-) diff --git a/neoexchange/core/forms.py b/neoexchange/core/forms.py index 719a480d8..8c0d77be9 100644 --- a/neoexchange/core/forms.py +++ b/neoexchange/core/forms.py @@ -69,6 +69,16 @@ ('4', '4'), ('5', '5')) +LC_QUALITIES = (('3', 'Unambiguous (3)'), + ('3-', 'Unique (3-)'), + ('2+', 'Possible Ambiguity (2+)'), + ('2', 'Within 30% accurate (2)'), + ('2-', 'Not well established (2-)'), + ('1+', 'Possibly Just Noise (1+)'), + ('1', 'Possibly Completely Wrong (1)'), + ('1-', 'Probably Completely Wrong (1-)'), + ('0', 'Debunked (0)')) + class SiteSelectWidget(forms.Select): """ @@ -441,3 +451,11 @@ class AddTargetForm(forms.Form): origin = forms.ChoiceField(choices=ORIGINS, widget=forms.HiddenInput()) target_name = forms.CharField(label="Enter target to add...", max_length=30, required=True, widget=forms.TextInput(attrs={'size': '20'}), error_messages={'required': _(u'Target name is required')}) + + +class AddPeriodForm(forms.Form): + period = forms.FloatField(label="Period", initial=1.000, required=True, widget=forms.DateTimeInput(attrs={'style': 'width: 75px;'})) + error = forms.FloatField(label="Error", initial=0.0, required=False, widget=forms.DateTimeInput(attrs={'style': 'width: 75px;'})) + quality = forms.ChoiceField(required=False, choices=LC_QUALITIES) + notes = forms.CharField(label="Notes", required=False, widget=forms.DateTimeInput(attrs={'style': 'width: 275px;'})) + preferred = forms.BooleanField(initial=False, required=False) diff --git a/neoexchange/core/static/core/css/styles.css b/neoexchange/core/static/core/css/styles.css index 53ef19800..a5743ac4b 100755 --- a/neoexchange/core/static/core/css/styles.css +++ b/neoexchange/core/static/core/css/styles.css @@ -1182,3 +1182,17 @@ ul.candidate-controls li:hover {background-color:#eee; } background: white; color: silver; } + +.collapsible { + background-color: #777; + color: white; + cursor: pointer; + border: none; + text-align: left; + outline: none; +} + +.active, .collapsible:hover { + background-color: #555; + color: white; +} diff --git a/neoexchange/core/templates/core/plot_lc.html b/neoexchange/core/templates/core/plot_lc.html index ba89179c2..8029319b3 100644 --- a/neoexchange/core/templates/core/plot_lc.html +++ b/neoexchange/core/templates/core/plot_lc.html @@ -12,6 +12,17 @@ {{ the_script|safe }} + + {% endblock %} {% block bodyclass %}page{% endblock %} @@ -25,13 +36,6 @@

Object: {{body.current_name}}

{% block main-content %} - -
- - {% block graphic %} - {{ lc_div|safe }} - {% endblock %} -
@@ -70,7 +74,48 @@

Object: {{body.current_name}}

{% endfor %} - +
{{period.update_time}}
+ {% if request.user.is_authenticated and perms.core.add_body %} +
+
+ {% csrf_token %} +
+
+ +
+
+ {{form.period}} +
+
+ {{form.error}} +
+
+ {{form.quality}} +
+
+ {{form.notes}} +
+
+ {{form.preferred}} +
+
+ {% for key, error in form.errors.items %} +
+ {{ error }} +
+ {% endfor %} +
+
+ + {% endif %}
+ +
+ + {% block graphic %} + {{ lc_div|safe }} + {% endblock %} +
+ {% endblock %} \ No newline at end of file diff --git a/neoexchange/core/views.py b/neoexchange/core/views.py index e6138634f..a93eeae94 100644 --- a/neoexchange/core/views.py +++ b/neoexchange/core/views.py @@ -53,7 +53,7 @@ from urllib.parse import urljoin from .forms import EphemQuery, ScheduleForm, ScheduleCadenceForm, ScheduleBlockForm, \ - ScheduleSpectraForm, MPCReportForm, SpectroFeasibilityForm, AddTargetForm + ScheduleSpectraForm, MPCReportForm, SpectroFeasibilityForm, AddTargetForm, AddPeriodForm from .models import * from astrometrics.ast_subs import determine_asteroid_type, determine_time_of_perih, \ convert_ast_to_comet @@ -167,7 +167,7 @@ class AddTarget(LoginRequiredMixin, FormView): def form_invalid(self, form, **kwargs): context = self.get_context_data(**kwargs) - return render(context['view'].request, self.template_name, {'form': form, }) + return render(context['view'].request, self.template_name, {'form': form}) def form_valid(self, form): origin = form.cleaned_data['origin'] @@ -2109,10 +2109,11 @@ def build_lookproject_list(disp=None): def look_project(request): - params = build_lookproject_list() + params = build_lookproject_list() params['form'] = AddTargetForm() return render(request, 'core/lookproject.html', params) + def check_for_block(form_data, params, new_body): """Checks if a block with the given name exists in the Django DB. Return 0 if no block found, 1 if found, 2 if multiple blocks found""" @@ -3885,8 +3886,9 @@ def get(self, request, *args, **kwargs): class LCPlot(LookUpBodyMixin, FormView): template_name = 'core/plot_lc.html' + form_class = AddPeriodForm - def get(self, request, *args, **kwargs): + def get(self, request, form=None, *args, **kwargs): period_list = PhysicalParameters.objects.filter(body=self.body, parameter_type='P') best_period = period_list.filter(preferred=True) if best_period: @@ -3894,8 +3896,10 @@ def get(self, request, *args, **kwargs): else: period = None script, div, meta_list = get_lc_plot(self.body, {'period': period}) + if not form: + form = AddPeriodForm() - return self.render_to_response(self.get_context_data(body=self.body, script=script, div=div, + return self.render_to_response(self.get_context_data(body=self.body, script=script, div=div, form=form, meta_list=meta_list, period_list=period_list)) def get_context_data(self, **kwargs): @@ -3912,6 +3916,36 @@ def get_context_data(self, **kwargs): params['table_path'] = BOKEH_URL.format('tables-'+bokeh.__version__) + 'js' return params + def form_invalid(self, form, **kwargs): + period_list = PhysicalParameters.objects.filter(body=self.body, parameter_type='P') + best_period = period_list.filter(preferred=True) + if best_period: + period = best_period[0].value + else: + period = None + script, div, meta_list = get_lc_plot(self.body, {'period': period}) + if not form: + form = AddPeriodForm() + context = self.get_context_data(body=self.body, script=script, div=div, form=form, meta_list=meta_list, period_list=period_list) + return self.render_to_response(context) + + def form_valid(self, form): + period_data = form.cleaned_data + period_dict = {'value': period_data['period'], + 'error': period_data['error'], + 'parameter_type': 'P', + 'units': 'h', + 'preferred': period_data['preferred'], + 'reference': 'NEOX', + 'quality': period_data['quality'], + 'notes': period_data['notes'] + } + self.body.save_physical_parameters(period_dict) + return super(LCPlot, self).form_valid(form) + + def get_success_url(self): + return reverse('lc_plot', kwargs={'pk': self.body.id}) + def import_alcdef(alcdef, meta_list, lc_list): """Pull LC data from ALCDEF Data Product. From ff59ff1864aa7bf150c62133c608928daa115d2a Mon Sep 17 00:00:00 2001 From: Joey Chatelain Date: Wed, 8 Dec 2021 11:07:43 -0800 Subject: [PATCH 06/23] do fancy CSS things --- neoexchange/core/static/core/css/styles.css | 7 +++++++ neoexchange/core/templates/core/plot_lc.html | 6 +++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/neoexchange/core/static/core/css/styles.css b/neoexchange/core/static/core/css/styles.css index a5743ac4b..9224aff9b 100755 --- a/neoexchange/core/static/core/css/styles.css +++ b/neoexchange/core/static/core/css/styles.css @@ -1190,9 +1190,16 @@ ul.candidate-controls li:hover {background-color:#eee; } border: none; text-align: left; outline: none; + box-shadow: 2px 2px 10px #777; } .active, .collapsible:hover { background-color: #555; color: white; } + +.content { + margin-bottom: 0px; + margin-top: 2px; + box-shadow: 2px 2px 10px #777; +} \ No newline at end of file diff --git a/neoexchange/core/templates/core/plot_lc.html b/neoexchange/core/templates/core/plot_lc.html index 8029319b3..47b700f09 100644 --- a/neoexchange/core/templates/core/plot_lc.html +++ b/neoexchange/core/templates/core/plot_lc.html @@ -77,12 +77,12 @@

Object: {{body.current_name}}

{% if request.user.is_authenticated and perms.core.add_body %} -
+
{% csrf_token %}
- +
{{form.period}} @@ -97,7 +97,7 @@

Object: {{body.current_name}}

{{form.notes}}
- {{form.preferred}} + {{form.preferred}}
{% for key, error in form.errors.items %} From d7eca769d38c0af96af998c4c3b65dca6c1dcc79 Mon Sep 17 00:00:00 2001 From: Joey Chatelain Date: Wed, 8 Dec 2021 14:36:39 -0800 Subject: [PATCH 07/23] add detail to summary table --- .../core/templates/core/data_summary.html | 32 ++++++++++++++++--- neoexchange/core/views.py | 2 +- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/neoexchange/core/templates/core/data_summary.html b/neoexchange/core/templates/core/data_summary.html index c498a15a2..4bc7d5971 100644 --- a/neoexchange/core/templates/core/data_summary.html +++ b/neoexchange/core/templates/core/data_summary.html @@ -49,6 +49,15 @@

LCO Light Curves

Period + + Quality + + + Source + + + Notes + {% endif %} @@ -71,14 +80,27 @@

LCO Light Curves

{{body.full_name}} - {% with body.rot_period as periods %} - {% for p in periods %} - {{p.value}} - {% endfor %} - {% endwith %} + {{period.value}} + {% if period.units %} + ({{period.units}}) + {% endif %} + {% if body.rot_period|length > 1 %} + [1 of {{body.rot_period|length}}] + {% endif %} + + + {{period.quality}} + + + {{period.reference}} + + {{period.notes}} + + {% endwith %} {% endwith %} {% endif %} {% endif %} diff --git a/neoexchange/core/views.py b/neoexchange/core/views.py index a93eeae94..807e54ef1 100644 --- a/neoexchange/core/views.py +++ b/neoexchange/core/views.py @@ -1806,7 +1806,7 @@ class LCDataListView(ListView): template_name = 'core/data_summary.html' alcdefs_blocks = DataProduct.content.sblock().filter(filetype=DataProduct.ALCDEF_TXT).select_related('content_type') block_ids = [x.object_id for x in alcdefs_blocks] - period_info = PhysicalParameters.objects.filter(parameter_type='P', preferred=True) + period_info = PhysicalParameters.objects.filter(parameter_type='P').order_by('-preferred') prefetch_period = Prefetch('physicalparameters_set', queryset=period_info, to_attr='rot_period') queryset = Body.objects.filter(superblock__pk__in=block_ids).distinct().prefetch_related(prefetch_period) param_list = [body.rot_period for body in queryset] From 6965f57a64cf0474298468581296d68463fe80e0 Mon Sep 17 00:00:00 2001 From: Joey Chatelain Date: Wed, 8 Dec 2021 15:14:52 -0800 Subject: [PATCH 08/23] add body status model field --- neoexchange/core/models/body.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/neoexchange/core/models/body.py b/neoexchange/core/models/body.py index 78d337065..952016fd5 100644 --- a/neoexchange/core/models/body.py +++ b/neoexchange/core/models/body.py @@ -114,6 +114,15 @@ ('/a', 'Reciprocal of semimajor axis') ) +STATUS_CHOICES = ( + ('LC', 'Light Curve Analysis Done'), + ('S', 'Spectroscopic Analysis Done'), + ('LS', 'LC & Spec Analysis Done'), + ('MD', 'More Observations Needed'), + ('0', 'No usable Data'), + ('P', 'Published') + ) + logger = logging.getLogger(__name__) @@ -149,6 +158,8 @@ class Body(models.Model): updated = models.BooleanField('Has this object been updated?', default=False) ingest = models.DateTimeField(default=datetime.utcnow, db_index=True) update_time = models.DateTimeField(blank=True, null=True, db_index=True) + analysis_status = models.CharField('Current Analysis Status', max_length=2, choices=STATUS_CHOICES, blank=True, null=True) + as_updated = models.DateTimeField(blank=True, null=True) def _compute_period(self): period = None From 7a909e62f009ad0bb9922161b550657450d21acb Mon Sep 17 00:00:00 2001 From: Joey Chatelain Date: Wed, 8 Dec 2021 16:20:10 -0800 Subject: [PATCH 09/23] add link to summary page --- neoexchange/core/models/body.py | 4 ++-- neoexchange/core/templates/base.html | 2 +- .../core/templates/core/data_summary.html | 16 ++++++++++++++++ neoexchange/core/views.py | 1 - 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/neoexchange/core/models/body.py b/neoexchange/core/models/body.py index 952016fd5..a65b9cea8 100644 --- a/neoexchange/core/models/body.py +++ b/neoexchange/core/models/body.py @@ -158,8 +158,8 @@ class Body(models.Model): updated = models.BooleanField('Has this object been updated?', default=False) ingest = models.DateTimeField(default=datetime.utcnow, db_index=True) update_time = models.DateTimeField(blank=True, null=True, db_index=True) - analysis_status = models.CharField('Current Analysis Status', max_length=2, choices=STATUS_CHOICES, blank=True, null=True) - as_updated = models.DateTimeField(blank=True, null=True) + analysis_status = models.CharField('Current Analysis Status', max_length=2, choices=STATUS_CHOICES, blank=True, null=True, db_index=True) + as_updated = models.DateTimeField(blank=True, null=True, db_index=True) def _compute_period(self): period = None diff --git a/neoexchange/core/templates/base.html b/neoexchange/core/templates/base.html index a755a74d1..9234d9e2e 100644 --- a/neoexchange/core/templates/base.html +++ b/neoexchange/core/templates/base.html @@ -139,7 +139,7 @@ Blocks
  • - Efficiency + Data
  • diff --git a/neoexchange/core/templates/core/data_summary.html b/neoexchange/core/templates/core/data_summary.html index 4bc7d5971..17f81bad3 100644 --- a/neoexchange/core/templates/core/data_summary.html +++ b/neoexchange/core/templates/core/data_summary.html @@ -58,6 +58,12 @@

    LCO Light Curves

    Notes + + Status + + + Status Updated + {% endif %} @@ -100,6 +106,16 @@

    LCO Light Curves

    {{period.notes}} + + {% if body.analysis_status %} + {{body.analysis_status}} + {% endif %} + + + {% if body.analysis_status %} + {{body.as_updated}} + {% endif %} + {% endwith %} {% endwith %} {% endif %} diff --git a/neoexchange/core/views.py b/neoexchange/core/views.py index 807e54ef1..3d08302c6 100644 --- a/neoexchange/core/views.py +++ b/neoexchange/core/views.py @@ -1809,7 +1809,6 @@ class LCDataListView(ListView): period_info = PhysicalParameters.objects.filter(parameter_type='P').order_by('-preferred') prefetch_period = Prefetch('physicalparameters_set', queryset=period_info, to_attr='rot_period') queryset = Body.objects.filter(superblock__pk__in=block_ids).distinct().prefetch_related(prefetch_period) - param_list = [body.rot_period for body in queryset] context_object_name = "data_list" paginate_by = 20 From 19437492df872906f89121923b55ed7fdae2ade0 Mon Sep 17 00:00:00 2001 From: Joey Chatelain Date: Tue, 14 Dec 2021 15:57:35 -0800 Subject: [PATCH 10/23] build status update form --- neoexchange/core/forms.py | 7 ++- neoexchange/core/models/body.py | 15 ++++--- neoexchange/core/models/spectra.py | 1 + .../core/templates/core/data_summary.html | 33 ++++++++++++-- neoexchange/core/templates/core/plot_lc.html | 20 +++++---- neoexchange/core/views.py | 44 +++++++++++++++++-- 6 files changed, 96 insertions(+), 24 deletions(-) diff --git a/neoexchange/core/forms.py b/neoexchange/core/forms.py index 8c0d77be9..0ff499acf 100644 --- a/neoexchange/core/forms.py +++ b/neoexchange/core/forms.py @@ -22,7 +22,7 @@ from django.core.exceptions import ValidationError from django.utils.translation import gettext_lazy as _ from astrometrics.sources_subs import fetch_sfu, fetch_filter_list -from .models import Body, Proposal, Block, StaticSource, ORIGINS +from .models import Body, Proposal, Block, StaticSource, ORIGINS, STATUS_CHOICES from astrometrics.time_subs import tomorrow logger = logging.getLogger(__name__) @@ -459,3 +459,8 @@ class AddPeriodForm(forms.Form): quality = forms.ChoiceField(required=False, choices=LC_QUALITIES) notes = forms.CharField(label="Notes", required=False, widget=forms.DateTimeInput(attrs={'style': 'width: 275px;'})) preferred = forms.BooleanField(initial=False, required=False) + + +class UpdateAnalysisStatusForm(forms.Form): + update_body = forms.ChoiceField(required=False, choices=[]) + status = forms.ChoiceField(required=False, choices=STATUS_CHOICES) diff --git a/neoexchange/core/models/body.py b/neoexchange/core/models/body.py index a65b9cea8..1183768f6 100644 --- a/neoexchange/core/models/body.py +++ b/neoexchange/core/models/body.py @@ -115,12 +115,13 @@ ) STATUS_CHOICES = ( - ('LC', 'Light Curve Analysis Done'), - ('S', 'Spectroscopic Analysis Done'), - ('LS', 'LC & Spec Analysis Done'), - ('MD', 'More Observations Needed'), - ('0', 'No usable Data'), - ('P', 'Published') + ('0', 'No Analysis Done'), + ('1', 'Light Curve Analysis Done'), + ('2', 'Spectroscopic Analysis Done'), + ('3', 'LC & Spec Analysis Done'), + ('10', 'More Observations Needed'), + ('20', 'Published'), + ('99', 'No usable Data') ) logger = logging.getLogger(__name__) @@ -158,7 +159,7 @@ class Body(models.Model): updated = models.BooleanField('Has this object been updated?', default=False) ingest = models.DateTimeField(default=datetime.utcnow, db_index=True) update_time = models.DateTimeField(blank=True, null=True, db_index=True) - analysis_status = models.CharField('Current Analysis Status', max_length=2, choices=STATUS_CHOICES, blank=True, null=True, db_index=True) + analysis_status = models.CharField('Current Analysis Status', max_length=2, choices=STATUS_CHOICES, db_index=True, default='0') as_updated = models.DateTimeField(blank=True, null=True, db_index=True) def _compute_period(self): diff --git a/neoexchange/core/models/spectra.py b/neoexchange/core/models/spectra.py index 2f3f26f8b..172aefc29 100644 --- a/neoexchange/core/models/spectra.py +++ b/neoexchange/core/models/spectra.py @@ -49,6 +49,7 @@ ('O', 'Other') ) + class SpectralInfo(models.Model): body = models.ForeignKey(Body, on_delete=models.CASCADE) taxonomic_class = models.CharField('Taxonomic Class', blank=True, null=True, max_length=6) diff --git a/neoexchange/core/templates/core/data_summary.html b/neoexchange/core/templates/core/data_summary.html index 17f81bad3..459797b16 100644 --- a/neoexchange/core/templates/core/data_summary.html +++ b/neoexchange/core/templates/core/data_summary.html @@ -41,6 +41,12 @@

    LCO Light Curves

    Obs + + Status + + + Status Updated + {% endif %} {% if data_type == 'LC' %} @@ -65,7 +71,6 @@

    LCO Light Curves

    Status Updated {% endif %} - @@ -82,6 +87,16 @@

    LCO Light Curves

    {{block.num_observed}}
    + + {% if block.body.analysis_status %} + {{block.body.analysis_status}} + {% endif %} + + + {% if block.body.analysis_status %} + {{block.body.as_updated}} + {% endif %} + {% endwith %} {% else %} {% if data_type == 'LC' %} @@ -108,12 +123,12 @@

    LCO Light Curves

    {% if body.analysis_status %} - {{body.analysis_status}} + {{body.get_analysis_status_display}} {% endif %} {% if body.analysis_status %} - {{body.as_updated}} + {{body.as_updated.date}} {% endif %} {% endwith %} @@ -128,6 +143,18 @@

    LCO Light Curves

    + {% csrf_token %} +
    + +
    + {{form.update_body}} +
    +
    + {{form.status}} +
    +
    +
    {% if is_paginated %} diff --git a/neoexchange/core/templates/core/plot_lc.html b/neoexchange/core/templates/core/plot_lc.html index 47b700f09..e03efafa7 100644 --- a/neoexchange/core/templates/core/plot_lc.html +++ b/neoexchange/core/templates/core/plot_lc.html @@ -36,7 +36,17 @@

    Object: {{body.current_name}}

    {% block main-content %} + + +
    + + {% block graphic %} + {{ lc_div|safe }} + {% endblock %} +
    +
    +
    Known Periods
    @@ -71,7 +81,7 @@

    Object: {{body.current_name}}

    - + {% endfor %} @@ -110,12 +120,4 @@

    Object: {{body.current_name}}

    {% endif %} - -
    - - {% block graphic %} - {{ lc_div|safe }} - {% endblock %} -
    - {% endblock %} \ No newline at end of file diff --git a/neoexchange/core/views.py b/neoexchange/core/views.py index 3d08302c6..2c5fe9c94 100644 --- a/neoexchange/core/views.py +++ b/neoexchange/core/views.py @@ -53,7 +53,7 @@ from urllib.parse import urljoin from .forms import EphemQuery, ScheduleForm, ScheduleCadenceForm, ScheduleBlockForm, \ - ScheduleSpectraForm, MPCReportForm, SpectroFeasibilityForm, AddTargetForm, AddPeriodForm + ScheduleSpectraForm, MPCReportForm, SpectroFeasibilityForm, AddTargetForm, AddPeriodForm, UpdateAnalysisStatusForm from .models import * from astrometrics.ast_subs import determine_asteroid_type, determine_time_of_perih, \ convert_ast_to_comet @@ -1801,23 +1801,59 @@ def get_context_data(self, **kwargs): return context -class LCDataListView(ListView): +class LCDataListDisplay(ListView): model = Body template_name = 'core/data_summary.html' alcdefs_blocks = DataProduct.content.sblock().filter(filetype=DataProduct.ALCDEF_TXT).select_related('content_type') block_ids = [x.object_id for x in alcdefs_blocks] period_info = PhysicalParameters.objects.filter(parameter_type='P').order_by('-preferred') prefetch_period = Prefetch('physicalparameters_set', queryset=period_info, to_attr='rot_period') - queryset = Body.objects.filter(superblock__pk__in=block_ids).distinct().prefetch_related(prefetch_period) + queryset = Body.objects.filter(superblock__pk__in=block_ids).distinct().prefetch_related(prefetch_period).order_by('-as_updated').order_by('analysis_status') context_object_name = "data_list" paginate_by = 20 def get_context_data(self, **kwargs): - context = super(LCDataListView, self).get_context_data(**kwargs) + context = super(LCDataListDisplay, self).get_context_data(**kwargs) context['data_type'] = 'LC' + body_choices_list = [(body.pk, body.current_name()) for body in context['data_list']] + form = UpdateAnalysisStatusForm() + form.fields['update_body'].choices = body_choices_list + context['form'] = form return context +class UpdateBodyStatus(SingleObjectMixin, FormView): + template_name = 'core/data_summary.html' + form_class = UpdateAnalysisStatusForm + model = Body + + def post(self, request, *args, **kwargs): + body_id = request.POST.get('update_body') + status_value = request.POST.get('status') + try: + body = Body.objects.get(pk=body_id) + body.analysis_status = status_value + body.as_updated = datetime.utcnow() + body.save() + except ObjectDoesNotExist: + logger.warning(f"Could not find a body for {body_id}.") + return redirect(reverse('lc_data_summary')) + + def get_success_url(self): + return reverse('lc_data_summary') + + +class LCDataListView(View): + + def get(self, request, *args, **kwargs): + view = LCDataListDisplay.as_view() + return view(request, *args, **kwargs) + + def post(self, request, *args, **kwargs): + view = UpdateBodyStatus.as_view() + return view(request, *args, **kwargs) + + def ranking(request): params = build_unranked_list_params() From 08ff0617dd5cafbd29c3f520c199f029f107af89 Mon Sep 17 00:00:00 2001 From: Joey Chatelain Date: Tue, 14 Dec 2021 16:16:36 -0800 Subject: [PATCH 11/23] make collapsible, add user req --- .../core/templates/core/data_summary.html | 46 +++++++++++++------ 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/neoexchange/core/templates/core/data_summary.html b/neoexchange/core/templates/core/data_summary.html index 459797b16..af1ae57df 100644 --- a/neoexchange/core/templates/core/data_summary.html +++ b/neoexchange/core/templates/core/data_summary.html @@ -3,6 +3,19 @@ {% block css-content %}{% endblock %} +{% block script-content %} + +{% endblock %} + {% block header %}Data Summary Page{% endblock %} {% block bodyclass %}page{% endblock %} @@ -89,12 +102,12 @@

    LCO Light Curves

    {% if block.body.analysis_status %} - {{block.body.analysis_status}} + {{block.body.get_analysis_status_display}} {% endif %}
    {% endwith %} @@ -143,18 +156,25 @@

    LCO Light Curves

    - {% csrf_token %} -
    - -
    - {{form.update_body}} -
    -
    - {{form.status}} -
    + {% if request.user.is_authenticated and perms.core.add_body %} +
    +
    +
    + {% csrf_token %} +
    + +
    + {{form.update_body}} +
    +
    + {{form.status}} +
    +
    +
    - + +
    + {% endif %}
    {% if is_paginated %} From 199e00a993bc3a772019fdb42008df5263e42d5a Mon Sep 17 00:00:00 2001 From: Joey Chatelain Date: Tue, 14 Dec 2021 17:04:46 -0800 Subject: [PATCH 12/23] get form to work on spec page --- .../core/templates/core/data_summary.html | 2 +- neoexchange/core/views.py | 56 ++++++++++++------- 2 files changed, 37 insertions(+), 21 deletions(-) diff --git a/neoexchange/core/templates/core/data_summary.html b/neoexchange/core/templates/core/data_summary.html index af1ae57df..65851f850 100644 --- a/neoexchange/core/templates/core/data_summary.html +++ b/neoexchange/core/templates/core/data_summary.html @@ -162,7 +162,7 @@

    LCO Light Curves

    {% csrf_token %}
    - +
    {{form.update_body}}
    diff --git a/neoexchange/core/views.py b/neoexchange/core/views.py index 2c5fe9c94..9c0d2dae5 100644 --- a/neoexchange/core/views.py +++ b/neoexchange/core/views.py @@ -1788,7 +1788,7 @@ def feasibility_check(data, body): return data -class SpecDataListView(ListView): +class SpecDataListDisplay(ListView): model = Block template_name = 'core/data_summary.html' queryset = Block.objects.filter(obstype=1).filter(num_observed__gt=0).order_by('-when_observed') @@ -1796,26 +1796,10 @@ class SpecDataListView(ListView): paginate_by = 20 def get_context_data(self, **kwargs): - context = super(SpecDataListView, self).get_context_data(**kwargs) + context = super(SpecDataListDisplay, self).get_context_data(**kwargs) context['data_type'] = 'Spec' - return context - - -class LCDataListDisplay(ListView): - model = Body - template_name = 'core/data_summary.html' - alcdefs_blocks = DataProduct.content.sblock().filter(filetype=DataProduct.ALCDEF_TXT).select_related('content_type') - block_ids = [x.object_id for x in alcdefs_blocks] - period_info = PhysicalParameters.objects.filter(parameter_type='P').order_by('-preferred') - prefetch_period = Prefetch('physicalparameters_set', queryset=period_info, to_attr='rot_period') - queryset = Body.objects.filter(superblock__pk__in=block_ids).distinct().prefetch_related(prefetch_period).order_by('-as_updated').order_by('analysis_status') - context_object_name = "data_list" - paginate_by = 20 - - def get_context_data(self, **kwargs): - context = super(LCDataListDisplay, self).get_context_data(**kwargs) - context['data_type'] = 'LC' - body_choices_list = [(body.pk, body.current_name()) for body in context['data_list']] + body_list = Body.objects.filter(block__in=context['data_list']).distinct() + body_choices_list = [(body.pk, body.current_name()) for body in body_list] form = UpdateAnalysisStatusForm() form.fields['update_body'].choices = body_choices_list context['form'] = form @@ -1843,6 +1827,38 @@ def get_success_url(self): return reverse('lc_data_summary') +class SpecDataListView(View): + + def get(self, request, *args, **kwargs): + view = SpecDataListDisplay.as_view() + return view(request, *args, **kwargs) + + def post(self, request, *args, **kwargs): + view = UpdateBodyStatus.as_view() + return view(request, *args, **kwargs) + + +class LCDataListDisplay(ListView): + model = Body + template_name = 'core/data_summary.html' + alcdefs_blocks = DataProduct.content.sblock().filter(filetype=DataProduct.ALCDEF_TXT).select_related('content_type') + block_ids = [x.object_id for x in alcdefs_blocks] + period_info = PhysicalParameters.objects.filter(parameter_type='P').order_by('-preferred') + prefetch_period = Prefetch('physicalparameters_set', queryset=period_info, to_attr='rot_period') + queryset = Body.objects.filter(superblock__pk__in=block_ids).distinct().prefetch_related(prefetch_period).order_by('-as_updated').order_by('analysis_status') + context_object_name = "data_list" + paginate_by = 20 + + def get_context_data(self, **kwargs): + context = super(LCDataListDisplay, self).get_context_data(**kwargs) + context['data_type'] = 'LC' + body_choices_list = [(body.pk, body.current_name()) for body in context['data_list']] + form = UpdateAnalysisStatusForm() + form.fields['update_body'].choices = body_choices_list + context['form'] = form + return context + + class LCDataListView(View): def get(self, request, *args, **kwargs): From 8df04fdf733129e56552f2fef8657622617861c7 Mon Sep 17 00:00:00 2001 From: Joey Chatelain Date: Sat, 18 Dec 2021 00:34:30 -0800 Subject: [PATCH 13/23] write tests, fix bugs --- neoexchange/core/models/blocks.py | 4 + neoexchange/core/models/body.py | 16 +- neoexchange/core/models/dataproducts.py | 9 +- neoexchange/core/models/proposal.py | 1 + .../core/templates/core/data_summary.html | 12 +- neoexchange/core/tests/test_dataproducts.py | 14 + neoexchange/core/tests/test_views.py | 264 +++++++----------- neoexchange/core/views.py | 12 +- .../neox/tests/test_block_summary_page.py | 22 +- .../neox/tests/test_data_summarypage.py | 132 ++++++++- 10 files changed, 280 insertions(+), 206 deletions(-) diff --git a/neoexchange/core/models/blocks.py b/neoexchange/core/models/blocks.py index 4848c21e7..3b24b191a 100644 --- a/neoexchange/core/models/blocks.py +++ b/neoexchange/core/models/blocks.py @@ -18,6 +18,7 @@ from django.db.models import Sum from django.utils.translation import gettext_lazy as _ from django.utils.functional import cached_property +from django.contrib.contenttypes.fields import GenericRelation from requests.compat import urljoin from numpy import frombuffer @@ -27,6 +28,7 @@ from core.models.body import Body from core.models.frame import Frame from core.models.proposal import Proposal +from core.models.dataproducts import DataProduct TELESCOPE_CHOICES = ( ('1m0', '1-meter'), @@ -62,6 +64,7 @@ class SuperBlock(models.Model): jitter = models.FloatField('Acceptable deviation before or after strict period (hours)', null=True, blank=True) timeused = models.FloatField('Time used (seconds)', null=True, blank=True) active = models.BooleanField(default=False) + dataproduct = GenericRelation(DataProduct, related_query_name='sblock') @cached_property def get_blocks(self): @@ -197,6 +200,7 @@ class Block(models.Model): active = models.BooleanField(default=False) reported = models.BooleanField(default=False) when_reported = models.DateTimeField(null=True, blank=True) + dataproduct = GenericRelation(DataProduct, related_query_name='block') def current_name(self): name = '' diff --git a/neoexchange/core/models/body.py b/neoexchange/core/models/body.py index 1183768f6..bd0a28580 100644 --- a/neoexchange/core/models/body.py +++ b/neoexchange/core/models/body.py @@ -115,13 +115,13 @@ ) STATUS_CHOICES = ( - ('0', 'No Analysis Done'), - ('1', 'Light Curve Analysis Done'), - ('2', 'Spectroscopic Analysis Done'), - ('3', 'LC & Spec Analysis Done'), - ('10', 'More Observations Needed'), - ('20', 'Published'), - ('99', 'No usable Data') + (0, 'No Analysis Done'), + (1, 'Light Curve Analysis Done'), + (2, 'Spectroscopic Analysis Done'), + (3, 'LC & Spec Analysis Done'), + (10, 'More Observations Needed'), + (20, 'Published'), + (99, 'No usable Data') ) logger = logging.getLogger(__name__) @@ -159,7 +159,7 @@ class Body(models.Model): updated = models.BooleanField('Has this object been updated?', default=False) ingest = models.DateTimeField(default=datetime.utcnow, db_index=True) update_time = models.DateTimeField(blank=True, null=True, db_index=True) - analysis_status = models.CharField('Current Analysis Status', max_length=2, choices=STATUS_CHOICES, db_index=True, default='0') + analysis_status = models.IntegerField('Current Analysis Status', choices=STATUS_CHOICES, db_index=True, default=0) as_updated = models.DateTimeField(blank=True, null=True, db_index=True) def _compute_period(self): diff --git a/neoexchange/core/models/dataproducts.py b/neoexchange/core/models/dataproducts.py index 47f14d106..2eea4d801 100644 --- a/neoexchange/core/models/dataproducts.py +++ b/neoexchange/core/models/dataproducts.py @@ -20,9 +20,6 @@ from django.dispatch import receiver from django.core.files.storage import default_storage -from core.models.body import Body -from core.models.blocks import Block, SuperBlock - class CoreQuerySet(models.QuerySet): def block(self): @@ -45,11 +42,9 @@ def fullbody(self, *args, **kwargs): else: block = ContentType.objects.get(app_label='core', model='block') sblock = ContentType.objects.get(app_label='core', model='superblock') - blockslist = Block.objects.filter(body=bodyid).values_list('id', flat=True) - sblockslist = SuperBlock.objects.filter(body=bodyid).values_list('id', flat=True) - query1 = Q(content_type=block, object_id__in=blockslist) + query1 = Q(content_type=block, block__body__pk=bodyid) query2 = Q(content_type=body, object_id=bodyid) - query3 = Q(content_type=sblock, object_id__in=sblockslist) + query3 = Q(content_type=sblock, sblock__body__pk=bodyid) return self.filter(query1 | query2 | query3) diff --git a/neoexchange/core/models/proposal.py b/neoexchange/core/models/proposal.py index ff87bf5aa..66a4a13e5 100644 --- a/neoexchange/core/models/proposal.py +++ b/neoexchange/core/models/proposal.py @@ -36,6 +36,7 @@ def __str__(self): title = self.title[0:10] return "%s %s" % (self.code, title) + class ProposalPermission(models.Model): """ Linking a user to proposals in NEOx to control their access diff --git a/neoexchange/core/templates/core/data_summary.html b/neoexchange/core/templates/core/data_summary.html index 65851f850..bb8b3da8e 100644 --- a/neoexchange/core/templates/core/data_summary.html +++ b/neoexchange/core/templates/core/data_summary.html @@ -101,12 +101,10 @@

    LCO Light Curves

    - {% if block.body.analysis_status %} - {{block.body.get_analysis_status_display}} - {% endif %} + {{block.body.get_analysis_status_display}}
    @@ -135,12 +133,10 @@

    LCO Light Curves

    - {% if body.analysis_status %} - {{body.get_analysis_status_display}} - {% endif %} + {{body.get_analysis_status_display}} diff --git a/neoexchange/core/tests/test_dataproducts.py b/neoexchange/core/tests/test_dataproducts.py index 14222a223..1f9538bf3 100644 --- a/neoexchange/core/tests/test_dataproducts.py +++ b/neoexchange/core/tests/test_dataproducts.py @@ -396,3 +396,17 @@ def test_dataproduct_delete(self): dp_qset = DataProduct.content.fullbody(bodyid=self.body.id).filter(filetype=DataProduct.PNG_ASTRO) # Overwrites old file self.assertIn(file_name, dp_qset[0].product.name) + + def test_reverse_lookup(self): + file_name = 'test_ALCDEF.txt' + file_content = "some text here" + + save_dataproduct(obj=self.test_sblock, filepath=None, filetype=DataProduct.ALCDEF_TXT, filename=file_name, content=file_content) + + sb = SuperBlock.objects.filter(dataproduct__filetype=DataProduct.ALCDEF_TXT) + raw_blk = Block.objects.filter(dataproduct__filetype=DataProduct.ALCDEF_TXT) + sb_blk = Block.objects.filter(superblock__dataproduct__filetype=DataProduct.ALCDEF_TXT) + + self.assertEqual(len(sb), 1) + self.assertEqual(len(raw_blk), 0) + self.assertEqual(len(sb_blk), 1) diff --git a/neoexchange/core/tests/test_views.py b/neoexchange/core/tests/test_views.py index 2fc3c61e2..17a665eb5 100644 --- a/neoexchange/core/tests/test_views.py +++ b/neoexchange/core/tests/test_views.py @@ -2519,182 +2519,187 @@ def setUp(self): self.nocheck_keys = ['ingest'] # Involves datetime.utcnow(), hard to check - self.expected_elements = {u'id' : 1, - 'name' : u'2014 UR', - 'provisional_name': None, - 'provisional_packed': None, - 'elements_type': u'MPC_MINOR_PLANET', - 'abs_mag' : 26.6, - 'argofperih': 222.91160, - 'longascnode': 24.87559, - 'eccentricity': 0.0120915, - 'epochofel': datetime(2016, 1, 13, 0), - 'orbit_rms': 99, - 'meandist': 0.9967710, - 'orbinc': 8.25708, - 'meananom': 221.74204, - 'epochofperih': None, - 'perihdist': None, - 'slope': 0.15, - 'origin' : u'M', - 'active' : True, - 'arc_length': 357.0, - 'discovery_date': datetime(2014, 10, 17, 0), - 'num_obs' : 147, - 'not_seen' : 5.5, - 'orbit_rms' : 0.57, - 'fast_moving' : False, - 'score' : None, - 'source_type' : 'N', - 'source_subtype_1' : None, - 'source_subtype_2': None, - 'update_time' : datetime(2015, 10, 9, 0), - 'updated' : True, - 'urgency' : None - } + self.expected_elements = {u'id': 1, + 'name': u'2014 UR', + 'provisional_name': None, + 'provisional_packed': None, + 'elements_type': u'MPC_MINOR_PLANET', + 'abs_mag' : 26.6, + 'argofperih': 222.91160, + 'longascnode': 24.87559, + 'eccentricity': 0.0120915, + 'epochofel': datetime(2016, 1, 13, 0), + 'meandist': 0.9967710, + 'orbinc': 8.25708, + 'meananom': 221.74204, + 'epochofperih': None, + 'perihdist': None, + 'slope': 0.15, + 'origin': u'M', + 'active': True, + 'arc_length': 357.0, + 'discovery_date': datetime(2014, 10, 17, 0), + 'num_obs': 147, + 'not_seen': 5.5, + 'orbit_rms': 0.57, + 'fast_moving': False, + 'score': None, + 'source_type': 'N', + 'source_subtype_1': None, + 'source_subtype_2': None, + 'update_time': datetime(2015, 10, 9, 0), + 'updated': True, + 'urgency': None, + 'analysis_status': 0, + 'as_updated': None + } # Elements from epoch=2018-03-23 set self.expected_elements_sp_comet = { - 'id' : 2, - 'name' : u'243P/NEAT', + 'id': 2, + 'name': u'243P/NEAT', 'provisional_name': None, 'provisional_packed': None, 'elements_type': u'MPC_COMET', - 'abs_mag' : 10.4, + 'abs_mag': 10.4, 'argofperih': 283.56217, 'longascnode': 87.66076, 'eccentricity': 0.3591386, 'epochofel': datetime(2018, 3, 23, 0), - 'orbit_rms': 99.0, 'meandist': None, 'orbinc': 7.64150, 'meananom': None, 'epochofperih': datetime(2018, 8, 26, 0, 59, 55, int(0.968*1e6)), 'perihdist': 2.4544160, 'slope': 15.5/2.5, - 'origin' : u'M', - 'active' : True, + 'origin': u'M', + 'active': True, 'arc_length': 5528.0, 'discovery_date': datetime(2003, 8, 1, 0), - 'num_obs' : 334, - 'not_seen' : -151.5, - 'orbit_rms' : 0.60, - 'fast_moving' : False, - 'score' : None, - 'source_type' : 'C', - 'source_subtype_1' : 'JF', + 'num_obs': 334, + 'not_seen': -151.5, + 'orbit_rms': 0.60, + 'fast_moving': False, + 'score': None, + 'source_type': 'C', + 'source_subtype_1': 'JF', 'source_subtype_2': None, - 'update_time' : datetime(2018, 9,19, 0), - 'updated' : True, - 'urgency' : None + 'update_time' : datetime(2018, 9, 19, 0), + 'updated': True, + 'urgency': None, + 'analysis_status': 0, + 'as_updated': None } # Elements from epoch=2016-04-19 set self.expected_elements_comet_set1 = { - 'id' : 3, - 'name' : u'C/2016 C2', + 'id': 3, + 'name': u'C/2016 C2', 'provisional_name': None, 'provisional_packed': None, 'elements_type': u'MPC_COMET', - 'abs_mag' : 13.8, + 'abs_mag': 13.8, 'argofperih': 214.01052, 'longascnode': 24.55858, 'eccentricity': 1.0000000, 'epochofel': datetime(2016, 4, 19, 0), - 'orbit_rms': 99.0, 'meandist': None, 'orbinc': 38.19233, 'meananom': None, 'epochofperih': datetime(2016, 4, 19, 0, 41, 44, int(0.736*1e6)), 'perihdist': 1.5671127, 'slope': 21/2.5, - 'origin' : u'M', - 'active' : True, + 'origin': u'M', + 'active': True, 'arc_length': 10.0, 'discovery_date': datetime(2016, 2, 8, 0), - 'num_obs' : 89, - 'not_seen' : 62.5, - 'orbit_rms' : 99.0, - 'fast_moving' : False, - 'score' : None, - 'source_type' : 'C', - 'source_subtype_1' : 'LP', + 'num_obs': 89, + 'not_seen': 62.5, + 'orbit_rms': 99.0, + 'fast_moving': False, + 'score': None, + 'source_type': 'C', + 'source_subtype_1': 'LP', 'source_subtype_2': None, - 'update_time' : datetime(2016, 2, 18, 0), - 'updated' : True, - 'urgency' : None + 'update_time': datetime(2016, 2, 18, 0), + 'updated': True, + 'urgency': None, + 'analysis_status': 0, + 'as_updated': None } # Elements from epoch=2016-07-30 set self.expected_elements_comet_set2 = { - 'id' : 3, - 'name' : u'C/2016 C2', + 'id': 3, + 'name': u'C/2016 C2', 'provisional_name': None, 'provisional_packed': None, 'elements_type': u'MPC_COMET', - 'abs_mag' : 13.8, + 'abs_mag': 13.8, 'argofperih': 214.40704, 'longascnode': 24.40401, 'eccentricity': 0.9755678, 'epochofel': datetime(2016, 7, 31, 0), - 'orbit_rms': 99.0, 'meandist': None, 'orbinc': 38.15649, 'meananom': None, 'epochofperih': datetime(2016, 4, 19, 14, 26, 29, int(0.472*1e6)), 'perihdist': 1.5597633, 'slope': 21.0/2.5, - 'origin' : u'M', - 'active' : True, + 'origin': u'M', + 'active': True, 'arc_length': 126, 'discovery_date': datetime(2016, 2, 8, 0), - 'num_obs' : 138, - 'not_seen' : 311.5, - 'orbit_rms' : 0.40, - 'fast_moving' : False, - 'score' : None, - 'source_type' : 'C', - 'source_subtype_1' : 'LP', + 'num_obs': 138, + 'not_seen': 311.5, + 'orbit_rms': 0.40, + 'fast_moving': False, + 'score': None, + 'source_type': 'C', + 'source_subtype_1': 'LP', 'source_subtype_2': None, - 'update_time' : datetime(2016, 6, 13, 0), - 'updated' : True, - 'urgency' : None + 'update_time': datetime(2016, 6, 13, 0), + 'updated': True, + 'urgency': None, + 'analysis_status': 0, + 'as_updated': None } # Elements from epoch=2019-04-27 set self.expected_elements_dnc_comet_set1 = { - 'id' : 4, - 'name' : u'C/2017 K2', + 'id': 4, + 'name': u'C/2017 K2', 'provisional_name': None, 'provisional_packed': None, 'elements_type': u'MPC_COMET', - 'abs_mag' : 6.3, + 'abs_mag': 6.3, 'argofperih': 236.10242, 'longascnode': 88.27001, 'eccentricity': 1.0003739, 'epochofel': datetime(2019, 4, 27, 0), - 'orbit_rms': 99.0, 'meandist': None, 'orbinc': 87.54153, 'meananom': None, 'epochofperih': datetime(2022, 12, 20, 10, 25, 51, int(0.168*1e6)), 'perihdist': 1.8037084, 'slope': 5.75/2.5, - 'origin' : u'O', - 'active' : True, + 'origin': u'O', + 'active': True, 'arc_length': 2339, 'discovery_date': datetime(2013, 5, 12, 0), - 'num_obs' : 1452, - 'not_seen' : -169.5, - 'orbit_rms' : 0.40, - 'fast_moving' : False, - 'score' : None, - 'source_type' : 'C', - 'source_subtype_1' : 'LP', + 'num_obs': 1452, + 'not_seen': -169.5, + 'orbit_rms': 0.40, + 'fast_moving': False, + 'score': None, + 'source_type': 'C', + 'source_subtype_1': 'LP', 'source_subtype_2': 'DN', - 'update_time' : datetime(2019, 10, 7, 0), - 'updated' : True, - 'urgency' : None + 'update_time': datetime(2019, 10, 7, 0), + 'updated': True, + 'urgency': None, + 'analysis_status': 0, + 'as_updated': None } self.maxDiff = None @@ -8398,68 +8403,3 @@ def test_display_text(self): dp = DataProduct.objects.filter(filetype=DataProduct.ALCDEF_TXT) response = display_textfile(request, dp[0].id) self.assertEqual(b"some text here", response.content) - -@override_settings(MEDIA_ROOT=tempfile.mkdtemp()) -@override_settings(DATA_ROOT=tempfile.mkdtemp()) -class TestLCDataListView(TestCase): - def setUp(self): - # Initialise with a test body and test proposal and test block/sblock - params = {'provisional_name': 'N999r0q', - 'name' : '2255', - 'abs_mag' : 21.0, - 'slope' : 0.15, - 'epochofel' : '2015-03-19 00:00:00', - 'meananom' : 325.2636, - 'argofperih' : 85.19251, - 'longascnode' : 147.81325, - 'orbinc' : 8.34739, - 'eccentricity' : 0.1896865, - 'meandist' : 1.2176312, - 'source_type' : 'U', - 'elements_type' : 'MPC_MINOR_PLANET', - 'active' : True, - 'origin' : 'M', - } - self.body, created = Body.objects.get_or_create(**params) - - neo_proposal_params = {'code': 'LCO2015A-009', - 'title': 'LCOGT NEO Follow-up Network' - } - self.neo_proposal, created = Proposal.objects.get_or_create(**neo_proposal_params) - - # Create test blocks - sblock_params = { - 'body': self.body, - 'proposal': self.neo_proposal, - 'block_start': '2015-04-20 13:00:00', - 'block_end': '2015-04-21 03:00:00', - 'tracking_number': '00042', - 'active': True, - } - self.test_sblock = SuperBlock.objects.create(**sblock_params) - block_params = {'telclass': '1m0', - 'site': 'cpt', - 'body': self.body, - 'superblock': self.test_sblock, - 'block_start': '2015-04-20 13:00:00', - 'block_end': '2015-04-21 03:00:00', - 'request_number': '10042', - 'num_exposures': 5, - 'exp_length': 42.0, - 'active': True, - 'num_observed': None, - 'reported': False - } - self.test_block = Block.objects.create(**block_params) - - def test_not_find_lc(self): - self.assertFalse(LCDataListView().find_lc()) - - def test_find_lc(self): - # Add ALCDEF Data Products - file_name = 'test_ALCDEF.txt' - file_content = "some text here" - save_dataproduct(obj=self.test_sblock, filepath=None, filetype=DataProduct.ALCDEF_TXT, filename=file_name, content=file_content) - - # find Alcdef Body - self.assertIn(self.body, LCDataListView().find_lc()) diff --git a/neoexchange/core/views.py b/neoexchange/core/views.py index 9c0d2dae5..5667bcb2d 100644 --- a/neoexchange/core/views.py +++ b/neoexchange/core/views.py @@ -1796,10 +1796,13 @@ class SpecDataListDisplay(ListView): paginate_by = 20 def get_context_data(self, **kwargs): + # define data_type context = super(SpecDataListDisplay, self).get_context_data(**kwargs) context['data_type'] = 'Spec' + # Define list of choices for status form body_list = Body.objects.filter(block__in=context['data_list']).distinct() body_choices_list = [(body.pk, body.current_name()) for body in body_list] + # Add form to context form = UpdateAnalysisStatusForm() form.fields['update_body'].choices = body_choices_list context['form'] = form @@ -1841,18 +1844,19 @@ def post(self, request, *args, **kwargs): class LCDataListDisplay(ListView): model = Body template_name = 'core/data_summary.html' - alcdefs_blocks = DataProduct.content.sblock().filter(filetype=DataProduct.ALCDEF_TXT).select_related('content_type') - block_ids = [x.object_id for x in alcdefs_blocks] period_info = PhysicalParameters.objects.filter(parameter_type='P').order_by('-preferred') prefetch_period = Prefetch('physicalparameters_set', queryset=period_info, to_attr='rot_period') - queryset = Body.objects.filter(superblock__pk__in=block_ids).distinct().prefetch_related(prefetch_period).order_by('-as_updated').order_by('analysis_status') - context_object_name = "data_list" + queryset = Body.objects.filter(superblock__dataproduct__filetype=DataProduct.ALCDEF_TXT).distinct().prefetch_related(prefetch_period).order_by('-as_updated').order_by('analysis_status') paginate_by = 20 + context_object_name = "data_list" def get_context_data(self, **kwargs): + # define data_type context = super(LCDataListDisplay, self).get_context_data(**kwargs) context['data_type'] = 'LC' + # Define list of choices for status form body_choices_list = [(body.pk, body.current_name()) for body in context['data_list']] + # Add form to context form = UpdateAnalysisStatusForm() form.fields['update_body'].choices = body_choices_list context['form'] = form diff --git a/neoexchange/neox/tests/test_block_summary_page.py b/neoexchange/neox/tests/test_block_summary_page.py index bbb02dd76..d31272468 100644 --- a/neoexchange/neox/tests/test_block_summary_page.py +++ b/neoexchange/neox/tests/test_block_summary_page.py @@ -18,6 +18,7 @@ from django.urls import reverse from django.contrib.auth.models import User from selenium import webdriver +from selenium.common.exceptions import NoSuchElementException class BlockSummaryTest(FunctionalTest): @@ -28,24 +29,27 @@ def setUp(self): self.password = 'simpson' self.email = 'bart@simpson.org' self.bart = User.objects.create_user(username=self.username, password=self.password, email=self.email) - self.bart.first_name= 'Bart' + self.bart.first_name = 'Bart' self.bart.last_name = 'Simpson' - self.bart.is_active=1 + self.bart.is_active = 1 self.bart.save() - super(BlockSummaryTest,self).setUp() + super(BlockSummaryTest, self).setUp() def test_can_view_block_summary(self): # A seasoned user comes along to the site. self.browser.get(self.live_server_url) - # He sees a link to EFFICIENCY on the front page. - link = self.browser.find_element_by_xpath(u'//a[text()="Efficiency"]') - url = self.live_server_url + '/block/' + 'summary/' - self.assertEqual(link.get_attribute('href'), url) + # He sees no link to EFFICIENCY on the front page. + try: + link = self.browser.find_element_by_xpath(u'//a[text()="Efficiency"]') + raise Exception("This should be a hidden link") + except NoSuchElementException: + pass - # He clicks the link and is taken to a page with the efficiency + # He instead manually enters the url for the page with the efficiency # details. - link.click() + url = self.live_server_url + '/block/' + 'summary/' + self.browser.get(url) self.browser.implicitly_wait(3) new_url = self.live_server_url + '/block/' + 'summary/' username_input = self.browser.find_element_by_id("username") diff --git a/neoexchange/neox/tests/test_data_summarypage.py b/neoexchange/neox/tests/test_data_summarypage.py index 97dda5689..5a3d2c5fa 100644 --- a/neoexchange/neox/tests/test_data_summarypage.py +++ b/neoexchange/neox/tests/test_data_summarypage.py @@ -18,11 +18,17 @@ from selenium.webdriver.common.keys import Keys from selenium.webdriver.support.ui import Select from selenium.webdriver.common.by import By +from selenium.common.exceptions import NoSuchElementException from django.conf import settings +from django.urls import reverse +from django.contrib.auth.models import User from datetime import datetime, date +from mock import patch +from neox.tests.mocks import MockDateTime from core.models import Block, SuperBlock, Frame, Body, PreviousSpectra, DataProduct from core.utils import save_dataproduct, save_to_default +from neox.tests.mocks import mock_lco_authenticate import os @@ -33,10 +39,12 @@ class SummaryPageTest(FunctionalTest): """ def setUp(self): + # Setup Basics super(SummaryPageTest, self).setUp() settings.MEDIA_ROOT = self.test_dir spectradir = os.path.abspath(os.path.join('photometrics', 'tests', 'test_spectra')) + # Copy files into temp media root spec_path = 'target_2df_ex.fits' save_to_default(os.path.join(spectradir, spec_path), spectradir) analog_path = 'analog_2df_ex.fits' @@ -44,6 +52,44 @@ def setUp(self): analog2_path = 'test_2df_ex.fits' save_to_default(os.path.join(spectradir, analog2_path), spectradir) + # Create a superuser to test login + self.username = 'bart' + self.password = 'simpson' + self.email = 'bart@simpson.org' + self.bart = User.objects.create_user(username=self.username, password=self.password, email=self.email) + self.bart.first_name = 'Bart' + self.bart.last_name = 'Simpson' + self.bart.is_active = 1 + self.bart.is_staff = 1 + self.bart.is_superuser = 1 + self.bart.save() + + # insert extra body + params = { 'name' : 'q382918r', + 'abs_mag' : 21.0, + 'slope' : 0.15, + 'epochofel' : '2015-03-19 00:00:00', + 'meananom' : 325.2636, + 'argofperih' : 85.19251, + 'longascnode' : 147.81325, + 'orbinc' : 8.34739, + 'eccentricity' : 0.1896865, + 'meandist' : 1.2176312, + 'source_type' : 'N', + 'elements_type' : 'MPC_MINOR_PLANET', + 'active' : True, + 'origin' : 'N', + 'ingest' : '2015-05-11 17:20:00', + 'score' : 85, + 'discovery_date': '2015-05-10 12:00:00', + 'update_time' : '2015-05-18 05:00:00', + 'num_obs' : 35, + 'arc_length' : 42.0, + 'not_seen' : 2.22, + 'updated' : False + } + self.body2, created = Body.objects.get_or_create(pk=3, **params) + # build individual target blocks sblock_params = { 'cadence' : False, @@ -246,16 +292,86 @@ def setUp(self): save_dataproduct(self.test_sblock, lcname, DataProduct.ALCDEF_TXT) + # Add period + period_dict = {'value': 12, + 'error': .3, + 'parameter_type': 'P', + 'units': 'h', + 'preferred': True, + 'reference': 'NEOX', + 'quality': '2-', + 'notes': "testy test tested" + } + self.body.save_physical_parameters(period_dict) + + @patch('neox.auth_backend.lco_authenticate', mock_lco_authenticate) + def test_login(self): + self.browser.get('%s%s' % (self.live_server_url, '/accounts/login/')) + username_input = self.browser.find_element_by_id("username") + username_input.send_keys(self.username) + password_input = self.browser.find_element_by_id("password") + password_input.send_keys(self.password) + with self.wait_for_page_load(timeout=10): + self.browser.find_element_by_id('login-btn').click() + # Wait until response is recieved + self.wait_for_element_with_id('page') + + @patch('core.views.datetime', MockDateTime) def test_summary_pages_exist(self): - self.browser.get(self.live_server_url+'/summary/spec/') + # Find the link to the Data Summary Page + self.browser.get(self.live_server_url) + link = self.browser.find_element_by_xpath(u'//a[text()="Data"]') + lc_summary_url = self.live_server_url + reverse('lc_data_summary') + self.assertIn(link.get_attribute('href'), lc_summary_url) + # Go check it out and land on the LC summary + with self.wait_for_page_load(timeout=10): + link.click() + new_url = self.browser.current_url + self.assertEqual(str(new_url), lc_summary_url) self.assertIn('Data Summary Page | LCO NEOx', self.browser.title) - self.check_for_header_in_table('id_ranked_targets', 'Date Target Name Block Obs') - test_lines = ['1 2019-09-27 N999r0q 6 1', '2 2019-07-27 N999r0q 5 1', '3 2019-07-27 N999r0q 5 1'] + self.check_for_header_in_table('id_ranked_targets', 'Target Name Period Quality Source Notes Status Status Updated') + test_lines = ['1 N999r0q 12.0 (h) 2- NEOX testy test tested No Analysis Done'] + for test_line in test_lines: + self.check_for_row_in_table('id_ranked_targets', test_line) + # Not logged in, can't see status form + try: + arrow_link = self.browser.find_element_by_id("arrow") + raise Exception("Should be logged in for this form") + except NoSuchElementException: + pass + + # ooo, there's a spec page? + link = self.browser.find_element_by_link_text('(Spec)') + spec_summary_url = self.live_server_url + reverse('spec_data_summary') + self.assertIn(link.get_attribute('href'), spec_summary_url) + # Go check it out and land on the spec summary + with self.wait_for_page_load(timeout=10): + link.click() + new_url = self.browser.current_url + self.assertEqual(str(new_url), spec_summary_url) + self.check_for_header_in_table('id_ranked_targets', 'Date Target Name Block Obs Status Status Updated') + test_lines = ['1 2019-09-27 N999r0q 6 1 No Analysis Done', '2 2019-07-27 N999r0q 5 1 No Analysis Done', '3 2019-07-27 N999r0q 5 1 No Analysis Done'] for test_line in test_lines: self.check_for_row_in_table('id_ranked_targets', test_line) - lc_link = self.browser.find_element_by_link_text('(LC)') + + # Login and head back to LC summary + self.test_login() + link = self.browser.find_element_by_xpath(u'//a[text()="Data"]') with self.wait_for_page_load(timeout=10): - lc_link.click() - lc_lines = ['1 N999r0q'] - for lc_line in lc_lines: - self.check_for_row_in_table('id_ranked_targets', lc_line) + link.click() + new_url = self.browser.current_url + self.assertEqual(str(new_url), lc_summary_url) + # Mock a time so things work + MockDateTime.change_date(2021, 12, 10) + # find dropdown button + arrow_link = self.browser.find_element_by_id("arrow") + arrow_link.click() + # Fill out Form and submit. + status_select = Select(self.browser.find_element_by_id("id_status")) + status_select.select_by_visible_text("Published") + update_button = self.browser.find_element_by_id("update_status-btn") + with self.wait_for_page_load(timeout=10): + update_button.click() + test_lines = ['1 N999r0q 12.0 (h) 2- NEOX testy test tested Published Dec. 10, 2021'] + for test_line in test_lines: + self.check_for_row_in_table('id_ranked_targets', test_line) From 6459c56496164e12e081172b47f693e7d7d615c9 Mon Sep 17 00:00:00 2001 From: Joey Chatelain Date: Sat, 18 Dec 2021 11:30:33 -0800 Subject: [PATCH 14/23] make default period form invalid --- neoexchange/core/forms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/neoexchange/core/forms.py b/neoexchange/core/forms.py index 0ff499acf..e42492986 100644 --- a/neoexchange/core/forms.py +++ b/neoexchange/core/forms.py @@ -454,7 +454,7 @@ class AddTargetForm(forms.Form): class AddPeriodForm(forms.Form): - period = forms.FloatField(label="Period", initial=1.000, required=True, widget=forms.DateTimeInput(attrs={'style': 'width: 75px;'})) + period = forms.FloatField(label="Period", initial=None, required=True, widget=forms.DateTimeInput(attrs={'style': 'width: 75px;'})) error = forms.FloatField(label="Error", initial=0.0, required=False, widget=forms.DateTimeInput(attrs={'style': 'width: 75px;'})) quality = forms.ChoiceField(required=False, choices=LC_QUALITIES) notes = forms.CharField(label="Notes", required=False, widget=forms.DateTimeInput(attrs={'style': 'width: 275px;'})) From 4a30ce4d3c5b8b9ba4c049f625f99a3d44e5c3ce Mon Sep 17 00:00:00 2001 From: Joey Chatelain Date: Mon, 20 Dec 2021 15:25:45 -0800 Subject: [PATCH 15/23] add LC_plot tests --- neoexchange/core/templates/core/plot_lc.html | 2 +- neoexchange/core/views.py | 12 ++--- neoexchange/neox/tests/test_plot_lc.py | 49 ++++++++++++++++++-- 3 files changed, 52 insertions(+), 11 deletions(-) diff --git a/neoexchange/core/templates/core/plot_lc.html b/neoexchange/core/templates/core/plot_lc.html index e03efafa7..d404b990f 100644 --- a/neoexchange/core/templates/core/plot_lc.html +++ b/neoexchange/core/templates/core/plot_lc.html @@ -68,7 +68,7 @@
    Known Periods
    - {% for period in period_list|dictsort:"update_time"%} + {% for period in period_list %} - - + + {% endfor %} From 1879e58c3fe268fd0e46f40cd869d9379757daf5 Mon Sep 17 00:00:00 2001 From: Joey Chatelain Date: Tue, 21 Dec 2021 12:06:31 -0800 Subject: [PATCH 17/23] rm quality flag if none --- neoexchange/core/templates/core/data_summary.html | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/neoexchange/core/templates/core/data_summary.html b/neoexchange/core/templates/core/data_summary.html index 93cd2923a..452f18b7f 100644 --- a/neoexchange/core/templates/core/data_summary.html +++ b/neoexchange/core/templates/core/data_summary.html @@ -124,7 +124,9 @@

    LCO Light Curves

    - {{period.quality}} + {% if period.quality %} + {{period.quality}} + {% endif %}
    {{period.reference}} {{period.notes}}{{period.update_time}}{{period.update_time.date}}
    {% if block.body.analysis_status %} - {{block.body.as_updated}} + {{block.body.as_updated.date}} {% endif %} - {% if block.body.analysis_status %} + {% if block.body.as_updated %} {{block.body.as_updated.date}} {% endif %} - {% if body.analysis_status %} + {% if body.as_updated %} {{body.as_updated.date}} {% endif %}
    {{forloop.counter}} {{period.value}} diff --git a/neoexchange/core/views.py b/neoexchange/core/views.py index 5667bcb2d..bddc346b6 100644 --- a/neoexchange/core/views.py +++ b/neoexchange/core/views.py @@ -305,11 +305,11 @@ def get_context_data(self, **kwargs): else: date = blk.block_start.isoformat(' ') data = { - 'date' : date, - 'num' : blk.num_observed if blk.num_observed else 0, - 'type' : blk.get_obstype_display(), - 'duration' : (blk.block_end - blk.block_start).seconds, - 'location' : blk.where_observed() + 'date': date, + 'num': blk.num_observed if blk.num_observed else 0, + 'type': blk.get_obstype_display(), + 'duration': (blk.block_end - blk.block_start).seconds, + 'location': blk.where_observed() } blks.append(data) context['blocks'] = json.dumps(blks) @@ -3944,7 +3944,7 @@ class LCPlot(LookUpBodyMixin, FormView): form_class = AddPeriodForm def get(self, request, form=None, *args, **kwargs): - period_list = PhysicalParameters.objects.filter(body=self.body, parameter_type='P') + period_list = PhysicalParameters.objects.filter(body=self.body, parameter_type='P').order_by('update_time').order_by('-preferred') best_period = period_list.filter(preferred=True) if best_period: period = best_period[0].value diff --git a/neoexchange/neox/tests/test_plot_lc.py b/neoexchange/neox/tests/test_plot_lc.py index 1ff5968dd..209902249 100644 --- a/neoexchange/neox/tests/test_plot_lc.py +++ b/neoexchange/neox/tests/test_plot_lc.py @@ -25,7 +25,7 @@ from core.models import Body, DataProduct from core.utils import save_dataproduct, save_to_default from mock import patch -from neox.tests.mocks import mock_lco_authenticate +from neox.tests.mocks import mock_lco_authenticate, MockDateTime from django.conf import settings import os @@ -37,6 +37,7 @@ class LighCurvePlotTest(FunctionalTest): + @patch('core.models.body.datetime', MockDateTime) def setUp(self): super(LighCurvePlotTest, self).setUp() settings.DATA_ROOT = self.test_dir @@ -70,7 +71,12 @@ def setUp(self): } self.body2, created = Body.objects.get_or_create(pk=2, **params) - self.body2.save_physical_parameters({'parameter_type': 'P', 'value': 5.27}) + MockDateTime.change_date(2021, 12, 10) + self.body2.save_physical_parameters({'parameter_type': 'P', + 'value': 5.27, + 'error': .0015, + 'quality': '2-', + 'notes': "testy test note"}) params = {'name': 'C/2017 K2', 'abs_mag': 7.0, @@ -106,6 +112,8 @@ def setUp(self): self.bart.first_name = 'Bart' self.bart.last_name = 'Simpson' self.bart.is_active = 1 + self.bart.is_staff = 1 + self.bart.is_superuser = 1 self.bart.save() update_proposal_permissions(self.bart, [{'code': self.neo_proposal.code}]) @@ -131,10 +139,10 @@ def test_no_lightcurve(self): self.assertIn('Lightcurve for object: N999r0q', self.browser.title) self.assertIn('Could not find any LC data', error_text) + @patch('core.models.body.datetime', MockDateTime) @patch('neox.auth_backend.lco_authenticate', mock_lco_authenticate) def test_can_view_lightcurve(self): # test opening up a ALCDEF file associated with a body save_dataproduct(self.body2, self.lcname, DataProduct.ALCDEF_TXT) - self.login() lc_url = reverse('lc_plot', args=[self.body2.id]) self.browser.get(self.live_server_url + lc_url) @@ -146,9 +154,42 @@ def test_can_view_lightcurve(self): # test opening up a ALCDEF file associated period_box = self.browser.find_element_by_xpath("/html/body[@class='page']/div[@id='page-wrapper']/div[@id='page']/div[@id='main']/div[@name='lc_plot']/div[@class='bk']/div[@class='bk'][2]/div[@class='bk'][2]/div[@class='bk'][2]/div[@class='bk']/div[@class='bk'][1]/div[@class='bk'][1]/div[@class='bk']/div[@class='bk bk-input-group']/div[@class='bk bk-spin-wrapper']/input[@class='bk bk-input']") period_text = self.browser.find_element_by_xpath("/html/body[@class='page']/div[@id='page-wrapper']/div[@id='page']/div[@id='main']/div[@name='lc_plot']/div[@class='bk']/div[@class='bk'][2]/div[@class='bk'][2]/div[@class='bk'][2]/div[@class='bk']/div[@class='bk'][1]/div[@class='bk'][1]/div[@class='bk']/div[@class='bk bk-input-group']/label[@class='bk']").text self.assertIn('Period (Default: 5.27h)', period_text) + # check for period table + self.check_for_header_in_table('id_periods', 'Period [hours] Source Notes Date') + test_lines = ['1 5.27 ±0.0015 (2-) None testy test note Dec. 10, 2021'] + for test_line in test_lines: + self.check_for_row_in_table('id_periods', test_line) + # Check for no form + try: + arrow_link = self.browser.find_element_by_id("arrow") + raise Exception("Should be logged in for this form") + except NoSuchElementException: + pass + # Login + self.login() + self.browser.get(self.live_server_url + lc_url) + self.assertIn('Lightcurve for object: 433', self.browser.title) + # find form + arrow_link = self.browser.find_element_by_id("arrow") + arrow_link.click() + # Fill out Form and submit. + MockDateTime.change_date(2021, 12, 12) + period_box = self.get_item_input_box("id_period") + period_box.send_keys('4.35') + preferred_box = self.browser.find_element_by_id("id_preferred") + preferred_box.click() + add_button = self.browser.find_element_by_id("add_new_period-btn") + with self.wait_for_page_load(timeout=10): + add_button.click() + # check for updated period table + self.check_for_header_in_table('id_periods', 'Period [hours] Source Notes Date') + test_lines = ['1 4.35 (3) NEOX Dec. 12, 2021', '2 5.27 ±0.0015 (2-) None testy test note Dec. 10, 2021'] + for test_line in test_lines: + self.check_for_row_in_table('id_periods', test_line) + # get current window pw = self.browser.current_window_handle - data_link = self.browser.find_element_by_xpath("/html/body/div[1]/div/div[3]/div/div/div[2]/div[2]/div[1]/div[2]/div[4]/div[3]/div/div[1]/div[7]/a") + data_link = self.browser.find_element_by_link_text("2019-01-12") self.assertEqual(len(self.browser.window_handles), 1) data_link.click() WebDriverWait(self.browser, timeout=10).until(EC.number_of_windows_to_be(2)) From 7f480a794d6a28d7ab22c807577c959dcfa227b3 Mon Sep 17 00:00:00 2001 From: Joey Chatelain Date: Mon, 20 Dec 2021 22:06:27 -0800 Subject: [PATCH 16/23] adjust long rows to work with firefox --- neoexchange/core/static/core/css/styles.css | 8 +++++++- neoexchange/core/templates/core/data_summary.html | 4 ++++ neoexchange/core/templates/core/plot_lc.html | 12 ++++++++++-- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/neoexchange/core/static/core/css/styles.css b/neoexchange/core/static/core/css/styles.css index 9224aff9b..ab6ea5597 100755 --- a/neoexchange/core/static/core/css/styles.css +++ b/neoexchange/core/static/core/css/styles.css @@ -26,7 +26,7 @@ table { border-collapse: collapse; } table.datatable { margin: 0px; padding: 0px; background-color: white; width: 100%!important; border-collapse: collapse; table-layout: fixed; color:#555;} table.datatable th, table.datatable td { text-align: left; padding: 8px; border: 0px; font-weight: normal; } table.datatable th { padding: 16px 8px; font-weight: bold; border-bottom: 1px solid #aaa;} -table.datatable td { border-bottom: 1px solid #e6e6e6; color: #202020; white-space: nowrap; overflow: auto; text-overflow: unset; } +table.datatable td { border-bottom: 1px solid #e6e6e6; color: #202020; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } table.datatable td a { display: block; } table.datatable .wider { width: 12%; } @@ -1202,4 +1202,10 @@ ul.candidate-controls li:hover {background-color:#eee; } margin-bottom: 0px; margin-top: 2px; box-shadow: 2px 2px 10px #777; +} + +.long-row { + display: block; + white-space: nowrap; + overflow-x: auto; } \ No newline at end of file diff --git a/neoexchange/core/templates/core/data_summary.html b/neoexchange/core/templates/core/data_summary.html index bb8b3da8e..93cd2923a 100644 --- a/neoexchange/core/templates/core/data_summary.html +++ b/neoexchange/core/templates/core/data_summary.html @@ -127,10 +127,14 @@

    LCO Light Curves

    +
    {{period.reference}} +
    +
    {{period.notes}} +
    {{body.get_analysis_status_display}} diff --git a/neoexchange/core/templates/core/plot_lc.html b/neoexchange/core/templates/core/plot_lc.html index d404b990f..2b942a12d 100644 --- a/neoexchange/core/templates/core/plot_lc.html +++ b/neoexchange/core/templates/core/plot_lc.html @@ -79,8 +79,16 @@
    Known Periods
    ({{period.quality}}) {% endif %}
    {{period.reference}}{{period.notes}} +
    + {{period.reference}} +
    +
    +
    + {{period.notes}} +
    +
    {{period.update_time.date}}
    From 5d0596a92d350927d9892993945f919cb4948069 Mon Sep 17 00:00:00 2001 From: Joey Chatelain Date: Wed, 22 Dec 2021 11:52:14 -0800 Subject: [PATCH 18/23] add migration --- ...8_2330_squashed_0064_auto_20211218_0114.py | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 neoexchange/core/migrations/0061_auto_20211208_2330_squashed_0064_auto_20211218_0114.py diff --git a/neoexchange/core/migrations/0061_auto_20211208_2330_squashed_0064_auto_20211218_0114.py b/neoexchange/core/migrations/0061_auto_20211208_2330_squashed_0064_auto_20211218_0114.py new file mode 100644 index 000000000..6f55c0197 --- /dev/null +++ b/neoexchange/core/migrations/0061_auto_20211208_2330_squashed_0064_auto_20211218_0114.py @@ -0,0 +1,46 @@ +# Generated by Django 3.1.13 on 2021-12-22 19:51 + +import datetime +from django.db import migrations, models + + +class Migration(migrations.Migration): + + replaces = [('core', '0061_auto_20211208_2330'), ('core', '0062_auto_20211214_2332'), ('core', '0063_auto_20211214_2345'), ('core', '0064_auto_20211218_0114')] + + dependencies = [ + ('core', '0060_auto_20210820_1933'), + ] + + operations = [ + migrations.AddField( + model_name='body', + name='as_updated', + field=models.DateTimeField(blank=True, db_index=True, null=True), + ), + migrations.AlterField( + model_name='dataproduct', + name='created', + field=models.DateTimeField(default=datetime.datetime.utcnow, verbose_name='Datetime of the products creation or most recent update.'), + ), + migrations.AlterField( + model_name='dataproduct', + name='filetype', + field=models.PositiveSmallIntegerField(choices=[(0, 'JPEG'), (1, 'Spectroscopy Guider GIF'), (22, 'Thumbnail Frame GIF'), (2, 'FITS Image'), (3, 'FITS Spectra'), (4, 'ALCDEF Lightcurve file'), (23, 'Periodogram output file'), (24, 'Model Lightcurve output file'), (25, 'Parameter file used to create DAMIT lightcurve models'), (26, 'Shape Model output file'), (5, 'MP4'), (6, 'CSV'), (7, 'PNG astrometric ref stars'), (8, 'PNG photometric ref stars'), (9, 'Block light curve PNG (phased)'), (10, 'Block light curve PNG (unphased)'), (11, 'Combined light curve PNG (phased)'), (12, 'Combined light curve PNG (unphased)'), (13, 'Period finder periodogram PNG'), (14, 'Period finder data window PNG'), (15, 'FWHM condition PNG'), (16, 'Zero point PNG'), (20, 'Planetary Data System (PDS) XML'), (99, 'Other')], verbose_name='Type of file to be stored.'), + ), + migrations.AlterField( + model_name='dataproduct', + name='product', + field=models.FileField(blank=True, upload_to='products/', verbose_name='Filefield for actual data product.'), + ), + migrations.AlterField( + model_name='dataproduct', + name='update', + field=models.BooleanField(default=True, verbose_name='Flag for allowing automated updates. Set to False for robust storage.'), + ), + migrations.AddField( + model_name='body', + name='analysis_status', + field=models.IntegerField(choices=[(0, 'No Analysis Done'), (1, 'Light Curve Analysis Done'), (2, 'Spectroscopic Analysis Done'), (3, 'LC & Spec Analysis Done'), (10, 'More Observations Needed'), (20, 'Published'), (99, 'No usable Data')], db_index=True, default=0, verbose_name='Current Analysis Status'), + ), + ] From b0cbeae2aa95af120e8c5bd0e6ad42796c7325e0 Mon Sep 17 00:00:00 2001 From: Joey Chatelain Date: Wed, 22 Dec 2021 11:56:14 -0800 Subject: [PATCH 19/23] update version/readme --- README.md | 5 +++++ neoexchange/neox/settings.py | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ebe067b0e..b6917c6d8 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,11 @@ Portal for scheduling observations of NEOs (and other Solar System objects) usin ## History +### 3.10.3 +* Update Summary pages for enhanced usability and utility +* Add body publication status +* Add form for updating period from LC plot page + ### 3.10.2 * Fix ADES header info for new telescopes and MuSCAT instrument (Issue #578) * Fix gif movie creation permission issues (Issue #580) diff --git a/neoexchange/neox/settings.py b/neoexchange/neox/settings.py index 1cbd93ab8..be4642a71 100644 --- a/neoexchange/neox/settings.py +++ b/neoexchange/neox/settings.py @@ -7,7 +7,7 @@ import rollbar -VERSION = '3.10.2' +VERSION = '3.10.3' CURRENT_PATH = os.path.dirname(os.path.realpath(__file__)) From 774023975d342b12902c5bc5d3ffb71d54b21f71 Mon Sep 17 00:00:00 2001 From: Joey Chatelain Date: Wed, 22 Dec 2021 16:24:44 -0800 Subject: [PATCH 20/23] add form validation for negative numbers --- neoexchange/core/forms.py | 9 +++++++++ neoexchange/neox/tests/test_plot_lc.py | 14 ++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/neoexchange/core/forms.py b/neoexchange/core/forms.py index e42492986..d1a7c527e 100644 --- a/neoexchange/core/forms.py +++ b/neoexchange/core/forms.py @@ -460,6 +460,15 @@ class AddPeriodForm(forms.Form): notes = forms.CharField(label="Notes", required=False, widget=forms.DateTimeInput(attrs={'style': 'width: 275px;'})) preferred = forms.BooleanField(initial=False, required=False) + def clean(self): + cleaned_data = super(AddPeriodForm, self).clean() + period = self.cleaned_data.get('period', None) + error = self.cleaned_data.get('error', None) + if period and period <= 0: + raise forms.ValidationError("Please enter a positive number for Period.") + if error and error < 0: + raise forms.ValidationError("Please enter a positive number, zero, or leave Error blank.") + class UpdateAnalysisStatusForm(forms.Form): update_body = forms.ChoiceField(required=False, choices=[]) diff --git a/neoexchange/neox/tests/test_plot_lc.py b/neoexchange/neox/tests/test_plot_lc.py index 209902249..74f40aa72 100644 --- a/neoexchange/neox/tests/test_plot_lc.py +++ b/neoexchange/neox/tests/test_plot_lc.py @@ -175,6 +175,20 @@ def test_can_view_lightcurve(self): # test opening up a ALCDEF file associated # Fill out Form and submit. MockDateTime.change_date(2021, 12, 12) period_box = self.get_item_input_box("id_period") + period_box.send_keys('-4.35') + add_button = self.browser.find_element_by_id("add_new_period-btn") + with self.wait_for_page_load(timeout=10): + add_button.click() + arrow_link = self.browser.find_element_by_id("arrow") + arrow_link.click() + error_msg = self.browser.find_element_by_class_name('errorlist').text + self.assertIn("Please enter a positive number for Period", error_msg) + test_lines = ['1 5.27 ±0.0015 (2-) None testy test note Dec. 10, 2021'] + for test_line in test_lines: + self.check_for_row_in_table('id_periods', test_line) + + period_box = self.get_item_input_box("id_period") + period_box.clear() period_box.send_keys('4.35') preferred_box = self.browser.find_element_by_id("id_preferred") preferred_box.click() From 6650e9fd5d869534e79b680b8d1cb62ea0bfaa2c Mon Sep 17 00:00:00 2001 From: Joey Chatelain Date: Sun, 2 Jan 2022 14:43:54 -0800 Subject: [PATCH 21/23] change quality flags --- neoexchange/core/forms.py | 12 ++------ .../migrations/0062_auto_20220102_1930.py | 18 ++++++++++++ neoexchange/core/models/body.py | 28 +++++++++++++++++-- .../core/templates/core/data_summary.html | 4 +-- neoexchange/core/templates/core/plot_lc.html | 4 +-- .../neox/tests/test_data_summarypage.py | 6 ++-- neoexchange/neox/tests/test_plot_lc.py | 8 ++++-- 7 files changed, 58 insertions(+), 22 deletions(-) create mode 100644 neoexchange/core/migrations/0062_auto_20220102_1930.py diff --git a/neoexchange/core/forms.py b/neoexchange/core/forms.py index d1a7c527e..5001cdc75 100644 --- a/neoexchange/core/forms.py +++ b/neoexchange/core/forms.py @@ -22,7 +22,7 @@ from django.core.exceptions import ValidationError from django.utils.translation import gettext_lazy as _ from astrometrics.sources_subs import fetch_sfu, fetch_filter_list -from .models import Body, Proposal, Block, StaticSource, ORIGINS, STATUS_CHOICES +from .models import Body, Proposal, Block, StaticSource, ORIGINS, STATUS_CHOICES, PHYSICAL_PARAMETER_QUALITIES from astrometrics.time_subs import tomorrow logger = logging.getLogger(__name__) @@ -69,15 +69,7 @@ ('4', '4'), ('5', '5')) -LC_QUALITIES = (('3', 'Unambiguous (3)'), - ('3-', 'Unique (3-)'), - ('2+', 'Possible Ambiguity (2+)'), - ('2', 'Within 30% accurate (2)'), - ('2-', 'Not well established (2-)'), - ('1+', 'Possibly Just Noise (1+)'), - ('1', 'Possibly Completely Wrong (1)'), - ('1-', 'Probably Completely Wrong (1-)'), - ('0', 'Debunked (0)')) +LC_QUALITIES = tuple((qual, PHYSICAL_PARAMETER_QUALITIES['P'][qual]) for qual in PHYSICAL_PARAMETER_QUALITIES['P']) class SiteSelectWidget(forms.Select): diff --git a/neoexchange/core/migrations/0062_auto_20220102_1930.py b/neoexchange/core/migrations/0062_auto_20220102_1930.py new file mode 100644 index 000000000..3339c0608 --- /dev/null +++ b/neoexchange/core/migrations/0062_auto_20220102_1930.py @@ -0,0 +1,18 @@ +# Generated by Django 3.1.13 on 2022-01-02 19:30 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0061_auto_20211208_2330_squashed_0064_auto_20211218_0114'), + ] + + operations = [ + migrations.AlterField( + model_name='physicalparameters', + name='quality', + field=models.IntegerField(blank=True, null=True, verbose_name='Physical Parameter Quality Designation'), + ), + ] diff --git a/neoexchange/core/models/body.py b/neoexchange/core/models/body.py index bd0a28580..62abc6970 100644 --- a/neoexchange/core/models/body.py +++ b/neoexchange/core/models/body.py @@ -12,6 +12,7 @@ """ from datetime import datetime, timedelta from math import degrees +import re import logging from astropy.time import Time @@ -124,6 +125,18 @@ (99, 'No usable Data') ) +PHYSICAL_PARAMETER_QUALITIES = {"P": {-99: 'Debunked (0)', + 0: 'Probably Completely Wrong (1-)', + 2: 'Possibly Completely Wrong (1)', + 3: 'Possibly Just Noise (1+)', + 5: 'Not well established (2-)', + 6: 'Within 30% accurate (2)', + 7: 'Possible Ambiguity (2+)', + 9: 'Unique (3-)', + 10: 'Unambiguous (3)', + } + } + logger = logging.getLogger(__name__) @@ -189,7 +202,7 @@ def _compute_one_over_a(self): period = property(_compute_period) recip_a = property(_compute_one_over_a) - one_over_a = property(_compute_one_over_a) + one_over_a = property(_compute_one_over_a) def characterization_target(self): # If we change the definition of Characterization Target, @@ -602,12 +615,23 @@ class PhysicalParameters(models.Model): value2 = models.FloatField('2nd component of Physical Parameter', blank=True, null=True) error2 = models.FloatField('Error for 2nd component of Physical Parameter', blank=True, null=True) units = models.CharField('Physical Parameter Units', blank=True, null=True, max_length=30) - quality = models.CharField('Physical Parameter Quality Designation', blank=True, null=True, max_length=10) + quality = models.IntegerField('Physical Parameter Quality Designation', blank=True, null=True) preferred = models.BooleanField('Is this the preferred value for this type of parameter?', default=False) reference = models.TextField('Reference for this value', blank=True, null=True) notes = models.TextField('Notes on this value', blank=True, null=True) update_time = models.DateTimeField(blank=True, null=True, db_index=True) + def quality_parser(self): + return PHYSICAL_PARAMETER_QUALITIES.get(self.parameter_type, {}).get(self.quality, self.quality) + + def quality_short(self): + quality_string = self.quality_parser() + if isinstance(quality_string, str): + short_string = re.search(r'\(.*?\)', quality_string).group() + if short_string: + return short_string + return f"({quality_string})" + class Meta: verbose_name = _('Physical Parameter') verbose_name_plural = _('Physical Parameters') diff --git a/neoexchange/core/templates/core/data_summary.html b/neoexchange/core/templates/core/data_summary.html index 452f18b7f..b1ebe5f66 100644 --- a/neoexchange/core/templates/core/data_summary.html +++ b/neoexchange/core/templates/core/data_summary.html @@ -124,8 +124,8 @@

    LCO Light Curves

    - {% if period.quality %} - {{period.quality}} + {% if period.quality is not None %} + {{period.quality_parser}} {% endif %}
    diff --git a/neoexchange/core/templates/core/plot_lc.html b/neoexchange/core/templates/core/plot_lc.html index 2b942a12d..7ffe89795 100644 --- a/neoexchange/core/templates/core/plot_lc.html +++ b/neoexchange/core/templates/core/plot_lc.html @@ -75,8 +75,8 @@
    Known Periods
    {% if period.error %} ±{{period.error}} {% endif %} - {% if period.quality %} - ({{period.quality}}) + {% if period.quality is not None %} + {{period.quality_short}} {% endif %}
    diff --git a/neoexchange/neox/tests/test_data_summarypage.py b/neoexchange/neox/tests/test_data_summarypage.py index 5a3d2c5fa..afa3ddcc0 100644 --- a/neoexchange/neox/tests/test_data_summarypage.py +++ b/neoexchange/neox/tests/test_data_summarypage.py @@ -299,7 +299,7 @@ def setUp(self): 'units': 'h', 'preferred': True, 'reference': 'NEOX', - 'quality': '2-', + 'quality': 5, 'notes': "testy test tested" } self.body.save_physical_parameters(period_dict) @@ -330,7 +330,7 @@ def test_summary_pages_exist(self): self.assertEqual(str(new_url), lc_summary_url) self.assertIn('Data Summary Page | LCO NEOx', self.browser.title) self.check_for_header_in_table('id_ranked_targets', 'Target Name Period Quality Source Notes Status Status Updated') - test_lines = ['1 N999r0q 12.0 (h) 2- NEOX testy test tested No Analysis Done'] + test_lines = ['1 N999r0q 12.0 (h) Not well established (2-) NEOX testy test tested No Analysis Done'] for test_line in test_lines: self.check_for_row_in_table('id_ranked_targets', test_line) # Not logged in, can't see status form @@ -372,6 +372,6 @@ def test_summary_pages_exist(self): update_button = self.browser.find_element_by_id("update_status-btn") with self.wait_for_page_load(timeout=10): update_button.click() - test_lines = ['1 N999r0q 12.0 (h) 2- NEOX testy test tested Published Dec. 10, 2021'] + test_lines = ['1 N999r0q 12.0 (h) Not well established (2-) NEOX testy test tested Published Dec. 10, 2021'] for test_line in test_lines: self.check_for_row_in_table('id_ranked_targets', test_line) diff --git a/neoexchange/neox/tests/test_plot_lc.py b/neoexchange/neox/tests/test_plot_lc.py index 74f40aa72..6a3a20bb0 100644 --- a/neoexchange/neox/tests/test_plot_lc.py +++ b/neoexchange/neox/tests/test_plot_lc.py @@ -19,7 +19,7 @@ from django.core.files.storage import default_storage from django.contrib.auth.models import User from neox.auth_backend import update_proposal_permissions -from selenium.webdriver.support.ui import WebDriverWait +from selenium.webdriver.support.ui import WebDriverWait, Select from selenium.webdriver.support import expected_conditions as EC from selenium.common.exceptions import NoSuchElementException from core.models import Body, DataProduct @@ -75,7 +75,7 @@ def setUp(self): self.body2.save_physical_parameters({'parameter_type': 'P', 'value': 5.27, 'error': .0015, - 'quality': '2-', + 'quality': 5, 'notes': "testy test note"}) params = {'name': 'C/2017 K2', @@ -192,12 +192,14 @@ def test_can_view_lightcurve(self): # test opening up a ALCDEF file associated period_box.send_keys('4.35') preferred_box = self.browser.find_element_by_id("id_preferred") preferred_box.click() + quality_choices = Select(self.browser.find_element_by_id('id_quality')) + quality_choices.select_by_visible_text("Unique (3-)") add_button = self.browser.find_element_by_id("add_new_period-btn") with self.wait_for_page_load(timeout=10): add_button.click() # check for updated period table self.check_for_header_in_table('id_periods', 'Period [hours] Source Notes Date') - test_lines = ['1 4.35 (3) NEOX Dec. 12, 2021', '2 5.27 ±0.0015 (2-) None testy test note Dec. 10, 2021'] + test_lines = ['1 4.35 (3-) NEOX Dec. 12, 2021', '2 5.27 ±0.0015 (2-) None testy test note Dec. 10, 2021'] for test_line in test_lines: self.check_for_row_in_table('id_periods', test_line) From 4ddb2e383726f778f5a8380ec8bf347163b4fb4a Mon Sep 17 00:00:00 2001 From: Joey Chatelain Date: Mon, 3 Jan 2022 08:59:23 -0800 Subject: [PATCH 22/23] add some docstrings --- neoexchange/core/models/body.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/neoexchange/core/models/body.py b/neoexchange/core/models/body.py index 62abc6970..88f3ebbed 100644 --- a/neoexchange/core/models/body.py +++ b/neoexchange/core/models/body.py @@ -622,11 +622,19 @@ class PhysicalParameters(models.Model): update_time = models.DateTimeField(blank=True, null=True, db_index=True) def quality_parser(self): - return PHYSICAL_PARAMETER_QUALITIES.get(self.parameter_type, {}).get(self.quality, self.quality) + """Retrieve quality description for given Parameter type + Return Quality description or quality int. + """ + quality_dict = PHYSICAL_PARAMETER_QUALITIES.get(self.parameter_type, {}) + quality_text_or_value = quality_dict.get(self.quality, self.quality) + return quality_text_or_value def quality_short(self): + """If it exists, return shortened parenthetical quality tag. + Else, return quality int. as string. + """ quality_string = self.quality_parser() - if isinstance(quality_string, str): + if not isinstance(quality_string, str): short_string = re.search(r'\(.*?\)', quality_string).group() if short_string: return short_string From f8a92e71c6401c84238c789b1ae867b475410a5f Mon Sep 17 00:00:00 2001 From: Joey Chatelain Date: Mon, 3 Jan 2022 13:39:59 -0800 Subject: [PATCH 23/23] update version number --- README.md | 2 +- neoexchange/neox/settings.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e7408e481..ea9b94cb4 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Portal for scheduling observations of NEOs (and other Solar System objects) usin ## History -### 3.10.4 +### 3.11.0 * Update Summary pages for enhanced usability and utility * Add body publication status * Add form for updating period from LC plot page diff --git a/neoexchange/neox/settings.py b/neoexchange/neox/settings.py index be4642a71..f6d215889 100644 --- a/neoexchange/neox/settings.py +++ b/neoexchange/neox/settings.py @@ -7,7 +7,7 @@ import rollbar -VERSION = '3.10.3' +VERSION = '3.11.0' CURRENT_PATH = os.path.dirname(os.path.realpath(__file__))