Exemplo n.º 1
0
    def __init__(self, user, *args, **kwargs):
        self.report_id = None
        if 'report_id' in kwargs:
            self.report_id = kwargs.pop('report_id')
        if 'chart_id' in kwargs:
            self.chart_id = kwargs.pop('chart_id')
            chart = get_object_or_404(Chart, pk=self.chart_id)
            self.report_id = chart.report_id

        super(ChartForm, self).__init__(*args, **kwargs)
        if not self.report_id:
            return

        report = get_object_or_404(Report, pk=self.report_id)
        chart = None
        if hasattr(self, 'chart_id'):
            chart = get_object_or_404(Chart, pk=self.chart_id)

        model = loads(report.model)

        object = model.name
        object = object.split('.')

        module_name = object[0] + '.' + object[1] + '.' + object[2]
        import_name = object[3]

        module = __import__(module_name, globals(), locals(), [import_name],
                            -1)
        classobj = getattr(module, import_name)

        unfiltered_set = classobj.objects.exclude(trash=True)

        set = []
        for s in unfiltered_set:
            filtered = False
            for field in model.fields:
                if field.filters and str(getattr(
                        s, field.name)) not in field.filters:
                    filtered = True
            if not filtered:
                set.append(s)

        # perhaps do type checking on a setting list of types (for each type)
        self.fields['grouping'].choices = [('', '--------')]

        # Check for group
        groupname = None
        groups = None
        for field in model.fields:
            self.fields['grouping'].choices.append(
                (str(field.name), str(field.name).replace('_', ' ').title()))
            if field.groupby == 1:
                self.fields['grouping'].initial = str(field.name)

        if chart:
            options = loads(chart.options)
            for f in options:
                if f in self.fields:
                    self.fields[f].initial = options[f]
Exemplo n.º 2
0
Arquivo: forms.py Projeto: 5n1p/treeio
    def __init__(self, user, *args, **kwargs):
        self.report_id = None
        if 'report_id' in kwargs:
            self.report_id = kwargs.pop('report_id')
        if 'chart_id' in kwargs:
            self.chart_id = kwargs.pop('chart_id')
            chart = get_object_or_404(Chart, pk=self.chart_id)
            self.report_id = chart.report_id

        super(ChartForm, self).__init__(*args, **kwargs)
        if not self.report_id:
            return

        report = get_object_or_404(Report, pk=self.report_id)
        chart = None
        if hasattr(self, 'chart_id'):
            chart = get_object_or_404(Chart, pk=self.chart_id)

        model = loads(report.model)

        object = model.name
        object = object.split('.')

        module_name = object[0] + '.' + object[1] + '.' + object[2]
        import_name = object[3]

        module = __import__(
            module_name, globals(), locals(), [import_name], -1)
        classobj = getattr(module, import_name)

        unfiltered_set = classobj.objects.exclude(trash=True)

        set = []
        for s in unfiltered_set:
            filtered = False
            for field in model.fields:
                if field.filters and str(getattr(s, field.name)) not in field.filters:
                    filtered = True
            if not filtered:
                set.append(s)

        # perhaps do type checking on a setting list of types (for each type)
        self.fields['grouping'].choices = [('', '--------')]

        # Check for group
        groupname = None
        groups = None
        for field in model.fields:
            self.fields['grouping'].choices.append(
                (str(field.name), str(field.name).replace('_', ' ').title()))
            if field.groupby == 1:
                self.fields['grouping'].initial = str(field.name)

        if chart:
            options = loads(chart.options)
            for f in options:
                if f in self.fields:
                    self.fields[f].initial = options[f]
Exemplo n.º 3
0
Arquivo: views.py Projeto: 5n1p/treeio
def report_group(request, report_id, field_name, response_format='html'):
    "View to Group by a given field in a report"

    t = get_object_or_404(Report, pk=report_id)
    if not request.user.get_profile().has_permission(t, mode='w'):
        return user_denied(request, message="You don't have access to this Report")

    model = loads(t.model)

    # Check if this field is already grouped, if so then remove grouping
    thisfield = model.get_field(field_name)
    if thisfield.groupby == 1:
        thisfield.groupby = 0
    else:
        # Other wise reset grouping and set selected field as groupfield
        for field in model.fields:
            field.groupby = 0

        field = model.get_field(field_name)
        field.groupby = 1

    t.model = dumps(model)
    t.save()

    return report_edit(request, report_id=report_id, response_format=response_format)
Exemplo n.º 4
0
def report_group(request, report_id, field_name, response_format='html'):
    "View to Group by a given field in a report"

    t = get_object_or_404(Report, pk=report_id)
    if not request.user.get_profile().has_permission(t, mode='w'):
        return user_denied(request,
                           message="You don't have access to this Report")

    model = loads(t.model)

    # Check if this field is already grouped, if so then remove grouping
    thisfield = model.get_field(field_name)
    if thisfield.groupby == 1:
        thisfield.groupby = 0
    else:
        # Other wise reset grouping and set selected field as groupfield
        for field in model.fields:
            field.groupby = 0

        field = model.get_field(field_name)
        field.groupby = 1

    t.model = dumps(model)
    t.save()

    return report_edit(request,
                       report_id=report_id,
                       response_format=response_format)
Exemplo n.º 5
0
def is_field_number(report, field_name):
    model = loads(report.model)

    classobj = model.get_class_object()
    field = classobj._meta.get_field_by_name(field_name)[0]

    if number_field_regex.match(field.get_internal_type()):
        return True
    return False
Exemplo n.º 6
0
def is_field_number(report, field_name):
    model = loads(report.model)

    classobj = model.get_class_object()
    field = classobj._meta.get_field_by_name(field_name)[0]

    if number_field_regex.match(field.get_internal_type()):
        return True
    return False
Exemplo n.º 7
0
Arquivo: views.py Projeto: 5n1p/treeio
def report_filter_remove(request, report_id, field_name, filter_index, response_format='html'):
    "Remove a Filter on a given field for a Report"

    report = get_object_or_404(Report, pk=report_id)
    if not request.user.get_profile().has_permission(report, mode='w'):
        return user_denied(request, message="You don't have write access to this Report")

    model = loads(report.model)
    field = model.get_field(field_name)
    field.filters.pop(int(filter_index) - 1)
    report.model = dumps(model)
    report.save()

    return HttpResponseRedirect(reverse('reports_report_edit', args=[int(report_id)]))
Exemplo n.º 8
0
    def save(self):
        # add filter to field
        if not self.data['choice']:
            return
        t = self.report
        model = loads(t.model)
        classobj = model.get_class_object()
        xfield = classobj._meta.get_field_by_name(self.field_name)[0]

        field = model.get_field(self.field_name)
        if not field.filters:
            field.filters = []

        c = self.data['choice']

        type = xfield.get_internal_type()
        if type == 'ManyToManyField':
            c = xfield.related.parent_model.objects.filter(pk=c)[0]
        if type == 'ForeignKey':
            c = xfield.related.parent_model.objects.filter(pk=c)[0]

        display_choice = c
        if hasattr(self.fields['choice'], 'choices'):
            for choice, dc in self.fields['choice'].choices:
                if unicode(c) == unicode(choice):
                    display_choice = dc
                    break

        for choice, dc in self.fields['operand'].choices:
            if unicode(self.data['operand']) == unicode(choice):
                display_operand = dc
                break

        display = "%s %s %s" % (field.get_human_name(), display_operand,
                                unicode(display_choice))
        field.filters.append({
            'choice': c,
            'operand': self.data['operand'],
            'display': display
        })
        t.model = dumps(model)
        t.save()
Exemplo n.º 9
0
def report_filter_remove(request,
                         report_id,
                         field_name,
                         filter_index,
                         response_format='html'):
    "Remove a Filter on a given field for a Report"

    report = get_object_or_404(Report, pk=report_id)
    if not request.user.get_profile().has_permission(report, mode='w'):
        return user_denied(
            request, message="You don't have write access to this Report")

    model = loads(report.model)
    field = model.get_field(field_name)
    field.filters.pop(int(filter_index) - 1)
    report.model = dumps(model)
    report.save()

    return HttpResponseRedirect(
        reverse('reports_report_edit', args=[int(report_id)]))
Exemplo n.º 10
0
Arquivo: forms.py Projeto: 5n1p/treeio
    def save(self):
        # add filter to field
        if not self.data['choice']:
            return
        t = self.report
        model = loads(t.model)
        classobj = model.get_class_object()
        xfield = classobj._meta.get_field_by_name(self.field_name)[0]

        field = model.get_field(self.field_name)
        if not field.filters:
            field.filters = []

        c = self.data['choice']

        type = xfield.get_internal_type()
        if type == 'ManyToManyField':
            c = xfield.related.parent_model.objects.filter(pk=c)[0]
        if type == 'ForeignKey':
            c = xfield.related.parent_model.objects.filter(pk=c)[0]

        display_choice = c
        if hasattr(self.fields['choice'], 'choices'):
            for choice, dc in self.fields['choice'].choices:
                if unicode(c) == unicode(choice):
                    display_choice = dc
                    break

        for choice, dc in self.fields['operand'].choices:
            if unicode(self.data['operand']) == unicode(choice):
                display_operand = dc
                break

        display = "%s %s %s" % (
            field.get_human_name(), display_operand, unicode(display_choice))
        field.filters.append({'choice': c,
                              'operand': self.data['operand'],
                              'display': display
                              })
        t.model = dumps(model)
        t.save()
Exemplo n.º 11
0
def report_edit(request, report_id=None, response_format='html'):
    "Create new report based on user choice"
    report = get_object_or_404(Report, pk=report_id)

    if not request.user.get_profile().has_permission(report, mode='w'):
        return user_denied(request,
                           message="You don't have access to edit this Report")
    model = loads(report.model)

    if request.POST and 'commit' in request.POST:
        # UPDATE MODEL
        if 'report_name' in request.POST:
            report.name = request.POST['report_name']
        fieldnames = []
        aggregations = {}
        for key in request.POST:
            if 'field' in key:
                fieldnames.append(request.POST[key])
            elif 'aggregation-' in key:
                aggregations[key[12:]] = request.POST[key]

        for field in model.fields:
            field.aggregation = aggregations.get(field.name, None)
            if field.name in fieldnames:
                field.display = True
            else:
                field.display = False

        report.model = dumps(model)
        report.save()

    if 'commit' in request.POST:
        return HttpResponseRedirect(
            reverse('reports_report_view', args=[report.id]))

    return render_to_response('reports/report_edit', {
        'report': report,
        'model': model,
    },
                              context_instance=RequestContext(request),
                              response_format=response_format)
Exemplo n.º 12
0
Arquivo: views.py Projeto: 5n1p/treeio
def report_edit(request, report_id=None, response_format='html'):
    "Create new report based on user choice"
    report = get_object_or_404(Report, pk=report_id)

    if not request.user.get_profile().has_permission(report, mode='w'):
        return user_denied(request, message="You don't have access to edit this Report")
    model = loads(report.model)

    if request.POST and 'commit' in request.POST:
        # UPDATE MODEL
        if 'report_name' in request.POST:
            report.name = request.POST['report_name']
        fieldnames = []
        aggregations = {}
        for key in request.POST:
            if 'field' in key:
                fieldnames.append(request.POST[key])
            elif 'aggregation-' in key:
                aggregations[key[12:]] = request.POST[key]

        for field in model.fields:
            field.aggregation = aggregations.get(field.name, None)
            if field.name in fieldnames:
                field.display = True
            else:
                field.display = False

        report.model = dumps(model)
        report.save()

    if 'commit' in request.POST:
        return HttpResponseRedirect(reverse('reports_report_view', args=[report.id]))

    return render_to_response('reports/report_edit',
                              {'report': report,
                               'model': model,
                               },
                              context_instance=RequestContext(request),
                              response_format=response_format)
Exemplo n.º 13
0
    def __init__(self, user, *args, **kwargs):
        if not (kwargs.has_key('report') and kwargs.has_key('field_name')):
            return
        report = kwargs.pop('report')
        field_name = kwargs.pop('field_name')
        super(FilterForm, self).__init__(*args, **kwargs)

        model = loads(report.model)

        self.report = report
        self.field_name = field_name

        classobj = model.get_class_object()
        field = classobj._meta.get_field_by_name(field_name)[0]
        # TODO: Provisions for ManyToMany fields
        self.fields['operand'] = forms.ChoiceField()
        if field.get_internal_type() == 'ForeignKey':
            self.fields['choice'] = forms.ModelChoiceField(
                queryset=Object.filter_permitted(
                    user, field.related.parent_model.objects.all(), mode='x'))
            fc = (('is', 'is'), ('not', 'is not'))
        elif field.get_internal_type() == 'DateTimeField':
            self.fields['choice'] = forms.DateTimeField()
            self.fields['choice'].widget.attrs.update(
                {'class': 'datetimepicker'})
            fc = (('beforedatetime', 'before'), ('afterdatetime', 'after'))
        elif field.get_internal_type() == 'DateField':
            self.fields['choice'] = forms.DateField()
            self.fields['choice'].widget.attrs.update({'class': 'datepicker'})
            fc = (('beforedate', 'before'), ('afterdate', 'after'), ('on',
                                                                     'on'))
        else:
            self.fields['choice'] = field.formfield()
            fc = (('is', 'is'), ('not', 'is not'))

        self.fields['operand'].choices = fc
        self.fields['operand'].label = ""
        self.fields['choice'].label = ""
        self.fields['choice'].help_text = ""
Exemplo n.º 14
0
Arquivo: forms.py Projeto: 5n1p/treeio
    def __init__(self, user, *args, **kwargs):
        if not (kwargs.has_key('report') and kwargs.has_key('field_name')):
            return
        report = kwargs.pop('report')
        field_name = kwargs.pop('field_name')
        super(FilterForm, self).__init__(*args, **kwargs)

        model = loads(report.model)

        self.report = report
        self.field_name = field_name

        classobj = model.get_class_object()
        field = classobj._meta.get_field_by_name(field_name)[0]
        # TODO: Provisions for ManyToMany fields
        self.fields['operand'] = forms.ChoiceField()
        if field.get_internal_type() == 'ForeignKey':
            self.fields['choice'] = forms.ModelChoiceField(queryset=Object.filter_permitted(user,
                                                                                            field.related.parent_model.objects.all(), mode='x'))
            fc = (('is', 'is'), ('not', 'is not'))
        elif field.get_internal_type() == 'DateTimeField':
            self.fields['choice'] = forms.DateTimeField()
            self.fields['choice'].widget.attrs.update(
                {'class': 'datetimepicker'})
            fc = (('beforedatetime', 'before'), ('afterdatetime', 'after'))
        elif field.get_internal_type() == 'DateField':
            self.fields['choice'] = forms.DateField()
            self.fields['choice'].widget.attrs.update({'class': 'datepicker'})
            fc = (('beforedate', 'before'), (
                'afterdate', 'after'), ('on', 'on'))
        else:
            self.fields['choice'] = field.formfield()
            fc = (('is', 'is'), ('not', 'is not'))

        self.fields['operand'].choices = fc
        self.fields['operand'].label = ""
        self.fields['choice'].label = ""
        self.fields['choice'].help_text = ""
Exemplo n.º 15
0
def display_chart(context, chart, skip_group=False):
    "Return HTML for chart"

    request = context['request']

    response_format = 'html'
    if 'response_format' in context:
        response_format = context['response_format']

    options = loads(chart.options)

    content = _get_report_content(chart.report, request)

    objs = content['set']

    chart_dict = {}

    field_name = options['grouping']

    model = loads(chart.report.model)

    chart_dict['yAxis'] = {'allowDecimals': False,
                           'title': {'text': model.name.split('.')[-1] + " Count vs. " + field_name.replace('_', ' ').title()}}
    chart_dict['xAxis'] = {}
    try:
        xfield = objs[0]._meta.get_field_by_name(field_name)[0]
    except:
        chart.delete()
        return

    def get_date(g, mindate):
        if g and g != datetime.min.date():
            return g
        else:
            return mindate

    if xfield.get_internal_type() == 'ManyToManyField':
        l = []
        for obj in objs:
            for mi in getattr(obj, field_name).all():
                l.append(unicode(mi))
    elif xfield.get_internal_type() == 'DateTimeField' or xfield.get_internal_type() == 'DateField':
        chart_dict['xAxis']['labels'] = {  # 'rotation':90,
            'align': 'left',
            'x': 3,
            'y': 15}
        l, m, datelist = [], [], []
        maxdate = None
        mindate = None
        for obj in objs:
            if getattr(obj, field_name):
                x = getattr(obj, field_name)
                if xfield.get_internal_type() == 'DateTimeField':
                    x = x.date()
                if not maxdate or x > maxdate:
                    maxdate = x
                if not mindate or x < mindate:
                    mindate = x
                datelist.append(x)
                if unicode(x) not in m:
                    m.append(unicode(x))
            else:
                datelist.append(datetime.min.date())
        while datetime.min.date() in datelist:
            datelist.append(mindate)
            datelist.remove(datetime.min.date())
        datelist = sorted(datelist, key=lambda g: get_date(g, mindate))
        l = [unicode(g) for g in datelist]

        # chart_dict['xAxis']['categories']=m

        chart_dict['xAxis']['type'] = 'datetime'
        td = maxdate - mindate
        #print (td.microseconds + (td.seconds + td.days * 24 * 3600) * 10**6) / 10**6
        chart_dict['zoomType'] = 'x'
        chart_dict['xAxis']['tickInterval'] = (
            td.microseconds + (td.seconds + td.days * 24 * 3600) * 10 ** 6) / 10 ** 4
        #chart_dict['xAxis']['tickWidth']= 0,
        chart_dict['maxZoom'] = 14 * 24 * 3600000  # 2wks
        #chart_dict['xAxis']['gridLineWidth']= 1,
        chart_dict['series'] = [{'name': model.name.split('.')[-1], 'data':[]}]
        for x in set(l):
            chart_dict['series'][0]['data'].append(('%s UTC' % x, l.count(x)))

    else:
        l = [unicode(obj.get_field_value(field_name)) for obj in objs]

    if not 'series' in chart_dict:
        chart_dict['series'] = []
        #chart_dict['series'].append({'name':field_name, 'data': [{'name': x, 'y':l.count(x)} for x in set(l)]})
        chart_dict['series'].append({'name': field_name.replace(
            '_', ' ').title(), 'data': [[x, l.count(x)] for x in set(l)]})
    # for x in set(l):
    #    chart_dict['series'].append({'name':x, 'data': l.count(x)})
    #chart_dict['series'].append({'data':[{'name':x, 'y': [l.count(x)]} for x in set(l)]})
        if not 'xAxis' in chart_dict:
            chart_dict['xAxis']['categories'] = [x for x in set(l)]
        # Chart type specific options

        if 'legend' in options and options['legend'] == 'on':
            chart_dict['legend'] = {
                'layout': 'vertical',
                'align': 'right',
                'verticalAlign': 'top',
                'x': -10,
                'y': 100,
                'borderWidth': 0
            }
    if 'title' in options:
        chart_dict['title'] = {'text': options['title']}

    # Create a hash and use it as a unqiue div id and var name for the chart.
    hasher = hashlib.md5()
    hasher.update(str(random()))
    id = 'chartcontainer' + str(hasher.hexdigest())
    # Disable animation for when saving as PDF
    chart_dict['chart'] = {'renderTo': id,
                           'defaultSeriesType': options['type']}
    #chart_dict['plotOptions'] = {'series': {'animation': False}}

    chart_dict['plotOptions'] = {'pie': {
        'allowPointSelect': True,
        'cursor': 'pointer',
        'dataLabels': {
            'enabled': False
        },
        'showInLegend': True
    }}

    chart_dict['credits'] = {'enabled': False}

    rendered_options = json.dumps(chart_dict)

    rendered_options = rendered_options[
        :-1] + ", tooltip: {formatter: function() {return '<b>'+ this.point.name +'</b>: '+ this.y;}}}"

    if 'type' in chart_dict['xAxis'] and chart_dict['xAxis']['type'] == 'datetime':
        rendered_options += """
        datedata = [];
        jQuery.each(options.series[0].data, function(i,item){
        date = Date.parse(item[0]);
        count = item[1];
        datedata.push([date, count]);
        });
      options.series[0].data = datedata;

      function merge_options(obj1,obj2){
        var obj3 = {};
        for (attrname in obj1) { obj3[attrname] = obj1[attrname]; }
        for (attrname in obj2) { obj3[attrname] = obj2[attrname]; }
        return obj3;
      }
      var dateoptions =  {


      tooltip: {
         shared: true,
         crosshairs: true

      },

      };


    options = merge_options(options, dateoptions);

              """

    return Markup(render_to_string('reports/tags/chart',
                                   {'rendered_options': rendered_options,
                                    'id': id,
                                    'chart_id': chart.id,
                                    'chart': chart,
                                    'name': options['title']},
                                   context_instance=RequestContext(request),
                                   response_format=response_format))
Exemplo n.º 16
0
def _get_report_content(report, request=None):
    model = loads(report.model)

    object = model.name
    object = object.split('.')

    module_name = object[0] + '.' + object[1] + '.' + object[2]
    import_name = object[3]

    module = __import__(module_name, globals(), locals(), [import_name], -1)
    classobj = getattr(module, import_name)

    if request:
        unfiltered_set = Object.filter_by_request(request, classobj.objects)
    else:
        unfiltered_set = classobj.objects.exclude(trash=True)

    # construct filter
    filters = {}
    excludes = {}
    for field in model.fields:
        for filter in field.filters:
            if filter['operand'] == 'is':
                filters.setdefault(field.name + '__in',
                                   []).append(filter['choice'])
            elif filter['operand'] == 'not':
                excludes.setdefault(field.name + '__in',
                                    []).append(filter['choice'])
            elif filter['operand'] == 'beforedate':
                filters[field.name + '__gte'] = datetime.date(
                    datetime.strptime(filter['choice'], '%m/%d/%Y'))
            elif filter['operand'] == 'afterdate':
                filters[field.name + '__lte'] = datetime.date(
                    datetime.strptime(filter['choice'], '%m/%d/%Y'))
            elif filter['operand'] == 'beforedatetime':
                filters[field.name + '__gte'] = datetime.strptime(
                    filter['choice'], '%m/%d/%Y %H:%M')
            elif filter['operand'] == 'afterdatetime':
                filters[field.name + '__lte'] = datetime.strptime(
                    filter['choice'], '%m/%d/%Y %H:%M')
            elif filter['operand'] == 'on':
                filters.setdefault(field.name + '__in', []).append(
                    datetime.strptime(filter['choice'], '%m/%d/%Y'))

    set = unfiltered_set.filter(**filters).exclude(**excludes)

    # Check for group
    groupname = None
    groups = None
    for field in model.fields:
        if field.groupby == 1:
            groupname = field.name

    if groupname:
        xfield = classobj._meta.get_field_by_name(groupname)[0]
        xtype = xfield.get_internal_type()
        if xtype == 'ManyToManyField':
            set = sorted(
                set,
                key=lambda item: (", ".join(
                    [unicode(i) for i in getattr(item, groupname).all()])),
                reverse=True)
            groups, groupnames = [], []
            for obj in set:
                for n in getattr(obj, groupname).all():
                    if n not in groupnames:
                        groupnames.append(n)
            for n in groupnames:
                l = []
                for obj in set:
                    if n in getattr(obj, groupname).all():
                        l.append(obj)
                groups.append((unicode(n), l))

        elif xtype == ('DateTimeField' or 'DateField'):
            set = set.order_by(groupname)
            #set = sorted(set, key = lambda item: getattr(item,groupname))
            # TODO: Fix this sort
            groups, groupnames, l, ng = [], [], [], []
            n = None

            if xtype == 'DateTimeField':

                def dt(ob):
                    return getattr(ob, groupname).date()
            else:

                def dt(ob):
                    return getattr(ob, groupname)

            for x in set:
                n = dt(x)
                if n:
                    break
            if n:
                for obj in set:
                    if getattr(obj, groupname):
                        if dt(obj) == n:
                            l.append(obj)
                        else:
                            groups.append((unicode(n), l))
                            l = []
                            n = dt(obj)
                            l.append(obj)
                    else:
                        ng.append(obj)
                if ng:
                    groups.append(('None', ng))

        else:
            set = sorted(
                set,
                key=lambda item: unicode(item.get_field_value(groupname)),
                reverse=True)
            groups = []
            for g, ks in groupby(
                    set,
                    key=lambda item: unicode(item.get_field_value(groupname))):
                groups.append((g, list(ks)))
            xfield = set[0]._meta.get_field_by_name(groupname)[0]

    # Count aggregate functions
    agg_funcs = {}
    for field in model.fields:  # get fields and aggregate functions for them
        if field.display and getattr(field, 'aggregation', None):
            xfield = classobj._meta.get_field_by_name(field.name)[0]
            if number_field_regex.match(xfield.get_internal_type()) \
                    and aggregate_functions.has_key(field.aggregation):
                agg_funcs[field.name] = aggregate_functions[
                    field.aggregation]['function']

    aggregations = {}
    if agg_funcs:
        for grouper, ls in groups if groups else (('set', set), ):
            data = {}
            for s in ls:
                for key in agg_funcs:
                    data.setdefault(key, []).append(getattr(s, key, 0))
            aggrs = {}
            for key, func in agg_funcs.items():
                aggrs[key] = func(data.get(key, [
                    0,
                ]))
            aggregations[grouper] = aggrs

    return {
        'model': model,
        'set': set,
        'groups': groups,
        'groupname': groupname,
        'aggregations': aggregations
    }
Exemplo n.º 17
0
Arquivo: views.py Projeto: 5n1p/treeio
def _get_report_content(report, request=None):
    model = loads(report.model)

    object = model.name
    object = object.split('.')

    module_name = object[0] + '.' + object[1] + '.' + object[2]
    import_name = object[3]

    module = __import__(module_name, globals(), locals(), [import_name], -1)
    classobj = getattr(module, import_name)

    if request:
        unfiltered_set = Object.filter_by_request(request, classobj.objects)
    else:
        unfiltered_set = classobj.objects.exclude(trash=True)

    # construct filter
    filters = {}
    excludes = {}
    for field in model.fields:
        for filter in field.filters:
            if filter['operand'] == 'is':
                filters.setdefault(field.name + '__in', []).append(filter['choice'])
            elif filter['operand'] == 'not':
                excludes.setdefault(field.name + '__in', []).append(filter['choice'])
            elif filter['operand'] == 'beforedate':
                filters[field.name + '__gte'] = datetime.date(datetime.strptime(filter['choice'], '%m/%d/%Y'))
            elif filter['operand'] == 'afterdate':
                filters[field.name + '__lte'] = datetime.date(datetime.strptime(filter['choice'], '%m/%d/%Y'))
            elif filter['operand'] == 'beforedatetime':
                filters[field.name + '__gte'] = datetime.strptime(filter['choice'], '%m/%d/%Y %H:%M')
            elif filter['operand'] == 'afterdatetime':
                filters[field.name + '__lte'] = datetime.strptime(filter['choice'], '%m/%d/%Y %H:%M')
            elif filter['operand'] == 'on':
                filters.setdefault(field.name + '__in', []).append(datetime.strptime(filter['choice'], '%m/%d/%Y'))

    set = unfiltered_set.filter(**filters).exclude(**excludes)

    # Check for group
    groupname = None
    groups = None
    for field in model.fields:
        if field.groupby == 1:
            groupname = field.name

    if groupname:
        xfield = classobj._meta.get_field_by_name(groupname)[0]
        xtype = xfield.get_internal_type()
        if xtype == 'ManyToManyField':
            set = sorted(set, key=lambda item: (
                ", ".join([unicode(i) for i in getattr(item, groupname).all()])), reverse=True)
            groups, groupnames = [], []
            for obj in set:
                for n in getattr(obj, groupname).all():
                    if n not in groupnames:
                        groupnames.append(n)
            for n in groupnames:
                l = []
                for obj in set:
                    if n in getattr(obj, groupname).all():
                        l.append(obj)
                groups.append((unicode(n), l))

        elif xtype == ('DateTimeField' or 'DateField'):
            set = set.order_by(groupname)
            #set = sorted(set, key = lambda item: getattr(item,groupname))
            # TODO: Fix this sort
            groups, groupnames, l, ng = [], [], [], []
            n = None

            if xtype == 'DateTimeField':
                def dt(ob):
                    return getattr(ob, groupname).date()
            else:
                def dt(ob):
                    return getattr(ob, groupname)

            for x in set:
                n = dt(x)
                if n:
                    break
            if n:
                for obj in set:
                    if getattr(obj, groupname):
                        if dt(obj) == n:
                            l.append(obj)
                        else:
                            groups.append((unicode(n), l))
                            l = []
                            n = dt(obj)
                            l.append(obj)
                    else:
                        ng.append(obj)
                if ng:
                    groups.append(('None', ng))

        else:
            set = sorted(set, key=lambda item: unicode(
                item.get_field_value(groupname)), reverse=True)
            groups = []
            for g, ks in groupby(set, key=lambda item: unicode(item.get_field_value(groupname))):
                groups.append((g, list(ks)))
            xfield = set[0]._meta.get_field_by_name(groupname)[0]

    # Count aggregate functions
    agg_funcs = {}
    for field in model.fields:  # get fields and aggregate functions for them
        if field.display and getattr(field, 'aggregation', None):
            xfield = classobj._meta.get_field_by_name(field.name)[0]
            if number_field_regex.match(xfield.get_internal_type()) \
                    and aggregate_functions.has_key(field.aggregation):
                agg_funcs[field.name] = aggregate_functions[
                    field.aggregation]['function']

    aggregations = {}
    if agg_funcs:
        for grouper, ls in groups if groups else (('set', set),):
            data = {}
            for s in ls:
                for key in agg_funcs:
                    data.setdefault(key, []).append(getattr(s, key, 0))
            aggrs = {}
            for key, func in agg_funcs.items():
                aggrs[key] = func(data.get(key, [0, ]))
            aggregations[grouper] = aggrs

    return {'model': model,
            'set': set,
            'groups': groups,
            'groupname': groupname,
            'aggregations': aggregations}
Exemplo n.º 18
0
def display_chart(context, chart, skip_group=False):
    "Return HTML for chart"

    request = context['request']

    response_format = 'html'
    if 'response_format' in context:
        response_format = context['response_format']

    options = loads(chart.options)

    content = _get_report_content(chart.report, request)

    objs = content['set']

    chart_dict = {}

    field_name = options['grouping']

    model = loads(chart.report.model)

    chart_dict['yAxis'] = {
        'allowDecimals': False,
        'title': {
            'text':
            model.name.split('.')[-1] + " Count vs. " +
            field_name.replace('_', ' ').title()
        }
    }
    chart_dict['xAxis'] = {}
    try:
        xfield = objs[0]._meta.get_field_by_name(field_name)[0]
    except:
        chart.delete()
        return

    def get_date(g, mindate):
        if g and g != datetime.min.date():
            return g
        else:
            return mindate

    if xfield.get_internal_type() == 'ManyToManyField':
        l = []
        for obj in objs:
            for mi in getattr(obj, field_name).all():
                l.append(unicode(mi))
    elif xfield.get_internal_type(
    ) == 'DateTimeField' or xfield.get_internal_type() == 'DateField':
        chart_dict['xAxis']['labels'] = {  #'rotation':90,
            'align': 'left',
            'x': 3,
            'y': 15
        }
        l, m, datelist = [], [], []
        maxdate = None
        mindate = None
        for obj in objs:
            if getattr(obj, field_name):
                x = getattr(obj, field_name)
                if xfield.get_internal_type() == 'DateTimeField':
                    x = x.date()
                if not maxdate or x > maxdate:
                    maxdate = x
                if not mindate or x < mindate:
                    mindate = x
                datelist.append(x)
                if unicode(x) not in m:
                    m.append(unicode(x))
            else:
                datelist.append(datetime.min.date())
        while datetime.min.date() in datelist:
            datelist.append(mindate)
            datelist.remove(datetime.min.date())
        datelist = sorted(datelist, key=lambda g: get_date(g, mindate))
        l = [unicode(g) for g in datelist]

        #chart_dict['xAxis']['categories']=m

        chart_dict['xAxis']['type'] = 'datetime'
        td = maxdate - mindate
        #print (td.microseconds + (td.seconds + td.days * 24 * 3600) * 10**6) / 10**6
        chart_dict['zoomType'] = 'x'
        chart_dict['xAxis']['tickInterval'] = (
            td.microseconds +
            (td.seconds + td.days * 24 * 3600) * 10**6) / 10**4
        #chart_dict['xAxis']['tickWidth']= 0,
        chart_dict['maxZoom'] = 14 * 24 * 3600000  #2wks
        #chart_dict['xAxis']['gridLineWidth']= 1,
        chart_dict['series'] = [{
            'name': model.name.split('.')[-1],
            'data': []
        }]
        for x in set(l):
            chart_dict['series'][0]['data'].append(('%s UTC' % x, l.count(x)))

    else:
        l = [unicode(obj.get_field_value(field_name)) for obj in objs]

    if not 'series' in chart_dict:
        chart_dict['series'] = []
        #chart_dict['series'].append({'name':field_name, 'data': [{'name': x, 'y':l.count(x)} for x in set(l)]})
        chart_dict['series'].append({
            'name':
            field_name.replace('_', ' ').title(),
            'data': [[x, l.count(x)] for x in set(l)]
        })
        #for x in set(l):
        #    chart_dict['series'].append({'name':x, 'data': l.count(x)})
        #chart_dict['series'].append({'data':[{'name':x, 'y': [l.count(x)]} for x in set(l)]})
        if not 'xAxis' in chart_dict:
            chart_dict['xAxis']['categories'] = [x for x in set(l)]
        #Chart type specific options

        if 'legend' in options and options['legend'] == 'on':
            chart_dict['legend'] = {
                'layout': 'vertical',
                'align': 'right',
                'verticalAlign': 'top',
                'x': -10,
                'y': 100,
                'borderWidth': 0
            }
    if 'title' in options:
        chart_dict['title'] = {'text': options['title']}

    #Create a hash and use it as a unqiue div id and var name for the chart.
    hasher = hashlib.md5()
    hasher.update(str(random()))
    id = 'chartcontainer' + str(hasher.hexdigest())
    #Disable animation for when saving as PDF
    chart_dict['chart'] = {
        'renderTo': id,
        'defaultSeriesType': options['type']
    }
    #chart_dict['plotOptions'] = {'series': {'animation': False}}

    chart_dict['plotOptions'] = {
        'pie': {
            'allowPointSelect': True,
            'cursor': 'pointer',
            'dataLabels': {
                'enabled': False
            },
            'showInLegend': True
        }
    }

    chart_dict['credits'] = {'enabled': False}

    rendered_options = json.dumps(chart_dict)

    rendered_options = rendered_options[:-1] + ", tooltip: {formatter: function() {return '<b>'+ this.point.name +'</b>: '+ this.y;}}}"

    if 'type' in chart_dict['xAxis'] and chart_dict['xAxis'][
            'type'] == 'datetime':
        rendered_options += """
        datedata = [];
        jQuery.each(options.series[0].data, function(i,item){
        date = Date.parse(item[0]);
        count = item[1];
        datedata.push([date, count]);
        });
      options.series[0].data = datedata;
      
      function merge_options(obj1,obj2){
        var obj3 = {};
        for (attrname in obj1) { obj3[attrname] = obj1[attrname]; }
        for (attrname in obj2) { obj3[attrname] = obj2[attrname]; }
        return obj3;
      }
      var dateoptions =  {
        
      
      tooltip: {
         shared: true,
         crosshairs: true
         
      },
      
      };

      
    options = merge_options(options, dateoptions);
    
              """

    return Markup(
        render_to_string('reports/tags/chart', {
            'rendered_options': rendered_options,
            'id': id,
            'chart_id': chart.id,
            'chart': chart,
            'name': options['title']
        },
                         context_instance=RequestContext(request),
                         response_format=response_format))