示例#1
0
def dialog(request, user):
    """
    Display new workpage for user (with new dialog to check)
    """
    log_record(user, request)
    topics = {x.topic_name: sorted([y.subtopic_name for y in x.subtopic_set.filter(active=True).all()]) for x in
              Topic.objects.filter(active=True)}
    # use cache to ensure that user receives the same record until he processes it or inactive for time X
    cached_record = cache.get(user)
    if cached_record:
        task = cached_record
    else:
        try:
            task = task_queue.get(block=False).dialog_list
        except Empty:
            return HttpResponse("<h1>Задачи закончились</h1>")
    next_record = {
        'context': {
            'customer': task['cus_id'],
            'dialog_date': task['dialog_date'],
            'dialog': sorted(task['dialog'],key=lambda d: (d['dialog_time'],d['event_id']))
        },
        'topics': sorted(topics.keys()),
        'topic_meta': topics,
    }
    cache.set(user, task)
    # set TTL for cached task
    cache.touch(user, 60 * 60 * 2)
    return render(request, 'intent_marker/dialog.html', next_record, RequestContext(request))
示例#2
0
    def test_img(self):
        """проверяем наличие тега img на странице поста, группе, профиле, главной странице"""
        url_reverse = [
            reverse("profile", args=[self.user]),
            reverse("group_posts", args=[self.group_1.slug]),
            reverse("index"),
        ]
        url = reverse("post_edit", args=[self.user, self.post.id])

        img = Image.new("RGB", (50, 50), "white")
        img.save("posts/tests/test_image.jpeg")
        image = SimpleUploadedFile(
            name="test_image.jpeg",
            content=open("posts/tests/test_image.jpeg", "rb").read(),
            content_type="image/jpeg",
        )

        context = {
            "text": "Это текст публикации",
            "group": self.group_1.id,
            "image": image,
        }
        update_post = self.authorized_client.post(url, context, follow=True)

        self.assertEqual(update_post.status_code, 200)
        self.assertContains(update_post, "<img")

        cache.touch(self.key, 0)

        for url in url_reverse:
            response = self.authorized_client.get(url)
            self.img_test(response)

        os.remove("posts/tests/test_image.jpeg")
示例#3
0
def get_objects_by_id(ids, model: models.Model,
                      cache_key: str) -> models.Model:
    if type(ids) in [int, str]:
        obj = cache.get(generate_cache_id(cache_key, {"id": ids}))
        if not obj:
            obj = model.objects.get(id=ids)
            set_cache(cache_key, {"id": ids}, obj)
        else:
            cache.touch(CACHE_KEY_MAP[cache_key].format(id=ids))
        return obj

    cache_keys = [generate_cache_id(cache_key, {"id": id}) for id in ids]
    obj_caches = cache.get_many(cache_keys)
    objs = {val.id: val for _, val in obj_caches.items()}
    retrieved_objs = objs.keys()
    objs_to_get = list(set(ids) - set(retrieved_objs))
    if objs_to_get:
        model_objs = model.objects.filter(id__in=objs_to_get)
        for obj in model_objs:
            objs[obj.id] = obj
            obj_caches[generate_cache_id(cache_key, {"id": obj.id})] = obj
        cache.set_many(obj_caches)
    for key in retrieved_objs:
        cache.touch(key)
    return objs
示例#4
0
 def test_cache(self):
     key = make_template_fragment_key('index_page')
     response_old = self.authorized_client.get(reverse('index'))
     new_post = Post.objects.create(author=self.user, text='Пример поста')
     response_new = self.authorized_client.get(reverse('index'))
     cache.touch(key, 0)
     response_newest = self.authorized_client.get(reverse('index'))
     self.assertNotEqual(response_old.content, response_newest.content)
示例#5
0
 def test_cache_after_time(self):
     response_old = self.authorized_client.get(reverse('index'))
     self.authorized_client.post(reverse('new_post'),
                                 {'text': 'Новое сообщение!!!'},
                                 follow=True)
     response_new = self.authorized_client.get(reverse('index'))
     self.assertEqual(response_old.content, response_new.content)
     cache.touch(self.key, 0)
     response_newest = self.authorized_client.get(reverse('index'))
     self.assertNotEqual(response_old.content, response_newest.content)
示例#6
0
 def get(self, request):
     get_params = request.GET.get('keys')
     if get_params is None:
         # Get all available keys
         keys = cache.keys('*')
     else:
         keys = get_params.split(',')
         # Reset TTL if get params are passed
         for key in keys:
             cache.touch(key, DEFAULT_TIMEOUT)
     return Response(cache.get_many(keys), status=status.HTTP_200_OK)
示例#7
0
 def test_cache_index(self):
     """проверка работы кэширования страницы index"""
     old_response = self.authorized_client.get(reverse("index"))
     url = reverse("new_post")
     response = self.authorized_client.post(
         url, {"text": "Текст публикации", "group": self.group_1.id}, follow=True
     )
     self.assertEqual(response.status_code, 200)
     self.assertEqual(old_response.content, response.content)
     cache.touch(self.key, 0)
     new_response = self.authorized_client.get(reverse("index"))
     self.assertNotEqual(old_response.content, new_response.content)
示例#8
0
 def _get_top_actors_cached(self):
     """
     ~ 60 seconds for the first time
     Milliseconds in the subsequent times
     :return:
     """
     actors = cache.get('top_actors')
     if actors:
         cache.touch('top_actors', 3600)
     else:
         actors = self._get_top_actors_even_better()
         cache.set('top_actors', actors, 3600)
     return actors
示例#9
0
 def inner(request, *args, **kwargs):
     is_login = request.session.get('is_login', False)
     random_str_token = request.session.get('token', 'None')
     token = True if cache.get(random_str_token, False) else False
     # 设置cache中config配置文件的过期时间
     if token:
         # 获取session过期时间
         time = request.session.get_expiry_age()
         # 更新cache过期时间
         cache.touch(random_str_token, time)
     if is_login and token:
         return func(request, *args, **kwargs)
     else:
         return redirect('%s?next=%s' % (settings.LOGIN_URL, request.path))
    def test_touch(self):
        # cache.touch() updates the timeout.
        cache.set('expire1', 'very quickly', timeout=1)
        self.assertIs(cache.touch('expire1', timeout=4), True)
        time.sleep(2)
        self.assertIs(cache.has_key('expire1'), True)
        time.sleep(3)
        self.assertIs(cache.has_key('expire1'), False)
        # cache.touch() works without the timeout argument.
        cache.set('expire1', 'very quickly', timeout=1)
        self.assertIs(cache.touch('expire1'), True)
        time.sleep(2)
        self.assertIs(cache.has_key('expire1'), True)

        self.assertIs(cache.touch('nonexistent'), False)
示例#11
0
def get_values_and_reset_ttl(keys):
    payload, status_code, error = {}, 200, {}
    try:
        payload = cache.get_many(keys)
        error = dict.fromkeys({*keys} - {*payload}, "Key is not cached")
        for k in payload.keys():
            cache.touch(k, CACHE_TTL)
        if not payload:
            status_code = 204
    except ConnectionError:
        error = 'Service Unavailable'
        status_code = 503
    except Exception as e:
        error = 'Internal Server Error'
        status_code = 500
    return dict(payload), status_code, error
示例#12
0
    def test_zero_timeout(self):
        """
        Passing in zero into timeout results in a value that is not cached
        """
        cache.set('key1', 'eggs', 0)
        self.assertIsNone(cache.get('key1'))

        cache.add('key2', 'ham', 0)
        self.assertIsNone(cache.get('key2'))

        cache.set_many({'key3': 'sausage', 'key4': 'lobster bisque'}, 0)
        self.assertIsNone(cache.get('key3'))
        self.assertIsNone(cache.get('key4'))

        cache.set('key5', 'belgian fries', timeout=5)
        cache.touch('key5', timeout=0)
        self.assertIsNone(cache.get('key5'))
示例#13
0
 def touch_cache(key, time_out):
     """
     Update the expired time of key
     :param key:
     :param time_out:
     :return:
     """
     return cache.touch(key, time_out)
示例#14
0
def index_dirty(timestamp=None):
    """Index dirty documents"""

    if timestamp is None:
        # starting a new dirty index process
        timestamp = timezone.now().isoformat()
        status = cache.get_or_set("solr_index_dirty_status",
                                  timestamp,
                                  timeout=7200)
        if status != timestamp:
            logger.info(
                "[SOLR INDEX] dirty run not starting, already in progress: %s",
                status)
            # a previous run is still running, do not run two in parallel
            return

        # on initial invocation, kick off dirty deletion
        deleted = Document.objects.filter(status=Status.deleted).values_list(
            "pk", flat=True)
        deleted_count = deleted.count()
        logger.info("[SOLR DELETE] %d documents to delete", deleted_count)
        for document_pk in deleted:
            celery_app.send_task("documentcloud.documents.tasks.solr_delete",
                                 args=[document_pk])

    else:
        # continuing a dirty indexing process, keep the cache alive
        cache.touch("solr_index_dirty_status", timeout=7200)

    status = cache.get("solr_index_dirty_status")
    if status == "cancel":
        # allow for an explicit cancellation of the process
        logger.info("[SOLR INDEX] dirty run cancelled")
        return

    documents = _dirty_prepare_documents()
    tasks = _batch_by_size(None, documents)
    chord(
        tasks,
        signature(
            "documentcloud.documents.tasks.solr_index_dirty_continue",
            args=[timestamp],
            immutable=True,
        ),
    ).delay()
示例#15
0
 def touch_view(self, request, object_id, extra_context=None):
     opts = self.model._meta
     msg_dict = {
         'name':
         opts.verbose_name,
         'obj':
         format_html('<a href="{}">{}</a>', urlquote(request.path),
                     object_id),
     }
     if cache.ttl(object_id) >= 3600:
         msg = format_html(
             'The {name} "{obj}" was touched unsuccessfully. (The default timeout is too small.)',
             **msg_dict)
         self.message_user(request, msg, messages.WARNING)
     else:
         cache.touch(object_id, 3600)
         msg = format_html('The {name} "{obj}" was touched successfully.',
                           **msg_dict)
         self.message_user(request, msg, messages.SUCCESS)
     return redirect('/admin/cache_manager/cache_server/')
    def touch(self, key, timeout):
        """
        Update the timeout for a given key in the cache.

        Returns True if the cache key was updated.

        This functionality is available in Django 2.1 and above.
        """
        if hasattr(cache, 'touch'):
            return cache.touch(key, timeout=timeout)
        return False
示例#17
0
    def test_forever_timeout(self):
        """
        Passing in None into timeout results in a value that is cached forever
        """
        cache.set('key1', 'eggs', None)
        self.assertEqual(cache.get('key1'), 'eggs')

        cache.add('key2', 'ham', None)
        self.assertEqual(cache.get('key2'), 'ham')
        added = cache.add('key1', 'new eggs', None)
        self.assertIs(added, False)
        self.assertEqual(cache.get('key1'), 'eggs')

        cache.set_many({'key3': 'sausage', 'key4': 'lobster bisque'}, None)
        self.assertEqual(cache.get('key3'), 'sausage')
        self.assertEqual(cache.get('key4'), 'lobster bisque')

        cache.set('key5', 'belgian fries', timeout=1)
        cache.touch('key5', timeout=None)
        time.sleep(2)
        self.assertEqual(cache.get('key5'), 'belgian fries')
示例#18
0
    def get_queryset(self):
        queryset = models.Member.objects.all()
        search = self.request.data.get('q', '').lower()

        if not cache.touch('search_strings'):
            utils.gen_search_strings()  # init cache

        search_strings = cache.get('search_strings', {})

        if len(search):
            choices = search_strings.keys()

            # get exact starts with matches
            results = [x for x in choices if x.startswith(search)]
            # then get exact substring matches
            results += [x for x in choices if search in x]

            if len(results) == 0 and len(search) >= 3:
                # then get fuzzy matches
                fuzzy_results = process.extract(search,
                                                choices,
                                                limit=NUM_SEARCH_RESULTS,
                                                scorer=fuzz.token_set_ratio)
                results += [x[0] for x in fuzzy_results]

            # remove dupes, truncate list
            results = list(OrderedDict.fromkeys(results))[:NUM_SEARCH_RESULTS]

            result_ids = [search_strings[x] for x in results]
            result_objects = [queryset.get(id=x) for x in result_ids]

            queryset = result_objects
        elif self.action == 'create':
            utils.gen_search_strings()  # update cache
            queryset = queryset.order_by('-vetted_date')

        return queryset
示例#19
0
def ingress_request(
    service_uuid,
    tracker,
    time,
    payload,
    ip,
    location,
    user_agent,
    dnt=False,
    identifier="",
):
    try:
        service = Service.objects.get(pk=service_uuid, status=Service.ACTIVE)
        log.debug(f"Linked to service {service}")

        if dnt and service.respect_dnt:
            return

        # Validate payload
        if payload.get("loadTime", 1) <= 0:
            payload["loadTime"] = None

        association_id_hash = sha1()
        association_id_hash.update(str(ip).encode("utf-8"))
        association_id_hash.update(str(user_agent).encode("utf-8"))
        session_cache_path = (
            f"session_association_{service.pk}_{association_id_hash.hexdigest()}"
        )

        # Create or update session
        session = None
        if cache.get(session_cache_path) is not None:
            cache.touch(session_cache_path, settings.SESSION_MEMORY_TIMEOUT)
            session = Session.objects.filter(pk=cache.get(session_cache_path),
                                             service=service).first()
        if session is None:
            initial = True

            log.debug("Cannot link to existing session; creating a new one...")

            ip_data = _geoip2_lookup(ip)
            log.debug(f"Found geoip2 data...")

            ua = user_agents.parse(user_agent)
            device_type = "OTHER"
            if (ua.is_bot
                    or (ua.browser.family or "").strip().lower() == "googlebot"
                    or (ua.device.family or ua.device.model
                        or "").strip().lower() == "spider"):
                device_type = "ROBOT"
            elif ua.is_mobile:
                device_type = "PHONE"
            elif ua.is_tablet:
                device_type = "TABLET"
            elif ua.is_pc:
                device_type = "DESKTOP"
            session = Session.objects.create(
                service=service,
                ip=ip if service.collect_ips else None,
                user_agent=user_agent,
                identifier=identifier.strip(),
                browser=ua.browser.family or "",
                device=ua.device.family or ua.device.model or "",
                device_type=device_type,
                os=ua.os.family or "",
                asn=ip_data.get("asn", ""),
                country=ip_data.get("country", ""),
                longitude=ip_data.get("longitude"),
                latitude=ip_data.get("latitude"),
                time_zone=ip_data.get("time_zone", ""),
            )
            cache.set(session_cache_path,
                      session.pk,
                      timeout=settings.SESSION_MEMORY_TIMEOUT)
        else:
            initial = False

            log.debug("Updating old session with new data...")

            # Update last seen time
            session.last_seen = timezone.now()
            if session.identifier == "" and identifier.strip() != "":
                session.identifier = identifier.strip()
            session.save()

        # Create or update hit
        idempotency = payload.get("idempotency")
        idempotency_path = f"hit_idempotency_{idempotency}"
        hit = None

        if idempotency is not None:
            if cache.get(idempotency_path) is not None:
                cache.touch(idempotency_path, settings.SESSION_MEMORY_TIMEOUT)
                hit = Hit.objects.filter(pk=cache.get(idempotency_path),
                                         session=session).first()
                if hit is not None:
                    # There is an existing hit with an identical idempotency key. That means
                    # this is a heartbeat.
                    log.debug(
                        "Hit is a heartbeat; updating old hit with new data..."
                    )
                    hit.heartbeats += 1
                    hit.last_seen = timezone.now()
                    hit.save()

        if hit is None:
            log.debug("Hit is a page load; creating new hit...")
            # There is no existing hit; create a new one
            hit = Hit.objects.create(
                session=session,
                initial=initial,
                tracker=tracker,
                # At first, location is given by the HTTP referrer. Some browsers
                # will send the source of the script, however, so we allow JS payloads
                # to include the location.
                location=payload.get("location", location),
                referrer=payload.get("referrer", ""),
                load_time=payload.get("loadTime"),
            )
            # Set idempotency (if applicable)
            if idempotency is not None:
                cache.set(idempotency_path,
                          hit.pk,
                          timeout=settings.SESSION_MEMORY_TIMEOUT)
    except Exception as e:
        log.exception(e)
        raise e
示例#20
0
def search(request):

    start_time = time.time()

    body = request.data

    player_name = body.get('player_name', None)
    platform = body.get('platform', None)

    player_response_cache_key = api_settings.PLAYER_RESPONSE_CACHE_KEY.format(
        player_name, platform)

    cached_player_response = cache.get(player_response_cache_key, None)

    if cached_player_response and 'data' in cached_player_response:
        return Response(cached_player_response)

    player_request_cache_key = api_settings.PLAYER_REQUEST_CACHE_KEY.format(
        player_name, platform)
    player_platform_url_cache_key = api_settings.PLAYER_PLATFORM_URL_CACHE_KEY.format(
        player_name, platform)
    player_player_url_cache_key = api_settings.PLAYER_URL_CACHE_KEY.format(
        player_name, platform)

    cached_platform_url = cache.get(player_platform_url_cache_key, None)
    cached_player_request = cache.get(player_request_cache_key, None)

    if not cached_platform_url:
        platform_url = build_url(platform)
        cache.set(player_platform_url_cache_key, platform_url, 60 * 30)
    else:
        platform_url = cached_platform_url

    cached_player_url = cache.get(player_player_url_cache_key, None)

    if not cached_player_url:
        player_url = build_player_url(base_url=platform_url,
                                      player_name=player_name)
        cache.set(player_player_url_cache_key, player_url, 60 * 30)
    else:
        player_url = cached_player_url

    if not cached_player_request or 'data' not in cached_player_request:
        player_request = make_request(player_url)

        if 'data' not in player_request:
            potential_current_player = Participant.objects.filter(
                player_name=player_name)
            if potential_current_player.exists():
                potential_current_player = potential_current_player.first()
                player_url = potential_current_player.player.api_url
                player_request = make_request(player_url)

        cache.set(cached_player_request, player_request, 120)
    else:
        player_request = cached_player_request

    ajax_data = {}

    player_data_length = 0

    if 'data' in player_request:

        api_ids = list(
            set(Match.objects.values_list('api_id', flat=True).distinct()))

        if isinstance(player_request['data'], list):
            player_id = player_request['data'][0]['id']
            player_data_length = (len(
                player_request['data'][0]['relationships']['matches']['data']
            ), [
                match['id'] for match in player_request['data'][0]
                ['relationships']['matches']['data']
                if get_player_match_id(player_id, match['id']) not in api_ids
            ])
        else:
            player_id = player_request['data']['id']
            player_data_length = (len(
                player_request['data']['relationships']['matches']['data']), [
                    match['id']
                    for match in player_request['data']['relationships']
                    ['matches']['data'] if get_player_match_id(
                        player_id, match['id']) not in api_ids
                ])

        if player_data_length[0] > 0:

            ajax_data['player_id'] = player_id
            ajax_data['player_name'] = player_name

            length_of_matches = len(player_data_length[1])

            if length_of_matches > 0:

                player_currently_processing_cache_key = api_settings.PLAYER_CURRENTLY_PROCESSING_CACHE_KEY.format(
                    player_id, platform)
                currently_processing = cache.get(
                    player_currently_processing_cache_key, None)

                if not currently_processing:
                    cache.set(player_currently_processing_cache_key, True, 60)
                    ajax_data['currently_processing'] = True
                    thread = threading.Thread(target=get_player_matches,
                                              kwargs={
                                                  'platform_url': platform_url,
                                                  'player_response':
                                                  player_request
                                              })
                    thread.daemon = True
                    thread.start()
                else:
                    ajax_data['currently_processing'] = False

            else:
                ajax_data[
                    'message'] = "No new matches to process for this user."
                ajax_data['no_new_matches'] = True
                if cached_player_url:
                    cache.touch(player_player_url_cache_key, 120)
                if cached_platform_url:
                    cache.touch(player_platform_url_cache_key, 120)
                if cached_player_request:
                    cache.touch(player_request_cache_key, 120)

        else:
            ajax_data[
                'error'] = "Sorry, looks like this player has not played any matches in the last 14 days."

    else:
        ajax_data['error'] = "Sorry, looks like this player does not exist."

    cache.set(player_response_cache_key, ajax_data, 120)
    return Response(ajax_data)
示例#21
0
def index(request):
    keys = request.GET.get('keys', None)
    if request.method == "GET" and not keys:
        data_keys = cache.keys('*')
        data = cache.get_many(data_keys)

        if len(data):
            cache.touch(data_keys, settings.CACHE_TTL)

        return HttpResponse(json.dumps(data), status=status.HTTP_200_OK)

    elif request.method == "GET" and keys:
        try:
            keys = keys.split(",")
            data = cache.get_many(keys)

            if len(data) == 0:
                return HttpResponse(json.dumps(data),
                                    status=status.HTTP_404_NOT_FOUND)
            elif len(data) != len(keys):
                cache.touch(keys, settings.CACHE_TTL)
                return HttpResponse(json.dumps(data),
                                    status=status.HTTP_207_MULTI_STATUS)
            else:
                cache.touch(keys, settings.CACHE_TTL)
                return HttpResponse(json.dumps(data),
                                    status=status.HTTP_200_OK)
        except Exception:
            return HttpResponse("Unprocessable Entity.",
                                status=status.HTTP_400_BAD_REQUEST)

    elif request.method == "POST":
        try:
            data = json.loads(request.body)
            failed_keys = cache.set_many(data, settings.CACHE_TTL)

            if failed_keys:
                return HttpResponse("Keys {} have not saved.".format(
                    failed_keys, data),
                                    status=status.HTTP_207_MULTI_STATUS)

            return HttpResponse("Data  {}, saved successfully.".format(data),
                                status=status.HTTP_201_CREATED)

        except Exception:
            return HttpResponse("Unprocessable Entity.",
                                status=status.HTTP_400_BAD_REQUEST)

    elif request.method == "PATCH":
        try:
            data = json.loads(request.body)
            failed_keys = cache.set_many(data, settings.CACHE_TTL)

            if failed_keys:
                return HttpResponse("Keys {} have not updated.".format(
                    failed_keys, data),
                                    status=status.HTTP_207_MULTI_STATUS)

            return HttpResponse("Data  {}, updated successfully.".format(data),
                                status=status.HTTP_202_ACCEPTED)

        except Exception:
            return HttpResponse("Unprocessable Entity.",
                                status=status.HTTP_400_BAD_REQUEST)
示例#22
0
    def receive(self, text_data):
        text_data_json = json.loads(text_data)

        if text_data_json['action'] == 'claim_color':
            color = Move.Color[text_data_json['color']]

            # Did they ask for a valid color?
            if not color:
                self.send(text_data=json.dumps({
                    'error': 'INVALID_COLOR',
                }))
                return

            cache_val = self.get_color_players()

            # Is the color available?
            if cache_val.get(
                    color) and cache_val.get(color) != self.player_identifier:
                self.send(text_data=json.dumps({
                    'error': 'COLOR_UNAVAILABLE',
                }))
                return

            #.Is the color on an opposing team?
            if not 'on the same team':
                self.send(text_data=json.dumps({
                    'error': 'OPPOSING_TEAM',
                }))
                return

            # Set that color-player in the db and the cache
            if self.scope['user'].is_authenticated:
                GamePlayer.objects.create(
                    game=Game.objects.get(uid=self.game_uid),
                    player=self.scope['user'],
                    color=color)
            cache_val[color] = self.player_identifier

            cache.set('game_%s_colors' % self.game_uid, cache_val, 3600)

            async_to_sync(self.channel_layer.group_send)(
                self.group_name, {
                    'type': 'broadcast_color_players',
                    'color_players': cache_val,
                })
        elif text_data_json['action'] == 'release_color':
            color = Move.Color[text_data_json['color']]

            cache_val = self.get_color_players()

            # Does the player control that color?
            if cache_val.get(color) != self.player_identifier:
                self.send(text_data=json.dumps({
                    'error': 'NOT_YOUR_COLOR',
                }))
                return

            # Delete that color-player from the db and the cache
            if self.scope['user'].is_authenticated:
                GamePlayer.objects.get(color=color,
                                       game__uid=self.game_uid).delete()
            del cache_val[color]

            cache.set('game_%s_colors' % self.game_uid, cache_val, 3600)

            async_to_sync(self.channel_layer.group_send)(
                self.group_name, {
                    'type': 'broadcast_color_players',
                    'color_players': cache_val,
                })
        elif text_data_json['action'] == 'release_all_colors':
            # Is this the game author?
            if self.scope['user'] != Game.objects.get(
                    uid=self.game_uid).author:
                self.send(text_data=json.dumps({
                    'error': 'NO_PERMISSION',
                }))
                return

            GamePlayer.objects.filter(game__uid=self.game_uid).delete()
            cache.delete('game_%s_colors' % self.game_uid)

            async_to_sync(self.channel_layer.group_send)(self.group_name, {
                'type': 'broadcast_color_players',
                'color_players': {},
            })
        elif text_data_json['action'] == 'make_move':
            game = Game.objects.get(uid=self.game_uid)
            hfen = game.hfen

            # Does the player's HFEN match the game's current HFEN?
            if text_data_json['hfen'] != hfen:
                self.send(text_data=json.dumps({
                    'error': 'OUTDATED_HFEN',
                    'hfen': hfen,
                }))
                return

            # Is it that color's turn?
            color = text_data_json['color']
            expected_color = hfen.split(' ')[1]
            if color != expected_color:
                self.send(
                    text_data=json.dumps({
                        'error': 'OUT_OF_TURN',
                        'color': color,
                        'expected_color': expected_color,
                    }))
                return

            # Does the player control that color?
            if False:
                #.todo
                self.send(text_data=json.dumps({
                    'error': 'NOT_YOUR_COLOR',
                    'color': color,
                }))
                return

            # Is the game over?
            state = Game.state_from_hfen(hfen)
            if state.is_terminal():
                self.send(text_data=json.dumps({
                    'error': 'GAME_OVER',
                }))
                return

            # Is the move legal?
            q = text_data_json['q']
            r = text_data_json['r']
            if (q, r) not in state.get_legal_moves():
                self.send(text_data=json.dumps({
                    'error': 'ILLEGAL_MOVE',
                }))
                return

            # Make the move
            move = Move()
            move.game = game
            if self.scope['user'].is_authenticated:
                move.player = self.scope['user']
            move.color = color
            move.q = q
            move.r = r
            move.save()

            # Renew the color-player cache
            cache.touch('game_%s_colors' % self.game_uid, 3600)

            state = state.make_move((q, r))
            hfen = state.hfen

            # Is the game over?
            if state.did_win():
                async_to_sync(self.channel_layer.group_send)(
                    self.group_name, {
                        'type': 'broadcast_game_over',
                        'result': 'RYGCBM'[state.prev_color_idx],
                    })

                # Delete the color-player cache
                cache.delete('game_%s_colors' % self.game_uid)
            elif len(state.get_legal_moves()) == 0:
                async_to_sync(self.channel_layer.group_send)(self.group_name, {
                    'type': 'broadcast_game_over',
                    'result': 'DRAW',
                })

                # Delete the color-player cache
                cache.delete('game_%s_colors' % self.game_uid)

            # Broadcast the new HFEN to everyone
            async_to_sync(self.channel_layer.group_send)(
                self.group_name, {
                    'type': 'broadcast_hfen',
                    'hfen': hfen,
                    'move': [move.color, move.q, move.r],
                })
示例#23
0
 def test_touch_with_timeout(self):
     cache.set("key1", "spam", timeout=0.1)
     cache.touch("key1")
     time.sleep(0.2)
     assert "key1" in cache
示例#24
0
def table(request):
    if not request.user.is_authenticated:
        return HttpResponse("Vous n'êtes pas connecté", status=403)

    params = parse(request)
    table_name = params["table_name"]
    last_draw = request.GET.get('draw', "0")  # 1 ?
    json_object = {
        "draw": str(int(last_draw) + 1),
        "editable": True,  # custom field, true to display edit/delete buttons
        "data": []
    }

    cache_key = table_name + request.user.username
    cache_result = cache.get(cache_key) if table_name != "payment" else None

    if cache_result:
        result = json.loads(cache_result)
        cache.touch(cache_key, 60)
    elif table_name == "water_element":
        if is_user_fountain(request):
            json_object["editable"] = False
        result = get_water_elements(request)
    elif table_name == "consumer":
        result = get_consumer_elements(request)
    elif table_name == "zone":
        if is_user_fountain(request):
            return HttpResponse(
                "Vous ne pouvez pas accéder à ces informations", status=403)
        result = get_zone_elements(request)
    elif table_name == "manager":
        if is_user_fountain(request):
            return HttpResponse(
                "Vous ne pouvez pas accéder à ces informations", status=403)
        result = get_manager_elements(request)
    elif table_name == "report":
        if is_user_zone(request):
            return HttpResponse(
                "Vous ne pouvez pas accéder à ces informations", status=403)
        result = get_last_reports(request)
    elif table_name == "ticket":
        result = get_ticket_elements(request)
    elif table_name == "logs":
        result = get_logs_elements(request, archived=False)
    elif table_name == "logs_history":
        result = get_logs_elements(request, archived=True)
    elif table_name == "payment":
        if is_user_fountain(request):
            json_object["editable"] = False
        result = get_payment_elements(request)
        if result is None:
            return success_200
    elif table_name == "consumer_full":
        result = get_all_details_consumers(request)
    elif table_name == "all_payment":
        if is_user_fountain(request):
            json_object["editable"] = False
        result = get_all_payments(request)
    else:
        return HttpResponse("Impossible de charger la table demandée (" +
                            table_name + ").",
                            status=404)

    if result is None:
        return HttpResponse("Problème à la récupération des données",
                            status=400)

    cache.set(cache_key, json.dumps(result), 60)
    json_object["recordsTotal"] = len(result)

    if request.GET.get('indexDB', None) == "true":
        json_object["data"] = result
        return HttpResponse(json.dumps(json_object), status=200)

    filtered = filter_search(params, result)

    if table_name == "logs" or table_name == "logs_history" or table_name == "report":
        if len(filtered) > 1:
            keys = list(filtered[0].keys())
            final = sorted(filtered,
                           key=lambda x: x[keys[params["column_ordered"]]],
                           reverse=params["type_order"] != "asc")
        else:
            final = filtered
    else:
        final = sorted(filtered,
                       key=lambda x: x[params["column_ordered"]],
                       reverse=params["type_order"] != "asc")

    if params["length_max"] == -1:
        json_object["data"] = final
    else:
        start = params["start"]
        stop = start + params["length_max"]
        json_object["data"] = final[start:stop]

    json_object["recordsFiltered"] = len(final)
    return HttpResponse(json.dumps(json_object), status=200)
示例#25
0
def ingress_request(service_uuid,
                    tracker,
                    time,
                    payload,
                    ip,
                    location,
                    user_agent,
                    dnt=False,
                    identifier=""):
    try:
        service = Service.objects.get(pk=service_uuid, status=Service.ACTIVE)
        log.debug(f"Linked to service {service}")

        if dnt and service.respect_dnt:
            return

        ip_data = _geoip2_lookup(ip)
        log.debug(f"Found geoip2 data")

        # Validate payload
        if payload.get("loadTime", 1) <= 0:
            payload["loadTime"] = None

        # Create or update session
        session = (
            Session.objects.filter(
                service=service,
                last_seen__gt=timezone.now() - timezone.timedelta(minutes=10),
                ip=ip,
                user_agent=user_agent,
            ).first()
            # We used to check for identifiers, but that can cause issues when people
            # re-open the page in a new tab, for example. It's better to match sessions
            # solely based on IP and user agent.
        )
        if session is None:
            log.debug("Cannot link to existing session; creating a new one...")
            ua = user_agents.parse(user_agent)
            initial = True
            device_type = "OTHER"
            if (ua.is_bot
                    or (ua.browser.family or "").strip().lower() == "googlebot"
                    or (ua.device.family or ua.device.model
                        or "").strip().lower() == "spider"):
                device_type = "ROBOT"
            elif ua.is_mobile:
                device_type = "PHONE"
            elif ua.is_tablet:
                device_type = "TABLET"
            elif ua.is_pc:
                device_type = "DESKTOP"
            session = Session.objects.create(
                service=service,
                ip=ip,
                user_agent=user_agent,
                identifier=identifier.strip(),
                browser=ua.browser.family or "",
                device=ua.device.family or ua.device.model or "",
                device_type=device_type,
                os=ua.os.family or "",
                asn=ip_data.get("asn", ""),
                country=ip_data.get("country", ""),
                longitude=ip_data.get("longitude"),
                latitude=ip_data.get("latitude"),
                time_zone=ip_data.get("time_zone", ""),
            )
        else:
            log.debug("Updating old session with new data...")
            initial = False
            # Update last seen time
            session.last_seen = timezone.now()
            if session.identifier == "" and identifier.strip() != "":
                session.identifier = identifier.strip()
            session.save()

        # Create or update hit
        idempotency = payload.get("idempotency")
        idempotency_path = f"hit_idempotency_{idempotency}"
        hit = None
        if idempotency is not None:
            if cache.get(idempotency_path) is not None:
                cache.touch(idempotency_path, 10 * 60)
                hit = Hit.objects.filter(pk=cache.get(idempotency_path),
                                         session=session).first()
                if hit is not None:
                    # There is an existing hit with an identical idempotency key. That means
                    # this is a heartbeat.
                    log.debug(
                        "Hit is a heartbeat; updating old hit with new data..."
                    )
                    hit.heartbeats += 1
                    hit.last_seen = timezone.now()
                    hit.save()
        if hit is None:
            log.debug("Hit is a page load; creating new hit...")
            # There is no existing hit; create a new one
            hit = Hit.objects.create(
                session=session,
                initial=initial,
                tracker=tracker,
                # At first, location is given by the HTTP referrer. Some browsers
                # will send the source of the script, however, so we allow JS payloads
                # to include the location.
                location=payload.get("location", location),
                referrer=payload.get("referrer", ""),
                load_time=payload.get("loadTime"),
            )
            # Set idempotency (if applicable)
            if idempotency is not None:
                cache.set(idempotency_path, hit.pk, timeout=10 * 60)
    except Exception as e:
        log.exception(e)
        raise e
示例#26
0
 def test_touch_already_expired(self):
     cache.set("key1", "spam", timeout=0.1)
     time.sleep(0.2)
     cache.touch("key1", timeout=0.4)
     assert "key1" not in cache
示例#27
0
 def touch(self, using=None, keep_parents=False):
     if cache.ttl(self.key) >= self.timeout:
         # print("The default timeout is too small, touch unsuccessfully.")
         return False
     else:
         return cache.touch(self.key, self.timeout)