def hasExceededDailyLimit(chat_id): dailyLog = getDailyLog(chat_id) if (dailyLog >= MAX_DAILY_LOG): sendMsg(chat_id, 'You have reached your daily limit for next bus queries') return True dailyLogKey = makeDailyLogKey(chat_id) db.incr(dailyLogKey, 1) db.expireat(dailyLogKey, getDailyLimitExpiryDate()) return False
def checkQueueUponStart(): for key in db.scan_iter("*" + KEY_QUEUE): key = key.decode("utf-8") currQ = getDbObj(key) if len(currQ) > 0: chat_id = key.replace(KEY_QUEUE, "") sendMsg( chat_id, 'The server restarted while you had pending requests. You will not receive updates for your pending requests below, so please resend them:\n' + '\n'.join(['- `{}`'.format(item) for item in currQ])) db.delete(key)
def getSavedNag(chat_id): key = makeNagKey(chat_id) keyInfo = getDbObj(key) if keyInfo is not None: interval, maxCount = keyInfo success = True else: sendMsg(chat_id, 'Can\'t retrieve last nag interval and repeats') interval, maxCount = -1, 1 success = False return success, interval, maxCount
def getSavedTrack(chat_id): key = makeTrackKey(chat_id) keyInfo = db.get(key) if keyInfo is not None: interval = float(keyInfo) success = True else: sendMsg(chat_id, 'Can\'t retrieve last track interval') interval = -1 success = False return success, interval
def getSavedService(chat_id): key = makeServKey(chat_id) keyInfo = getDbObj(key) if keyInfo is not None: busStopNo, routeNo = keyInfo success = True else: sendMsg( chat_id, 'Can\'t retrieve last successfully queried bus stop and route number' ) busStopNo, routeNo = '', '' success = False return success, busStopNo, routeNo
def replyBusInfo(chat_id, text, message=None): textAction = re.sub('\n.*', '', text) textList = [item.strip() for item in textAction.split(' ')] if len(textList) == 3: command, busStopNo, routeNo = textList processBusInfo(chat_id, busStopNo, routeNo, message=message) elif len(textList) == 2: command, busStopNo = textList processBusStop(chat_id, busStopNo) elif len(textList) == 1: # command = textList[0] success, busStopNo, routeNo = getSavedService(chat_id) if success: processBusInfo(chat_id, busStopNo, routeNo) else: sendMsg(chat_id, helpText)
def showFav(chat_id): favKey = makeFavKey(chat_id) initDbList(favKey) currFavs = getDbObj(favKey) if len(currFavs) == 0: reply_markup = telegram.ReplyKeyboardRemove() sendMsg(chat_id, "You have no favourite commands", reply_markup=reply_markup) else: reply_markup = telegram.ReplyKeyboardMarkup( keyboard=[[item] for item in currFavs], resize_keyboard=True, one_time_keyboard=True) sendMsg(chat_id, "Here are your favourite commands:", reply_markup=reply_markup)
def showStar(chat_id): starKey = makeStarKey(chat_id) initDbList(starKey) currStars = getDbObj(starKey) if len(currStars) == 0: reply_markup = telegram.ReplyKeyboardRemove() sendMsg(chat_id, "You have no starred bus stops", reply_markup=reply_markup) else: reply_markup = telegram.ReplyKeyboardMarkup( keyboard=[["/info {}".format(item)] for item in currStars], resize_keyboard=True, one_time_keyboard=True) sendMsg(chat_id, "Here are your starred bus stops:", reply_markup=reply_markup)
def showHist(chat_id): histKey = makeHistKey(chat_id) initDbList(histKey) history = getDbObj(histKey) if len(history) == 0: reply_markup = telegram.ReplyKeyboardRemove() sendMsg(chat_id, "You have no recent commands", reply_markup=reply_markup) else: reply_markup = telegram.ReplyKeyboardMarkup( keyboard=[[item] for item in history], resize_keyboard=True, one_time_keyboard=True) sendMsg(chat_id, "Here are your recent commands:", reply_markup=reply_markup)
def replyCommand(chat_id, text, message=None): text = text.strip() lowerText = text.lower() lowerText = re.sub('^/', '', lowerText) if re.match(r'next *', lowerText) or re.match(r'remind *', lowerText) or re.match(r'nag *', lowerText) or re.match(r'tracks? *', lowerText): replyNextBus(chat_id, text, 0, False, message) elif re.match(r'info *', lowerText): replyBusInfo(chat_id, text, message) elif re.match(r'save *\|', lowerText) or re.match(r'delete *\|', lowerText): editFav(chat_id, text) elif re.match(r'counter *', lowerText): replyDailyLog(chat_id) elif re.match(r'fav *', lowerText): showFav(chat_id) elif re.match(r'history *', lowerText): showHist(chat_id) elif re.match(r'starred *', lowerText): showStar(chat_id) elif re.match(r'help *', lowerText): sendMsg(chat_id, helpTextFull) else: sendMsg(chat_id, helpText)
def replyLocation(chat_id, loc): # not the fastest method, but the dataset is quite small so this is fast enough for now dicty = readStopDict() nearbyList = [] for key, val in dicty.items(): dist = getHaversineDistance(loc.latitude, loc.longitude, val["Latitude"], val["Longitude"]) nearbyList.append((val, dist)) nearbyList = sorted(nearbyList, key=itemgetter(1))[:5] nearbyListStr = [ "_{}_ @ {} (*{}*), {:.2f} km\n{}".format(a["Description"], a["RoadName"], a["BusStopCode"], b, ", ".join(a["Services"])) for a, b in nearbyList ] msg = "\n\n".join(nearbyListStr) makeData = lambda x: serialise({"c": "constr", "s": x}) reply_markup = makeInlineKeyboard( [(a["Description"], makeData(a["BusStopCode"])) for a, b in nearbyList], cols=2) sendMsg(chat_id, msg, reply_markup)
def editFav(chat_id, text): textList = [item.strip() for item in text.split('|')] if (len(textList) == 2): command, action = textList command = command.lower() command = re.sub('^/', '', command) else: sendMsg(chat_id, helpText) return favKey = makeFavKey(chat_id) initDbList(favKey) matchingIndexes = [ i for (i, val) in enumerate(getDbObj(favKey)) if val == action ] if command == 'save': if len(matchingIndexes) == 0: addToDbList(favKey, action) reply_markup = telegram.ReplyKeyboardRemove() sendMsg(chat_id, "Command saved to your favourites!", reply_markup=reply_markup) else: sendMsg(chat_id, 'You have already saved this command') elif command == 'delete': if len(matchingIndexes) == 0: sendMsg(chat_id, 'No matching commands found in your favourites') else: for i in matchingIndexes: popFromDbList(favKey, i) reply_markup = telegram.ReplyKeyboardRemove() sendMsg(chat_id, "Command removed from your favourites!", reply_markup=reply_markup) else: sendMsg(chat_id, helpText)
def replyDailyLog(chat_id): dailyLog = getDailyLog(chat_id) sendMsg(chat_id, 'Today you have made ' + str(dailyLog) + ' next bus queries')
def callTimerDown(waitSecs, chat_id, text, count): sendMsg( chat_id, "Sorry, timer service is not available now, so we can only reply with info on demand but can't send alerts." ) removeFromQueue(chat_id, text)
def replyNextBus(chat_id, text, count, fromQ, message=None): if (fromQ): removeFromQueue(chat_id, text) textAction = re.sub('\n.*', '', text) textAction = re.sub('^/', '', textAction) textList = [item.strip() for item in textAction.split(' ')] interval = -1 maxCount = 1 isTracking = False isTrackingSilent = False textList[0] = textList[0].lower() if textList[0] == 'next': if len(textList) == 3: command, busStopNo, routeNo = textList elif len(textList) == 1: command = textList[0] success, busStopNo, routeNo = getSavedService(chat_id) if success == False: return text = ' '.join([command, busStopNo, routeNo]) else: updateMsg(chat_id, helpText, message=message) return elif textList[0] == 'remind': if len(textList) == 4: command, busStopNo, routeNo, interval = textList interval = float(interval) elif len(textList) == 3: command, busStopNo, routeNo = textList success, interval = getSavedRemind(chat_id) if success == False: return text = ' '.join([command, busStopNo, routeNo, str(interval)]) elif len(textList) == 2: command, interval = textList interval = float(interval) success, busStopNo, routeNo = getSavedService(chat_id) if success == False: return text = ' '.join([command, busStopNo, routeNo, str(interval)]) elif len(textList) == 1: command = textList[0] success, busStopNo, routeNo = getSavedService(chat_id) if success == False: return success, interval = getSavedRemind(chat_id) if success == False: return text = ' '.join([command, busStopNo, routeNo, str(interval)]) else: updateMsg(chat_id, helpText, message=message) return remindKey = makeRemindKey(chat_id) db.set(remindKey, interval) elif textList[0] == 'nag': if len(textList) == 5: command, busStopNo, routeNo, interval, maxCount = textList interval = float(interval) maxCount = int(maxCount) elif len(textList) == 3: command, interval, maxCount = textList interval = float(interval) maxCount = int(maxCount) success, busStopNo, routeNo = getSavedService(chat_id) if success == False: return text = ' '.join( [command, busStopNo, routeNo, str(interval), str(maxCount)]) elif len(textList) == 1: command = textList[0] success, busStopNo, routeNo = getSavedService(chat_id) if success == False: return success, interval, maxCount = getSavedNag(chat_id) if success == False: return text = ' '.join( [command, busStopNo, routeNo, str(interval), str(maxCount)]) else: updateMsg(chat_id, helpText, message=message) return nagKey = makeNagKey(chat_id) saveDbObj(nagKey, (interval, maxCount)) elif textList[0] == 'track' or textList[0] == 'tracks': if len(textList) == 4: command, busStopNo, routeNo, interval = textList interval = float(interval) elif len(textList) == 3: command, busStopNo, routeNo = textList success, interval = getSavedTrack(chat_id) if success == False: return text = ' '.join([command, busStopNo, routeNo, str(interval)]) elif len(textList) == 2: command, interval = textList interval = float(interval) success, busStopNo, routeNo = getSavedService(chat_id) if success == False: return text = ' '.join([command, busStopNo, routeNo, str(interval)]) elif len(textList) == 1: command = textList[0] success, busStopNo, routeNo = getSavedService(chat_id) if success == False: return success, interval = getSavedTrack(chat_id) if success == False: return text = ' '.join([command, busStopNo, routeNo, str(interval)]) else: updateMsg(chat_id, helpText, message=message) return trackKey = makeTrackKey(chat_id) db.set(trackKey, interval) isTracking = True if (command == 'tracks'): isTrackingSilent = True else: sendMsg(chat_id, helpText) return if not fromQ: saveHistory(chat_id, text) if hasExceededDailyLimit(chat_id): return response = getNextBuses(busStopNo, routeNo) waitSecs = -1 reply = "" if type(response) is tuple: responseStatus = response[0] reply = response[1] if responseStatus != -1: serviceKey = makeServKey(chat_id) saveDbObj(serviceKey, (busStopNo, routeNo)) if responseStatus == 1: remTime = response[2] if interval != -1: if command == 'remind': if remTime <= 0: waitSecs = 0 else: waitSecs = (remTime - interval) * 60 elif command == 'nag': waitSecs = (interval) * 60 elif command == 'track' or command == 'tracks': waitSecs = 0 if remTime > interval: waitMins = 0 trackSeq = [0, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144] for (i, num) in enumerate(trackSeq): if remTime <= num: if i != 0: waitMins = trackSeq[i] - trackSeq[i - 1] break if (remTime - waitMins) < interval: waitMins = remTime - interval waitSecs = (waitMins) * 60 shouldSendMsg = False if (not isTrackingSilent) or (waitSecs < 60) or ( count > MAX_TRACKING_COUNT) or (count == 0): shouldSendMsg = True count += 1 if maxCount > MAX_COUNT: maxCount = MAX_COUNT if (count == 1) and (waitSecs >= 60): shouldSendMsg = True reply += '\nDon\'t be insane, that\'s way too many times. Will only update you ' + str( MAX_COUNT) + ' more times' if isTracking: maxCount = MAX_TRACKING_COUNT if count == maxCount + 1: if shouldSendMsg and reply: reply = '_Final update_\n' + reply elif (count <= maxCount) and (waitSecs != -1): if waitSecs < 60: if shouldSendMsg and reply: reply = '_Final update_\n' + reply else: addToQueue(chat_id, text) callTimerHandler(waitSecs, chat_id, text, count) if shouldSendMsg and reply: reply_markup = makeRoutesInlineKeyboard(busStopNo, chat_id) updateMsg(chat_id, reply, reply_markup=reply_markup, message=message)