<commit_before>import json
import plotly.offline as opy
import plotly.graph_objs as go
from django import template
from django.utils.safestring import mark_safe
from django.utils.datastructures import SortedDict
from django.contrib import messages
from django.contrib.auth.decorators import permission_required, login_required
from django.http import HttpResponseRedirect, HttpResponse
from django.shortcuts import render, get_object_or_404
from django.core.urlresolvers import reverse
from survey.models import LocationType, Location, MultiChoiceAnswer, Interview
from survey.forms.indicator import IndicatorForm, IndicatorVariableForm, IndicatorFormulaeForm
from survey.forms.filters import IndicatorFilterForm
from survey.models import Indicator, Survey, Answer, IndicatorVariable, IndicatorVariableCriteria
from survey.forms.enumeration_area import LocationsFilterForm

@login_required
@permission_required('auth.can_view_batches')
def new(request):
    indicator_form = IndicatorForm()
    if request.method == 'POST':
        indicator_form = IndicatorForm(data=request.POST)
        if indicator_form.is_valid():
            indicator_form.save()
            messages.success(request, "Indicator successfully created.")
            return HttpResponseRedirect(reverse('list_indicator_page'))
        messages.error(request, "Indicator was not created.")
    request.breadcrumbs([
        ('Indicators', reverse('list_indicator_page')),
    ])

    return render(request, 'indicator/new.html',
                  {'indicator_form': indicator_form, 'title': 'Add Indicator', 'button_label': 'Create',
                   'cancel_url': reverse('list_indicator_page'), 'action': '/indicators/new/',
                   'variable_form': IndicatorVariableForm(None)})

@login_required
def edit(request, indicator_id):
    indicator = Indicator.objects.get(id=indicator_id)
    indicator_form = IndicatorForm(instance=indicator)
    if request.method == 'POST':
        indicator_form = IndicatorForm(data=request.POST, instance=indicator)
        if indicator_form.is_valid():
            indicator_form.save()
            messages.success(request, "Indicator successfully edited.")
            return HttpResponseRedirect("/indicators/")
        messages.error(request, "Indicator was not successfully edited.")
    request.breadcrumbs([
        ('Indicators', reverse('list_indicator_page')),
    ])
    context = {'indicator_form': indicator_form, 'title': 'Edit Indicator',
               'button_label': 'Save', 'cancel_url': reverse('list_indicator_page'),
               'variable_form': IndicatorVariableForm(None)}
    return render(request, 'indicator/new.html', context)

def _process_form(indicator_filter_form, indicators):
    if indicator_filter_form.is_valid():
        survey_id = indicator_filter_form.cleaned_data['survey']
        batch_id = indicator_filter_form.cleaned_data['batch']
        module_id = indicator_filter_form.cleaned_data['module']
        if batch_id.isdigit() and module_id.isdigit():
            indicators = indicators.filter(batch=batch_id, module=module_id)
        elif not batch_id.isdigit() and module_id.isdigit():
            indicators = indicators.filter(module=module_id)
        elif batch_id.isdigit() and not module_id.isdigit():
            indicators = indicators.filter(batch__id=batch_id)
        elif survey_id.isdigit():
            batches = Survey.objects.get(id=survey_id).batches.values_list('id', flat=True)
            indicators = indicators.filter(batch__id__in=batches)
    return indicators

@login_required
@permission_required('auth.can_view_batches')
def index(request):
    indicators = Indicator.objects.all()
    indicator_filter_form = IndicatorFilterForm(data=request.GET)
    indicators = _process_form(indicator_filter_form, indicators)

    return render(request, 'indicator/index.html',
                  {'indicators': indicators, 'indicator_filter_form': indicator_filter_form})

@login_required
@permission_required('auth.can_view_batches')
def delete(request, indicator_id):
    indicator = Indicator.objects.get(id=indicator_id)
    indicator.indicator_criteria.all().delete()
    indicator.delete()
    messages.success(request, 'Indicator successfully deleted.')
    return HttpResponseRedirect('/indicators/')

@login_required
@permission_required('auth.can_view_household_groups')
def add_indicator_variable(request, indicator_id):
    indicator = Indicator.get(pk=indicator_id)
    request.breadcrumbs([
        ('Indicators', reverse('list_indicator_page')),
        ('Variable List', reverse('view_indicator_variables', args=(indicator_id, ))),
    ])
    return _add_variable(request, indicator=indicator)

def _add_variable(request, indicator=None):
    form_action = reverse('add_variable')
    parameter_questions = []
    if indicator:
        form_action = reverse("add_indicator_variable", args=(indicator.id, ))
        form_action = reverse("add_indicator_variable", args=(indicator.id, ))
        parameter_questions = indicator.eqset.all_questions
    variable_form = IndicatorVariableForm(indicator)
    if request.method == 'POST':
        variable_form = IndicatorVariableForm(indicator, data=request.POST)
        if variable_form.is_valid():
            variable = variable_form.save()
            if request.is_ajax() is False:
                messages.success(request, 'Variable successfully saved.')
            return HttpResponseRedirect(reverse('edit_indicator_variable', args=(variable.pk, )))
    context = {'variable_form': variable_form,
               'indicator': indicator,
               'title': "Manage Indicator Criteria",
               'button_label': 'Save',
               'id': 'add_group_form',
               "v_form_action": form_action,
               'cancel_url': reverse('list_indicator_page'),
               'parameter_questions': parameter_questions,
               'condition_title': "Conditions"}

    if request.is_ajax():
        context['cancel_url'] = None
        return render(request, 'indicator/indicator_form.html', context)
    return render(request, 'indicator/indicator_variable.html', context)

def add_variable(request):
    return _add_variable(request)

def ajax_edit_indicator_variable(request):
    if request.is_ajax():
        variable_id = request.GET.get('id')
        return edit_indicator_variable(request, variable_id)

@login_required
@permission_required('auth.can_view_household_groups')
def edit_indicator_variable(request, variable_id):
    variable = IndicatorVariable.get(id=variable_id)
    variable_form = IndicatorVariableForm(variable.indicator, instance=variable)
    parameter_questions = []
    if variable.indicator:
        parameter_questions = variable.indicator.eqset.all_questions
    if request.method == 'POST':
        variable_form = IndicatorVariableForm(variable.indicator, instance=variable, data=request.POST)
        if variable_form.is_valid():
            variable_form.save()
            if request.is_ajax() is False:
                messages.success(request, 'Variable successfully saved.')
            return HttpResponseRedirect(reverse('edit_indicator_variable', args=(variable.pk, )))
    context = {'variable_form': variable_form,
               'indicator': variable.indicator,
               'title': "Manage Indicator Criteria",
               'button_label': 'Save',
               'id': 'add_group_form',
               "v_form_action": reverse("edit_indicator_variable", args=(variable_id, )),
               'cancel_url': reverse('list_indicator_page'),
               'parameter_questions': parameter_questions,
               'conditions': variable.criteria.all(),
               'condition_title': "Conditions"}
    if request.is_ajax():
        context['cancel_url'] = None
        return render(request, 'indicator/indicator_form.html', context)
    breadcrumbs = [
        ('Indicators', reverse('list_indicator_page')),
    ]
    if variable.indicator:
        breadcrumbs.append(
        ('Variable List', reverse('view_indicator_variables', args=(variable.indicator.pk, ))))
    request.breadcrumbs(breadcrumbs)
    return render(request, 'indicator/indicator_variable.html', context)

@login_required
@permission_required('auth.can_view_household_groups')
def delete_indicator_variable(request, variable_id):
    get_object_or_404(IndicatorVariable, id=variable_id).delete()
    if request.is_ajax():
        return add_variable(request)
    messages.info(request, 'Variable removed successfully')
    return HttpResponseRedirect(reverse('list_indicator_page'))

@login_required
@permission_required('auth.can_view_household_groups')
def ajax_delete_indicator_variable(request):
    if request.is_ajax():
        variable_id = request.GET.get('id')
        return delete_indicator_variable(request, variable_id)

@login_required
@permission_required('auth.can_view_household_groups')
def delete_indicator_criteria(request, indicator_criteria_id):
    criterion = get_object_or_404(IndicatorVariableCriteria, id=indicator_criteria_id)
    variable = criterion.variable
    criterion.delete()
    if request.is_ajax() is False:
        messages.info(request, 'condition removed successfully')
    return HttpResponseRedirect(reverse('edit_indicator_variable', args=(variable.pk, )))

def view_indicator_variables(request, indicator_id):
    indicator = get_object_or_404(Indicator, id=indicator_id)
    request.breadcrumbs([
        ('Indicators', reverse('list_indicator_page')),
    ])
    context = {'indicator': indicator, 'variables': indicator.variables.all()}
    return render(request, 'indicator/indicator_variable_list.html', context)

@login_required
def variables(request):
    # return questions before last question
    if request.GET.get('id', None):
        indicator = Indicator.get(pk=request.GET.get('id', None))
        json_dump = json.dumps(list(indicator.variables.values_list('name', flat=True)))
    else:
        var_ids = request.GET.getlist('var_id[]')
        json_dump = json.dumps(list(IndicatorVariable.objects.filter(id__in=var_ids).values_list('name', flat=True)))
    return HttpResponse(json_dump, content_type='application/json')

@login_required
@permission_required('auth.can_view_batches')
def indicator_formula(request, indicator_id):
    indicator = Indicator.get(id=indicator_id)
    if request.method == 'POST':
        formulae_form = IndicatorFormulaeForm(instance=indicator, data=request.POST)
        if formulae_form.is_valid():
            formulae_form.save()
            messages.info(request, 'Formulae has been saved!')
            return HttpResponseRedirect(reverse('list_indicator_page'))
    else:
        formulae_form = IndicatorFormulaeForm(instance=indicator)
    request.breadcrumbs([
        ('Indicator List', reverse('list_indicator_page')),
    ])
    context = {'indicator_form': formulae_form, 'title': 'Indicator Formulae',
               'button_label': 'Save', 'cancel_url': reverse('list_indicator_page')}
    return render(request, 'indicator/formulae.html', context)

@permission_required('auth.can_view_batches')
def simple_indicator(request, indicator_id):
    hierarchy_limit = 2
    selected_location = Location.objects.get(parent__isnull=True)
    params = request.GET or request.POST
    locations_filter = LocationsFilterForm(data=params)
    first_level_location_analyzed = Location.objects.filter(
        type__name__iexact="country")[0]
    indicator = Indicator.objects.get(id=indicator_id)
    request.breadcrumbs([
        ('Indicator List', reverse('list_indicator_page')),
    ])
    if locations_filter.last_location_selected:
        selected_location = locations_filter.last_location_selected
    report_locations = selected_location.get_children().order_by('name')
    reports_df = indicator.get_data(report_locations)
    # hence set the location where the report is based. i.e the child current selected location.
    context = {'request': request, 'indicator': indicator,
               'locations_filter': locations_filter,
               'selected_location': selected_location,
               }
    context['report'] = mark_safe(reports_df.to_html(
        classes='table table-striped table-bordered table-hover table-sort'))
    variable_names = indicator.active_variables()

    def make_hover_text(row):
        return '\n'.join(['%s %s'% (row[name], name) for name in variable_names])
    reports_df['hover-text'] = reports_df.apply(make_hover_text, axis=1)
    if report_locations:
        trace1 = go.Bar(x=reports_df.index,
                        y=reports_df[indicator.REPORT_FIELD_NAME], x0=0, y0=0,
                        name=indicator.name,
                        text=reports_df['hover-text'],)
        data = go.Data([trace1])
        margin = go.Margin(pad=15)
        layout = go.Layout(title=indicator.name, xaxis={'title': report_locations[0].type.name},
                           yaxis={'title': 'Values per %s' % report_locations[0].type.name},
                           margin=margin,
                           annotations=[dict(x=xi, y=yi,
                                             text=str(yi),
                                             xanchor='center',
                                             yanchor='bottom',
                                             showarrow=False,
                                             ) for xi, yi in zip(reports_df.index,
                                                                 reports_df[indicator.REPORT_FIELD_NAME])])
        figure = go.Figure(data=data, layout=layout)
        graph_div = opy.plot(figure, auto_open=False, output_type='div', show_link=False)
        context['graph'] = mark_safe(graph_div)
    return render(request, 'indicator/simple_indicator.html', context)

<commit_msg>adjustment on indicator<commit_after>import json
import plotly.offline as opy
import plotly.graph_objs as go
from django import template
from django.utils.safestring import mark_safe
from django.utils.datastructures import SortedDict
from django.contrib import messages
from django.contrib.auth.decorators import permission_required, login_required
from django.http import HttpResponseRedirect, HttpResponse
from django.shortcuts import render, get_object_or_404
from django.core.urlresolvers import reverse
from survey.models import LocationType, Location, MultiChoiceAnswer, Interview
from survey.forms.indicator import IndicatorForm, IndicatorVariableForm, IndicatorFormulaeForm
from survey.forms.filters import IndicatorFilterForm
from survey.models import Indicator, Survey, Answer, IndicatorVariable, IndicatorVariableCriteria
from survey.forms.enumeration_area import LocationsFilterForm

@login_required
@permission_required('auth.can_view_batches')
def new(request):
    indicator_form = IndicatorForm()
    if request.method == 'POST':
        indicator_form = IndicatorForm(data=request.POST)
        if indicator_form.is_valid():
            indicator_form.save()
            messages.success(request, "Indicator successfully created.")
            return HttpResponseRedirect(reverse('list_indicator_page'))
        messages.error(request, "Indicator was not created.")
    request.breadcrumbs([
        ('Indicators', reverse('list_indicator_page')),
    ])

    return render(request, 'indicator/new.html',
                  {'indicator_form': indicator_form, 'title': 'Add Indicator', 'button_label': 'Create',
                   'cancel_url': reverse('list_indicator_page'), 'action': '/indicators/new/',
                   'variable_form': IndicatorVariableForm(None)})

@login_required
def edit(request, indicator_id):
    indicator = Indicator.objects.get(id=indicator_id)
    indicator_form = IndicatorForm(instance=indicator)
    if request.method == 'POST':
        indicator_form = IndicatorForm(data=request.POST, instance=indicator)
        if indicator_form.is_valid():
            indicator_form.save()
            messages.success(request, "Indicator successfully edited.")
            return HttpResponseRedirect("/indicators/")
        messages.error(request, "Indicator was not successfully edited.")
    request.breadcrumbs([
        ('Indicators', reverse('list_indicator_page')),
    ])
    context = {'indicator_form': indicator_form, 'title': 'Edit Indicator',
               'button_label': 'Save', 'cancel_url': reverse('list_indicator_page'),
               'variable_form': IndicatorVariableForm(None)}
    return render(request, 'indicator/new.html', context)

def _process_form(indicator_filter_form, indicators):
    if indicator_filter_form.is_valid():
        survey_id = indicator_filter_form.cleaned_data['survey']
        batch_id = indicator_filter_form.cleaned_data['batch']
        module_id = indicator_filter_form.cleaned_data['module']
        if batch_id.isdigit() and module_id.isdigit():
            indicators = indicators.filter(batch=batch_id, module=module_id)
        elif not batch_id.isdigit() and module_id.isdigit():
            indicators = indicators.filter(module=module_id)
        elif batch_id.isdigit() and not module_id.isdigit():
            indicators = indicators.filter(batch__id=batch_id)
        elif survey_id.isdigit():
            batches = Survey.objects.get(id=survey_id).batches.values_list('id', flat=True)
            indicators = indicators.filter(batch__id__in=batches)
    return indicators

@login_required
@permission_required('auth.can_view_batches')
def index(request):
    indicators = Indicator.objects.all()
    indicator_filter_form = IndicatorFilterForm(data=request.GET)
    indicators = _process_form(indicator_filter_form, indicators)

    return render(request, 'indicator/index.html',
                  {'indicators': indicators, 'indicator_filter_form': indicator_filter_form})

@login_required
@permission_required('auth.can_view_batches')
def delete(request, indicator_id):
    indicator = Indicator.objects.get(id=indicator_id)
    indicator.indicator_criteria.all().delete()
    indicator.delete()
    messages.success(request, 'Indicator successfully deleted.')
    return HttpResponseRedirect('/indicators/')

@login_required
@permission_required('auth.can_view_household_groups')
def add_indicator_variable(request, indicator_id):
    indicator = Indicator.get(pk=indicator_id)
    request.breadcrumbs([
        ('Indicators', reverse('list_indicator_page')),
        ('Variable List', reverse('view_indicator_variables', args=(indicator_id, ))),
    ])
    return _add_variable(request, indicator=indicator)

def _add_variable(request, indicator=None):
    form_action = reverse('add_variable')
    parameter_questions = []
    if indicator:
        form_action = reverse("add_indicator_variable", args=(indicator.id, ))
        form_action = reverse("add_indicator_variable", args=(indicator.id, ))
        parameter_questions = indicator.eqset.all_questions
    variable_form = IndicatorVariableForm(indicator)
    if request.method == 'POST':
        variable_form = IndicatorVariableForm(indicator, data=request.POST)
        if variable_form.is_valid():
            variable = variable_form.save()
            if request.is_ajax() is False:
                messages.success(request, 'Variable successfully saved.')
            return HttpResponseRedirect(reverse('edit_indicator_variable', args=(variable.pk, )))
    context = {'variable_form': variable_form,
               'indicator': indicator,
               'title': "Manage Indicator Criteria",
               'button_label': 'Save',
               'id': 'add_group_form',
               "v_form_action": form_action,
               'cancel_url': reverse('list_indicator_page'),
               'parameter_questions': parameter_questions,
               'condition_title': "Conditions"}

    if request.is_ajax():
        context['cancel_url'] = None
        return render(request, 'indicator/indicator_form.html', context)
    return render(request, 'indicator/indicator_variable.html', context)

def add_variable(request):
    return _add_variable(request)

def ajax_edit_indicator_variable(request):
    if request.is_ajax():
        variable_id = request.GET.get('id')
        return edit_indicator_variable(request, variable_id)

@login_required
@permission_required('auth.can_view_household_groups')
def edit_indicator_variable(request, variable_id):
    variable = IndicatorVariable.get(id=variable_id)
    variable_form = IndicatorVariableForm(variable.indicator, instance=variable)
    parameter_questions = []
    if variable.indicator:
        parameter_questions = variable.indicator.eqset.all_questions
    if request.method == 'POST':
        variable_form = IndicatorVariableForm(variable.indicator, instance=variable, data=request.POST)
        if variable_form.is_valid():
            variable_form.save()
            if request.is_ajax() is False:
                messages.success(request, 'Variable successfully saved.')
            return HttpResponseRedirect(reverse('edit_indicator_variable', args=(variable.pk, )))
    context = {'variable_form': variable_form,
               'indicator': variable.indicator,
               'title': "Manage Indicator Criteria",
               'button_label': 'Save',
               'id': 'add_group_form',
               "v_form_action": reverse("edit_indicator_variable", args=(variable_id, )),
               'cancel_url': reverse('list_indicator_page'),
               'parameter_questions': parameter_questions,
               'conditions': variable.criteria.all(),
               'condition_title': "Conditions"}
    if request.is_ajax():
        context['cancel_url'] = None
        return render(request, 'indicator/indicator_form.html', context)
    breadcrumbs = [
        ('Indicators', reverse('list_indicator_page')),
    ]
    if variable.indicator:
        breadcrumbs.append(
        ('Variable List', reverse('view_indicator_variables', args=(variable.indicator.pk, ))))
    request.breadcrumbs(breadcrumbs)
    return render(request, 'indicator/indicator_variable.html', context)

@login_required
@permission_required('auth.can_view_household_groups')
def delete_indicator_variable(request, variable_id):
    get_object_or_404(IndicatorVariable, id=variable_id).delete()
    if request.is_ajax():
        return add_variable(request)
    messages.info(request, 'Variable removed successfully')
    return HttpResponseRedirect(reverse('list_indicator_page'))

@login_required
@permission_required('auth.can_view_household_groups')
def ajax_delete_indicator_variable(request):
    if request.is_ajax():
        variable_id = request.GET.get('id')
        return delete_indicator_variable(request, variable_id)

@login_required
@permission_required('auth.can_view_household_groups')
def delete_indicator_criteria(request, indicator_criteria_id):
    criterion = get_object_or_404(IndicatorVariableCriteria, id=indicator_criteria_id)
    variable = criterion.variable
    criterion.delete()
    if request.is_ajax() is False:
        messages.info(request, 'condition removed successfully')
    return HttpResponseRedirect(reverse('edit_indicator_variable', args=(variable.pk, )))

def view_indicator_variables(request, indicator_id):
    indicator = get_object_or_404(Indicator, id=indicator_id)
    request.breadcrumbs([
        ('Indicators', reverse('list_indicator_page')),
    ])
    context = {'indicator': indicator, 'variables': indicator.variables.all()}
    return render(request, 'indicator/indicator_variable_list.html', context)

@login_required
def variables(request):
    # return questions before last question
    if request.GET.get('id', None):
        indicator = Indicator.get(pk=request.GET.get('id', None))
        json_dump = json.dumps(list(indicator.variables.values_list('name', flat=True)))
    else:
        var_ids = request.GET.getlist('var_id[]')
        json_dump = json.dumps(list(IndicatorVariable.objects.filter(id__in=var_ids).values_list('name', flat=True)))
    return HttpResponse(json_dump, content_type='application/json')

@login_required
@permission_required('auth.can_view_batches')
def indicator_formula(request, indicator_id):
    indicator = Indicator.get(id=indicator_id)
    if request.method == 'POST':
        formulae_form = IndicatorFormulaeForm(instance=indicator, data=request.POST)
        if formulae_form.is_valid():
            formulae_form.save()
            messages.info(request, 'Formulae has been saved!')
            return HttpResponseRedirect(reverse('list_indicator_page'))
    else:
        formulae_form = IndicatorFormulaeForm(instance=indicator)
    request.breadcrumbs([
        ('Indicator List', reverse('list_indicator_page')),
    ])
    context = {'indicator_form': formulae_form, 'title': 'Indicator Formulae',
               'button_label': 'Save', 'cancel_url': reverse('list_indicator_page')}
    return render(request, 'indicator/formulae.html', context)

@permission_required('auth.can_view_batches')
def simple_indicator(request, indicator_id):
    hierarchy_limit = 2
    selected_location = Location.objects.get(parent__isnull=True)
    params = request.GET or request.POST
    locations_filter = LocationsFilterForm(data=params)
    first_level_location_analyzed = Location.objects.filter(
        type__name__iexact="country")[0]
    indicator = Indicator.objects.get(id=indicator_id)
    request.breadcrumbs([
        ('Indicator List', reverse('list_indicator_page')),
    ])
    if locations_filter.last_location_selected:
        selected_location = locations_filter.last_location_selected
    report_locations = selected_location.get_children().order_by('name')
    reports_df = indicator.get_data(report_locations)
    # hence set the location where the report is based. i.e the child current selected location.
    context = {'request': request, 'indicator': indicator,
               'locations_filter': locations_filter,
               'selected_location': selected_location,
               }
    context['report'] = mark_safe(reports_df.to_html(
        classes='table table-striped table-bordered table-hover table-sort'))
    variable_names = indicator.active_variables()

    def make_hover_text(row):
        return '<br />'.join(['%s: %s' % ( name, row[name]) for name in variable_names])
    reports_df['hover-text'] = reports_df.apply(make_hover_text, axis=1)
    if report_locations:
        trace1 = go.Bar(x=reports_df.index,
                        y=reports_df[indicator.REPORT_FIELD_NAME], x0=0, y0=0,
                        name=indicator.name,
                        text=reports_df['hover-text'],)
        data = go.Data([trace1])
        margin = go.Margin(pad=15)
        layout = go.Layout(title=indicator.name, xaxis={'title': report_locations[0].type.name},
                           yaxis={'title': 'Values per %s' % report_locations[0].type.name},
                           margin=margin,
                           annotations=[dict(x=xi, y=yi,
                                             text=str(yi),
                                             xanchor='center',
                                             yanchor='bottom',
                                             showarrow=False,
                                             ) for xi, yi in zip(reports_df.index,
                                                                 reports_df[indicator.REPORT_FIELD_NAME])])
        figure = go.Figure(data=data, layout=layout)
        graph_div = opy.plot(figure, auto_open=False, output_type='div', show_link=False)
        context['graph'] = mark_safe(graph_div)
    return render(request, 'indicator/simple_indicator.html', context)

<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
"""
Created on Thu Nov 14 15:21:19 2013
Main Widget for entering filter specifications

@author: beike, Christian Münker
"""
import sys, os
from PyQt4 import QtGui

# import databroker from one level above if this file is run as __main__
# for test purposes
if __name__ == "__main__":
    __cwd__ = os.path.dirname(os.path.abspath(__file__))
    sys.path.append(__cwd__ + '/..')

import databroker as db

import SelectFilter, filterOrder, UnitBox, NumBox # ResponseType,

"""
Zur Eingabe aller Parameter und Einstellungen
"""

class ChooseParams(QtGui.QWidget):

    def __init__(self, DEBUG = True):
        super(ChooseParams, self).__init__()
        # "Properties" of all filter types:
        self.choose_design_list=(
                               ['firls','LP',['Fs','F_pass','F_stop'],[48000,9600,12000],False,True,"val",["Enter a weight value for each band below",["W_pass","W_stop"],[1,1]]],
                               ['firls','HP',['Fs','F_pass','F_stop'],[48000,9600,12000],False,True,"val",["Enter a weight value for each band below",["W_pass","W_stop"],[1,1]]],
                               ['firls','BP',['Fs','F_stop1','F_pass1','F_stop2','F_pass2'],[48000,7200,9600,12000,14400],False,True,"val",["Enter a weight value for each band below",["W_stop1","W_pass","W_stop2"],[1,1,1]]],
                               ['firls','BS',['Fs','F_pass1','F_stop1','F_pass2','F_stop2'],[48000,7200,9600,12000,14400],False,True,"val",["Enter a weight value for each band below",["W_pass1","W_stop","W_pass2"],[1,1,1]]],
                               ['equiripple','LP',['Fs','F_pass','F_stop'],[48000,9600,12000],True,True,"val",["Enter a weight value for each band below",["W_pass","W_stop"],[1,1]]],
                               ['equiripple','HIL',['Fs','F_pass','F_stop'],[48000,9600,12000],True,True,"val",["Enter a weight value for each band below",["W_pass","W_stop"],[1,1]]],
                               ['equiripple','HP',['Fs','F_pass','F_stop'],[48000,9600,12000],True,True,"val",["Enter a weight value for each band below",["W_pass","W_stop"],[1,1]]],
                               ['equiripple','BP',['Fs','F_stop1','F_pass1','F_stop2','F_pass2'],[48000,7200,9600,12000,14400],True,True,"val",["Enter a weight value for each band below",["W_stop1","W_pass","W_stop2"],[1,1,1]]],
                               ['equiripple','BS',['Fs','F_pass1','F_stop1','F_pass2','F_stop2'],[48000,7200,9600,12000,14400],True,True,"val",["Enter a weight value for each band below",["W_pass1","W_stop","W_pass2"],[1,1,1]]],
                               ['window','LP',['Fs','Fc'],[48000,10800],False,True,"txt","The attenuation at cutoff frequencies is fixed at 6 dB (half the passband gain)"],
                               ['window','HP',['Fs','Fc'],[48000,10800],False,True,"txt","The attenuation at cutoff frequencies is fixed at 6 dB (half the passband gain)"],
                               ['window','BP',['Fs','Fc1','Fc2'],[48000,8400,13200],False,True,"txt","The attenuation at cutoff frequencies is fixed at 6 dB (half the passband gain)"],
                               ['window','BS',['Fs','Fc1','Fc2'],[48000,8400,13200],False,True,"txt","The attenuation at cutoff frequencies is fixed at 6 dB (half the passband gain)"],
                               ['butter','LP',['Fs','Fc'],[48000,10800],True,True,"txt","The attenuation at cutoff frequencies is fixed at 3 dB (half the passband power)"],
                               ['butter','HP',['Fs','Fc'],[48000,10800],True,True,"txt","The attenuation at cutoff frequencies is fixed at 3 dB (half the passband power)"],
                               ['butter','BP',['Fs','Fc1','Fc2'],[48000,8400,13200],True,True,"txt","The attenuation at cutoff frequencies is fixed at 3 dB (half the passband power)"],
                               ['butter','BS',['Fs','Fc1','Fc2'],[48000,8400,13200],True,True,"txt","The attenuation at cutoff frequencies is fixed at 3 dB (half the passband power)"],
                               ['ellip','LP',['Fs','F_pass'],[48000,9600],True,True,"unt",[["dB","Squared"],["A_pass","A_stop"],[1,80]]],
                               ['ellip','HP',['Fs','F_pass'],[48000,14400],True,True,"unt",[["dB","Squared"],["A_pass","A_stop"],[1,80]]],
                               ['ellip','BP',['Fs','F_pass1','F_pass2'],[48000,9600,12000],True,True,"unt",[["dB","Squared"],["A_stop1","A_pass","A_stop2"],[60,1,80]]],
                               ['ellip','BS',['Fs','F_pass1','F_pass2'],[48000,9600,12000],True,True,"unt",[["dB","Squared"],["A_pass1","A_stop","A_pass2"],[5,60,1]]],
                               ['cheby1','LP',['Fs','F_pass'],[48000,9600],True,True,"unt",[["dB","Squared"],["A_pass"],[1]]],
                               ['cheby1','HP',['Fs','F_pass'],[48000,14400],True,True,"unt",[["dB","Squared"],["A_pass"],[1]]],
                               ['cheby1','BP',['Fs','F_pass1','F_pass2'],[48000,9600,12000],True,True,"unt",[["dB","Squared"],["A_pass"],[1]]],
                               ['cheby1','BS',['Fs','F_pass1','F_pass2'],[48000,9600,12000],True,True,"unt",[["dB","Squared"],["A_pass"],[1]]],
                               ['cheby2','LP',['Fs','F_pass'],[48000,9600],True,True,"unt",[["dB","Squared"],["A_pass","A_stop"],[1,80]]],
                               ['cheby2','HP',['Fs','F_pass'],[48000,14400],True,True,"unt",[["dB","Squared"],["A_pass","A_stop"],[1,80]]],
                               ['cheby2','BP',['Fs','F_pass1','F_pass2'],[48000,9600,12000],True,True,"unt",[["dB","Squared"],["A_stop1","A_pass","A_stop2"],[60,1,80]]],
                               ['cheby2','BS',['Fs','F_pass1','F_pass2'],[48000,9600,12000],True,True,"unt",[["dB","Squared"],["A_pass1","A_stop","A_pass2"],[5,60,1]]]
                                )
        self.DEBUG = DEBUG
        self.initUI()
        """
        choose_design_list[0]: Label / Design Method (string)
        choose_design_list[1]: Response Type ('rt', string)
        -- Frequency Specifications
        choose_design_list[2]: Label Frequencies (list of strings)
        choose_design_list[3]: Frequencies (list of numbers)
        choose_design_list[4]: Flag, Enable Min (???) (Boolean)
        choose_design_list[5]: Flag, Check Manual Order (Boolean)
        -- Amplitude / Weight Specifications
        choose_design_list[6]: Selector (string):
            'txt' ->
                choose_design_list[7]: Text-Info (string)
             'unt' ->
                choose_design_list[7]: List of lists for Gains containing
                                            [Units, Labels, Defaultvalues]
             'val' ->
                choose_design_list[7]: List of lists for Weights containing
                                            [Infostring, Labels, Defaultvalues]
        """

    def initUI(self):
        """
        Create all widgets:

        sf : Select Filter with response type rt (LP, ...),
              filter type ft (IIR, ...), and design method dm (cheby1, ...)
        fo : Filter Order (numeric or 'min')
        fs : Frequency Specifications
        ms : Magnitude Specifications with the subwidgets
            txt : only text field for comments / instruction
            val : infostring (title), Label, value
            unt : unit, label, value

        """

        self.sf = SelectFilter.SelectFilter()
        self.fo = filterOrder.FilterOrder()
        self.fs = UnitBox.UnitBox(
                    ["Hz", "Normalize 0 to 1", "kHz", "MHz", "GHz"],
                    ['Fs', 'F_pass', 'F_stop'], [48000,9600,12000], "Frequenz")

        self.ms_txt = QtGui.QLabel(self)
        self.ms_txt.setText("Enter a weight value for each band below")
        self.ms_txt.setWordWrap(True)

        self.ms_unt = UnitBox.UnitBox(["dB","Squared"],["A_pass","A_stop"],[1,80],"Magnitude")
        self.ms_val = NumBox.NumBox(
                "Enter a weight value for each band below",
                ["W_pass","W_stop"],[1,1])
        self.ms_last = "val"
        # Magnitude Widgets not needed at the moment are made
        # invisible but are always present!
        self.ms_txt.setVisible(False)
        self.ms_val.setVisible(True)
        self.ms_unt.setVisible(False)
        """
        LAYOUT
        """
        self.layout=QtGui.QGridLayout()
        self.layout.addWidget(self.sf,0,0)  # Design Method (IIR - ellip, ...)
        self.layout.addWidget(self.fo,2,0)  # Filter Order
        self.layout.addWidget(self.fs,3,0)  # Freq. Specifications
        self.layout.addWidget(self.ms_txt,4,0)  # Mag. Spec. - text
        self.layout.addWidget(self.ms_val,5,0)   #       - value
        self.layout.addWidget(self.ms_unt,6,0)   #       - unit

        self.setLayout(self.layout)
        #----------------------------------------------------------------------
        # SIGNALS & SLOTS
        # Call chooseDesignMethod every time filter selection is changed:
        self.sf.comboResponseType.activated.connect(self.chooseDesignMethod)
        self.sf.comboFilterType.activated.connect(self.chooseDesignMethod)
        self.sf.comboDesignMethod.activated.connect(self.chooseDesignMethod)

        self.chooseDesignMethod() # first time initialization

    def chooseDesignMethod(self):
        """
        Depending on SelectFilter and frequency specs, the values of the
        widgets fo, fs are recreated. For widget ms, the visibility is changed
        as well.
        """

        if self.DEBUG:
            print(db.gD["curFilter"])

        j=0
        found = False
        while not found:
           # print self.choose_design_list[j][0]+":"+self.choose_design_list[j][1]
            if self.choose_design_list[j][0]== db.gD["curFilter"]["dm"] \
            and self.choose_design_list[j][1] == db.gD["curFilter"]["rt"]:
                found = True
                choosen=self.choose_design_list[j][2:]
            j += 1

        self.rebuildFrequFiltOrd(choosen[0],choosen[1],choosen[2],choosen[3])
        self.rebuildMag(choosen[4],choosen[5])
        self.setLayout(self.layout)

    def rebuildFrequFiltOrd(self,liste=[],default=[],enMin=True,checkMan=True):
        """
        Hilfsfunktion zur Aktualisierung des Frequenz-Widget und der FilterOrdnung
        """
        self.fs.set(liste, default)
        self.fo.chkMin.setEnabled(enMin)
        self.fo.chkManual.setChecked(checkMan)

    def rebuildMag(self,string,liste=[]):
        """
        Hilfsfunktion zur Aktualisierung der Magnitude Specifications
        """
        #print "_________________________"
       # print liste
       # print string
       # print"_________________________"
        if string == "txt":  # only Info-Text
            self.ms_txt.setText(liste)
            self.ms_txt.setVisible(True)
            self.ms_unt.setVisible(False)
            self.ms_val.setVisible(False)
            self.ms_last="txt"
        if string == "unt" : # create subwidget with unit + label
            self.ms_unt.set(liste[1],liste[2])
            self.ms_unt.setVisible(True)
            self.ms_val.setVisible(False)
            self.ms_txt.setVisible(False)
            self.ms_last="unt"
        if string == "val" :  # create subwidget with title, unit + label
            self.ms_val.set(liste[0],liste[1],liste[2])
            self.ms_val.setVisible(True)
            self.ms_txt.setVisible(False)
            self.ms_unt.setVisible(False)
            self.ms_last="val"

    def get(self):
        """
        Return a dict with the currently selected filter specifications
        """
#        ret = db.gD["curFilter"] # return selected filter design
        ret = {}
        ret.update(self.fo.get()) # collect data from filter order widget
        ret.update(self.fs.get()) # collect data from frequ. spec. widget

        if self.ms_last=="unt":
            ret.update( self.ms_unt.get()) # magnitude specs with unit
        if self.ms_last=="val" :
            ret.update( self.ms_val.get()) # magnitude specs with "all"
        if self.DEBUG: print(ret)
        return ret

#------------------------------------------------------------------------------

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    form = ChooseParams()
    form.show()
    form.get()

    app.exec_()

 <commit_msg>Changes in interfaces to NumBox and UnitBox, args -> kwargs Signed-off-by: chipmuenk <mail@chipmuenk.de><commit_after># -*- coding: utf-8 -*-
"""
Created on Thu Nov 14 15:21:19 2013
Main Widget for entering filter specifications

@author: beike, Christian Münker
"""
import sys, os
from PyQt4 import QtGui

# import databroker from one level above if this file is run as __main__
# for test purposes
if __name__ == "__main__":
    __cwd__ = os.path.dirname(os.path.abspath(__file__))
    sys.path.append(__cwd__ + '/..')

import databroker as db

import SelectFilter, filterOrder, UnitBox, NumBox # ResponseType,

"""
Zur Eingabe aller Parameter und Einstellungen
"""

class ChooseParams(QtGui.QFrame):

    def __init__(self, DEBUG = True):
        super(ChooseParams, self).__init__()
#        self.setStyleSheet("margin:5px; border:1px solid rgb(0, 0, 0); ")
#        self.setStyleSheet("background-color: rgb(255,0,0); margin:5px; border:1px solid rgb(0, 255, 0); ")

        # "Properties" of all filter types:
        self.choose_design_list=(
                               ['firls','LP',['Fs','F_pass','F_stop'],[48000,9600,12000],False,True,"val",["Enter a weight value for each band below",["W_pass","W_stop"],[1,1]]],
                               ['firls','HP',['Fs','F_pass','F_stop'],[48000,9600,12000],False,True,"val",["Enter a weight value for each band below",["W_pass","W_stop"],[1,1]]],
                               ['firls','BP',['Fs','F_stop1','F_pass1','F_stop2','F_pass2'],[48000,7200,9600,12000,14400],False,True,"val",["Enter a weight value for each band below",["W_stop1","W_pass","W_stop2"],[1,1,1]]],
                               ['firls','BS',['Fs','F_pass1','F_stop1','F_pass2','F_stop2'],[48000,7200,9600,12000,14400],False,True,"val",["Enter a weight value for each band below",["W_pass1","W_stop","W_pass2"],[1,1,1]]],
                               ['equiripple','LP',['Fs','F_pass','F_stop'],[48000,9600,12000],True,True,"val",["Enter a weight value for each band below",["W_pass","W_stop"],[1,1]]],
                               ['equiripple','HIL',['Fs','F_pass','F_stop'],[48000,9600,12000],True,True,"val",["Enter a weight value for each band below",["W_pass","W_stop"],[1,1]]],
                               ['equiripple','HP',['Fs','F_pass','F_stop'],[48000,9600,12000],True,True,"val",["Enter a weight value for each band below",["W_pass","W_stop"],[1,1]]],
                               ['equiripple','BP',['Fs','F_stop1','F_pass1','F_stop2','F_pass2'],[48000,7200,9600,12000,14400],True,True,"val",["Enter a weight value for each band below",["W_stop1","W_pass","W_stop2"],[1,1,1]]],
                               ['equiripple','BS',['Fs','F_pass1','F_stop1','F_pass2','F_stop2'],[48000,7200,9600,12000,14400],True,True,"val",["Enter a weight value for each band below",["W_pass1","W_stop","W_pass2"],[1,1,1]]],
                               ['window','LP',['Fs','Fc'],[48000,10800],False,True,"txt","The attenuation at cutoff frequencies is fixed at 6 dB (half the passband gain)"],
                               ['window','HP',['Fs','Fc'],[48000,10800],False,True,"txt","The attenuation at cutoff frequencies is fixed at 6 dB (half the passband gain)"],
                               ['window','BP',['Fs','Fc1','Fc2'],[48000,8400,13200],False,True,"txt","The attenuation at cutoff frequencies is fixed at 6 dB (half the passband gain)"],
                               ['window','BS',['Fs','Fc1','Fc2'],[48000,8400,13200],False,True,"txt","The attenuation at cutoff frequencies is fixed at 6 dB (half the passband gain)"],
                               ['butter','LP',['Fs','Fc'],[48000,10800],True,True,"txt","The attenuation at cutoff frequencies is fixed at 3 dB (half the passband power)"],
                               ['butter','HP',['Fs','Fc'],[48000,10800],True,True,"txt","The attenuation at cutoff frequencies is fixed at 3 dB (half the passband power)"],
                               ['butter','BP',['Fs','Fc1','Fc2'],[48000,8400,13200],True,True,"txt","The attenuation at cutoff frequencies is fixed at 3 dB (half the passband power)"],
                               ['butter','BS',['Fs','Fc1','Fc2'],[48000,8400,13200],True,True,"txt","The attenuation at cutoff frequencies is fixed at 3 dB (half the passband power)"],
                               ['ellip','LP',['Fs','F_pass'],[48000,9600],True,True,"unit",[["dB","Squared"],["A_pass","A_stop"],[1,80]]],
                               ['ellip','HP',['Fs','F_pass'],[48000,14400],True,True,"unit",[["dB","Squared"],["A_pass","A_stop"],[1,80]]],
                               ['ellip','BP',['Fs','F_pass1','F_pass2'],[48000,9600,12000],True,True,"unit",[["dB","Squared"],["A_stop1","A_pass","A_stop2"],[60,1,80]]],
                               ['ellip','BS',['Fs','F_pass1','F_pass2'],[48000,9600,12000],True,True,"unit",[["dB","Squared"],["A_pass1","A_stop","A_pass2"],[5,60,1]]],
                               ['cheby1','LP',['Fs','F_pass'],[48000,9600],True,True,"unit",[["dB","Squared"],["A_pass"],[1]]],
                               ['cheby1','HP',['Fs','F_pass'],[48000,14400],True,True,"unit",[["dB","Squared"],["A_pass"],[1]]],
                               ['cheby1','BP',['Fs','F_pass1','F_pass2'],[48000,9600,12000],True,True,"unit",[["dB","Squared"],["A_pass"],[1]]],
                               ['cheby1','BS',['Fs','F_pass1','F_pass2'],[48000,9600,12000],True,True,"unit",[["dB","Squared"],["A_pass"],[1]]],
                               ['cheby2','LP',['Fs','F_pass'],[48000,9600],True,True,"unit",[["dB","Squared"],["A_pass","A_stop"],[1,80]]],
                               ['cheby2','HP',['Fs','F_pass'],[48000,14400],True,True,"unit",[["dB","Squared"],["A_pass","A_stop"],[1,80]]],
                               ['cheby2','BP',['Fs','F_pass1','F_pass2'],[48000,9600,12000],True,True,"unit",[["dB","Squared"],["A_stop1","A_pass","A_stop2"],[60,1,80]]],
                               ['cheby2','BS',['Fs','F_pass1','F_pass2'],[48000,9600,12000],True,True,"unit",[["dB","Squared"],["A_pass1","A_stop","A_pass2"],[5,60,1]]]
                                )
        self.DEBUG = DEBUG
        self.initUI()
        """
        choose_design_list[0]: Label / Design Method (string)
        choose_design_list[1]: Response Type ('rt', string)
        -- Frequency Specifications
        choose_design_list[2]: Label Frequencies (list of strings)
        choose_design_list[3]: Frequencies (list of numbers)
        choose_design_list[4]: Flag, Enable Min (???) (Boolean)
        choose_design_list[5]: Flag, Check Manual Order (Boolean)
        -- Amplitude / Weight Specifications
        choose_design_list[6]: Selector (string):
            'txt' ->
                choose_design_list[7]: Text-Info (string)
             'unt' ->
                choose_design_list[7]: List of lists for Gains containing
                                            [Units, Labels, Defaultvalues]
             'val' ->
                choose_design_list[7]: List of lists for Weights containing
                                            [Infostring, Labels, Defaultvalues]
        """

    def initUI(self):
        """
        Create all widgets:

        sf : Select Filter with response type rt (LP, ...),
              filter type ft (IIR, ...), and design method dm (cheby1, ...)
        fo : Filter Order (numeric or 'min')
        fs : Frequency Specifications
        ms : Magnitude Specifications with the subwidgets
            txt : only text field for comments / instruction
            val : infostring (title), Label, value
            unt : unit, label, value

        """

        self.sf = SelectFilter.SelectFilter()
        self.fo = filterOrder.FilterOrder()
        self.fs = UnitBox.UnitBox(
                    units = ["Hz", "Normalize 0 to 1", "kHz", "MHz", "GHz"],
                    labels = ['Fs', 'F_pass', 'F_stop'],
                    defaults = [48000,9600,12000], name = "Frequenz")

        self.ms_txt = QtGui.QLabel(self)
        self.ms_txt.setText("Enter a weight value for each band below")
        self.ms_txt.setWordWrap(True)

        self.ms_unt = UnitBox.UnitBox(units = ["dB","Squared"],
                                      labels = ["A_pass","A_stop"],
                                      defaults = [1,80], name = "Magnitude")

        self.ms_val = NumBox.NumBox(
                title = "Enter a weight value for each band below",
                labels = ["W_pass","W_stop"],defaults = [1,1])
        self.ms_last = "val"
        # Magnitude Widgets not needed at the moment are made
        # invisible but are always present!
        self.ms_txt.setVisible(False)
        self.ms_val.setVisible(True)
        self.ms_unt.setVisible(False)
        """
        LAYOUT
        """
        self.layout=QtGui.QGridLayout()
        self.layout.addWidget(self.sf,0,0)  # Design Method (IIR - ellip, ...)
        self.layout.addWidget(self.fo,2,0)  # Filter Order
        self.layout.addWidget(self.fs,3,0)  # Freq. Specifications
        self.layout.addWidget(self.ms_txt,4,0)  # Mag. Spec. - text
        self.layout.addWidget(self.ms_val,5,0)   #       - value
        self.layout.addWidget(self.ms_unt,6,0)   #       - unit

        self.setLayout(self.layout)
        #----------------------------------------------------------------------
        # SIGNALS & SLOTS
        # Call chooseDesignMethod every time filter selection is changed:
#        self.fo.chkManual.clicked.connect(self.chooseDesignMethod)
        self.fo.chkMin.clicked.connect(self.chooseDesignMethod)
        self.sf.comboResponseType.activated.connect(self.chooseDesignMethod)
        self.sf.comboFilterType.activated.connect(self.chooseDesignMethod)
        self.sf.comboDesignMethod.activated.connect(self.chooseDesignMethod)

        self.chooseDesignMethod() # first time initialization

    def chooseDesignMethod(self):
        """
        Depending on SelectFilter and frequency specs, the values of the
        widgets fo, fs are recreated. For widget ms, the visibility is changed
        as well.
        """

        if self.DEBUG:
            print(db.gD["curFilter"])

        j=0
        found = False
        while not found:
           # print self.choose_design_list[j][0]+":"+self.choose_design_list[j][1]
            if self.choose_design_list[j][0]== db.gD["curFilter"]["dm"] \
            and self.choose_design_list[j][1] == db.gD["curFilter"]["rt"]:
                found = True
                choosen=self.choose_design_list[j][2:]
                choosen[0] = freqLabels = self.choose_design_list[j][2]
                choosen[1] = freqSpecs = self.choose_design_list[j][3]
                choosen[2] = enableMin = self.choose_design_list[j][4]
                choosen[3] = manOrder = self.choose_design_list[j][5]
                choosen[4] = typeTxtbox = self.choose_design_list[j][6]
                choosen[5] = lstA_W_T = self.choose_design_list[j][7]
            j += 1

        self.rebuildFrequFiltOrd(freqLabels, freqSpecs,
                                 enMin = enableMin, checkMan = manOrder)
        self.rebuildMag(typeTxtbox, lstA_W_T)
        self.setLayout(self.layout)

    def rebuildFrequFiltOrd(self,liste=[],defaults=[],enMin=True,checkMan=True):
        """
        Hilfsfunktion zur Aktualisierung des Frequenz-Widget und der FilterOrdnung
        """
        self.fs.set(labels = liste, defaults = defaults)
        self.fo.chkMin.setEnabled(enMin)
#        self.fo.chkManual.setChecked(checkMan)

    def rebuildMag(self,string,lstA_W_T=[]):
        """
        Hilfsfunktion zur Aktualisierung der Magnitude Specifications
        """

        if string == "txt":  # only Info-Text
            self.ms_txt.setText(lstA_W_T)
            self.ms_txt.setVisible(True)
            self.ms_unt.setVisible(False)
            self.ms_val.setVisible(False)
            self.ms_last="txt"
        if string == "unit" : # create subwidget with unit + label
            self.ms_unt.set(labels = lstA_W_T[1], defaults = lstA_W_T[2])
            self.ms_unt.setVisible(True)
            self.ms_val.setVisible(False)
            self.ms_txt.setVisible(False)
            self.ms_last="unit"
        if string == "val" :  # create subwidget with title, unit + label
            self.ms_val.set(title = lstA_W_T[0],labels = lstA_W_T[1], defaults = lstA_W_T[2])
            self.ms_val.setVisible(True)
            self.ms_txt.setVisible(False)
            self.ms_unt.setVisible(False)
            self.ms_last="val"

    def get(self):
        """
        Return a dict with the currently selected filter specifications
        """
#        ret = db.gD["curFilter"] # return selected filter design
        ret = {}
        ret.update(self.fo.get()) # collect data from filter order widget
        ret.update(self.fs.get()) # collect data from frequ. spec. widget

        if self.ms_last=="unit":
            ret.update( self.ms_unt.get()) # magnitude specs with unit
        if self.ms_last=="val" :
            ret.update( self.ms_val.get()) # magnitude specs with "all"
        if self.DEBUG: print(ret)
        return ret

#------------------------------------------------------------------------------

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    form = ChooseParams()
    form.show()
    form.get()

    app.exec_()

 <|endoftext|>


<commit_before>#!/usr/bin/env python3

#  Copyright (C) 2015-2016 Ben Klein. All rights reserved.
#
#  This file was based upon an example class of the Qt Toolkit.
#
#  This application is licensed under the GNU GPLv3 License, included with
#  this application source.

import sys

# Qt GUI stuff
from PyQt4 import QtCore, QtGui
from PyQt4.QtCore import QSettings

# Airplay Things:
import discovery

class Window(QtGui.QDialog):
    def __init__(self):
        super(Window, self).__init__()

        self.settings = QSettings('open-airplay')
        # Establishes a hook on our system settings.
        # http://pyqt.sourceforge.net/Docs/PyQt4/pyqt_qsettings.html

        # Place items in our window.
        self.createIconGroupBox() # Tray Icon Settings
        self.createMessageGroupBox() # Test notification group
        self.createDeviceListGroupBox() # Airplay server selection

        # Set the iconlabel to it's minimum width without scollbaring.
        self.iconLabel.setMinimumWidth(self.durationLabel.sizeHint().width())

        # Create action groups to put actionable items into.
        self.createActions()
        self.createTrayIcon()

        # Attach clicks on things to actual functions
        self.showMessageButton.clicked.connect(self.showMessage)
        self.showIconCheckBox.toggled.connect(self.trayIconVisible)
        self.systrayClosePromptCheckBox.toggled.connect(self.setSystrayClosePrompt)
        self.iconComboBox.currentIndexChanged.connect(self.setIcon)
        self.trayIcon.messageClicked.connect(self.messageClicked)
        self.trayIcon.activated.connect(self.iconActivated)

        # Finally add the GUI item groupings we made to the layout and init it.
        mainLayout = QtGui.QVBoxLayout()
        mainLayout.addWidget(self.iconGroupBox)
        mainLayout.addWidget(self.deviceListGroupBox)
        mainLayout.addWidget(self.messageGroupBox)
        self.setLayout(mainLayout)

        # Set our System Tray Presence
        self.iconComboBox.setCurrentIndex(1)
        self.trayIcon.show()
        self.trayIcon.setToolTip("OpenAirplay")

        # Set our basic window things.
        self.setWindowTitle("OpenAirplay Settings")
        self.resize(400, 300)

        # If the user chose not to show the system tray icon:
        if self.settings.value('systrayicon', type=bool) is False:
            print("The user chose not to show the system tray icon.")
            self.trayIconVisible(False)

        # Setup stuff to poll available receivers every 3 seconds.
        self.oldReceiverList = []
        self.timer=QtCore.QTimer()
        self.timer.start(3000)
        self.timer.timeout.connect(self.updateReceivers)

        # Start discovery of airplay receivers:
        discovery.start()

    def setVisible(self, visible):
        # When we want to 'disappear' into the system tray.
        self.minimizeAction.setEnabled(visible)
        self.maximizeAction.setEnabled(not self.isMaximized())
        self.restoreAction.setEnabled(self.isMaximized() or not visible)
        super(Window, self).setVisible(visible)

    def closeEvent(self, event):
        # When someone clicks to close the window, not the tray icon.
        if self.trayIcon.isVisible():
            if self.settings.value('promptOnClose_systray', type=bool):
                print("The program is returning to the system tray, user notified.")
                QtGui.QMessageBox.information(self, "Systray",
                    "The program will keep running in the system tray. \
                    To terminate the program, choose Quit in \
                    the menu of the system tray airplay icon.")
            else:
                print("Program returned to system tray, user chose not to be notified.")
            self.hide()
            event.ignore()
            print("Closing to System Tray")
        else:
            print("Tray Icon not visible, quitting.")
            self.quit("Exit: No system tray instance to close to.")

    def setIcon(self, index):
        # Sets the selected icon in the tray and taskbar.
        icon = self.iconComboBox.itemIcon(index)
        self.trayIcon.setIcon(icon)
        self.setWindowIcon(icon)

    def setSystrayClosePrompt(self, preference):
        print("Prompt on close is now " + str(preference))
        self.settings.setValue('promptOnClose_systray', preference)

    def trayIconVisible(self, preference):
        self.trayIcon.setVisible(preference)
        self.settings.setValue('systrayicon', preference)

    def iconActivated(self, reason):
        if reason in (QtGui.QSystemTrayIcon.Trigger, QtGui.QSystemTrayIcon.DoubleClick):
            self.iconComboBox.setCurrentIndex(
                (self.iconComboBox.currentIndex() + 1)
                % self.iconComboBox.count())
        elif reason == QtGui.QSystemTrayIcon.MiddleClick:
            self.showMessage()

    def showMessage(self):
        # Show the message that was typed in the boxes
        icon = QtGui.QSystemTrayIcon.MessageIcon(
            self.typeComboBox.itemData(self.typeComboBox.currentIndex()))
        self.trayIcon.showMessage(self.titleEdit.text(),
                                  self.bodyEdit.toPlainText(), icon,
                                  self.durationSpinBox.value() * 1000)

    def messageClicked(self):
        # In the case that someone clicks on the notification popup (impossible on Ubuntu Unity)
        QtGui.QMessageBox.information(None, "OpenAirplay Help", "If you need help with OpenAirplay, "
        "see the Github page to file bug reports or see further documentation and help.")

    def updateReceivers(self):
        if list(set(discovery.airplayReceivers) - set(self.oldReceiverList)) != []:
            # The new list has items oldReceiverList doesn't!
            for item in list(set(discovery.airplayReceivers) - set(self.oldReceiverList)):
                self.oldReceiverList.append(item)
                print("Adding device: " + item)
                item = QtGui.QListWidgetItem(item)
                self.deviceSelectList.addItem(item)
        if list(set(self.oldReceiverList) - set(discovery.airplayReceivers)) != []:
            # Items have been removed from the list!
            for item in list(set(self.oldReceiverList) - set(discovery.airplayReceivers)):
                self.oldReceiverList.remove(item)
                print("Removed device: " + item)
                items = self.deviceSelectList.findItems(item, QtCore.Qt.MatchExactly)
                for x in items:
                    self.deviceSelectList.takeItem(self.deviceSelectList.row(x))

    def createIconGroupBox(self): # Add the SysTray preferences window grouping
        self.iconGroupBox = QtGui.QGroupBox("Tray Icon")

        self.iconLabel = QtGui.QLabel("Icon:")

        self.iconComboBox = QtGui.QComboBox()
        self.iconComboBox.addItem(QtGui.QIcon('images/Airplay-Light'), "Black Icon")
        self.iconComboBox.addItem(QtGui.QIcon('images/Airplay-Dark'), "White Icon")

        self.showIconCheckBox = QtGui.QCheckBox("Show tray icon")
        self.showIconCheckBox.setChecked(self.settings.value('systrayicon', type=bool))
        print("Got systrayicon from settings:" + str(self.settings.value('systrayicon', type=bool)))

        self.systrayClosePromptCheckBox = QtGui.QCheckBox("Systray Close warning")
        self.systrayClosePromptCheckBox.setChecked(self.settings.value('promptOnClose_systray', type=bool))
        print("Got promptOnClose_systray from settings:" + str(self.settings.value('promptOnClose_systray', type=bool)))

        iconLayout = QtGui.QHBoxLayout()
        iconLayout.addWidget(self.iconLabel)
        iconLayout.addWidget(self.iconComboBox)
        iconLayout.addStretch()
        iconLayout.addWidget(self.showIconCheckBox)
        iconLayout.addWidget(self.systrayClosePromptCheckBox)
        self.iconGroupBox.setLayout(iconLayout)

    # Creates the device selection list.
    def createDeviceListGroupBox(self):
        self.deviceListGroupBox = QtGui.QGroupBox("Airplay to")

        self.deviceSelectList = QtGui.QListWidget()
        deviceSelectListNoDisplayItem = QtGui.QListWidgetItem("No display.")
        self.deviceSelectList.addItem(deviceSelectListNoDisplayItem)

        # layout
        deviceListLayout = QtGui.QHBoxLayout()
        deviceListLayout.addWidget(self.deviceSelectList)
        self.deviceListGroupBox.setLayout(deviceListLayout)

    def createMessageGroupBox(self): # Add the message test GUI window grouping.
        self.messageGroupBox = QtGui.QGroupBox("Balloon Message Test:")

        typeLabel = QtGui.QLabel("Type:")

        self.typeComboBox = QtGui.QComboBox()
        self.typeComboBox.addItem("None", QtGui.QSystemTrayIcon.NoIcon)
        self.typeComboBox.addItem(self.style().standardIcon(
                QtGui.QStyle.SP_MessageBoxInformation), "Information", QtGui.QSystemTrayIcon.Information)
        self.typeComboBox.addItem(self.style().standardIcon(
                QtGui.QStyle.SP_MessageBoxWarning), "Warning", QtGui.QSystemTrayIcon.Warning)
        self.typeComboBox.addItem(self.style().standardIcon(
                QtGui.QStyle.SP_MessageBoxCritical), "Critical", QtGui.QSystemTrayIcon.Critical)
        self.typeComboBox.setCurrentIndex(1)

        self.durationLabel = QtGui.QLabel("Duration:")

        self.durationSpinBox = QtGui.QSpinBox()
        self.durationSpinBox.setRange(2, 15)
        self.durationSpinBox.setSuffix("s")
        self.durationSpinBox.setValue(5)

        durationWarningLabel = QtGui.QLabel("(some systems might ignore this hint)")
        durationWarningLabel.setIndent(10)

        titleLabel = QtGui.QLabel("Title:")

        self.titleEdit = QtGui.QLineEdit("Cannot connect to network")

        bodyLabel = QtGui.QLabel("Body:")

        self.bodyEdit = QtGui.QTextEdit()
        self.bodyEdit.setPlainText("Don't believe me. Honestly, I don't have a clue.")

        self.showMessageButton = QtGui.QPushButton("Show Message")
        self.showMessageButton.setDefault(True)

        messageLayout = QtGui.QGridLayout()
        messageLayout.addWidget(typeLabel, 0, 0)
        messageLayout.addWidget(self.typeComboBox, 0, 1, 1, 2)
        messageLayout.addWidget(self.durationLabel, 1, 0)
        messageLayout.addWidget(self.durationSpinBox, 1, 1)
        messageLayout.addWidget(durationWarningLabel, 1, 2, 1, 3)
        messageLayout.addWidget(titleLabel, 2, 0)
        messageLayout.addWidget(self.titleEdit, 2, 1, 1, 4)
        messageLayout.addWidget(bodyLabel, 3, 0)
        messageLayout.addWidget(self.bodyEdit, 3, 1, 2, 4)
        messageLayout.addWidget(self.showMessageButton, 5, 4)
        messageLayout.setColumnStretch(3, 1)
        messageLayout.setRowStretch(4, 1)
        self.messageGroupBox.setLayout(messageLayout)

    def createActions(self): # Create Actions that can be taken from the System Tray Icon
        self.minimizeAction = QtGui.QAction("Mi&nimize", self, triggered=self.hide)

        self.maximizeAction = QtGui.QAction("Ma&ximize", self, triggered=self.showMaximized)

        self.restoreAction = QtGui.QAction("&Restore", self, triggered=self.showNormal)

        self.quitAction = QtGui.QAction("&Quit", self, triggered=QtGui.qApp.quit)

    def createTrayIcon(self):
        self.trayIconMenu = QtGui.QMenu(self)
        self.trayIconMenu.addAction(self.minimizeAction)
        self.trayIconMenu.addAction(self.maximizeAction)
        self.trayIconMenu.addAction(self.restoreAction)
        self.trayIconMenu.addSeparator()
        self.trayIconMenu.addAction(self.quitAction)

        self.trayIcon = QtGui.QSystemTrayIcon(self)
        self.trayIcon.setContextMenu(self.trayIconMenu)

    def quit(self, reason):
        del self.settings
        #discovery.stop()
        sys.exit(reason)

if __name__ == '__main__':

    app = QtGui.QApplication(sys.argv)

    if not QtGui.QSystemTrayIcon.isSystemTrayAvailable():
        QtGui.QMessageBox.critical(None, "Systray", "I couldn't detect any system tray on this system.")
        sys.exit(1)

    QtGui.QApplication.setQuitOnLastWindowClosed(False)

    window = Window()
    window.show()

    # After teh progreem endz:
    sys.exit(app.exec_()) # Goodbye World
<commit_msg>Cleaned up list output of recievers.<commit_after>#!/usr/bin/env python3

#  Copyright (C) 2015-2016 Ben Klein. All rights reserved.
#
#  This file was based upon an example class of the Qt Toolkit.
#
#  This application is licensed under the GNU GPLv3 License, included with
#  this application source.

import sys

# Qt GUI stuff
from PyQt4 import QtCore, QtGui
from PyQt4.QtCore import QSettings

# Airplay Things:
import discovery

class Window(QtGui.QDialog):
    def __init__(self):
        super(Window, self).__init__()

        self.settings = QSettings('open-airplay')
        # Establishes a hook on our system settings.
        # http://pyqt.sourceforge.net/Docs/PyQt4/pyqt_qsettings.html

        # Place items in our window.
        self.createIconGroupBox() # Tray Icon Settings
        self.createMessageGroupBox() # Test notification group
        self.createDeviceListGroupBox() # Airplay server selection

        # Set the iconlabel to it's minimum width without scollbaring.
        self.iconLabel.setMinimumWidth(self.durationLabel.sizeHint().width())

        # Create action groups to put actionable items into.
        self.createActions()
        self.createTrayIcon()

        # Attach clicks on things to actual functions
        self.showMessageButton.clicked.connect(self.showMessage)
        self.showIconCheckBox.toggled.connect(self.trayIconVisible)
        self.systrayClosePromptCheckBox.toggled.connect(self.setSystrayClosePrompt)
        self.iconComboBox.currentIndexChanged.connect(self.setIcon)
        self.trayIcon.messageClicked.connect(self.messageClicked)
        self.trayIcon.activated.connect(self.iconActivated)

        # Finally add the GUI item groupings we made to the layout and init it.
        mainLayout = QtGui.QVBoxLayout()
        mainLayout.addWidget(self.iconGroupBox)
        mainLayout.addWidget(self.deviceListGroupBox)
        mainLayout.addWidget(self.messageGroupBox)
        self.setLayout(mainLayout)

        # Set our System Tray Presence
        self.iconComboBox.setCurrentIndex(1)
        self.trayIcon.show()
        self.trayIcon.setToolTip("OpenAirplay")

        # Set our basic window things.
        self.setWindowTitle("OpenAirplay Settings")
        self.resize(400, 300)

        # If the user chose not to show the system tray icon:
        if self.settings.value('systrayicon', type=bool) is False:
            print("The user chose not to show the system tray icon.")
            self.trayIconVisible(False)

        # Setup stuff to poll available receivers every 3 seconds.
        self.oldReceiverList = []
        self.timer=QtCore.QTimer()
        self.timer.start(3000)
        self.timer.timeout.connect(self.updateReceivers)

        # Start discovery of airplay receivers:
        discovery.start()

    def setVisible(self, visible):
        # When we want to 'disappear' into the system tray.
        self.minimizeAction.setEnabled(visible)
        self.maximizeAction.setEnabled(not self.isMaximized())
        self.restoreAction.setEnabled(self.isMaximized() or not visible)
        super(Window, self).setVisible(visible)

    def closeEvent(self, event):
        # When someone clicks to close the window, not the tray icon.
        if self.trayIcon.isVisible():
            if self.settings.value('promptOnClose_systray', type=bool):
                print("The program is returning to the system tray, user notified.")
                QtGui.QMessageBox.information(self, "Systray",
                    "The program will keep running in the system tray. \
                    To terminate the program, choose Quit in \
                    the menu of the system tray airplay icon.")
            else:
                print("Program returned to system tray, user chose not to be notified.")
            self.hide()
            event.ignore()
            print("Closing to System Tray")
        else:
            print("Tray Icon not visible, quitting.")
            self.quit("Exit: No system tray instance to close to.")

    def setIcon(self, index):
        # Sets the selected icon in the tray and taskbar.
        icon = self.iconComboBox.itemIcon(index)
        self.trayIcon.setIcon(icon)
        self.setWindowIcon(icon)

    def setSystrayClosePrompt(self, preference):
        print("Prompt on close is now " + str(preference))
        self.settings.setValue('promptOnClose_systray', preference)

    def trayIconVisible(self, preference):
        self.trayIcon.setVisible(preference)
        self.settings.setValue('systrayicon', preference)

    def iconActivated(self, reason):
        if reason in (QtGui.QSystemTrayIcon.Trigger, QtGui.QSystemTrayIcon.DoubleClick):
            self.iconComboBox.setCurrentIndex(
                (self.iconComboBox.currentIndex() + 1)
                % self.iconComboBox.count())
        elif reason == QtGui.QSystemTrayIcon.MiddleClick:
            self.showMessage()

    def showMessage(self):
        # Show the message that was typed in the boxes
        icon = QtGui.QSystemTrayIcon.MessageIcon(
            self.typeComboBox.itemData(self.typeComboBox.currentIndex()))
        self.trayIcon.showMessage(self.titleEdit.text(),
                                  self.bodyEdit.toPlainText(), icon,
                                  self.durationSpinBox.value() * 1000)

    def messageClicked(self):
        # In the case that someone clicks on the notification popup (impossible on Ubuntu Unity)
        QtGui.QMessageBox.information(None, "OpenAirplay Help", "If you need help with OpenAirplay, "
        "see the Github page to file bug reports or see further documentation and help.")

    def updateReceivers(self):
        if list(set(discovery.airplayReceivers) - set(self.oldReceiverList)) != []:
            # The new list has items oldReceiverList doesn't!
            for item in list(set(discovery.airplayReceivers) - set(self.oldReceiverList)):
                self.oldReceiverList.append(item)
                print("Adding device: " + item)
                # Convert item to string to remove the excess info
                item = QtGui.QListWidgetItem(str(item).replace("._airplay._tcp.local.", ""))
                self.deviceSelectList.addItem(item)
        if list(set(self.oldReceiverList) - set(discovery.airplayReceivers)) != []:
            # Items have been removed from the list!
            for item in list(set(self.oldReceiverList) - set(discovery.airplayReceivers)):
                self.oldReceiverList.remove(item)
                print("Removed device: " + item)
                items = self.deviceSelectList.findItems(item, QtCore.Qt.MatchExactly)
                for x in items:
                    self.deviceSelectList.takeItem(self.deviceSelectList.row(x))

    def createIconGroupBox(self): # Add the SysTray preferences window grouping
        self.iconGroupBox = QtGui.QGroupBox("Tray Icon")

        self.iconLabel = QtGui.QLabel("Icon:")

        self.iconComboBox = QtGui.QComboBox()
        self.iconComboBox.addItem(QtGui.QIcon('images/Airplay-Light'), "Black Icon")
        self.iconComboBox.addItem(QtGui.QIcon('images/Airplay-Dark'), "White Icon")

        self.showIconCheckBox = QtGui.QCheckBox("Show tray icon")
        self.showIconCheckBox.setChecked(self.settings.value('systrayicon', type=bool))
        print("Got systrayicon from settings:" + str(self.settings.value('systrayicon', type=bool)))

        self.systrayClosePromptCheckBox = QtGui.QCheckBox("Systray Close warning")
        self.systrayClosePromptCheckBox.setChecked(self.settings.value('promptOnClose_systray', type=bool))
        print("Got promptOnClose_systray from settings:" + str(self.settings.value('promptOnClose_systray', type=bool)))

        iconLayout = QtGui.QHBoxLayout()
        iconLayout.addWidget(self.iconLabel)
        iconLayout.addWidget(self.iconComboBox)
        iconLayout.addStretch()
        iconLayout.addWidget(self.showIconCheckBox)
        iconLayout.addWidget(self.systrayClosePromptCheckBox)
        self.iconGroupBox.setLayout(iconLayout)

    # Creates the device selection list.
    def createDeviceListGroupBox(self):
        self.deviceListGroupBox = QtGui.QGroupBox("Airplay to")

        self.deviceSelectList = QtGui.QListWidget()
        deviceSelectListNoDisplayItem = QtGui.QListWidgetItem("No display.")
        self.deviceSelectList.addItem(deviceSelectListNoDisplayItem)

        # layout
        deviceListLayout = QtGui.QHBoxLayout()
        deviceListLayout.addWidget(self.deviceSelectList)
        self.deviceListGroupBox.setLayout(deviceListLayout)

    def createMessageGroupBox(self): # Add the message test GUI window grouping.
        self.messageGroupBox = QtGui.QGroupBox("Balloon Message Test:")

        typeLabel = QtGui.QLabel("Type:")

        self.typeComboBox = QtGui.QComboBox()
        self.typeComboBox.addItem("None", QtGui.QSystemTrayIcon.NoIcon)
        self.typeComboBox.addItem(self.style().standardIcon(
                QtGui.QStyle.SP_MessageBoxInformation), "Information", QtGui.QSystemTrayIcon.Information)
        self.typeComboBox.addItem(self.style().standardIcon(
                QtGui.QStyle.SP_MessageBoxWarning), "Warning", QtGui.QSystemTrayIcon.Warning)
        self.typeComboBox.addItem(self.style().standardIcon(
                QtGui.QStyle.SP_MessageBoxCritical), "Critical", QtGui.QSystemTrayIcon.Critical)
        self.typeComboBox.setCurrentIndex(1)

        self.durationLabel = QtGui.QLabel("Duration:")

        self.durationSpinBox = QtGui.QSpinBox()
        self.durationSpinBox.setRange(2, 15)
        self.durationSpinBox.setSuffix("s")
        self.durationSpinBox.setValue(5)

        durationWarningLabel = QtGui.QLabel("(some systems might ignore this hint)")
        durationWarningLabel.setIndent(10)

        titleLabel = QtGui.QLabel("Title:")

        self.titleEdit = QtGui.QLineEdit("Cannot connect to network")

        bodyLabel = QtGui.QLabel("Body:")

        self.bodyEdit = QtGui.QTextEdit()
        self.bodyEdit.setPlainText("Don't believe me. Honestly, I don't have a clue.")

        self.showMessageButton = QtGui.QPushButton("Show Message")
        self.showMessageButton.setDefault(True)

        messageLayout = QtGui.QGridLayout()
        messageLayout.addWidget(typeLabel, 0, 0)
        messageLayout.addWidget(self.typeComboBox, 0, 1, 1, 2)
        messageLayout.addWidget(self.durationLabel, 1, 0)
        messageLayout.addWidget(self.durationSpinBox, 1, 1)
        messageLayout.addWidget(durationWarningLabel, 1, 2, 1, 3)
        messageLayout.addWidget(titleLabel, 2, 0)
        messageLayout.addWidget(self.titleEdit, 2, 1, 1, 4)
        messageLayout.addWidget(bodyLabel, 3, 0)
        messageLayout.addWidget(self.bodyEdit, 3, 1, 2, 4)
        messageLayout.addWidget(self.showMessageButton, 5, 4)
        messageLayout.setColumnStretch(3, 1)
        messageLayout.setRowStretch(4, 1)
        self.messageGroupBox.setLayout(messageLayout)

    def createActions(self): # Create Actions that can be taken from the System Tray Icon
        self.minimizeAction = QtGui.QAction("Mi&nimize", self, triggered=self.hide)

        self.maximizeAction = QtGui.QAction("Ma&ximize", self, triggered=self.showMaximized)

        self.restoreAction = QtGui.QAction("&Restore", self, triggered=self.showNormal)

        self.quitAction = QtGui.QAction("&Quit", self, triggered=QtGui.qApp.quit)

    def createTrayIcon(self):
        self.trayIconMenu = QtGui.QMenu(self)
        self.trayIconMenu.addAction(self.minimizeAction)
        self.trayIconMenu.addAction(self.maximizeAction)
        self.trayIconMenu.addAction(self.restoreAction)
        self.trayIconMenu.addSeparator()
        self.trayIconMenu.addAction(self.quitAction)

        self.trayIcon = QtGui.QSystemTrayIcon(self)
        self.trayIcon.setContextMenu(self.trayIconMenu)

    def quit(self, reason):
        del self.settings
        #discovery.stop()
        sys.exit(reason)

if __name__ == '__main__':

    app = QtGui.QApplication(sys.argv)

    if not QtGui.QSystemTrayIcon.isSystemTrayAvailable():
        QtGui.QMessageBox.critical(None, "Systray", "I couldn't detect any system tray on this system.")
        sys.exit(1)

    QtGui.QApplication.setQuitOnLastWindowClosed(False)

    window = Window()
    window.show()

    # After teh progreem endz:
    sys.exit(app.exec_()) # Goodbye World
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-

#
#
#  Copyright 2013 Netflix, Inc.
#
#     Licensed under the Apache License, Version 2.0 (the "License");
#     you may not use this file except in compliance with the License.
#     You may obtain a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#     Unless required by applicable law or agreed to in writing, software
#     distributed under the License is distributed on an "AS IS" BASIS,
#     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#     See the License for the specific language governing permissions and
#     limitations under the License.
#
#

import fcntl
import functools
import logging
import os
import re
import stat
import envoy
from time import sleep
from aminator.config import config

log = logging.getLogger(__name__)
pid = os.getpid()

BIND_MOUNTS = config.bind_mounts
DEVICE_PREFIXES = config.device_prefixes

def mounted(dir=None):
    """
    :type dir: str
    :param dir: device or mount point to look for in /proc/mounts

    :rtype: bool
    :return: True if dir is found in /proc/mounts.
    """
    if dir is None:
        return False
    # strip trailing white space then add a single space
    # anchor to differentiate from, say, sdf1 and sdf11
    dir = dir.rstrip()
    dir += " "
    pattern = re.compile(dir)
    with open("/proc/mounts") as mounts:
        return any(pattern.search(mount) for mount in mounts)

def os_node_exists(dev=None):
    """
    :type dev: str
    :param dev: path to device node, eg. /dev/sdf1
    :rtype: bool
    :return: True if dev is a device node
    """
    if dev is None:
        return False
    try:
        mode = os.stat(dev).st_mode
    except OSError:
        return False
    return stat.S_ISBLK(mode)

def native_device_prefix():
    for prefix in DEVICE_PREFIXES:
        if any(device.startswith(prefix) for device in os.listdir('/sys/block')):
            return prefix
    else:
        return None

def device_prefix(source_device):
    # strip off any incoming /dev/ foo
    source_device_name = os.path.basename(source_device)
    # if we have a subdevice/partition...
    if source_device_name[-1].isdigit():
        # then its prefix is the name minus the last TWO chars
        return source_device_name[:-2:]
    else:
        # otherwise, just strip the last one
        return source_device_name[:-1:]

def native_block_device(source_device):
    native_prefix = native_device_prefix()
    source_device_prefix = device_prefix(source_device)
    if source_device_prefix == native_prefix:
        # we're okay, using the right name already, just return the same name
        return source_device
    else:
        # sub out the bad prefix for the good
        return source_device.replace(source_device_prefix, native_prefix)

def shlog(command):
    log.debug(command)
    ret = envoy.run(command)
    for x in (ret.std_err + ret.std_out).splitlines():
        log.debug(x)
    return(ret.status_code == 0)

def fsck(dev):
    return shlog("fsck -y {}".format(dev))

def mount(dev, mnt, opts=""):
    """shell command wrapper for mounting device to mount point
    :type dev: str
    :param dev: device node to mount
    :type mnt: str
    :param mnt: directory mount point
    :rtype: bool
    :return: True if mount succeeds.
    """
    return shlog("mount {} {} {}".format(opts, dev, mnt))

def unmount(dev):
    """shell command wrapper for unmounting device
    :type dev: str
    :param dev: device node to mount
    :rtype: bool
    :return: True if unmount succeeds.
    """
    return shlog("umount {}".format(dev))

def busy_mount(mnt):
    return shlog('lsof -X {}'.format(mnt))

def chroot_mount(dev, mnt):
    """mount dev on mnt with BIND_MOUNTS mounted to mnt/{bid_dirs}
    :type dev: str
    :param dev: device node to mount
    :rtype: bool
    :return: True if unmount succeeds.
    """
    if not mounted(mnt):
        if not mount(dev, mnt):
            return False
    for _dir in BIND_MOUNTS:
        bind_mnt = os.path.join(mnt, _dir.lstrip('/'))
        if not os.path.exists(bind_mnt):
            log.debug(bind_mnt + " does not exist.")
            return False
        if not mounted(bind_mnt):
            if not mount(_dir, bind_mnt, '--bind'):
                return False
    return True

def chroot_unmount(mnt):
    if busy_mount(mnt):
        return False
    if not mounted(mnt):
        return True
    for _dir in BIND_MOUNTS:
        bind_mnt = os.path.join(mnt, _dir.lstrip('/'))
        if not mounted(bind_mnt):
            continue
        if not unmount(bind_mnt):
            return False
    return unmount(mnt)

# Retry decorator with backoff
# http://wiki.python.org/moin/PythonDecoratorLibrary#Retry
def retry(ExceptionToCheck, tries=3, delay=0.5, backoff=1, logger=None):
    '''Retries a function or method until it returns True.

    delay sets the initial delay in seconds, and backoff sets the factor by which
    the delay should lengthen after each failure. backoff must be greater than 1,
    or else it isn't really a backoff. tries must be at least 0, and delay
    greater than 0.'''
    if logger is None:
        logger = log

    def deco_retry(f):
        def f_retry(*args, **kwargs):
            mtries, mdelay = tries, delay
            while mtries > 0:
                try:
                    return f(*args, **kwargs)
                except ExceptionToCheck, e:
                    logger.debug(e)
                    sleep(mdelay)
                    mtries -= 1
                    mdelay *= backoff
            return f(*args, **kwargs)
        return f_retry  # true decorator
    return deco_retry

# http://wiki.python.org/moin/PythonDecoratorLibrary#Alternate_memoize_as_nested_functions
def memoize(obj):
    cache = obj.cache = {}

    @functools.wraps(obj)
    def memoizer(*args, **kwargs):
        if args not in cache:
            cache[args] = obj(*args, **kwargs)
        return cache[args]
    return memoizer

def copy_image(src, dst):
    """dd like utility for copying image files.
       eg.
       copy_image('/dev/sdf1','/mnt/bundles/ami-name.img')
    """
    try:
        src_fd = os.open(src, os.O_RDONLY)
        dst_fd = os.open(dst, os.O_WRONLY | os.O_CREAT, 0644)
        blks = 0
        blksize = 64 * 1024
        log.debug("copying %s to %s" % (src, dst))
        while True:
            buf = os.read(src_fd, blksize)
            if len(buf) <= 0:
                log.debug("%d %d blocks written." % (blks, blksize))
                os.close(src_fd)
                os.close(dst_fd)
                break
            out = os.write(dst_fd, buf)
            if out < blksize:
                log.debug("wrote %d bytes." % (out))
            blks += 1
    except os.OSError as e:
        log.debug("%s: errno[%d]: %s." % (e.filename, e.errno, e.strerror))
        return False
    return True

class Flock(object):
    """simple blocking exclusive file locker
       eg:
       with Flock(lockfilepath):
           ...
    """
    def __init__(self, file=""):
        if not os.path.exists(os.path.dirname(file)):
            raise(Exception)
        self.fh = open(file, 'a')

    def __enter__(self):
        fcntl.flock(self.fh, fcntl.LOCK_EX)
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        fcntl.flock(self.fh, fcntl.LOCK_UN)
        self.fh.close()

def locked(file=""):
    """
    :return: True if file is locked.
    """
    if not os.path.exists(os.path.dirname(file)):
        raise(Exception)
    fh = open(file, 'a')
    try:
        fcntl.flock(fh, fcntl.LOCK_EX | fcntl.LOCK_NB)
        ret = False
    except IOError as e:
        log.debug("%s is locked: %s" % (file, e))
        ret = True
    fh.close()
    return ret
<commit_msg>fix for issue #15 - chroot_unmount() may fail cc/@bmoyles<commit_after># -*- coding: utf-8 -*-

#
#
#  Copyright 2013 Netflix, Inc.
#
#     Licensed under the Apache License, Version 2.0 (the "License");
#     you may not use this file except in compliance with the License.
#     You may obtain a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#     Unless required by applicable law or agreed to in writing, software
#     distributed under the License is distributed on an "AS IS" BASIS,
#     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#     See the License for the specific language governing permissions and
#     limitations under the License.
#
#

import fcntl
import functools
import logging
import os
import re
import stat
import envoy
from time import sleep
from aminator.config import config

log = logging.getLogger(__name__)
pid = os.getpid()

BIND_MOUNTS = config.bind_mounts
DEVICE_PREFIXES = config.device_prefixes

def mounted(dir=None):
    """
    :type dir: str
    :param dir: device or mount point to look for in /proc/mounts

    :rtype: bool
    :return: True if dir is found in /proc/mounts.
    """
    if dir is None:
        return False
    # strip trailing white space then add a single space
    # anchor to differentiate from, say, sdf1 and sdf11
    dir = dir.rstrip()
    dir += " "
    pattern = re.compile(dir)
    with open("/proc/mounts") as mounts:
        return any(pattern.search(mount) for mount in mounts)

def os_node_exists(dev=None):
    """
    :type dev: str
    :param dev: path to device node, eg. /dev/sdf1
    :rtype: bool
    :return: True if dev is a device node
    """
    if dev is None:
        return False
    try:
        mode = os.stat(dev).st_mode
    except OSError:
        return False
    return stat.S_ISBLK(mode)

def native_device_prefix():
    for prefix in DEVICE_PREFIXES:
        if any(device.startswith(prefix) for device in os.listdir('/sys/block')):
            return prefix
    else:
        return None

def device_prefix(source_device):
    # strip off any incoming /dev/ foo
    source_device_name = os.path.basename(source_device)
    # if we have a subdevice/partition...
    if source_device_name[-1].isdigit():
        # then its prefix is the name minus the last TWO chars
        return source_device_name[:-2:]
    else:
        # otherwise, just strip the last one
        return source_device_name[:-1:]

def native_block_device(source_device):
    native_prefix = native_device_prefix()
    source_device_prefix = device_prefix(source_device)
    if source_device_prefix == native_prefix:
        # we're okay, using the right name already, just return the same name
        return source_device
    else:
        # sub out the bad prefix for the good
        return source_device.replace(source_device_prefix, native_prefix)

def shlog(command):
    log.debug(command)
    ret = envoy.run(command)
    for x in (ret.std_err + ret.std_out).splitlines():
        log.debug(x)
    return(ret.status_code == 0)

def fsck(dev):
    return shlog("fsck -y {}".format(dev))

def mount(dev, mnt, opts=""):
    """shell command wrapper for mounting device to mount point
    :type dev: str
    :param dev: device node to mount
    :type mnt: str
    :param mnt: directory mount point
    :rtype: bool
    :return: True if mount succeeds.
    """
    return shlog("mount {} {} {}".format(opts, dev, mnt))

def unmount(dev):
    """shell command wrapper for unmounting device
    :type dev: str
    :param dev: device node to mount
    :rtype: bool
    :return: True if unmount succeeds.
    """
    return shlog("umount {}".format(dev))

def busy_mount(mnt):
    return shlog('lsof -X {}'.format(mnt))

def chroot_mount(dev, mnt):
    """mount dev on mnt with BIND_MOUNTS mounted to mnt/{bid_dirs}
    :type dev: str
    :param dev: device node to mount
    :rtype: bool
    :return: True if unmount succeeds.
    """
    if not mounted(mnt):
        if not mount(dev, mnt):
            return False
    for _dir in BIND_MOUNTS:
        bind_mnt = os.path.join(mnt, _dir.lstrip('/'))
        if not os.path.exists(bind_mnt):
            log.debug(bind_mnt + " does not exist.")
            return False
        if not mounted(bind_mnt):
            if not mount(_dir, bind_mnt, '--bind'):
                return False
    return True

def chroot_unmount(mnt):
    if busy_mount(mnt):
        return False
    if not mounted(mnt):
        return True
    for _mnt in lifo_mounts(mnt):
        if not unmount(_mnt):
            return False
    return unmount(mnt)

def lifo_mounts(root=None):
    """return list of mount points mounted on 'root'
    and below in lifo order from /proc/mounts."""
    ret = []
    if root is None:
        return ret
    with open('/proc/mounts') as proc_mounts:
        mount_entries = proc_mounts.readlines()
        mount_entries.reverse()
        for line in mount_entries:
            if re.search(root + '( |/)', line):
                ret.append(line.split()[1])
    return ret

# Retry decorator with backoff
# http://wiki.python.org/moin/PythonDecoratorLibrary#Retry
def retry(ExceptionToCheck, tries=3, delay=0.5, backoff=1, logger=None):
    '''Retries a function or method until it returns True.

    delay sets the initial delay in seconds, and backoff sets the factor by which
    the delay should lengthen after each failure. backoff must be greater than 1,
    or else it isn't really a backoff. tries must be at least 0, and delay
    greater than 0.'''
    if logger is None:
        logger = log

    def deco_retry(f):
        def f_retry(*args, **kwargs):
            mtries, mdelay = tries, delay
            while mtries > 0:
                try:
                    return f(*args, **kwargs)
                except ExceptionToCheck, e:
                    logger.debug(e)
                    sleep(mdelay)
                    mtries -= 1
                    mdelay *= backoff
            return f(*args, **kwargs)
        return f_retry  # true decorator
    return deco_retry

# http://wiki.python.org/moin/PythonDecoratorLibrary#Alternate_memoize_as_nested_functions
def memoize(obj):
    cache = obj.cache = {}

    @functools.wraps(obj)
    def memoizer(*args, **kwargs):
        if args not in cache:
            cache[args] = obj(*args, **kwargs)
        return cache[args]
    return memoizer

def copy_image(src, dst):
    """dd like utility for copying image files.
       eg.
       copy_image('/dev/sdf1','/mnt/bundles/ami-name.img')
    """
    try:
        src_fd = os.open(src, os.O_RDONLY)
        dst_fd = os.open(dst, os.O_WRONLY | os.O_CREAT, 0644)
        blks = 0
        blksize = 64 * 1024
        log.debug("copying %s to %s" % (src, dst))
        while True:
            buf = os.read(src_fd, blksize)
            if len(buf) <= 0:
                log.debug("%d %d blocks written." % (blks, blksize))
                os.close(src_fd)
                os.close(dst_fd)
                break
            out = os.write(dst_fd, buf)
            if out < blksize:
                log.debug("wrote %d bytes." % (out))
            blks += 1
    except os.OSError as e:
        log.debug("%s: errno[%d]: %s." % (e.filename, e.errno, e.strerror))
        return False
    return True

class Flock(object):
    """simple blocking exclusive file locker
       eg:
       with Flock(lockfilepath):
           ...
    """
    def __init__(self, file=""):
        if not os.path.exists(os.path.dirname(file)):
            raise(Exception)
        self.fh = open(file, 'a')

    def __enter__(self):
        fcntl.flock(self.fh, fcntl.LOCK_EX)
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        fcntl.flock(self.fh, fcntl.LOCK_UN)
        self.fh.close()

def locked(file=""):
    """
    :return: True if file is locked.
    """
    if not os.path.exists(os.path.dirname(file)):
        raise(Exception)
    fh = open(file, 'a')
    try:
        fcntl.flock(fh, fcntl.LOCK_EX | fcntl.LOCK_NB)
        ret = False
    except IOError as e:
        log.debug("%s is locked: %s" % (file, e))
        ret = True
    fh.close()
    return ret
<|endoftext|>


<commit_before>import os

from django.forms import Form
from django.test import TestCase

from snowpenguin.django.recaptcha2.fields import ReCaptchaField
from snowpenguin.django.recaptcha2.widgets import ReCaptchaWidget

class RecaptchaTestForm(Form):
    recaptcha = ReCaptchaField(widget=ReCaptchaWidget())

class TestRecaptchaForm(TestCase):
    def setUp(self):
        os.environ['RECAPTCHA_DISABLE'] = 'True'

    def test_dummy_validation(self):
        form = RecaptchaTestForm({})
        self.assertTrue(form.is_valid())

    def tearDown(self):
        del os.environ['RECAPTCHA_DISABLE']
<commit_msg>Check possible exception with wrong key data<commit_after>import os

from django.forms import Form
from django.test import TestCase

from snowpenguin.django.recaptcha2.fields import ReCaptchaField
from snowpenguin.django.recaptcha2.widgets import ReCaptchaWidget

class RecaptchaTestForm(Form):
    recaptcha = ReCaptchaField(widget=ReCaptchaWidget())

class TestRecaptchaForm(TestCase):
    def setUp(self):
        os.environ['RECAPTCHA_DISABLE'] = 'True'

    def test_dummy_validation(self):
        form = RecaptchaTestForm({})
        self.assertTrue(form.is_valid())

    def test_dummy_error(self):
        del os.environ['RECAPTCHA_DISABLE']
        form = RecaptchaTestForm({})
        self.assertFalse(form.is_valid())

    def tearDown(self):
        del os.environ['RECAPTCHA_DISABLE']
<|endoftext|>