示例#1
0
def sendSettings(message):
  markup = settingsMarkup(message.chat.id)

  chatID = message.chat.id
  currentChat = Chats.getChat(message.chat.id)
  lastMessage = currentChat.settings.lastMessageId

  # * Deleting previous "settings" message
  try:
    if lastMessage[0]:
      bot.delete_message(chatID, lastMessage[0])
  except Exception:
    pass

  # * Sending new one
  settingsMessage = bot.send_message(
    chatID,
    message.replies.stg.msgTitle,
    reply_markup=markup
  )

  # * Setting new messageID when the message was send to be able to delete this one,
  # * when new settings will be sent

  currentChat.settings.lastMessageId = [
    settingsMessage.message_id,
    message.from_user.id
  ]
  currentChat.save()
示例#2
0
def findWord(message):
    """Will look for the requested word in the database and send inforamation about it"""

    args = extractArgs(message.text)
    chatID = message.chat.id
    currentChat = Chats.getChat(chatID)

    # * Checking if the arguments where provided
    if not args:
        bot.send_message(chatID, message.replies.fw[2])
        return

    # * Looking for words saving info about them and sending the result
    foundWords = []
    theirNumbers = []

    for word in currentChat.words:
        if word.text in args:
            foundWords.append(word.text)
            theirNumbers.append(word.sentTimes)

    if not foundWords:
        bot.send_message(chatID, message.replies.fw[1])
    else:
        for part in stringForStats(chatID, foundWords, theirNumbers):
            bot.send_message(chatID, part)
示例#3
0
def callbackAdditionalButtons(call):
  chatId = call.message.chat.id
  currentChat = Chats.getChat(chatId)
  settingsStrings = call.replies.stg.strings

  # ? All buttons
  # * Edit values buttons
  if call.data == 'stgEditValues':
    botReplies = call.replies.stg
    userDmId = currentChat.settings.lastMessageId[1]

    # * Creating a markup with all settings names, whose value can be edited
    markup = InlineKeyboardMarkup()
    for setting in settingsStrings:
      for button in setting:
        if button[2]:
          # * Converts in a strange way to get 'Test String' from 'testString'
          text = settingForUser(button[3])
          tempButton = InlineKeyboardButton(
            text,
            callback_data=dumps([
              button[1].replace('stg', 'edit'),
              button[3]
            ])
          )
          markup.row(tempButton)

    checkChat(userDmId)
    dmChat = Chats.getChat(userDmId)
    dmChat.settings.editMessageInfo['originalChatId'] = call.message.chat.id
    dmChat.save()

    originalChatUsername = call.message.chat.username
    if originalChatUsername:
      addUrlButton(markup, call.replies.goToChat[0], originalChatUsername)

    bot.send_message(userDmId, botReplies.editorMessage, reply_markup=markup)

  # * More info button
  if call.data == 'stgMoreInfo':
    allSettingsNames = []
    for setting in settingsStrings:
      for button in setting:
        allSettingsNames.append(settingForUser(button[3]))

    text = '\n\n'.join(call.replies.stg.additionalInfo).format(*allSettingsNames)
    bot.send_message(chatId, text, parse_mode='html')
示例#4
0
def callbackSettingsEditors(call):
  currentChat = Chats.getChat(call.message.chat.id)
  # * Sending a helping message and updating the DB
  newMessage = bot.send_message(call.message.chat.id, call.replies.stg.sendNewValue)
  
  addingInfoTo = currentChat.settings.editMessageInfo
  addingInfoTo['requestMessageId'] = newMessage.message_id
  addingInfoTo['requestChatId'] = newMessage.chat.id
  addingInfoTo['commandName'] = call.additionalInfo
  addingInfoTo['callbackId'] = call.id

  currentChat.save()
示例#5
0
    def __init__(self, objectWithID=None):
        if objectWithID:
            chatID = self.idFromObject(objectWithID)
            try:
                currentChat = Chats.getChat(chatID)

                self._language = currentChat.language
            except Chats.DoesNotExist:
                checkChat(chatID)
                self._language = 'eng'

            self._strings = replies[self._language]
示例#6
0
def sendGlobalTopWord(message):
    topWordText = ''
    chatId = message.chat.id

    # * Checking if we has statistics atleast in one chat
    if not Chats.objects(words__not__size=0):
        bot.send_message(chatId, message.replies.nos)
        return

    # * Here will be saved the chat object which was most commonly used word,
    # * none of the words in other chats weren't sent as much times
    # * as particular word in this chat was.

    chatWithTop = Chats()

    # * Searches for the chat, which has the most used word in it
    # * (more ditailed description of this is written above the 'chatWithTop' variable defenition)

    sentTimes = 0
    while Chats.objects(words__sentTimes__gt=sentTimes):
        allMatching = Chats.objects(words__sentTimes__gt=sentTimes)
        if len(allMatching) == 1 or len(allMatching) == sentTimes + 2:
            chatWithTop = allMatching[0]
            topWordText = chatWithTop.topWord.text

            break
        sentTimes += 1

    # * Looks for this word in every chat and add its writtenTime to general
    sentEverywhere = 0
    for chat in Chats.objects(words__text=topWordText):
        for word in chat.words:
            if word.text == topWordText:
                sentEverywhere += word.sentTimes

    resultString = Language(message).strs.gtw.format(topWordText,
                                                     sentEverywhere)
    bot.send_message(chatId,
                     resultString,
                     reply_markup=getDeleteMarkup(commands.gtw, message))
示例#7
0
def clearStats(message):
    """
  Clears the Chat object for current chat, so there will be no information
  to use left, but it leaves the object in the database,
  so there will be no need to create a new one
  """

    # * Cleaning the chat Document
    currentChat = Chats.getChat(message.chat.id)
    currentChat.words = []
    currentChat.sentMessages = currentChat.sentWords = 0
    currentChat.topWord = Word(text='', sentTimes=0)
    currentChat.save()

    # adder = IDAdder(currentChat,)
    bot.send_message(message.chat.id, message.replies.sclrd)
示例#8
0
def sendTopWord(message):
    """Gets from the DB most commonly used word objects and sends it to the chat"""

    chatID = message.chat.id

    currentChat = Chats.getChat(chatID)
    topWord = currentChat.topWord

    if topWord.text:
        toSend = message.replies.tw.format(topWord.text, topWord.sentTimes)

        bot.send_message(chatID,
                         toSend,
                         reply_markup=getDeleteMarkup(commands.tw, message))
    else:
        bot.send_message(chatID, message.replies.nos)
示例#9
0
def modifyMessage(bot_instance, message):
  chatID = message.chat.id
  checkChat(chatID)
  currentChat = Chats.getChat(chatID)

  # * Setting bot replies
  message.replies = Language(message.chat.id).strs

  # ? Resposes
  # * Saving bot responses to the DB trough ReponsesManager class and deleting old messages
  if not message.text is None and '/' in message.text:
    deleteAfter = currentChat.settings['removeAfter']['value']

    editor = ResponsesManager(currentChat)
    editor.addResponse(message.message_id)

    try:
      # * Deleting a reponse and all connected messages. Will delete everywhere
      if len(currentChat.responses) > deleteAfter:
        # * Spltting information about the oldest reponses into variables and deleting
        # * "main" nessage + other message, which were sent when the command was sent

        # * Splitting info to access it easier
        oldestResponse = list(currentChat.responses.items())[0]
        oldestResponseChatId = oldestResponse[0]
        oldestResponseIds = oldestResponse[1]['connectedIDs']

        # * Deleting data from the DB and removing "main" message in the chat
        editor.deleteResponse(oldestResponseChatId)
        bot_instance.delete_message(chatID, oldestResponseChatId)

        # * Deleting other messages
        if oldestResponseIds:
          for chatId, addtionalIds in oldestResponseIds.items():
            if not isinstance(addtionalIds, list):
              addtionalIds = [addtionalIds]

            for id in addtionalIds:
              bot_instance.delete_message(chatId, id)

    except apihelper.ApiException as error:
      print(error)

    currentChat.save()
示例#10
0
def callbackInline(call):
  """Function to control inline buttonsm won't be used anywhere, just in the decorator"""

  if call.message:
    chatID = call.message.chat.id

    if call.data == 'toClearTrue':
      markup = types.InlineKeyboardMarkup(row_width = 1)
      keyboardItem1 = types.InlineKeyboardButton(call.replies.skeyboard[1], callback_data = 'deleteMessage')
      markup.add(keyboardItem1)

      bot.delete_message(chatID, call.message.message_id - 1)
      bot.edit_message_text(call.message.text, chatID, call.message.message_id, reply_markup = markup)

      # * Cleaning the chat Document
      currentChat = Chats.getChat(call.additionalInfo)
      currentChat.words = []
      currentChat.sentMessages = currentChat.sentWords = 0
      currentChat.topWord = Word(text='', sentTimes=0)
      currentChat.save()

      bot.send_message(chatID, call.replies.sclrd)

    if call.data == 'deleteMessage':
      bot.answer_callback_query(call.id, show_alert=False, text=call.replies.notf[0])
      bot.delete_message(chatID, call.message.message_id)
    if call.data == 'deleteWithCommand':
      bot.answer_callback_query(call.id, show_alert=False, text=call.replies.notf[1])
      bot.delete_message(chatID, call.message.message_id)
      bot.delete_message(chatID, call.additionalInfo)

    # * Handles changing language settings
    if call.data == 'setLangRu':
      Language(chatID).lang = (call, 'ru')

    if call.data == 'setLangEng':
      Language(chatID).lang = (call, 'eng')

    if call.data == 'setLangEng' or call.data == 'setLangRu':
      call.replies = Language(chatID).strs
      bot.answer_callback_query(call.id, show_alert = False, text = call.replies.sectl[1])
      bot.delete_message(chatID, call.message.message_id)
示例#11
0
def callbackSettings(call):
  chatId = call.message.chat.id
  currentChat = Chats.getChat(chatId)
  settingsStrings = call.replies.stg.strings

  # * Toggling setting, if a simple callback
  for i, callback in enumerate(allSettingsCallbacks):
    if call.data == callback:
      Settings.toggleSetting(currentChat, settingsStrings[i][0][3])

  # * Upating the message
  markup = settingsMarkup(chatId)
  try:
    bot.edit_message_text(
      Language(chatId).strs.stg.msgTitle, chatId,
      call.message.message_id,
      reply_markup=markup,
    )

    bot.answer_callback_query(call.id, Language(chatId).strs.stg.success)
  except ApiException as e:
    print(e)
示例#12
0
    def lang(self, values) -> None:
        objectWithID, newLanguage = values
        currentChat = Chats()

        # * Checking if provided language exists in the database
        if newLanguage in implamentedLanguages:
            for _ in range(2):
                chatID = self.idFromObject(objectWithID)
                try:
                    currentChat = Chats.getChat(chatID)
                except Chats.DoesNotExist:
                    checkChat(chatID)

        currentChat.language = newLanguage
        currentChat.save()

        self._strings = replies[newLanguage]
        self._language = newLanguage
示例#13
0
def stringForStats(chatID, words, wordNumbers, additionalInfo=False, chatName=None):
  """
  Returns a formated in a speial way string using all information
  bot has to use in /stats command and not only
  """

  if not words:
    return None

  wordWrittenTimes = 1
  result = []

  # * Creating an array of ceratiain format. It will look somethig like this
  # & [['Word(s), which was/were written 1 time(s).', '"first"'],
  # & ['Word(s), which was/were written 2 time(s).', '"second"']]

  while wordWrittenTimes <= max(wordNumbers):
    # * Skipping an iterations if we don't have words which where written this much times
    if wordWrittenTimes not in wordNumbers:
      wordWrittenTimes += 1
      continue

    # * Adds all info to the string, we get info from the DB
    oneLine = [Language(chatID).strs.s[1].format(wordWrittenTimes)]
    for i, word in enumerate(words):
      if wordWrittenTimes == wordNumbers[i]:
        oneLine.append (f'"{word}"')

    # * Adding one like of words which where written same number of times
    # * and incrementing the variable responcible for everything

    result.append(oneLine)
    wordWrittenTimes += 1

  messages = [[]]
  for item in result:
    messages[-1].append(item)

    if len(reduce(lambda a, b : ''.join(a) + ''.join(b), messages[-1])) >= 3000:
      messages.append([])

  # * Adding each to make a strings which will look something like this
  # & 'Word(s), which was/were written 1 time(s).\n"first"'

  allMessages = []
  for index, message in enumerate(messages):
    singleMessage = []
    if not chatName is None and not index:
      singleMessage.append(Language(chatID).strs.s[4].format(
        chatName
      ))

    for item in message:
      messageText = f'{item[0]}\n{", ".join(item[1:])}'
      singleMessage.append(messageText)
    allMessages.append(singleMessage)

  # * Making a string out of our array and adding more info to the string if we want to
  result = []
  currentChat = Chats.getChat(chatID)

  for message in allMessages:
    # * Checking if we need additional info and add it
    if message == allMessages[-1] and additionalInfo:
      message.append(Language(chatID).strs.s[0].format(
        currentChat.sentMessages,
        currentChat.sentWords
      ))

    # * Adding all together, to get a final result
    result.append('\n\n'.join(message))

  for i, item in enumerate(result):
    if len(item) >= 3000:
      del result[i]

      chuncks = []
      j = 0
      for j in range(0, len(item), item.index(',', j+2950) + 1):
        try:
          chuncks.append(item[0+j:item.index(',', j+2950) + 1])
        except Exception:
          chuncks.append(item[j - 1:])
        # string[0+i:length+string.index(',', i - 50)] for i in range(0, len(string), length)

      for j, chunk in enumerate(chuncks):
        result.insert(i + j, chunk)

  return result
示例#14
0
def settingsMarkup(chatID):
  markup = InlineKeyboardMarkup()
  currentSettings = Chats.objects(ID=chatID).get().settings
  settingsStrings = Language(chatID).strs.stg.strings

  for index, setting in enumerate(currentSettings):

    # * Will stop the foop if we have already iterated through all settings.
    # * Has to be stopped because "settings" object contains not only settings values,
    # * but some additional info connected to /settings command

    if index >= len(settingsStrings):
      break

    isOnString = '❌'
    settingObject = currentSettings[setting]

    if isinstance(settingObject, bool) and settingObject:
      isOnString = '✅'
    elif isinstance(settingObject, dict) and settingObject['haveTo']:
      isOnString = '✅'

    # * Creaing and adding all buttons to the markup. Will create using 2D array in config
    newButtons = []
    for index, buttonInfo in enumerate(settingsStrings[index]):
      buttonText = buttonInfo[0]

      # * Formating button text if can be formated
      if canFormat(buttonText):
        buttonText = buttonText.format(settingObject['value'])

      tempButton = InlineKeyboardButton(
        f'{buttonText}',
        callback_data=buttonInfo[1],
      )

      if not index:
        tempButton = InlineKeyboardButton(
          f'{buttonText} {isOnString}',
          callback_data=buttonInfo[1]
        )

      newButtons.append(tempButton)
    markup.row(*newButtons)

  # ? Additional buttons
  buttonText = Language(chatID).strs.stg

  # * Editing button
  markup.row(InlineKeyboardButton(
    buttonText.editButtonValue,
    callback_data=additionalButtonCallbacks[0],
  ))

  # * Button to get more info
  markup.row(InlineKeyboardButton(
    buttonText.moreInfoButtonValue,
    callback_data=additionalButtonCallbacks[1]
  ))

  # * Button to move to Bot's chat
  addUrlButton(markup, Language(chatID).strs.goToBot[0], bot.get_me().username)

    # tempButton = InlineKeyboardButton(
    #   f'{settingsStrings[index][0]} {isOnString}',
    #   callback_data=settingsStrings[index][1]
    # )

    # markup.add(tempButton)

  return markup
示例#15
0
def modifyMessage(bot_instance, message):
  # * Checking if a message id an a chat id match a those which are in the DB.
  # * Then we assume, that the message it's a new value for a setting, so we
  # * change it.

  currentChat = Chats.getChat(message.chat.id)
  
  if currentChat is None:
    return

  editMessageInfo = currentChat.settings.editMessageInfo

  if (editMessageInfo and
      editMessageInfo['requestMessageId'] + 1 == message.message_id and
      editMessageInfo['requestChatId'] == message.chat.id):

    try:
      editArgument = int(message.text.split()[0])

      # * Changing setting value and sending user a reponse
      originalChatId = editMessageInfo['originalChatId']
      chatWeToChange = Chats.getChat(originalChatId)
      strings = Language(originalChatId).strs
      originalChat = Chats.getChat(originalChatId)

      # * Checking if new value is not the same as it was before
      oldValue = Settings.getSettingsValue(originalChat, editMessageInfo['commandName'])
      print(editArgument, oldValue)
      if editArgument == oldValue:
        raise ValueError()

    except ValueError as e:
      print(e)
      bot.send_message(message.chat.id, strings.stg.valueIsWrong)
      editMessageInfo['requestMessageId'] = message.message_id + 1
      currentChat.save()

    # * Changes setting
    Settings.setSettingValue(
      chatWeToChange,
      editMessageInfo['commandName'],
      editArgument
    )

    # * Deleting the spare replies, when the number of saved replies
    # * is higher then the new value of removeAfter

    idsToRemove = []
    if editMessageInfo['commandName'] == 'removeAfter' and oldValue > editArgument:
      for i, response in enumerate(originalChat.responses.items()):
        if i >= oldValue - editArgument:
          break

        try:
          bot_instance.delete_message(originalChatId, int(response[0]))
          if response[1]['connectedIDs']:
            for chatId, ids in response[1]['connectedIDs'].items():
              for id in ids:
                # pass
                bot_instance.delete_message(int(chatId), id)
        except ApiException as e:
          print(e)

        idsToRemove.append(response[0])

      for toRemove in idsToRemove:
        del originalChat.responses[toRemove]
      originalChat.save()

    # * Updates settings message in the originalChat
    bot.edit_message_text(
      strings.stg.msgTitle,
      originalChatId,
      originalChat.settings.lastMessageId[0],
      reply_markup=settingsMarkup(originalChatId)
    )

    # * Answering
    bot.answer_callback_query(
      editMessageInfo['callbackId'],
      strings.stg.changeSuccess
    )
示例#16
0
def countWords(message):
  """
  Handles text messages. Upates and save new information to the database,
  so it will be up-to-date to the real chat history. It's a main part of this bot
  """

  global savedMessageID

  # * If a message contains a slash and it wasn't handled yet, command doesn' exist
  if message.text.strip()[0] == '/':
    bot.send_message(message.chat.id, message.replies.cnf)

  elif not 'http' in message.text:
    splitedMessage = splitSentence(message.text)

    if '' not in splitedMessage:
      # * Checking if current chat exists in the database an getting its object to use
      currentChat = Chats.getChat(message.chat.id)

      # * Update "counters" in database
      currentChat.sentWords += len(splitedMessage)
      currentChat.sentMessages += 1

      wordsList = []
      for part in splitedMessage:
        wordLower = part.lower()

        # * Adds a word in the list, if it's not fond in it
        wordsList = [word.text for word in currentChat.words]
        if not wordLower in wordsList or not currentChat.words:
          # * Adds new Word object object to the DB if there is't any
          tempWord = Word(
            text = wordLower,
            sentTimes = 1
          )

          currentChat.words.append(tempWord)

        # * Incriments the number of the word if it's found in the list
        else:
          # * Doing the same stuff, but in mongoDB
          for word in currentChat.words:
            if word.text == wordLower:
              word.sentTimes += 1
              break

        # * Updating the topWord object in the DB
        wordNumbers = [word.sentTimes for word in currentChat.words]
        topSentTimes = currentChat.topWord.sentTimes

        if topSentTimes < max(wordNumbers) or not currentChat.topWord.text:
          wordsList = [word.text for word in currentChat.words]
          topIndex = wordNumbers.index(max(wordNumbers))

          currentChat.topWord = Word(
            text = wordsList[topIndex],
            sentTimes = max(wordNumbers)
          )

      print('savingTheDB')
      currentChat.save()
示例#17
0
def sendStats(message):
  """
  Sends a message with all words information in a special formated string,
  which is provide by 'stringsForStats' functionm. Gets informations from the
  database and splits the result of the funcion unsing built-in 'untils' methods.
  """

  chatID = message.chat.id
  clearButton = types.InlineKeyboardButton(
    message.replies.skeyboard[0],
    callback_data=dumps(['toClearTrue', chatID])
  )

  # * Getting info from the DB to pass into the function
  currentChat = Chats.getChat(chatID)
  wordObjects = currentChat.words
  wordNumbers = [word.sentTimes for word in wordObjects]
  words = [word.text for word in wordObjects]

  sendToPrivate = Chats.getSettings(chatID)['sendPrivate']

  chatName = None
  if sendToPrivate:
    chatName = message.chat.username

  formatedStrings = stringForStats(chatID, words, wordNumbers, True, chatName)
  markup = None

  # * Allowes to save message ids. More info in the class doc string
  editor = ResponsesManager(currentChat)

  if not formatedStrings:
    tempMessage = bot.send_message(message.chat.id, message.replies.nos)
    editor.addIDs(message.message_id, tempMessage)
    return

  # * If specified in settings will set chatID variable to users chat id,
  # * so the statistics will be sent not to the chat but to user pesonaly.
  if sendToPrivate:
    chatID = message.from_user.id

  if formatedStrings:
    # * Sending a splited message and adding an inline keyboard to the last element,
    # * so the user will be able to everything faster and more comftable.

    try:
      for index, part in enumerate(formatedStrings):
        if index + 1 == len(formatedStrings):
          markup = getDeleteMarkup(commands.s, message, clearButton)
          if message.chat.username and Chats.getSettings(message.chat.id)['sendPrivate']:
            addUrlButton(markup, message.replies.goToChat[0], message.chat.username)


        tempMessage = bot.send_message(
          chatID, part,
          reply_markup=markup, disable_notification=True, parse_mode='html'
        )

        editor.addIDs(message.message_id, tempMessage, chatID)

      if Chats.getSettings(message.chat.id)['sendPrivate'] and message.chat.type != 'private':
        markup = types.InlineKeyboardMarkup()
        addUrlButton(markup, message.replies.goToBot[1], bot.get_me().username)

        editor.addIDs(
          message.message_id,
          bot.send_message(
            message.chat.id,
            message.replies.s[2].format(
              bot.get_me().username
            ),
            reply_markup=markup
          ))

    except apihelper.ApiException as e:
      print(e)
      editor.addIDs(
        message.message_id,
        bot.send_message(
          message.chat.id,
          message.replies.s[3].format(
            bot.get_me().username
      )))