コード例 #1
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)
コード例 #2
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)
コード例 #3
0
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)
コード例 #4
0
def forwards_func(apps, schema_editor):
    job_model = apps.get_model('ura', 'UraJob')
    user_model = apps.get_model('users', 'User')

    orgs = user_model.objects.filter(is_active=True, supervisor__isnull=False)
    units_cache = {}
    routes_cache = {}

    for org in orgs.iterator():
        print('Organization %s' % org.username)
        sess_id = get_wialon_session_key(org)
        units = get_units(sess_id)
        units_cache[org.pk] = {
            u['id']: '%s (%s) [%s]' % (u['name'], u['number'], u['vin'])
            for u in units
        }

        routes = get_routes(sess_id)
        logout_session(org, sess_id)
        routes_cache[org.pk] = {r['id']: r['name'] for r in routes}

    sess_id = None
    print('Jobs count: %s' % job_model.objects.count())

    i = 0
    for job in job_model.objects.iterator():
        i += 1
        if not job.user_id:
            print('%s: Job %s missed due to lack of user' % (i, job.pk))
            continue

        unit_title = route_title = None

        try:
            unit_id = int(job.unit_id)
            unit_title = units_cache.get(job.user_id, {}).get(unit_id)
            if unit_title:
                job.unit_title = unit_title
        except (ValueError, TypeError, AttributeError):
            pass

        try:
            route_id = int(job.route_id)
            route_title = routes_cache.get(job.user_id, {}).get(route_id)
            if route_title:
                job.route_title = route_title
        except (ValueError, TypeError, AttributeError):
            pass

        if unit_title or route_title:
            job.save()

        print('%s: unit=%s, route=%s (%s)' %
              (i, unit_title, route_title, job.created))
コード例 #5
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()
コード例 #6
0
ファイル: moving.py プロジェクト: mindcrimer/geolead
    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)
コード例 #7
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)
コード例 #8
0
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)
コード例 #9
0
def cache_geozones():
    print('Caching geozones...')

    with transaction.atomic():
        i = 1
        users = User.objects.filter(supervisor__isnull=False,
                                    wialon_username__isnull=False,
                                    wialon_password__isnull=False).exclude(
                                        wialon_username='', wialon_password='')

        print('%s users found' % len(users))

        for user in users:
            sess_id = get_wialon_session_key(user)
            print('%s) User %s processing' % (i, user))

            routes = get_routes(sess_id, with_points=True)
            logout_session(user, sess_id)
            del sess_id

            print('%s routes found' % len(routes))

            for route in routes:
                print('Route %s' % route['name'])

                name = route['name'].strip()
                job_template, created = StandardJobTemplate.objects.get_or_create(
                    wialon_id=str(route['id']),
                    defaults={
                        'title': name,
                        'user': user
                    })

                existing_points = set()
                if not created:
                    if job_template.title != name:
                        job_template.title = name
                    job_template.user = user
                    job_template.save()

                    existing_points = {p for p in job_template.points.all()}

                # убираем дубли (когда одна и та же геозона дублируется в маршруте)
                route['points'] = {r['id']: r
                                   for r in route['points']}.values()

                print('%s points found, already exist: %s' %
                      (len(route['points']), len(existing_points)))

                for point in route['points']:
                    name = point['name'].strip()
                    standard_point, created = StandardPoint.objects.get_or_create(
                        job_template=job_template,
                        wialon_id=str(point['id']),
                        defaults={'title': name})

                    if not created:
                        existing_points.discard(standard_point)

                        if standard_point.title != name:
                            standard_point.title = name
                            standard_point.save()

                if existing_points:
                    print('Points to remove: %s' %
                          ', '.join([str(x) for x in existing_points]))
                    for existing_point in existing_points:
                        existing_point.delete()

            sleep(.3)
            i += 1
コード例 #10
0
ファイル: utils.py プロジェクト: mindcrimer/geolead
def exec_report(user,
                template_id,
                sess_id,
                dt_from,
                dt_to,
                report_resource_id=None,
                object_id=None,
                attempts=3):

    if report_resource_id is None:
        error = 'не выявлено'
        try:
            report_resource_id = get_wialon_report_resource_id(user, sess_id)
        except WialonException as e:
            error = e

        if not report_resource_id:
            raise ReportException(
                'Не удалось получить ID ресурса для пользователя %s '
                '(наименование ресурса: %s). Ошибка: %s' %
                (str(user), user.wialon_resource_name, error))

    if object_id is None:
        error = 'не выявлено'
        try:
            object_id = get_wialon_report_object_id(user, sess_id)
        except WialonException as e:
            error = e

        if not object_id:
            raise ReportException(
                'Не удалось получить ID группового объекта для пользователя %s '
                '(наименование группового объекта: %s). Ошибка: %s' %
                (str(user), user.wialon_group_object_name, error))

    # замедляем в случае чего, для прохождения лимита
    throttle_report(user)

    r = requests.post(
        settings.WIALON_BASE_URL + '?svc=report/exec_report&sid=' + sess_id, {
            'params':
            json.dumps({
                'reportResourceId': report_resource_id,
                'reportTemplateId': template_id,
                'reportTemplate': None,
                'reportObjectId': object_id,
                'reportObjectSecId': 0,
                'interval': {
                    'flags': 0,
                    'from': dt_from,
                    'to': dt_to
                }
            }),
            'sid':
            sess_id
        })

    result = load_requests_json(r)

    if 'error' in result:
        # сессия неожиданно устарела (такое очень редко и необъяснимо бывает) - отправляем еще раз
        if result['error'] == 1:
            if attempts > 1:
                # генерируем новую сессию
                sess_id = get_wialon_session_key(user, invalidate=True)
                result = exec_report(user,
                                     template_id,
                                     sess_id,
                                     dt_from,
                                     dt_to,
                                     report_resource_id=report_resource_id,
                                     object_id=object_id,
                                     attempts=attempts - 1)
                logout_session(user, sess_id)
                return result

            raise ReportException(WIALON_SESSION_EXPIRED)
        raise ReportException(WIALON_INTERNAL_EXCEPTION % result)

    return result
コード例 #11
0
ファイル: set_jobs.py プロジェクト: mindcrimer/geolead
    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)