Beispiel #1
0
def clear_report_log():
    print('Cleaning report log...')
    # удаляем записи лога запросов отчетов старше 1 часа
    until_dt = utcnow() - datetime.timedelta(seconds=60 * 60)
    result = models.WialonReportLog.objects.filter(created__lte=until_dt).delete()
    if result[0]:
        print('%s WialonReportLog rows deleted' % result[0])

    until_dt = utcnow() - datetime.timedelta(days=30)
    result = models.ReportEmailDeliveryLog.objects.filter(created__lte=until_dt).delete()
    if result[0]:
        print('%s ReportEmailDeliveryLog rows deleted' % result[0])
Beispiel #2
0
def remove_old_job_log():
    print('Removing old records...')

    until = utcnow() - datetime.timedelta(days=31)
    print('Until %s' % until)
    res = JobLog.objects.filter(created__lt=until).delete()
    print('%s records removed' % res[0])
Beispiel #3
0
    def post(self, request, *args, **kwargs):

        doc = request.data.xpath('/routesRequest')
        if len(doc) < 1:
            return error_response('Не найден объект routesRequest',
                                  code='routesRequest_not_found')

        doc = doc[0]
        doc_id = doc.get('idDoc', '')
        if not doc_id:
            return error_response('Не указан параметр idDoc',
                                  code='idDoc_not_found')

        try:
            org_id = int(doc.get('idOrg', ''))
        except ValueError:
            org_id = 0

        sess_id = get_wialon_session_key(request.user)
        try:
            routes = get_routes(sess_id)
        except APIProcessError as e:
            return error_response(str(e), code=e.code)
        finally:
            logout_session(request.user, sess_id)

        context = self.get_context_data(**kwargs)
        context.update({
            'doc_id': doc_id,
            'create_date': utcnow(),
            'routes': routes,
            'org_id': org_id
        })

        return XMLResponse('ura/routes.xml', context)
Beispiel #4
0
def remove_expired_notifications():
    print('Cleaning expired notifications...')
    # удаляем старые шаблоны уведомлений
    notifications = Notification.objects\
        .filter(expired_at__lt=utcnow())\
        .select_related('job', 'job__user')

    session_cache = {}

    i = 0
    for notification in notifications.iterator():
        user = notification.job.user
        if user not in session_cache:
            sess_id = get_wialon_session_key(user)
            session_cache[user] = sess_id
        else:
            sess_id = session_cache[user]

        try:
            remove_notification(notification, user, sess_id)
        except WialonException as e:
            print(e)
        else:
            notification.delete()
        i += 1

    for user, sess_id in session_cache.items():
        logout_session(user, sess_id)

    print('%s expired notifications removed' % i)
Beispiel #5
0
    def download_xls(self, request, context=None, *args, **kwargs):
        from reports.utils import utc_to_local_time

        if context is None:
            context = request.session.get(self.get_session_key())

        if not context:
            messages.error(
                request, 'Данные отчета не найдены. Сначала выполните отчет')
            context = super(BaseReportView, self).get_context_data(**kwargs)
            context = self.get_default_context_data(**context)
            return self.render_to_response(context)

        dt = utcnow()
        if request.session.get('user'):
            user = User.objects.filter(
                is_active=True,
                wialon_username=self.request.session.get('user')).first()

            if user and user.timezone:
                dt = utc_to_local_time(dt, user.timezone)

        filename = 'report_%s.xls' % dt.strftime('%Y%m%d_%H%M%S')

        self.workbook = xlwt.Workbook()
        worksheet = self.workbook.add_sheet('Отчет')

        self.write_xls_data(worksheet, context)

        response = HttpResponse(content_type='application/vnd.ms-excel')
        response[
            'Content-Disposition'] = 'attachment; filename="%s"' % filename
        self.workbook.save(response)
        return response
def email_reports():
    print('Mailing monthly driving style total report...')
    reports = models.DrivingStyleTotalReportDelivery.objects.published()

    now = utcnow()

    for report in reports:
        print('Monthly VCHM Driving style total report %s' % report)

        for user in report.users.all():
            local_now = utc_to_local_time(now, user.timezone)

            if not user.email:
                print('Skipping user %s (no email)' % user)
                continue

            print('User %s' % user)
            sess_id = None

            try:
                # получаем отчеты через HTTP
                sess_id = get_wialon_session_key(user)
                # если время выполнения - 1е число месяца, то отчет сформируется за прошлый месяц,
                # иначе отчет подготовится за текущий месяц вчерашний день включительно.
                date_to = (local_now - datetime.timedelta(days=1)).date()
                date_from = date_to.replace(day=1)

                res = make_report(report,
                                  user,
                                  sess_id,
                                  date_from=date_from,
                                  date_to=date_to,
                                  attempts=0)

                filename = 'total_vchm_driving_report_%s.xls' % user.pk
                log = models.ReportEmailDeliveryLog(
                    user=user,
                    email=user.email,
                    report_type=EmailDeliveryReportTypeEnum.DRIVING_STYLE,
                    subject='Сводный отчет о качестве вождения (ВЧМ)',
                    body='Здравствуйте, %s. Отчет по вложении.' %
                    user.full_name)
                content = ContentFile(res.content)
                log.report.save(filename, content, save=False)
                log.save()
                log.send(reraise=True)

            except Exception as e:
                print('Error: %s' % e)
                send_trigger_email('Ошибка в работе системы рассылки отчетов',
                                   extra_data={
                                       'Exception': str(e),
                                       'Traceback': traceback.format_exc(),
                                       'report': report,
                                       'user': user
                                   })
            finally:
                if sess_id:
                    logout_session(user, sess_id)
Beispiel #7
0
 def get_executed_reports_count(for_user):
     """
     Изучаем сколько запросов сделано за минуту
     (и на всякий случай добавим еще 5 минут)
     """
     since_dt = utcnow() - datetime.timedelta(
         seconds=settings.WIALON_REPORTS_LIMIT_PERIOD)
     count = WialonReportLog.objects.filter(user=for_user,
                                            created__gte=since_dt).count()
     return count
Beispiel #8
0
    def index(self, force=False):
        now = utcnow()
        if force \
                or self.last_modified is None \
                or now - self.last_modified > CACHE_TIMEOUT:

            self.vars = defaultdict(dict)

            values = DbConfig.objects.filter(status=StatusEnum.PUBLIC)
            for value in values.iterator():
                for lang in settings.LANGUAGE_CODES:
                    self.vars[lang][value.key] = getattr(
                        value, 'value_' + lang)
            self.last_modified = now
Beispiel #9
0
    def post(self, request, *args, **kwargs):

        doc = request.data.xpath('/echoRequest')
        if len(doc) < 1:
            return error_response('Не найден объект echoRequest', code='echoRequest_not_found')

        doc = doc[0]
        doc_id = doc.get('idDoc', '')
        if not doc_id:
            return error_response('Не указан параметр idDoc', code='idDoc_not_found')

        context = self.get_context_data(**kwargs)
        context.update({
            'doc_id': doc_id,
            'create_date': utcnow()
        })
        return XMLResponse('ura/echo.xml', context)
Beispiel #10
0
    def post(self, request, **kwargs):
        units = []

        context = self.get_context_data(**kwargs)
        context.update({'now': utcnow(), 'units': units})

        units_els = request.data.xpath('/getMoving/unit')
        if not units_els:
            logout_session(request.user, self.sess_id)
            return error_response('Не указаны объекты типа unit',
                                  code='units_not_found')

        self.get_geozones_report_template_id()

        for unit_el in units_els:
            self.get_input_data(unit_el)
            self.unit_id = int(self.input_data.get('unit_id'))
            self.get_job()
            self.get_route()
            self.get_report_data()
            self.get_object_messages()

            self.ride_points = []
            unit_info = {
                'id':
                self.unit_id,
                'date_begin':
                utc_to_local_time(self.input_data['date_begin'],
                                  request.user.timezone),
                'date_end':
                utc_to_local_time(self.input_data['date_end'],
                                  request.user.timezone),
                'points':
                self.ride_points
            }

            self.prepare_geozones_visits()
            self.process_messages()
            self.report_post_processing(unit_info)
            self.update_job_points_cache()
            self.prepare_output_data()

            units.append(unit_info)

        logout_session(request.user, self.sess_id)
        return XMLResponse('ura/moving.xml', context)
Beispiel #11
0
    def get(self, request, **kwargs):
        now = utc_to_local_time(utcnow(), request.user.timezone)
        local_dt_from = now.replace(hour=0, minute=0, second=0)
        local_dt_to = now.replace(hour=23, minute=59, second=59)
        user = User.objects.get(pk=1)
        sess_id = get_wialon_session_key(user)
        moving_service = self.service_class(
            user=user,
            local_dt_from=local_dt_from,
            local_dt_to=local_dt_to,
            sess_id=sess_id
        )
        moving_service.exec_report()
        moving_service.analyze()
        logout_session(user, sess_id)

        return success_response()
Beispiel #12
0
    def post(self, request, **kwargs):
        jobs = []
        print('Start getRaces:\n' + str(request.body))

        context = self.get_context_data(**kwargs)
        context.update({
            'now': utcnow(),
            'jobs': jobs
        })

        jobs_els = request.data.xpath('/getRaces/job')

        if not jobs_els:
            logout_session(request.user, self.sess_id)
            return error_response('Не указаны объекты типа job', code='jobs_not_found')

        self.get_geozones_report_template_id()

        for job_el in jobs_els:
            self.get_input_data(job_el)
            self.unit_id = int(self.input_data.get('unit_id'))
            self.get_job()
            self.get_route()
            self.points_dict_by_name = {x['name']: x['id'] for x in self.route['points']}

            self.get_report_data()
            self.get_object_messages()
            self.prepare_geozones_visits()

            self.ride_points = []
            self.process_messages()

            races = []
            job_info = {
                'obj': self.job,
                'races': races
            }

            self.make_races(races)

            self.report_post_processing(job_info)
            self.prepare_output_data(job_info)
            jobs.append(job_info)

        logout_session(request.user, self.sess_id)
        return XMLResponse('ura/races.xml', context)
Beispiel #13
0
    def post(self, request, *args, **kwargs):
        jobs = []
        jobs_els = request.data.xpath('/breakJobs/job')

        if jobs_els:

            for j in jobs_els:
                data = parse_xml_input_data(request, self.model_mapping, j)

                job_id = data.pop('job_id')
                if not job_id:
                    return error_response('Не указан параметр idJob',
                                          code='idJob_not_found')

                if data.get('new_date_end'
                            ) and data['new_date_end'] <= data['date_begin']:
                    self.model.objects.filter(pk=job_id).delete()
                else:
                    try:
                        self.job = self.model.objects.get(pk=job_id)
                    except self.model.DoesNotExist:
                        return error_response('Задание с ID=%s не найдено' %
                                              job_id,
                                              code='job_not_found')

                    for k, v in data.iems():
                        if k == 'new_date_end':
                            k = 'date_end'
                        elif k == 'date_end' and 'new_date_end' in data and data[
                                'new_date_end']:
                            continue

                        setattr(self.job, k, v)
                        self.job.save()
                    jobs.append(self.job)

        context = self.get_context_data(**kwargs)
        context.update({'now': utcnow(), 'breakJobs': jobs})

        return XMLResponse('ura/ackBreakJobs.xml', context)
Beispiel #14
0
    def post(self, request, *args, **kwargs):

        doc = request.data.xpath('/orgRequest')
        if len(doc) < 1:
            return error_response('Не найден объект orgRequest',
                                  code='orgRequest_not_found')

        doc = doc[0]
        doc_id = doc.get('idDoc', '')
        if not doc_id:
            return error_response('Не указан параметр idDoc',
                                  code='idDoc_not_found')

        orgs = User.objects.filter(supervisor=request.user, is_active=True)

        context = self.get_context_data(**kwargs)
        context.update({
            'doc_id': doc_id,
            'orgs': orgs,
            'create_date': utcnow()
        })

        return XMLResponse('ura/orgs.xml', context)
def email_reports(period=None):
    print('Mailing %s driving style report...' % period)
    if not period or period not in ('daily', 'weekly', 'monthly'):
        print('Period not specified')
        return

    reports = models.DrivingStyleReportDelivery.objects.published()
    period_verbose = ''
    if period == 'daily':
        period_verbose = 'Ежедневный'
        reports = reports.filter(is_daily=True)
    elif period == 'weekly':
        period_verbose = 'Еженедельный'
        reports = reports.filter(is_weekly=True)
    elif period == 'monthly':
        period_verbose = 'Ежемесячный'
        reports = reports.filter(is_monthly=True)

    now = utcnow()

    for report in reports:
        print('%s VCHM Driving style report %s' % (period, report))

        for user in report.users.all():
            local_now = utc_to_local_time(now, user.timezone)

            if not user.email:
                print('Skipping user %s (no email)' % user)
                continue

            if local_now.hour != SEND_HOUR:
                print('Skipping user %s (%s != %s)' %
                      (user, local_now.hour, SEND_HOUR))
                continue

            print('User %s' % user)
            sess_id = None

            try:
                # получаем отчеты через HTTP
                sess_id = get_wialon_session_key(user)
                date_from = date_to = (local_now -
                                       datetime.timedelta(days=1)).date()

                if period == 'daily':
                    date_from = date_to
                elif period == 'weekly':
                    date_from = (local_now - datetime.timedelta(days=7)).date()
                elif period == 'monthly':
                    date_from = date_to.replace(day=1)

                res = make_report(report,
                                  user,
                                  sess_id,
                                  date_from=date_from,
                                  date_to=date_to,
                                  attempts=0)

                filename = '%s_vchm_driving_report_%s.xls' % (period, user.pk)
                log = models.ReportEmailDeliveryLog(
                    user=user,
                    email=user.email,
                    report_type=EmailDeliveryReportTypeEnum.DRIVING_STYLE,
                    subject='%s отчет о качестве вождения (ВЧМ)' %
                    period_verbose,
                    body='Здравствуйте, %s. Отчет по вложении.' %
                    user.full_name)
                content = ContentFile(res.content)
                log.report.save(filename, content)
                log.save()
                log.send(reraise=True)

            except Exception as e:
                print('Error: %s' % e)
                send_trigger_email('Ошибка в работе системы рассылки отчетов',
                                   extra_data={
                                       'Exception': str(e),
                                       'Traceback': traceback.format_exc(),
                                       'report': report,
                                       'user': user
                                   })
            finally:
                if sess_id:
                    logout_session(user, sess_id)
Beispiel #16
0
 def actual(self):
     return self.filter(publish_date__lte=utcnow())
Beispiel #17
0
 def not_actual(self):
     return self.filter(publish_date__gt=utcnow())
Beispiel #18
0
    def update_last_sensor_data(self, report_row, attempt=0):

        date_slice_from = attempt * LAST_SIGNAL_STEP
        date_slice_to = (attempt + 1) * LAST_SIGNAL_STEP

        if date_slice_to > LAST_SIGNAL_UNTIL:
            return report_row

        now = local_date_to = utc_to_local_time(utcnow(), self.user.timezone)

        if date_slice_from:
            local_date_to = now - datetime.timedelta(days=date_slice_from)

        local_date_from = now - datetime.timedelta(days=date_slice_to)
        dt_from, dt_to = get_period(local_date_from, local_date_to,
                                    self.user.timezone)

        print('Пробуем период поиска последнего сигнала %s - %s (попытка %s)' %
              (local_date_from, local_date_to, attempt + 1))
        cleanup_and_request_report(self.user, self.sensors_template_id,
                                   self.sess_id)
        r = exec_report(self.user,
                        self.sensors_template_id,
                        self.sess_id,
                        dt_from,
                        dt_to,
                        object_id=report_row['unit_id'])

        for table_index, table_info in enumerate(r['reportResult']['tables']):
            label = table_info['label'].split('(')[0].strip()

            if table_info[
                    'name'] != 'unit_sensors_tracing' or label != report_row[
                        'sensor']:
                continue

            if table_info['rows'] == 0:
                return self.update_last_sensor_data(report_row,
                                                    attempt=attempt + 1)

            rows = get_report_rows(self.sess_id, table_index, rows=1, level=1)

            if not rows:
                return self.update_last_sensor_data(report_row,
                                                    attempt=attempt + 1)

            dt, place = rows[0]['c'][2], rows[0]['c'][4]

            if isinstance(dt, dict):
                dt = datetime.datetime.utcfromtimestamp(dt['v'])
                dt = utc_to_local_time(dt, self.user.timezone)
            else:
                dt = parse_wialon_report_datetime(dt)

            if isinstance(place, dict) and 't' in place:
                place = place['t']

            if place:
                report_row['place'] = place

            if dt:
                report_row['dt'] = dt
                report_row[
                    'sum_broken_work_time'] = self.get_sum_broken_work_time(
                        report_row['unit_id'],
                        local_to_utc_time(dt, self.user.timezone),
                        report_row['job_date_end'])
            return report_row

        return self.update_last_sensor_data(report_row, attempt=attempt + 1)
Beispiel #19
0
    def post(self, request, *args, **kwargs):
        jobs = []
        jobs_els = request.data.xpath('/setJobs/job')
        sess_id = get_wialon_session_key(request.user)

        if jobs_els:

            for j in jobs_els:
                data = parse_xml_input_data(request, self.model_mapping, j)

                name = data.get('name')
                if not name:
                    logout_session(request.user, sess_id)
                    return error_response('Не указан параметр jobName',
                                          code='jobName_not_found')

                routes = get_routes(sess_id, with_points=True)
                units = get_units(sess_id)

                routes_ids = [x['id'] for x in routes]
                if data['route_id'] not in routes_ids:
                    return error_response(
                        'Шаблон задания idRoute неверный или не принадлежит текущей организации',
                        code='route_permission')

                units_cache = {
                    u['id']:
                    '%s (%s) [%s]' % (u['name'], u['number'], u['vin'])
                    for u in units
                }

                try:
                    data['unit_title'] = units_cache.get(int(data['unit_id']))
                except (ValueError, TypeError, AttributeError):
                    pass

                if not data['unit_title']:
                    return error_response(
                        'Объект ID=%s не найден в текущем ресурсе организации'
                        % data['unit_id'],
                        code='unit_not_found_permission')

                routes_cache = {r['id']: r for r in routes}
                try:
                    data['route_title'] = routes_cache.get(
                        int(data['route_id']), {}).get('name')
                except (ValueError, TypeError, AttributeError):
                    pass

                data['user'] = request.user
                self.job = self.model.objects.create(**data)
                register_job_notifications(self.job,
                                           sess_id,
                                           routes_cache=routes_cache)
                logout_session(request.user, sess_id)
                jobs.append(self.job)

        context = self.get_context_data(**kwargs)
        context.update({'now': utcnow(), 'acceptedJobs': jobs})

        return XMLResponse('ura/ackjobs.xml', context)