def _get(self, *args, **kwargs): if not getattr(self, '_authorized', None) and getattr( conf, 'LEETCODE_COOKIES', False): for kw in conf.LEETCODE_COOKIES: REQ.add_cookie(**kw) setattr(self, '_authorized', True) return REQ.get(*args, **kwargs)
def _get(url, *args, **kwargs): page = REQ.get(url, *args, **kwargs) if 'document.cookie="RCPC="+toHex(slowAES.decrypt(c,2,a,b))+";' in page: matches = re.findall(r'(?P<var>[a-z]+)=toNumbers\("(?P<value>[^"]*)"\)', page) variables = {} for variable, value in matches: variables[variable] = [int(value[i:i + 2], 16) for i in range(0, len(value), 2)] size = len(variables['a']) ret = AESModeOfOperation().decrypt(variables['c'], None, 2, variables['a'], size, variables['b']) rcpc = ''.join(('0' if x < 16 else '') + hex(x)[2:] for x in map(ord, ret)) REQ.add_cookie('RCPC', rcpc) match = re.search('document.location.href="(?P<url>[^"]*)"', page) url = match.group('url') page = REQ.get(url, *args, **kwargs) REQ.save_cookie() return page
def _get_private_standings(self, users=None, statistics=None): REQ.add_cookie('session', conf.ADVENTOFCODE_SESSION, '.adventofcode.com') page = REQ.get(self.url.rstrip('/') + '.json') data = json.loads(page) year = int(data['event']) problems_infos = OrderedDict() times = defaultdict(list) def items_sort(d): return sorted(d.items(), key=lambda i: int(i[0])) result = {} total_members = len(data['members']) tz = timezone(timedelta(hours=-5)) for r in data['members'].values(): handle = r.pop('id') row = result.setdefault(handle, OrderedDict()) row['member'] = handle row['solving'] = r.pop('local_score') row['name'] = r.pop('name') row['global_score'] = r.pop('global_score') row['stars'] = r.pop('stars') ts = int(r.pop('last_star_ts')) if ts: row['last_star'] = ts solutions = r.pop('completion_day_level') problems = row.setdefault('problems', OrderedDict()) for day, solution in items_sort(solutions): if not solution: continue day = str(day) for star, res in items_sort(solution): star = str(star) k = f'{day}.{star}' if k not in problems_infos: problems_infos[k] = { 'name': day, 'code': k, 'group': day, 'subname': '*', 'subname_class': 'first-star' if star == '1' else 'both-stars', 'url': urljoin(self.url, f'/{year}/day/{day}'), '_order': (int(day), int(star)), 'visible': False } times[k].append(res['get_star_ts']) day_start_time = datetime(year=year, month=12, day=int(day), tzinfo=tz) time = datetime.fromtimestamp(res['get_star_ts'], tz=timezone.utc) problems[k] = { 'ts': res['get_star_ts'], 'time': self.to_time(time - day_start_time), 'absolute_time': self.to_time(time - day_start_time.replace(day=1)), } if not problems: result.pop(handle) for v in times.values(): v.sort() for row in result.values(): problems = row.setdefault('problems', {}) for k, p in row['problems'].items(): ts = p.pop('ts') rank = times[k].index(ts) + 1 score = total_members - rank + 1 p['time_in_seconds'] = ts p['result'] = score last = None for idx, r in enumerate(sorted(result.values(), key=lambda r: -r['solving']), start=1): if r['solving'] != last: last = r['solving'] rank = idx r['place'] = rank problems = list( sorted(problems_infos.values(), key=lambda p: p['_order'])) for p in problems: p.pop('_order') ret = { 'hidden_fields': {'last_star', 'stars', 'ranks'}, 'result': result, 'fields_types': { 'last_star': ['timestamp'] }, 'problems': problems, } now = datetime.now(tz=tz) if now.year == year and now.month == 12: start = now.replace(hour=0, minute=0, second=0) delta = start - now if delta < timedelta(): delta += timedelta(days=1, seconds=42) if delta > timedelta(hours=23): delta = timedelta(minutes=5) else: delta = min(delta, timedelta(hours=4)) ret['timing_statistic_delta'] = delta return ret