import requests from bs4 import BeautifulSoup # MIT import urllib.parse class Game: def __init__(self, name,link,img): self.name = name.strip() self.link = link.strip() self.img = img.strip() if not name or not link or not img: raise ValueError("Please enter a name, link and img!") def __eq__(self, other): return self.name == other.name and self.link == other.link and self.img == other.img def get_csv_line(self): return f"{self.name};{self.link};{self.img}" class ModuleFreeGames: def __init__(self, subscriber, send_a, log): self.tag = "%20s - " % "mFreeGames" self.log = log self.game_dict = self.load_freegames_from_csv() self.subscriber = subscriber self.send_a = send_a self.log.debug(f"{self.tag}Modul FreeGames geladen") def crawl_game_list(self): temp_dict = {} try: data = requests.get("https://www.freegamesyo.com/").text soup = BeautifulSoup(data, features="html.parser") number = 0 for li in soup.find_all('li'): link = li.a['href'] name = li.find('h2').text img = li.find('noscript').find('img') src = img['src'] if name not in temp_dict: game = Game(name, link, f"game_{number}.jpeg") img_link = "https://www.freegamesyo.com"+urllib.parse.unquote(src) img_data = requests.get(img_link).content with open(game.img, 'wb') as handler: # can be overwritten because this will be the new list handler.write(img_data) temp_dict[name] = game number += 1 except Exception as ex: self.log.error(f"{self.tag}Failed crawling game list: {ex}") self.save_gamelist(temp_dict) return temp_dict def check_for_new_stuff(self): new = self.crawl_game_list() send_update = False for game in new: if game not in self.game_dict: send_update = True break self.game_dict = new # always overwrite to delete old games return send_update def auto_newsletter(self): send_update = self.check_for_new_stuff() if send_update: self.send_newsletter() def send_newsletter(self): for receiver in self.subscriber.values(): self.send_game(receiver) def send_game(self, receiver): for game in self.game_dict.values(): message = game.name + ":\n" message += game.link + " " self.send_a(message, receiver, f"/home/pi/signalbot/" + game.img) #self.send(message, receiver) def freegames(self, receiver): send_update = self.check_for_new_stuff() if send_update: if receiver in self.subscriber.values(): self.send_newsletter() else: self.send_game(receiver) self.send_newsletter() else: self.send_game(receiver) def load_freegames_from_csv(self): lines = [] try: with open("/home/pi/signalbot/freegameslist.csv", 'r', encoding='utf16') as f: lines = f.readlines() except IOError as exc: self.log.error( f"{self.tag}Reading freegameslist from csv failed: {exc}") temp_dict = {} for line in lines: try: game = self.interpret_game_line(line) temp_dict[game.name] = game except (SyntaxError, ValueError) as exc: self.log.warning(f"{self.tag}Error while interpreting game line:{line}; Error: {exc}") return temp_dict def interpret_game_line(self, line): splitted = line.strip().split(";") if not (len(splitted) == 3): raise SyntaxError("Invalid game syntax! Needs to be: 'name;link;img_filename'") return Game(splitted[0].strip(), splitted[1].strip(), splitted[2].strip()) def save_gamelist(self, gamelist): try: with open("/home/pi/signalbot/freegameslist.csv", 'w', encoding='utf16') as f: for game in gamelist.values(): f.write(f"{game.name};{game.link};{game.img}\n") except IOError as exc: self.log.error(f"{self.tag}saving game to '/home/pi/signalbot/freegameslist.csv' failed: {exc}")