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))
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")
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
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)
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)
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)
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)
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
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)
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
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'))
def touch_cache(key, time_out): """ Update the expired time of key :param key: :param time_out: :return: """ return cache.touch(key, time_out)
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()
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
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')
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
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
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)
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)
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], })
def test_touch_with_timeout(self): cache.set("key1", "spam", timeout=0.1) cache.touch("key1") time.sleep(0.2) assert "key1" in cache
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)
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
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
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)