def getAjaxResponse(*args, login_data, isAjax=True, timeout=3600, additionalCacheKey=None, **params): key = get_cache_key(login_data, *args, additionalCacheKey=additionalCacheKey, **params) resp_str = redis.get(key) resp = json.loads(resp_str.decode('utf-8')) if resp_str else None if not resp or not timeout: relogin = False while True: (success, cookies) = login(login_data, updateCache=relogin) if not success: return cookies, None try: if isAjax: resp = cc_func(*args, cookies=cookies, login_data=login_data, params=params) else: resp = cc_api(*args, cookies=cookies, login_data=login_data, params=params) except Exception as e: resp_str = redis.get(key + "_latest") if resp_str: resp_time = float(redis.get(key + "_latest:time")) resp = json.loads(resp_str.decode('utf-8')) msg = f'Server unavailable. Data is from {datetime.fromtimestamp(resp_time)}' return msg, resp['data'] else: return "Error: Server unavailable!", None if resp['status'] == 'success': break elif relogin: break else: # retry relogin = True if resp['status'] != 'success' or 'data' not in resp: if 'message' in resp: return resp['message'], None else: return str(resp), None else: resp_str = json.dumps(resp) redis.set(key, resp_str, ex=timeout) redis.set(key + "_latest", resp_str) redis.set(key + "_latest:time", datetime.now().timestamp()) return None, resp['data']
def _loadCache(self, key): entr_str = redis.get(key) return pickle.loads(entr_str) if entr_str else None
def message(update, context): bot = context.bot user_id = update.message.from_user.id login_key = get_user_login_key(user_id) login_data_str = redis.get(login_key) text = update.message.text if login_data_str: login_data = json.loads(login_data_str) else: # not logged in, check if login data sent and don't continue afterwards check_login(context, update, text) return bot.send_chat_action(chat_id=update.message.chat_id, action=telegram.ChatAction.TYPING) mode = redis.get(mode_key(update)) if mode: mode = mode.decode('UTF-8') # print(f"In mode {mode}") redis.delete(mode_key(update)) if mode == 'calendar': calendar(context, update, login_data, mode_key(update), text) elif mode == 'rooms': if text in RAUM_ZEIT_MARKUP: cur_time_markup = [[f'{text}: {r}'] for r in room_markup] send_message(context, update, "Welche Räume?", telegram.ParseMode.HTML, ReplyKeyboardMarkup(cur_time_markup)) elif text in RAUM_EXTENDED_MARKUP: redis.set(mode_key(update), 'room_search') send_message( context, update, "Gib den Namen der Raumbelegung (oder einen Teil ein):", None, EMPTY_MARKUP) elif mode == 'song': (success, res) = songs.search(login_data, text) if success: for msg in res: send_message(context, update, msg, telegram.ParseMode.HTML, mainMarkup()) else: send_message(context, update, res, None, mainMarkup()) elif mode == 'person': success = person(context, update, text, mainMarkup(), login_data) if success is False: redis.set(mode_key(update), mode) elif mode == 'group': group(context, update, text, mainMarkup(), login_data=login_data) elif mode == 'room_search': msgs = parseRaeumeByText(login_data, text) for msg in msgs: send_message(context, update, msg, telegram.ParseMode.HTML, mainMarkup()) elif mode == 'calendar_search': try: msgs = parseCalendarByText(login_data, text) for msg in msgs: send_message(context, update, msg, telegram.ParseMode.HTML, mainMarkup()) except Exception as e: eMsg = ''.join( traceback.format_exception(type(e), e, e.__traceback__)) msg = f"Failed!\nException: {eMsg}" logger.error(msg) send_message(context, update, msg, None, mainMarkup()) elif mode == 'signup': parse_signup(context, update, login_data, mainMarkup(), text) else: # no special mode m1 = re.match('([A-Za-z0-9äöü ]+): ([A-Za-zäöü]+)', text) m2 = re.match('/dl_([0-9]+)_([0-9]+)', text) mPerson = re.match('/P([0-9]+)', text) mPersonContact = re.match('/C([0-9]+)', text) mGroup = re.match('/G([0-9]+)', text) mEvent = re.match('/E([0-9]+)', text) mQR = re.match('/Q([0-9]+)', text) mAgenda = re.match('/A([0-9]+)', text) mSong1 = re.match('/S([0-9]+)$', text) mSong2 = re.match('/S([0-9]+)_([0-9]+)', text) if m1: zeit = m1.group(1) room = m1.group(2) if m1 and zeit in RAUM_ZEIT_MARKUP and room in room_markup: try: if zeit == 'Heute': msgs = parseRaeumeByTime(login_data, room, dayRange=0) elif zeit == 'Nächste 7 Tage': msgs = parseRaeumeByTime(login_data, room, dayRange=7) elif zeit == 'Morgen': msgs = parseRaeumeByTime(login_data, room, dayRange=0, dayOffset=1) for msg in msgs: send_message(context, update, msg, telegram.ParseMode.HTML, mainMarkup()) except Exception as e: eMsg = ''.join( traceback.format_exception(type(e), e, e.__traceback__)) msg = f"Failed!\nException: {eMsg}" logger.error(msg) send_message(context, update, msg, None, mainMarkup()) elif m2: song_id = m2.group(1) file_id = m2.group(2) song(context, update, file_id, login_data, mainMarkup(), song_id) elif mPerson: person(context, update, text, mainMarkup(), login_data) elif mPersonContact: person(context, update, text, mainMarkup(), login_data, contact=True) elif mGroup: group(context, update, text, mainMarkup(), login_data=login_data) elif mEvent: g_id = mEvent.group(1) print_event(context, update, g_id, login_data, mainMarkup()) elif mQR: g_id = mQR.group(1) qr = groups.get_qrcode(login_data, g_id) if qr: try: bot.send_photo(update.effective_chat.id, photo=qr, caption="QR-Code fürs Check-In", parse_mode=telegram.ParseMode.HTML, reply_markup=mainMarkup(), timeout=30) except Exception as e: send_message( context, update, "<i>Konnte QR-Code nicht senden :(</i>\n" + str(e), telegram.ParseMode.HTML, mainMarkup()) else: send_message(context, update, "<i>Konnte QR-Code nicht abrufen :(</i>\n", telegram.ParseMode.HTML, mainMarkup()) elif mSong1 or mSong2: try: arrId = None if mSong1: songid = mSong1.group(1) else: songid = mSong2.group(1) arrId = mSong2.group(2) (success, msg) = songs.byID(login_data, song_id=songid, arrangement_id=arrId) send_message(context, update, msg, telegram.ParseMode.HTML, mainMarkup()) except Exception as e: eMsg = ''.join( traceback.format_exception(type(e), e, e.__traceback__)) msg = f"Failed!\nException: {eMsg}" logger.error(msg) send_message(context, update, msg, None, mainMarkup()) elif mAgenda: a_id = mAgenda.group(1) agenda(context, update, login_data, a_id, mainMarkup()) elif text == MARKUP_ROOMS: redis.set(mode_key(update), 'rooms') send_message( context, update, "Welcher Zeitraum?", telegram.ParseMode.HTML, ReplyKeyboardMarkup([RAUM_ZEIT_MARKUP, RAUM_EXTENDED_MARKUP])) elif text == MARKUP_CALENDAR: redis.set(mode_key(update), 'calendar') send_message( context, update, "Welcher Zeitraum?", telegram.ParseMode.HTML, ReplyKeyboardMarkup([RAUM_ZEIT_MARKUP, RAUM_EXTENDED_MARKUP])) elif text == MARKUP_BIRTHDAYS: try: msg = parseGeburtstage(login_data=login_data) send_message(context, update, msg, telegram.ParseMode.HTML, mainMarkup()) except Exception as e: msg = f"Failed!\nException: {e}" logger.error(msg) send_message(context, update, msg, None, mainMarkup()) elif text == MARKUP_SONGS: redis.set(mode_key(update), 'song') send_message(context, update, "Gib den Namen/Author (oder einen Teil davon ein):", None, EMPTY_MARKUP) elif text == MARKUP_PEOPLE: redis.set(mode_key(update), 'person') send_message( context, update, "Gib den Namen (oder einen Teil ein) oder eine Telefonnumer ein:", None, EMPTY_MARKUP) elif text == MARKUP_GROUPS: redis.set(mode_key(update), 'group') send_message(context, update, "Gib den Namen (oder einen Teil ein):", None, EMPTY_MARKUP) elif text == MARKUP_EVENTS: list_events(context, login_data, mainMarkup(), update) else: send_message( context, update, "Unbekannter Befehl, du kannst einen der Buttons unten nutzen", None, mainMarkup())
def login(login_data=None, updateCache=False, login_token=False): key = get_cache_key(login_data, 'login_cookies', usePerson=True) cookies_pickle = redis.get(key) cookies = pickle.loads(cookies_pickle) if cookies_pickle else None # Check if session cookie still valid if cookies and not updateCache: data = cc_func('resource', 'pollForNews', cookies, login_data=login_data) if not data or 'data' not in data: cookies = None else: data = data['data'] userid = data['userid'] if not userid or userid == -1: cookies = None if not cookies or updateCache: # need to login using permanent login key logger.info(f"Cookie is invalid for {login_data['personid']}") key_token = get_cache_key(login_data, 'login_token', usePerson=True) login_key_pickle = redis.get(key_token) login_key = pickle.loads( login_key_pickle) if login_key_pickle else None resp1 = requests.head(login_data['url']) cookies = resp1.cookies if not login_key or login_token: # login key not valid, try login token logger.info( f"Getting new login token for {login_data['personid']}") login_url = urljoin( login_data['url'], f"?q=profile&loginstr={login_data['token']}&id={login_data['personid']}" ) resp = requests.get(login_url, cookies=cookies) if 'Der verwendete Login-Link ist nicht mehr aktuell und kann deshalb nicht mehr verwendet werden.' in resp.text: redis.delete(get_user_login_key(login_data['telegramid'])) return False, 'Login fehlgeschlagen, versuchs es mit einem neuen Link.' else: # get new login key & cookies using login token data = cc_api(f'persons/{login_data["personid"]}/logintoken', cookies=cookies, login_data=login_data, returnJson=True) if data['status'] == 'success': inner_data = data['data'] # cookies = resp.cookies.get_dict() redis.set(key_token, pickle.dumps(inner_data['data'])) redis.set(key, pickle.dumps(cookies.get_dict())) else: return False, 'Login fehlgeschlagen, bitte log dich neu ein.' else: # get new cookies using login key try: token_url = f'whoami?login_token={login_key}&user_id={login_data["personid"]}' data = cc_api(token_url, cookies, login_data=login_data, returnJson=True) if data['status'] == 'success': logger.info(data) redis.set(key, pickle.dumps(cookies.get_dict())) else: logger.warning(data) return False, f'Login fehlgeschlagen, bitte log dich neu ein.' except Exception as e: return False, f'Could not renew token:\n{str(e)}' # redis.delete(get_user_login_key(login_data['telegramid'])) # return False, 'Login fehlgeschlagen, versuchs es mit einem neuen Link.' return True, cookies