Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

python-telegram-bot v7 compatability + more #35

Merged
merged 17 commits into from
Aug 18, 2017
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Config file
config.json

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
Expand Down
17 changes: 9 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,19 @@

[![License: AGPL v3](https://img.shields.io/badge/License-AGPL%20v3-blue.svg)](./LICENSE)

Telegram Bot that allows you to play the popular card game UNO via inline queries. The bot currently runs as [@unobot](http://telegram.me/unobot)
Telegram Bot that allows you to play the popular card game UNO via inline queries. The bot currently runs as [@unobot](http://telegram.me/unobot).

To run the bot yourself, you will need:
- Python (tested with 3.4 and 3.5)
- The [python-telegram-bot](https://github.com/python-telegram-bot/python-telegram-bot) module version 5.0.0
- Python (tested with 3.4+)
- The [python-telegram-bot](https://github.com/python-telegram-bot/python-telegram-bot) module
- [Pony ORM](https://ponyorm.com/)

## Setup
- Get a bot token from [@BotFather](http://telegram.me/BotFather) and place it in `credentials.py`
- Convert all language files from .po to .mo using `msgfmt unobot.po -o unobot.mo`
- Use `/setinline` and `/setinlinefeedback` with BotFather for your bot
- Get a bot token from [@BotFather](http://telegram.me/BotFather) and change configurations in `config.json`.
- Convert all language files from `.po` files to `.mo` files using `msgfmt unobot.po -o unobot.mo`.
Also try `find . -maxdepth 2 -type d -name 'LC_MESSAGES' -exec bash -c 'msgfmt {}/unobot.po -o {}/unobot.mo' \;`.
- Use `/setinline` and `/setinlinefeedback` with BotFather for your bot.

Then run the bot with `python3 bot.py`
Then run the bot with `python3 bot.py`.

Code documentation is minimal but there
Code documentation is minimal but there.
71 changes: 55 additions & 16 deletions bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.


import logging
from datetime import datetime
from random import randint
Expand Down Expand Up @@ -45,13 +44,16 @@

from simple_commands import help

#import json
#with open("config.json","r") as f:
# config = json.loads(f.read())
#forbidden = config.get("black_list", None)

logging.basicConfig(
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
level=logging.INFO)
logger = logging.getLogger(__name__)


@user_locale
def notify_me(bot, update):
"""Handler for /notify_me command, pm people for next game"""
Expand Down Expand Up @@ -88,14 +90,50 @@ def new_game(bot, update):
del gm.remind_dict[update.message.chat_id]

game = gm.new_game(update.message.chat)
game.owner = update.message.from_user
game.starter = update.message.from_user
game.owner.append(update.message.from_user.id)
send_async(bot, chat_id,
text=_("Created a new game! Join the game with /join "
"and start the game with /start"))

if botan:
botan.track(update.message, 'New games')

@user_locale
def kill_game(bot, update):
"""Handler for the /kill command"""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Recommend put a tip for command in /help

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK

chat = update.message.chat
user = update.message.from_user
games = gm.chatid_games.get(chat.id)

if update.message.chat.type == 'private':
help(bot, update)
return

if not games:
send_async(bot, chat.id,
text=_("There is no running game in this chat."))
return

game = games[-1]

if user.id in game.owner:

try:
gm.end_game(chat, user)
send_async(bot, chat.id, text=__("Game ended!", multi=game.translate))

except NoGameInChatError:
send_async(bot, chat.id,
text=_("The game is not started yet. "
"Join the game with /join and start the game with /start"),
reply_to_message_id=update.message.message_id)

else:
send_async(bot, chat.id,
text=_("Only the game creator ({name}) and admin can do that.")
.format(name=game.starter.first_name),
reply_to_message_id=update.message.message_id)

@user_locale
def join_game(bot, update):
Expand Down Expand Up @@ -321,16 +359,16 @@ def close_game(bot, update):

game = games[-1]

if game.owner.id == user.id:
if user.id in game.owner:
game.open = False
send_async(bot, chat.id, text=_("Closed the lobby. "
"No more players can join this game."))
return

else:
send_async(bot, chat.id,
text=_("Only the game creator ({name}) can do that.")
.format(name=game.owner.first_name),
text=_("Only the game creator ({name}) and admin can do that.")
.format(name=game.starter.first_name),
reply_to_message_id=update.message.message_id)
return

Expand All @@ -349,15 +387,15 @@ def open_game(bot, update):

game = games[-1]

if game.owner.id == user.id:
if user.id in game.owner:
game.open = True
send_async(bot, chat.id, text=_("Opened the lobby. "
"New players may /join the game."))
return
else:
send_async(bot, chat.id,
text=_("Only the game creator ({name}) can do that")
.format(name=game.owner.first_name),
text=_("Only the game creator ({name}) and admin can do that.")
.format(name=game.starter.first_name),
reply_to_message_id=update.message.message_id)
return

Expand All @@ -376,16 +414,16 @@ def enable_translations(bot, update):

game = games[-1]

if game.owner.id == user.id:
if user.id in game.owner:
game.translate = True
send_async(bot, chat.id, text=_("Enabled multi-translations. "
"Disable with /disable_translations"))
return

else:
send_async(bot, chat.id,
text=_("Only the game creator ({name}) can do that")
.format(name=game.owner.first_name),
text=_("Only the game creator ({name}) and admin can do that.")
.format(name=game.starter.first_name),
reply_to_message_id=update.message.message_id)
return

Expand All @@ -404,7 +442,7 @@ def disable_translations(bot, update):

game = games[-1]

if game.owner.id == user.id:
if user.id in game.owner:
game.translate = False
send_async(bot, chat.id, text=_("Disabled multi-translations. "
"Enable them again with "
Expand All @@ -413,8 +451,8 @@ def disable_translations(bot, update):

else:
send_async(bot, chat.id,
text=_("Only the game creator ({name}) can do that")
.format(name=game.owner.first_name),
text=_("Only the game creator ({name}) and admin can do that.")
.format(name=game.starter.first_name),
reply_to_message_id=update.message.message_id)
return

Expand Down Expand Up @@ -728,6 +766,7 @@ def do_call_bluff(bot, player):
dispatcher.add_handler(CallbackQueryHandler(select_game))
dispatcher.add_handler(CommandHandler('start', start_game, pass_args=True))
dispatcher.add_handler(CommandHandler('new', new_game))
dispatcher.add_handler(CommandHandler('kill', kill_game))
dispatcher.add_handler(CommandHandler('join', join_game))
dispatcher.add_handler(CommandHandler('leave', leave_game))
dispatcher.add_handler(CommandHandler('open', open_game))
Expand All @@ -740,7 +779,7 @@ def do_call_bluff(bot, player):
dispatcher.add_handler(CommandHandler('notify_me', notify_me))
simple_commands.register()
settings.register()
dispatcher.add_handler(MessageHandler([Filters.status_update], status_update))
dispatcher.add_handler(MessageHandler(Filters.status_update, status_update))
dispatcher.add_error_handler(error)

start_bot(updater)
Expand Down
10 changes: 4 additions & 6 deletions card.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.


from telegram.emoji import Emoji

# Colors
RED = 'r'
BLUE = 'b'
Expand All @@ -30,10 +28,10 @@
COLORS = (RED, BLUE, GREEN, YELLOW)

COLOR_ICONS = {
RED: Emoji.HEAVY_BLACK_HEART,
BLUE: Emoji.BLUE_HEART,
GREEN: Emoji.GREEN_HEART,
YELLOW: Emoji.YELLOW_HEART,
RED: '❤️',
BLUE: '💙',
GREEN: '💚',
YELLOW: '💛',
BLACK: '⬛️'
}

Expand Down
8 changes: 8 additions & 0 deletions config.json.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"token": "token_here",
"botan_token": null,
"admin_list": [0],
"open_lobby": true,
"enable_translations": false,
"workers": 32
}
21 changes: 0 additions & 21 deletions credentials.py

This file was deleted.

14 changes: 8 additions & 6 deletions game.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,25 @@


import logging
import json
from datetime import datetime

from deck import Deck
import card as c


class Game(object):
""" This class represents a game of UNO """
current_player = None
reversed = False
draw_counter = 0
choosing_color = False
started = False
owner = None
open = True
translate = False
draw_counter = 0
players_won = 0
starter = None
with open("config.json","r") as f:
config = json.loads(f.read())
owner = config.get("admin_list", None)
open = config.get("open_lobby", True)
translate = config.get("enable_translations", False)

def __init__(self, chat):
self.chat = chat
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
python-telegram-bot==5
python-telegram-bot
pony
22 changes: 11 additions & 11 deletions settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.


from telegram import ReplyKeyboardMarkup, Emoji
from telegram import ReplyKeyboardMarkup
from telegram.ext import CommandHandler, RegexHandler

from utils import send_async
Expand All @@ -44,12 +44,12 @@ def show_settings(bot, update):
us = UserSetting(id=update.message.from_user.id)

if not us.stats:
stats = Emoji.BAR_CHART + ' ' + _("Enable statistics")
stats = '📊' + ' ' + _("Enable statistics")
else:
stats = Emoji.CROSS_MARK + ' ' + _("Delete all statistics")
stats = '❌' + ' ' + _("Delete all statistics")

kb = [[stats], [Emoji.EARTH_GLOBE_EUROPE_AFRICA + ' ' + _("Language")]]
send_async(bot, chat.id, text=Emoji.WRENCH + ' ' + _("Settings"),
kb = [[stats], ['🌍' + ' ' + _("Language")]]
send_async(bot, chat.id, text='🔧' + ' ' + _("Settings"),
reply_markup=ReplyKeyboardMarkup(keyboard=kb,
one_time_keyboard=True))

Expand All @@ -60,20 +60,20 @@ def kb_select(bot, update, groups):
user = update.message.from_user
option = groups[0]

if option == Emoji.BAR_CHART:
if option == '📊':
us = UserSetting.get(id=user.id)
us.stats = True
send_async(bot, chat.id, text=_("Enabled statistics!"))

elif option == Emoji.EARTH_GLOBE_EUROPE_AFRICA:
elif option == '🌍':
kb = [[locale + ' - ' + descr]
for locale, descr
in sorted(available_locales.items())]
send_async(bot, chat.id, text=_("Select locale"),
reply_markup=ReplyKeyboardMarkup(keyboard=kb,
one_time_keyboard=True))

elif option == Emoji.CROSS_MARK:
elif option == '❌':
us = UserSetting.get(id=user.id)
us.stats = False
us.first_places = 0
Expand All @@ -98,9 +98,9 @@ def locale_select(bot, update, groups):

def register():
dispatcher.add_handler(CommandHandler('settings', show_settings))
dispatcher.add_handler(RegexHandler('^([' + Emoji.BAR_CHART +
Emoji.EARTH_GLOBE_EUROPE_AFRICA +
Emoji.CROSS_MARK + ']) .+$',
dispatcher.add_handler(RegexHandler('^([' + '📊' +
'🌍' +
'❌' + ']) .+$',
kb_select, pass_groups=True))
dispatcher.add_handler(RegexHandler(r'^(\w\w_\w\w) - .*',
locale_select, pass_groups=True))
11 changes: 5 additions & 6 deletions shared_vars.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,20 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.


import json
from telegram.ext import Updater
from telegram.contrib.botan import Botan

from game_manager import GameManager
from database import db
from credentials import TOKEN, BOTAN_TOKEN

db.bind('sqlite', 'uno.sqlite3', create_db=True)
db.generate_mapping(create_tables=True)

gm = GameManager()
updater = Updater(token=TOKEN, workers=32)
with open("config.json","r") as f:
config = json.loads(f.read())
updater = Updater(token=config.get("token"), workers=config.get("workers", 32))
dispatcher = updater.dispatcher

botan = False
if BOTAN_TOKEN:
botan = Botan(BOTAN_TOKEN)
botan = Botan(config.get("botan_token", None))
1 change: 1 addition & 0 deletions simple_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
"Other commands (only game creator):\n"
"/close - Close lobby\n"
"/open - Open lobby\n"
"/kill - Terminate the game\n"
"/enable_translations - Translate relevant texts into all "
"languages spoken in a game\n"
"/disable_translations - Use English for those texts\n\n"
Expand Down
Loading