Skip to content

Commit

Permalink
Merge pull request #10 from GianmarcoBasile/test
Browse files Browse the repository at this point in the history
Test
  • Loading branch information
GianmarcoBasile authored Jan 27, 2024
2 parents 61422aa + 2fb727b commit 1c572c1
Show file tree
Hide file tree
Showing 18 changed files with 597 additions and 91 deletions.
Binary file added .coverage
Binary file not shown.
5 changes: 5 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[run]
omit =
src/main.py
src/bot.py
src/database.py
File renamed without changes.
4 changes: 3 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
python-telegram-bot
python-telegram-bot[job-queue]
python-dotenv
redis
pymongo==3.12.3
requests
json_stream
1 change: 1 addition & 0 deletions requirements_dev.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
pytest
pytest-mock
pytest-cov
pytest-asyncio
pylint
273 changes: 205 additions & 68 deletions src/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,93 +2,230 @@
"""Module providing commands for the bot"""

import json
import requests
from database import initialize_db as db
from utils import get_game_list
from utils import (
get_game_list,
get_game_id_by_name,
check_similarities,
get_games_record,
update_games_record,
)
from news_parser import parser
from telegram.constants import ParseMode

redis_instance = db('localhost', 6379)
mongo_instance = db("mongodb://localhost", 27017)
app_list = get_game_list()
required_argument = 'This command requires one argument: '
syntax_error = "The correct syntax for this command is: "


async def start(update, context):
redis_instance.set(update.message.from_user['username'], json.dumps({'games': {}}))
await update.message.reply_text('Welcome to Steam News Bot!')
sender = update.message.from_user["username"]
if not mongo_instance["USERS"]["users"].find_one(
{"chat_id": update.message.chat_id}
):
mongo_instance["USERS"]["users"].insert_one(
{"chat_id": update.message.chat_id, "user": sender, "games": {}}
)
await update.message.reply_text("Welcome to Steam News Bot!")


async def addGame(update, context):
games_record = {}
try:
if context.args:
game_name = ' '.join(context.args).lower()
game_name = " ".join(context.args).lower()
if game_name in app_list.values():
games_list = json.loads(redis_instance.get(update.message.from_user['username']))['games']
if not games_list:
games_json = {'games': {0: game_name}}
redis_instance.set(update.message.from_user['username'], json.dumps(games_json))
await update.message.reply_text('Games set to ' + game_name)
else:
games = []
games_json = json.loads(redis_instance.get(update.message.from_user['username']))
if game_name not in games_json['games'].values():
games_json['games'].update({len(games_json['games']): game_name})
games = list(games_json['games'].values())
redis_instance.set(update.message.from_user['username'], json.dumps(games_json))
await update.message.reply_text('Games set to ' + str(games).replace('[', '').replace(']', '').replace("'", ''))
try:
games_record = get_games_record(
update.message.from_user["username"]
)
except Exception as e:
print(e)
if game_name not in games_record["games"].values():
if games_record["games"] == {}:
games_record["games"] = {"0": game_name}
else:
await update.message.reply_text('Game already in your favorites')
games_record["games"].update(
{str(int(max(games_record["games"])) + 1): game_name}
)
update_games_record(
update.message.from_user["username"], games_record
)
await update.message.reply_text(
"Game " + str(game_name) + " added to the list"
)
else:
await update.message.reply_text("The game is already in the list")
else:
await update.message.reply_text('Game not found')
suggestions = check_similarities(game_name)
if len(suggestions) > 0:
await update.message.reply_text(
"Game not found. Maybe you meant: " + suggestions
)
else:
await update.message.reply_text("The game is not a steam game")
else:
await update.message.reply_text(required_argument + '/addgame <game_name>')
await update.message.reply_text(syntax_error + "/addgame <game_name>")
except Exception as e:
print(e)

async def deleteGame(update, context):

async def deleteGame(update, context):
if context.args:
game_name = ' '.join(context.args).lower()
games_list = json.loads(redis_instance.get(update.message.from_user['username']))['games']
if not games_list:
await update.message.reply_text('The favourite game list is empty')
game_name = " ".join(context.args).lower()
try:
games_record = get_games_record(update.message.from_user["username"])
except Exception as e:
print(e)
if game_name in games_record["games"].values():
games_record["games"].pop(
str(list(games_record["games"].values()).index(game_name))
)
update_games_record(update.message.from_user["username"], games_record)
await update.message.reply_text(
"Game " + str(game_name) + " deleted from the list"
)
else:
games_json = json.loads(redis_instance.get(update.message.from_user['username']))
if game_name in games_json['games'].values():
for key, value in games_json['games'].items():
if value == game_name:
games_json['games'].pop(key)
break
new_games_json = {'games':{}}
for key, value in games_json['games'].items():
new_games_json['games'].update({len(new_games_json['games']): value})
redis_instance.set(update.message.from_user['username'], json.dumps(new_games_json))
await update.message.reply_text('Game ' + str(game_name)+ ' removed from the list')
else:
await update.message.reply_text('The game is not in the list')
await update.message.reply_text("The game is not in the list")
else:
await update.message.reply_text(required_argument + '/deletegame <game_name>')
await update.message.reply_text(syntax_error + "/deletegame <game_name>")


async def clearGamesList(update, context):
redis_instance.set(update.message.from_user['username'], json.dumps({'games': {}}))
await update.message.reply_text('Game list cleared')

# async def getNews(update, context):
# global game_id
# if context.args:
# r = requests.get('http://api.steampowered.com/ISteamNews/GetNewsForApp/v0002/?appid=' + getGameIdByName(context.args[0]) + '&count=3&maxlength=300&format=json')
# print(r.json())
# await update.message.reply_text('News for game ' + context.args[0])
# elif not context.args and game_id != '':
# r = requests.get('http://api.steampowered.com/ISteamNews/GetNewsForApp/v0002/?appid=' + game_id + '&count=3&maxlength=300&format=json')
# print(r.json())
# await update.message.reply_text('News for game ' + game_id)
# else:
# await update.message.reply_text('La sintassi del comando prevede che tu abbia prima settato un gioco oppure che tu inserisca un argomento: /getnews <game_id>')

# async def getNews(context):
# global game_id
# print('gameid:', game_id)
# r = requests.get('http://api.steampowered.com/ISteamNews/GetNewsForApp/v0002/?appid=' + game_id + '&count=3&maxlength=300&format=json')
# print(r.json())
# return r.json()
if not context.args:
try:
games_record = get_games_record(update.message.from_user["username"])
except Exception as e:
print(e)
games_record["games"] = {}
update_games_record(update.message.from_user["username"], games_record)
await update.message.reply_text("Games list cleared")
else:
await update.message.reply_text(syntax_error + "/cleargameslist")


async def getNews(update, context):
if not context.args:
try:
games = get_games_record(update.message.from_user["username"])
for game in games["games"].values():
r = requests.get(
"http://api.steampowered.com/ISteamNews/GetNewsForApp/v0002/?appid="
+ str(get_game_id_by_name(game))
+ "&count=5&maxlength=50000&format=json"
)
news_list = r.json()["appnews"]["newsitems"]
# added_news = []
for news in news_list:
news_message = parser(news)
await update.message.reply_text(
news_message, parse_mode=ParseMode.HTML
)
except Exception as e:
print(e)
else:
await update.message.reply_text(syntax_error + "/getnews")


async def getNewsAuto(context): # pragma: no cover
users = mongo_instance["USERS"]["users"].find()
for user in users:
for game in user["games"].values():
r = requests.get(
"http://api.steampowered.com/ISteamNews/GetNewsForApp/v0002/?appid="
+ str(get_game_id_by_name(game))
+ "&count=1&maxlength=50000&format=json"
)
news_list = r.json()["appnews"]["newsitems"]
for news in news_list:
news_message = parser(news)
await context.bot.send_message(
user["chat_id"], news_message, parse_mode=ParseMode.HTML
)


async def getFavoriteGames(update, context):
games = list(json.loads(redis_instance.get(update.message.from_user['username']))['games'].values())
print(games)
await update.message.reply_text('Favorite Games: ' + str(games).replace('[', '').replace(']', '').replace("'", ''))
if not context.args:
try:
games_record = get_games_record(update.message.from_user["username"])
except Exception as e:
print(e)
games = list(games_record["games"].values())
await update.message.reply_text(
"Favorite Games: "
+ str(games).replace("[", "").replace("]", "").replace("'", "")
)
else:
await update.message.reply_text(syntax_error + "/favoritegames")


async def saleOnGames(update, context): # pragma: no cover
if not context.args:
games_record = mongo_instance["USERS"]["users"].find_one(
{"user": update.message.from_user["username"]}
)
for game in games_record["games"].values():
game_id = str(get_game_id_by_name(game))
r = requests.get(
"https://store.steampowered.com/api/appdetails/?appids="
+ game_id
+ "&currency=EUR"
)
req = r.json()[game_id]
if req["success"]:
curr_game = req["data"]
if curr_game["is_free"]:
await update.message.reply_text("The game " + game + " is free")
elif (
curr_game["price_overview"]["initial"]
== curr_game["price_overview"]["final"]
):
await update.message.reply_text(
"The game "
+ game
+ " is not on sale. It costs "
+ curr_game["price_overview"]["final_formatted"]
)
else:
await update.message.reply_text(
"The game "
+ game
+ " is on sale for "
+ curr_game["price_overview"]["final_formatted"]
+ " instead of "
+ curr_game["price_overview"]["initial_formatted"]
)
else:
await update.message.reply_text(syntax_error + "/checksales")


async def saleOnGamesAuto(context): # pragma: no cover
users = mongo_instance["USERS"]["users"].find()
for user in users:
for game in user["games"].values():
game_id = str(get_game_id_by_name(game))
r = requests.get(
"https://store.steampowered.com/api/appdetails/?appids="
+ game_id
+ "&currency=EUR"
)
req = r.json()[game_id]
if req["success"]:
curr_game = req["data"]
if curr_game["is_free"]:
continue
elif (
curr_game["price_overview"]["initial"]
== curr_game["price_overview"]["final"]
):
await context.bot.send_message(
user["chat_id"], game + " is not on sale"
)
else:
await context.bot.send_message(
user["chat_id"],
game
+ " is on sale for "
+ curr_game["price_overview"]["final_formatted"],
)
11 changes: 8 additions & 3 deletions src/database.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
"""Module providing Database API."""
import pymongo


import redis
def initialize_db(host, port):
"""Initialize Database."""
db = redis.Redis(host=host, port=port, decode_responses=True)
return db
try:
mongo = pymongo.MongoClient(host + ":" + str(port) + "/", connectTimeoutMS=5000)
except pymongo.errors.ServerSelectionTimeoutError as e:
print("Error connecting to the database: " + str(e))
return None
return mongo
47 changes: 36 additions & 11 deletions src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,52 @@
from dotenv import load_dotenv
from telegram.ext import CommandHandler
from bot import Bot
from commands import start, addGame, getFavoriteGames, deleteGame,clearGamesList
from commands import (
start,
addGame,
getFavoriteGames,
deleteGame,
clearGamesList,
getNews,
getNewsAuto,
saleOnGames,
saleOnGamesAuto,
)

load_dotenv()
API_KEY = os.environ['API_KEY']
API_KEY = os.environ["API_KEY"]
bot_instance = Bot(API_KEY)

# http://api.steampowered.com/ISteamNews/GetNewsForApp/v0002/?appid=440&count=3&maxlength=300&format=json


def main():
"""Main function which runs the bot and adds the handlers"""
# Commands
bot_instance.application.add_handler(CommandHandler('start', start))
# application.add_handler(CommandHandler('getnews', getNews))
bot_instance.application.add_handler(CommandHandler('addgame', addGame))
bot_instance.application.add_handler(CommandHandler('favoritegames', getFavoriteGames))
#il nome del comando nel bot è favoritegame, da modificare in favoritegames
bot_instance.application.add_handler(CommandHandler('deletegame', deleteGame))
bot_instance.application.add_handler(CommandHandler('cleargameslist', clearGamesList))
# application.job_queue.run_repeating(getNews, interval=10, first=0)
bot_instance.application.add_handler(CommandHandler("start", start))
bot_instance.application.add_handler(CommandHandler("getnews", getNews))
bot_instance.application.add_handler(CommandHandler("checksales", saleOnGames))
bot_instance.application.add_handler(CommandHandler("addgame", addGame))
bot_instance.application.add_handler(
CommandHandler("favoritegames", getFavoriteGames)
)
bot_instance.application.add_handler(CommandHandler("deletegame", deleteGame))
bot_instance.application.add_handler(
CommandHandler("cleargameslist", clearGamesList)
)
# Jobs: get news every 24 hours
bot_instance.application.job_queue.run_once(getNewsAuto, 0)
bot_instance.application.job_queue.run_repeating(
getNewsAuto, interval=86400, first=0
)
# Jobs: check for sales every 24 hours
bot_instance.application.job_queue.run_once(saleOnGamesAuto, 5)
bot_instance.application.job_queue.run_repeating(
saleOnGamesAuto, interval=86400, first=0
)
# Run bot
bot_instance.application.run_polling(1.0)

if __name__ == '__main__':

if __name__ == "__main__":
main()
Loading

0 comments on commit 1c572c1

Please sign in to comment.