Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # -*- coding: utf-8 -*-
- import time
- import telepot
- from telepot.loop import MessageLoop
- from telepot.namedtuple import InlineKeyboardMarkup, InlineKeyboardButton
- from os.path import isfile, join, split, splitext
- from os import listdir
- import random
- import pickle
- bot_id = "BOT_TOKEN"
- bot_tag = "YOUR_@TAG"
- bot_help = "This bot is useless.\n I'm testing it and for now has:\n\n - /booty : booty pictures\n\n - /booty_rate : rate the pictures\n\n - /help : this message"
- #==============================================================================
- # # Helper functions
- #==============================================================================
- def get_pathname(path):
- ''' Little function to split the path in path, name, extension'''
- path, nameext = split(path)
- name, ext = splitext(nameext)
- return path, name, ext
- def cut_path(path):
- ''' This function takes a path and outputs the path cut with the ... after the
- the first folder after the first character and completes the name with the filename or the last folder
- '''
- endidx = 5
- char = path[endidx]
- while char != '/' and endidx < len(path):
- endidx += 1
- char = path[endidx]
- inpath = path[:endidx + 1 ]
- rpath = path[::-1]
- idx = 1
- char = rpath[idx]
- while char != "/" and idx < len(rpath):
- idx += 1
- char = rpath[idx]
- endpath = path[len(path) - idx - 1 : ]
- outpath = inpath + "..." + endpath
- return outpath
- #==============================================================================
- # # Messages classes
- #==============================================================================
- class PersonName:
- def __init__(self, msg):
- self.id = msg['id']
- self.first_name = msg["first_name"]
- self.username = None
- self.language_code = None
- # optional arguments
- try:
- self.username = msg["username"]
- except KeyError:
- pass
- try:
- self.language_code = msg["language_code"]
- except KeyError:
- pass
- def info(self):
- if len(self.first_name) > 13:
- sname = self.first_name[:10] + "..."
- else:
- sname = self.first_name
- return "{0}(@{1})".format(sname, self.username)
- class Chat:
- def __init__(self, chat):
- self.id = chat["id"]
- self.type = chat["type"]
- if self.type == "private":
- self.person = PersonName(chat)
- if self.type == "supergroup":
- self.title = chat["title"]
- def info(self):
- description = ""
- if self.type == "supergroup":
- description += self.title
- if self.type == "private":
- description += self.person.info()
- return "{0} | {1}".format(self.type, description)
- class Photo:
- def __init__(self, photo):
- self.file_id = photo["file_id"]
- self.file_size = photo.get("file_size")
- self.width = photo["width"]
- self.height = photo["height"]
- self.file_path = None
- try:
- self.file_path = photo["file_path"]
- except KeyError:
- pass
- class Message:
- def __init__(self, msg):
- content_type, chat_type, chat_id = telepot.glance(msg)
- self.original = msg
- self.message_id = msg["message_id"]
- self.mfrom = PersonName(msg["from"])
- self.chat = Chat(msg["chat"])
- self.date = msg["date"]
- self.content_type = content_type
- self.text = None
- self.photo = None
- self.reply = None
- if self.content_type == "text":
- self.text = msg["text"]
- if self.content_type == "photo":
- self.photo = [ Photo(pic) for pic in msg["photo"] ]
- try:
- self.reply = Message(msg["reply_to_message"])
- except KeyError:
- pass
- def info(self):
- return "Message ({0}) from: {1}\nin chat: {2}".format(
- self.content_type,
- self.mfrom.info(),
- self.chat.info()
- )
- def print_message(self):
- if self.content_type == "text":
- print(self.text)
- else:
- print("message content not supported")
- #==============================================================================
- # Define the databases
- #==============================================================================
- class ChatDatabase:
- filepath = "./data/chatdb.txt"
- def __init__(self):
- # create a database for the chat ids
- self.db = []
- self.previous_db = []
- # create a file where to store the chat ids
- self.loadChats()
- def addChat(self, chatid):
- self.db.append(chatid)
- def isNew(self, chatid):
- if chatid not in self.db:
- return True
- else:
- return False
- def getChat(self, chatid):
- for chat in self.db:
- if chat == chatid:
- return chat
- def loadChats(self):
- try:
- with open(self.filepath, "r") as f:
- s = f.readlines()
- self.db = []
- for line in s:
- if line != '\n':
- self.db.append(int(line[:-1]))
- self.previous_db.append(int(line[:-1]))
- print("Successfully imported: ", len(self.previous_db), "chats id")
- except IOError:
- print("Chat Database file not available")
- pass
- except Exception as e:
- print(e)
- raise e
- def writeChats(self):
- for chat in self.db:
- if chat not in self.previous_db:
- with open(self.filepath, "a") as f:
- f.write(str(chat) + "\n")
- self.previous_db.append(chat)
- class UsersDb:
- def __init__(self):
- pass
- class ImagesDB:
- filepath = "./data/images_db.txt"
- def __init__(self):
- # create a database for the chat ids
- self.db = {}
- self.previous_db = []
- # create a file where to store the chat ids
- self.loadPics()
- def addPathPic(self, path, picid):
- self.db[path] = picid
- def isNew(self, path):
- if path not in self.db.keys():
- print("New Path found:", path)
- return True
- else:
- print(path, "already in database")
- return False
- def getPicId(self, path):
- return self.db[path]
- def loadPics(self):
- try:
- with open(self.filepath, "r") as f:
- s = f.readlines()
- self.db = {}
- for line in s:
- if line != '\n':
- sp = line[:-1].split("-:-")
- path = sp[0]
- picid = sp[1]
- self.db[path] = picid
- self.previous_db.append(path)
- print("Successfully imported: ", len(self.previous_db), "images id or path")
- except IOError:
- print("Images database not yet available")
- pass
- except Exception as e:
- print(e)
- raise e
- def writePics(self):
- for path, picid in self.db.items():
- if path not in self.previous_db:
- with open(self.filepath, "a") as f:
- f.write(path + "-:-" + picid + "\n")
- self.previous_db.append(path)
- class ImageFolder:
- def __init__(self, path):
- self.path = path
- self.pictures = []
- self.gatherPictures()
- def gatherPictures(self):
- # for now gather all the files, next check for picture extensions
- p = self.path
- names = [f for f in listdir(p) if isfile(join(p, f))]
- for imgname in names:
- path, name, ext = get_pathname(imgname)
- if ext in ['.jpg', '.png']:
- imagepath = join(self.path, imgname)
- self.pictures.append(imagepath)
- def getPicture(self, idx):
- return self.pictures[idx]
- def getSize(self):
- return len(self.pictures)
- class InlineDatabase:
- def __init__(self):
- self.db = []
- def isNew(self, message):
- if (message.chat.id, message.message_id) in self.db:
- return False
- else:
- return True
- def add(self, message):
- self.db.append((message.chat.id, message.message_id))
- indb = InlineDatabase()
- class VotePicture:
- def __init__(self, path):
- #path of pic
- self.path = path
- self.id = None
- # list of who voted
- self.voterids = []
- # count
- self.upvote = 0
- self.downvote = 0
- # message ids
- self.creation_message_ids = []
- def addVoterId(self, voterid):
- print("Adding:", voterid)
- self.voterids.append(voterid)
- def addCreationMessage(self, msg):
- self.creation_message_ids.append((msg.chat.id, msg.message_id))
- def hasVoted(self, voterid):
- if voterid in self.voterids:
- return True
- return False
- def upCountUp(self):
- self.count += 1
- def downCountUp(self):
- self.downvote += 1
- def getScore(self):
- return "u {0}|{1} d".format(self.upvote, self.downvote)
- def getScoreEmoji(self):
- return "👍 {0} | {1} 👎 ".format(self.upvote, self.downvote)
- class VoteDB:
- def __init__(self):
- self.dbfolder = "./data/votepics/"
- self.votepicturesdb = []
- self.imgcount = 0
- self.load_database()
- def add(self, votepicture):
- self.imgcount += 1
- votepicture.id = self.imgcount
- self.votepicturesdb.append(votepicture)
- self.update_database()
- def isNew(self, votepicture):
- if type(votepicture) is VotePicture:
- if votepicture.id in [pic.id for pic in self.votepicturesdb]:
- return False
- return True
- if type(votepicture) is str:
- if votepicture in [pic.path for pic in self.votepicturesdb]:
- return False
- return True
- def get_id_to_picvote(self, picvoteid):
- for picvote in self.votepicturesdb:
- if picvote.id == picvoteid:
- return picvote
- print("id not found")
- def get_file_to_picture(self, file):
- for pic in self.votepicturesdb:
- if pic.path == file:
- return pic
- print("path not found")
- def dump_picture(self, picture):
- path, name, ext = get_pathname(picture.path)
- filename = self.dbfolder + name + ".pickle"
- with open(filename, 'wb') as f:
- pickle.dump(picture, f)
- def load_picture(self, filename):
- path, name, ext = get_pathname(filename)
- if isfile(filename) and ext == ".pickle":
- with open(filename, 'rb') as f:
- data = pickle.load(f)
- return data
- return None
- def update_database(self):
- for picture in self.votepicturesdb:
- self.dump_picture(picture)
- def load_database(self):
- names = [join(self.dbfolder, f) for f in listdir(self.dbfolder)]
- tmp_db = []
- c = 0
- for name in names:
- pic = self.load_picture(name)
- if pic is not None:
- tmp_db.append(pic)
- c += 1
- print("Loaded", c, "votepictures")
- print("clear previous database and Assign new stuff")
- self.votepicturesdb = tmp_db
- def showScores(self):
- for image in self.votepicturesdb:
- _, name, ext = get_pathname(image.path)
- print("{0}: {1}".format(name+ext, image.getScore()))
- def handle(msg):
- print("-------------------\n NEW MESSAGE \n-------------------")
- m = Message(msg)
- print(m.info())
- if cdb.isNew(m.chat.id):
- print("New chat", m.chat.id)
- cdb.addChat(m.chat.id)
- bot.sendMessage(m.chat.id, "HELLO I'm a goddamn fucking bot")
- bot.sendMessage(m.chat.id, bot_help)
- cdb.writeChats()
- if m.reply is not None:
- print("found a reply")
- if m.reply.mfrom.id == bot_id:
- if m.reply.content_type == "text":
- bot.editMessageText((m.reply.chat.id, m.reply.message_id), m.reply.text + " PROOOT!")
- if m.content_type == "text":
- print("text message detected")
- print("'{0}'".format(str(m.text)))
- # commands
- if m.text == "/booty" or m.text == "/booty" + bot_tag:
- # chose a picture from the folder random from it
- file_idx = int(random.uniform(0, imgbooty.getSize()))
- file = imgbooty.getPicture(file_idx)
- if idb.isNew(file):
- bot.sendMessage(m.chat.id, "loading...")
- # read from folder
- f = open(file, 'rb')
- r = bot.sendPhoto(m.chat.id, f)
- # store the picture id and hashmap to file
- rm = Message(r)
- idb.addPathPic(file, rm.photo[0].file_id)
- #update database
- idb.writePics()
- picmessage = "Image {0} of {1}".format(file_idx + 1, imgbooty.getSize())
- print(picmessage)
- pic = vdb.get_file_to_picture(file)
- if pic is not None:
- caption = picmessage + "\nScore: " + pic.getScoreEmoji() + "\nTo vote use /booty_rate"
- else:
- caption = picmessage + "\nNobody voted yet "
- bot.sendPhoto(m.chat.id, idb.getPicId(file), caption = caption)
- # add in description?
- elif m.text == "/inline":
- # inline test
- keyboard = InlineKeyboardMarkup(inline_keyboard=[
- [InlineKeyboardButton(text='Press me', callback_data='press')],
- [InlineKeyboardButton(text='like me', callback_data='like')]
- ])
- c_m = bot.sendMessage(m.chat.id, 'Use inline keyboard', reply_markup=keyboard)
- creation_m = Message(c_m)
- if indb.isNew(creation_m):
- indb.add(creation_m)
- print(len(indb.db))
- elif m.text == "/booty_rate" or m.text == "/booty_rate" + bot_tag:
- # get the picture
- image_voted_already = True
- trials = 0
- while image_voted_already and trials <= len(vdb.votepicturesdb):
- file_idx = int(random.uniform(0, imgbooty.getSize()))
- file = imgbooty.getPicture(file_idx)
- if idb.isNew(file):
- bot.sendMessage(m.chat.id, "loading...")
- f = open(file, 'rb')
- r = bot.sendPhoto(m.chat.id, f)
- rm = Message(r)
- idb.addPathPic(file, rm.photo[0].file_id)
- idb.writePics()
- if vdb.isNew(file):
- picture = VotePicture(file)
- vdb.add(picture)
- else:
- picture = vdb.get_file_to_picture(file)
- # check if the person requesting the command has already voted
- if m.mfrom.id in picture.voterids:
- image_voted_already = True
- trials += 1
- print(trials)
- else:
- image_voted_already = False
- if image_voted_already == True and m.chat.type == "private":
- bot.sendMessage(m.chat.id, "You voted all the pictueres.\nNew one will come in the next updates\nUse /booty for results")
- else:
- keyboard = InlineKeyboardMarkup(inline_keyboard=[
- [InlineKeyboardButton(text='like 👍 - ' + str(picture.upvote),
- callback_data='brlike_' + str(picture.id))],
- [InlineKeyboardButton(text='dislike 👎 - '+ str(picture.downvote),
- callback_data='brdislike_' + str(picture.id))]
- ])
- if idb.isNew(file):
- bot.sendMessage(m.chat.id, "loading...")
- f = open(file, 'rb')
- c_m = bot.sendPhoto(m.chat.id, f, reply_markup=keyboard)
- idb.addPathPic(file, c_m.photo[0].file_id)
- idb.writePics()
- else:
- c_m = bot.sendPhoto(m.chat.id, idb.getPicId(picture.path), reply_markup=keyboard)
- creation_m = Message(c_m)
- picture.addCreationMessage(creation_m)
- elif m.text == "/help" or m.text == "/help" + bot_tag:
- bot.sendMessage(m.chat.id, bot_help)
- else:
- if m.chat.type == "private":
- bot.sendMessage(m.chat.id, m.text + " prot!")
- else:
- print("message content not supported")
- def query(msg):
- print("-------------------\n NEW QUERY \n-------------------")
- query_id, from_id, query_data = telepot.glance(msg, flavor='callback_query')
- print('Callback Query:', query_id, from_id, query_data)
- if query_data == "press":
- keyboard = InlineKeyboardMarkup(inline_keyboard=[
- [InlineKeyboardButton(text='Press me - edited', callback_data='press')],
- [InlineKeyboardButton(text='like me - edided', callback_data='like')]
- ])
- for cmid in indb.db:
- bot.editMessageReplyMarkup(cmid, keyboard)
- bot.answerCallbackQuery(query_id, text='Got it')
- if query_data == "like":
- bot.answerCallbackQuery(query_id, text='Liked it')
- if query_data == "bootyrate_like":
- print("Like")
- elif query_data == "bootyrate_dislike":
- print("Dislike")
- if query_data.startswith("br"):
- s = query_data.split('_')
- picid = int(s[1])
- pic = vdb.get_id_to_picvote(picid)
- print(pic.voterids)
- if pic.hasVoted(from_id):
- print("Already voted")
- return None
- else:
- pic.addVoterId(from_id)
- if query_data.startswith("brlike"):
- pic.upvote += 1
- #the picture
- print("The picture:", pic.path, "has received an upvote")
- print("total count:", pic.upvote)
- if query_data.startswith("brdislike"):
- pic.downvote += 1
- #the picture
- print("The picture:", pic.path, "has received a downvote")
- print("total count:", pic.downvote)
- # rested the inline keyboard
- keyboard = InlineKeyboardMarkup(inline_keyboard=[
- [InlineKeyboardButton(text='like 👍 - ' + str(pic.upvote),
- callback_data='brlike_' + str(pic.id))],
- [InlineKeyboardButton(text='dislike 👎 - '+ str(pic.downvote),
- callback_data='brdislike_' + str(pic.id))]
- ])
- print("Updating database...")
- vdb.update_database()
- for cmid in pic.creation_message_ids:
- bot.editMessageReplyMarkup(cmid, keyboard)
- idb = ImagesDB()
- imgbooty = ImageFolder("./data/booty/pic/")
- cdb = ChatDatabase()
- vdb = VoteDB()
- MessageLoop(bot,{'chat': handle,
- 'callback_query': query}).run_as_thread()
- print ('Listening ...')
- # Keep the program running.
- while 1:
- time.sleep(10)
Advertisement
Add Comment
Please, Sign In to add comment