import json from django.contrib import messages from django.utils.safestring import mark_safe from django.shortcuts import render, redirect, get_object_or_404, HttpResponse from django.contrib.auth.decorators import login_required from apps.main.models import Experiment, Device from apps.main.views import sidebar from .models import RCConfiguration, RCLine, RCLineType, RCLineCode, RCClock from .forms import RCConfigurationForm, RCLineForm, RCLineViewForm, RCLineEditForm, RCImportForm, RCLineCodesForm, RCClockForm def conf(request, conf_id): conf = get_object_or_404(RCConfiguration, pk=conf_id) lines = RCLine.objects.filter(rc_configuration=conf).order_by('channel') clk = RCClock.objects.filter(rc_configuration=conf).first() if clk is None: clk = RCClock(rc_configuration=conf) clk.save() for line in lines: params = json.loads(line.params) line.form = RCLineViewForm(extra_fields=params, line=line) if 'params' in params: line.subforms = [RCLineViewForm(extra_fields=fields, line=line, subform=True) for fields in params['params']] kwargs = {} kwargs['clock'] = clk kwargs['dev_conf'] = conf kwargs['rc_lines'] = lines kwargs['dev_conf_keys'] = ['ipp_unit', 'ntx', 'clock_divider', 'clock', 'time_before', 'time_after', 'sync', 'sampling_reference', 'control_tx', 'control_sw'] kwargs['title'] = 'Configuration' kwargs['suptitle'] = 'Detail' kwargs['button'] = 'Edit Configuration' ###### SIDEBAR ###### kwargs.update(sidebar(conf=conf)) return render(request, 'rc_conf.html', kwargs) @login_required def conf_edit(request, conf_id): conf = get_object_or_404(RCConfiguration, pk=conf_id) clock = RCClock.objects.get(rc_configuration=conf) lines = RCLine.objects.filter(rc_configuration=conf).order_by('channel') for line in lines: params = json.loads(line.params) line.form = RCLineEditForm(conf=conf, line=line, extra_fields=params) line.subform = False if 'params' in params: line.subforms = [RCLineEditForm(extra_fields=fields, line=line, subform=i) for i, fields in enumerate(params['params'])] line.subform = True if request.method=='GET': form = RCConfigurationForm(instance=conf) form_clock = RCClockForm(instance=clock) elif request.method=='POST': line_data = {} conf_data = {} clock_data = {} extras = [] #classified post fields for label,value in request.POST.items(): if label=='csrfmiddlewaretoken': continue if label.count('|')==0: if label in ('mode', 'multiplier', 'divisor', 'reference', 'frequency'): clock_data[label] = value else: conf_data[label] = value continue elif label.split('|')[0]!='-1': extras.append(label) continue x, pk, name = label.split('|') if name=='codes': value = [s for s in value.split('\r\n') if s] if pk in line_data: line_data[pk][name] = value else: line_data[pk] = {name:value} #update conf form_clock = RCClockForm(clock_data, instance=clock) form = RCConfigurationForm(conf_data, instance=conf) if form_clock.is_valid() and form.is_valid(): form_clock.save() form.save() #update lines fields extras.sort() xxs = {} for label in extras: x, pk, name = label.split('|') if pk not in line_data: line_data[pk] = {} if 'params' not in line_data[pk]: line_data[pk]['params'] = [] xxs[pk] = [] if x not in xxs[pk]: line_data[pk]['params'].append({}) xxs[pk].append(x) for label in extras: x, pk, name = label.split('|') line_data[pk]['params'][int(x)][name] = float(request.POST[label]) for pk, params in line_data.items(): line = RCLine.objects.get(pk=pk) if line.line_type.name in ('windows', 'prog_pulses'): if 'params' not in params: params['params'] = [] line.params = json.dumps(params) line.save() #update pulses field conf.update_pulses() messages.success(request, 'RC Configuration successfully updated') return redirect(conf.get_absolute_url()) kwargs = {} kwargs['dev_conf'] = conf kwargs['form'] = form kwargs['form_clock'] = form_clock kwargs['rc_lines'] = lines kwargs['edit'] = True kwargs['title'] = 'RC Configuration' kwargs['suptitle'] = 'Edit' kwargs['button'] = 'Update' return render(request, 'rc_conf_edit.html', kwargs) def add_line(request, conf_id, line_type_id=None, code_id=None): conf = get_object_or_404(RCConfiguration, pk=conf_id) if request.method=='GET': if line_type_id: line_type = get_object_or_404(RCLineType, pk=line_type_id) if code_id: form = RCLineForm(initial={'rc_configuration':conf_id, 'line_type': line_type_id, 'code_id': code_id}, extra_fields=json.loads(line_type.params)) else: form = RCLineForm(initial={'rc_configuration':conf_id, 'line_type': line_type_id}, extra_fields=json.loads(line_type.params)) else: line_type = {'id':0} form = RCLineForm(initial={'rc_configuration':conf_id}) if request.method=='POST': line_type = get_object_or_404(RCLineType, pk=line_type_id) form = RCLineForm(request.POST, extra_fields=json.loads(line_type.params)) if form.is_valid(): form.save() form.instance.update_pulses() return redirect('url_edit_rc_conf', conf.id) kwargs = {} kwargs['form'] = form kwargs['title'] = 'RC Configuration' kwargs['suptitle'] = 'Add Line' kwargs['button'] = 'Add' kwargs['previous'] = conf.get_absolute_url_edit() kwargs['dev_conf'] = conf kwargs['line_type'] = line_type return render(request, 'rc_add_line.html', kwargs) def edit_codes(request, conf_id, line_id, code_id=None): conf = get_object_or_404(RCConfiguration, pk=conf_id) line = get_object_or_404(RCLine, pk=line_id) params = json.loads(line.params) if request.method=='GET': if code_id: code = get_object_or_404(RCLineCode, pk=code_id) form = RCLineCodesForm(instance=code) else: initial = {'code': params['code'], 'codes': params['codes'] if 'codes' in params else [], 'number_of_codes': len(params['codes']) if 'codes' in params else 0, 'bits_per_code': len(params['codes'][0]) if 'codes' in params else 0, } form = RCLineCodesForm(initial=initial) if request.method=='POST': form = RCLineCodesForm(request.POST) if form.is_valid(): params['code'] = request.POST['code'] params['codes'] = [s for s in request.POST['codes'].split('\r\n') if s] line.params = json.dumps(params) line.save() messages.success(request, 'Line: "%s" has been updated.' % line) return redirect('url_edit_rc_conf', conf.id) kwargs = {} kwargs['form'] = form kwargs['title'] = line kwargs['suptitle'] = 'Edit' kwargs['button'] = 'Update' kwargs['dev_conf'] = conf kwargs['previous'] = conf.get_absolute_url_edit() kwargs['line'] = line return render(request, 'rc_edit_codes.html', kwargs) def add_subline(request, conf_id, line_id): conf = get_object_or_404(RCConfiguration, pk=conf_id) line = get_object_or_404(RCLine, pk=line_id) if request.method == 'POST': if line: params = json.loads(line.params) subparams = json.loads(line.line_type.params) if 'params' in subparams: dum = {} for key, value in subparams['params'].items(): dum[key] = value['value'] params['params'].append(dum) line.params = json.dumps(params) line.save() return redirect('url_edit_rc_conf', conf.id) kwargs = {} kwargs['title'] = 'Add new' kwargs['suptitle'] = '%s to %s' % (line.line_type.name, line) return render(request, 'confirm.html', kwargs) def remove_line(request, conf_id, line_id): conf = get_object_or_404(RCConfiguration, pk=conf_id) line = get_object_or_404(RCLine, pk=line_id) if request.method == 'POST': if line: try: channel = line.channel line.delete() for ch in range(channel+1, RCLine.objects.filter(rc_configuration=conf).count()+1): l = RCLine.objects.get(rc_configuration=conf, channel=ch) l.channel = l.channel-1 l.save() messages.success(request, 'Line: "%s" has been deleted.' % line) except: messages.error(request, 'Unable to delete line: "%s".' % line) return redirect('url_edit_rc_conf', conf.id) kwargs = {} kwargs['object'] = line kwargs['delete'] = True kwargs['title'] = 'Delete' kwargs['suptitle'] = 'Line' kwargs['previous'] = conf.get_absolute_url_edit() return render(request, 'confirm.html', kwargs) def remove_subline(request, conf_id, line_id, subline_id): conf = get_object_or_404(RCConfiguration, pk=conf_id) line = get_object_or_404(RCLine, pk=line_id) if request.method == 'POST': if line: params = json.loads(line.params) params['params'].remove(params['params'][int(subline_id)-1]) line.params = json.dumps(params) line.save() return redirect('url_edit_rc_conf', conf.id) kwargs = {} kwargs['object'] = line kwargs['object_name'] = line.line_type.name kwargs['delete_view'] = True kwargs['title'] = 'Confirm delete' return render(request, 'confirm.html', kwargs) def update_lines_position(request, conf_id): conf = get_object_or_404(RCConfiguration, pk=conf_id) if request.method=='POST': ch = 0 for item in request.POST['items'].split('&'): line = RCLine.objects.get(pk=item.split('=')[-1]) line.channel = ch line.save() ch += 1 lines = RCLine.objects.filter(rc_configuration=conf).order_by('channel') for line in lines: params = json.loads(line.params) line.form = RCLineEditForm(conf=conf, line=line, extra_fields=params) if 'params' in params: line.subform = True line.subforms = [RCLineEditForm(extra_fields=fields, line=line, subform=i) for i, fields in enumerate(params['params'])] html = render(request, 'rc_lines.html', {'dev_conf':conf, 'rc_lines':lines, 'edit':True}) data = {'html': html.content.decode('utf8')} return HttpResponse(json.dumps(data), content_type="application/json") return redirect('url_edit_rc_conf', conf.id) def import_file(request, conf_id): conf = get_object_or_404(RCConfiguration, pk=conf_id) if request.method=='POST': form = RCImportForm(request.POST, request.FILES) if form.is_valid(): try: data = conf.import_from_file(request.FILES['file_name']) conf.dict_to_parms(data) conf.update_pulses() messages.success(request, 'Configuration "%s" loaded succesfully' % request.FILES['file_name']) return redirect(conf.get_absolute_url_edit()) except Exception as e: messages.error(request, 'Error parsing file: "%s" - %s' % (request.FILES['file_name'], repr(e))) else: messages.warning(request, 'Your current configuration will be replaced') form = RCImportForm() kwargs = {} kwargs['form'] = form kwargs['title'] = 'RC Configuration' kwargs['suptitle'] = 'Import file' kwargs['button'] = 'Upload' kwargs['previous'] = conf.get_absolute_url() return render(request, 'rc_import.html', kwargs) def plot_pulses(request, conf_id): conf = get_object_or_404(RCConfiguration, pk=conf_id) km = True if 'km' in request.GET else False script, div = conf.plot_pulses(km=km) kwargs = {} kwargs['no_sidebar'] = True kwargs['title'] = 'RC Pulses' kwargs['suptitle'] = conf.name kwargs['div'] = mark_safe(div) kwargs['script'] = mark_safe(script) kwargs['units'] = conf.km2unit kwargs['kms'] = 1/conf.km2unit if km: kwargs['km_selected'] = True if 'json' in request.GET: return HttpResponse(json.dumps({'div':mark_safe(div), 'script':mark_safe(script)}), content_type="application/json") else: return render(request, 'rc_pulses.html', kwargs) def plot_pulses2(request, conf_id): conf = get_object_or_404(RCConfiguration, pk=conf_id) km = True if 'km' in request.GET else False script, div = conf.plot_pulses2(km=km) kwargs = {} kwargs['no_sidebar'] = True kwargs['title'] = 'RC Pulses' kwargs['suptitle'] = conf.name kwargs['div'] = mark_safe(div) kwargs['script'] = mark_safe(script) kwargs['units'] = conf.km2unit kwargs['kms'] = 1/conf.km2unit if km: kwargs['km_selected'] = True if 'json' in request.GET: return HttpResponse(json.dumps({'div':mark_safe(div), 'script':mark_safe(script)}), content_type="application/json") else: return render(request, 'rc_pulses.html', kwargs) def conf_raw(request, conf_id): conf = get_object_or_404(RCConfiguration, pk=conf_id) raw = conf.write_device(raw=True) return HttpResponse(raw, content_type='application/json')