def get_list_contents(self): result = set() print("read_list_contents", self.list_path) with open(self.list_path, "rb") as f: for line in f.readlines(): line = line.strip() if not line: continue print(line) parts = line.rsplit("(", 1) name = parts[0] platform = None if len(parts) == 2: parts = parts[1][:-1].split(",", 1) platform = parts[0] if len(parts) == 2: # FIXME variant... pass print(name, platform) cmp_game = GameNameUtil.create_cmpname(name) if platform: cmp_platform = GameNameUtil.create_cmpname(platform) result.add((cmp_game, cmp_platform)) else: result.add(cmp_game) return result
def game_filter(row): # print(game_info) game_filter_set = self.get_list_contents() # print(self.game_filter_set) cmp_game = GameNameUtil.create_cmpname(row[ROW_NAME]) # print("check -- ", cmp_game) if cmp_game in game_filter_set: return True cmp_platform = GameNameUtil.create_cmpname(row[ROW_PLATFORM]) # print("check -- ", (cmp_game, cmp_platform)) if (cmp_game, cmp_platform) in game_filter_set: return True return False
def _get_state_dir(self): config_name = self.config_name if not config_name: config_name = "Default" # Use a temporary state dir, for now, to avoid problems with # floppy overlays etc interfering with net play. if self.fsgc.netplay.enabled: # It is possible to manually specify the state dir. config_name = self.fsgc.config.get("__netplay_state_dir_name") if not config_name: # This is the default behavior, create a clean state # dir for the net play session. netplay_game = self.fsgc.config.get("__netplay_game") if netplay_game: config_name = "Net Play ({0})".format(netplay_game) # Convert the config name to a name which can be represented on # the file system (really all/most filesystems). config_name = GameNameUtil.create_fs_name(config_name) letter = self.get_letter(config_name) if not letter: config_name = "Default" letter = self.get_letter(config_name) # We use an existing state dir in a "letter" dir if it already # exists (legacy support). path = os.path.join( FSGSDirectories.get_save_states_dir(), letter, config_name ) if os.path.exists(path): return path # If not, we use a direct sub-folder of save states dir. path = os.path.join(FSGSDirectories.get_save_states_dir(), config_name) return path
def update_search(self): search = LauncherSettings.get("config_search").strip().lower() print("search for", search) words = [] special = [] for word in search.split(" "): word = word.strip() if not word: continue if ":" in word[1:-1]: special.append(word) else: words.append(word) terms = GameNameUtil.extract_search_terms(" ".join(words)) terms.update(special) database = Database.get_instance() try: have = int(LauncherSettings.get("database_show_games")) except ValueError: # default is show all downloadable and locally available games have = 1 items = database.find_games_new( " ".join(terms), have=have, list_uuid=LauncherSettings.get("game_list_uuid"), ) self.set_items(items)
def _get_state_dir(self): config_name = self.config_name if not config_name: config_name = "Default" # Use a temporary state dir, for now, to avoid problems with # floppy overlays etc interfering with net play. if self.fsgc.netplay.enabled: # It is possible to manually specify the state dir. config_name = self.fsgc.config.get("__netplay_state_dir_name") if not config_name: # This is the default behavior, create a clean state # dir for the net play session. netplay_game = self.fsgc.config.get("__netplay_game") if netplay_game: config_name = "Net Play ({0})".format(netplay_game) # Convert the config name to a name which can be represented on # the file system (really all/most filesystems). config_name = GameNameUtil.create_fs_name(config_name) letter = self.get_letter(config_name) if not letter: config_name = "Default" letter = self.get_letter(config_name) # We use an existing state dir in a "letter" dir if it already # exists (legacy support). path = os.path.join(FSGSDirectories.get_save_states_dir(), letter, config_name) if os.path.exists(path): return path # If not, we use a direct sub-folder of save states dir. path = os.path.join(FSGSDirectories.get_save_states_dir(), config_name) return path
def update_search(self): search = LauncherSettings.get("config_search").strip().lower() print("search for", search) words = [] special = [] for word in search.split(" "): word = word.strip() if not word: continue if ":" in word[1:-1]: special.append(word) else: words.append(word) terms = GameNameUtil.extract_search_terms(" ".join(words)) terms.update(special) database = Database.get_instance() try: have = int(LauncherSettings.get("database_show_games")) except ValueError: # default is show all downloadable and locally available games have = 1 items = database.find_games_new( " ".join(terms), have=have, list_uuid=LauncherSettings.get("game_list_uuid")) self.set_items(items)
def main(): Application("fs-uae-game-system") if "--unsupported" in sys.argv: if "--http-server" in sys.argv: from fsgs.http.server import http_server_main return http_server_main() if len(sys.argv) < 3: print("") print("usage: fsgs run <game>") print("") print("game:") print(" - search term(s) identifying a single game") print(" - path to a .fsgs file") print(" - path to a recognized cartridge ROM or disk file format") print("") sys.exit(1) assert sys.argv[1] == "run" game_arg = " ".join(sys.argv[2:]) print(game_arg) if os.path.exists(game_arg): load_file(game_arg) else: search = game_arg.lower() database = Database.instance() # cursor.execute("SELECT id FROM game WHERE name like") terms = GameNameUtil.extract_search_terms(search) found_games = database.find_games_new(" ".join(terms)) games = [] for game in found_games: print(list(game)) if game[0]: # only process entries with a game uuid games.append(game) game_uuid = None if len(games) == 0: print("no games found") sys.exit(2) if len(games) > 1: matches = 0 for row in games: if row[1].lower() == search: if game_uuid is None: game_uuid = row[0] matches += 1 if matches != 1: print("") print("More than one game matches:") print("") for row in games: print(" {0} ({1})".format(row[1], row[2])) print(" {0}".format(row[0])) print("") sys.exit(3) game_uuid = games[0][0] assert game_uuid variant_uuid = find_preferred_variant(game_uuid) load_game_variant(variant_uuid) fsgs.run_game()
def get_state_dir(self): """This is the old deprecated save sate directory for games.""" state_dir = os.path.join(FSGSDirectories.get_save_states_dir(), GameNameUtil.create_fs_name(self.get_name())) if not os.path.exists(state_dir): os.makedirs(state_dir) if self.fsgc.game.variant.uuid: uuid_file = os.path.join(state_dir, "uuid.txt") with io.open(uuid_file, "w", encoding="UTF-8") as f: f.write(self.fsgc.game.variant.uuid + "\n") # timestamp_file = os.path.join(state_dir, "timestamp.txt") # with open(timestamp_file, "wb") as f: # f.write("\n") return state_dir
def get_state_dir(self): state_dir = os.path.join( FSGSDirectories.get_save_states_dir(), GameNameUtil.create_fs_name(self.get_name())) if not os.path.exists(state_dir): os.makedirs(state_dir) if self.fsgs.game.variant.uuid: uuid_file = os.path.join(state_dir, "uuid.txt") with io.open(uuid_file, "w", encoding="UTF-8") as f: f.write(self.fsgs.game.variant.uuid + "\n") # timestamp_file = os.path.join(state_dir, "timestamp.txt") # with open(timestamp_file, "wb") as f: # f.write("\n") return state_dir
def get_image_path(self): cmp_name = GameNameUtil.create_cmpname(self.name) # FIXME: FIXME: DISABLED TEMPORARILY # FIXME: USING 512-size only for now # if False and os.path.exists("../fs-game-database/game/texture"): # if os.path.exists("../fs-game-database/game/texture"): # base_path = "../fs-game-database/game/texture" # path = os.path.join(base_path, NameUtil.create_cmpname( # self.platform), cmp_name, "front-512.jpg") # #self.platform), cmp_name, "front-1024.jpg") # if os.path.exists(path): # return path # #else: # base_path = os.path.join(pyapp.app.get_data_dir(), "texture") # if os.path.exists("c:\\data\\game\\info"): # base_path = "c:\\data\\game\\info" # else: # base_path = os.path.join(pyapp.app.get_data_dir(), "info") # base_path = os.path.join(GameCenter.data_dir, "info") # path = os.path.join(base_path, NameUtil.create_cmpname(self.platform), # cmp_name, "front.jpg") # if not os.path.exists(path): # base_path = "c:\\data\\game\\info" # path = os.path.join(base_path, NameUtil.create_cmpname( # self.platform), cmp_name, "front.jpg") # #cmp_name, "front-1024.jpg") # if not os.path.exists(path): # path = os.path.join(base_path, # NameUtil.create_cmpname(self.platform), # cmp_name, "front-512.jpg") # path = os.path.join(NameUtil.create_cmpname(self.platform), # cmp_name, "front.jpg") # return path # return self.game_info[5] + "?s=512&t=jpg" if not self.game_info[5]: return None return self.game_info[5] + "?w=480&h=640&t=cc&f=jpg"
def get_image_path(self): cmp_name = GameNameUtil.create_cmpname(self.name) # FIXME: FIXME: DISABLED TEMPORARILY # FIXME: USING 512-size only for now # if False and os.path.exists("../fs-game-database/game/texture"): # if os.path.exists("../fs-game-database/game/texture"): # base_path = "../fs-game-database/game/texture" # path = os.path.join(base_path, NameUtil.create_cmpname( # self.platform), cmp_name, "front-512.jpg") # #self.platform), cmp_name, "front-1024.jpg") # if os.path.exists(path): # return path # #else: # base_path = os.path.join(pyapp.app.get_data_dir(), "texture") # if os.path.exists("c:\\data\\game\\info"): # base_path = "c:\\data\\game\\info" # else: # base_path = os.path.join(pyapp.app.get_data_dir(), "info") # base_path = os.path.join(GameCenter.data_dir, "info") # path = os.path.join(base_path, NameUtil.create_cmpname(self.platform), # cmp_name, "front.jpg") # if not os.path.exists(path): # base_path = "c:\\data\\game\\info" # path = os.path.join(base_path, NameUtil.create_cmpname( # self.platform), cmp_name, "front.jpg") # #cmp_name, "front-1024.jpg") # if not os.path.exists(path): # path = os.path.join(base_path, # NameUtil.create_cmpname(self.platform), # cmp_name, "front-512.jpg") # path = os.path.join(NameUtil.create_cmpname(self.platform), # cmp_name, "front.jpg") # return path # return self.game_info[5] + "?s=512&t=jpg" if not self.game_info[5]: return None return self.game_info[5] + "?w=480&h=640&t=lbcover&f=jpg"
def create_search_results_menu(text): global current_menu try: if text == current_menu.search_text: return False except AttributeError: pass new_menu = SearchResultsMenu("Search Results") new_menu.search_text = text # words = [v.strip() for v in text.lower().split(" ")] # print "Creating search results for", words new_menu.top.append_left( SearchTextItem("Search: {0}_".format(text))) # clause = [] # args = [] # for word in words: # clause.append("AND name like ?") # args.append("%{0}%".format(word)) # clause = " ".join(clause) terms = GameNameUtil.extract_search_terms(text.lower()) for item in MenuItem.create_game_items(terms): new_menu.append(item) if len(new_menu) == 0: new_menu.append(NoItem("No Search Results")) # if hasattr(current_menu, "search_text"): # # replace current search menu, not append to path # #new_menu.parent_menu = current_menu.parent_menu # replace = True # else: # #new_menu.parent_menu = current_menu # replace = False replace = isinstance(current_menu, SearchResultsMenu) print("create search results menu") # set_current_menu(new_menu) enter_menu(new_menu, replace=replace) return True
def scan_game_database(self, helper, database_name, game_database): """ :type helper: ScanHelper :type database_name: str :type game_database: fsgs.GameDatabase.GameDatabase """ database_cursor = helper.database.cursor() # this holds a list of game entry UUIDs which must exist / be checked # after variants have been processed # ensure_updated_games = set() game_database_cursor = game_database.cursor() # this list will contain game entries which are not variants game_rows = [] game_database_cursor.execute( "SELECT id, uuid FROM game WHERE data != ''" ) for row in game_database_cursor: if self.stop_check(): return variant_id, variant_uuid_bin = row variant_uuid = binary_to_uuid(variant_uuid_bin) update_stamp = variant_id existing_variant = helper.existing_variants.get( variant_uuid, (None, None, None) ) existing_game = helper.existing_games.get( variant_uuid, (None, None, None) ) if update_stamp == existing_game[0]: # Game entry, not updated. game_rows.append(row) continue if update_stamp == existing_variant[0]: # entry was already updated and has not changed if existing_variant[1] and not helper.deleted_files: # have this entry already and no files have been deleted # since the last time # print("skipping variant (no deleted files)") helper.variant_seen(variant_uuid) continue if not existing_variant[1] and not helper.added_files: # do not have this entry, but no files have been added # since the last time # print("skipping variant (no added files)") helper.variant_seen(variant_uuid) continue else: # when the game entry has changed, we always check it # regardless of file database status, since file_list may # have been changed, or download status... (or other info # needs to be corrected) # print("[SCANNER] Changed: {}".format(variant_uuid)) pass self.scan_count += 1 self.set_status( gettext("Scanning game variants ({count} scanned)").format( count=self.scan_count ), variant_uuid, ) try: doc = self.fsgs.game.get_game_values_for_id( game_database, variant_id ) except IncompleteGameException as e: print("[SCANNER]", repr(e)) continue file_list_json = doc.get("file_list", "") if not file_list_json: # not a game variant... (parent game only probably) game_rows.append(row) continue entry_type = int(doc.get("_type", "0")) if (entry_type & GAME_ENTRY_TYPE_VARIANT) == 0: # game entry is not tagged with variant -- add to game list # instead game_rows.append(row) continue helper.variant_seen(variant_uuid) all_files_found = True try: file_list = json.loads(file_list_json) except Exception: # invalid JSON string # FIXME: log error all_files_found = False file_list = [] for file_item in file_list: if file_item["name"].endswith("/"): # skip directory entries: continue result = self.fsgs.file.check_sha1(file_item["sha1"]) if not result: all_files_found = False break if all_files_found: have_variant = 4 elif doc.get("download_file", ""): have_variant = 2 elif doc.get("download_page", ""): have_variant = 1 else: have_variant = 0 parent_uuid = doc.get("parent_uuid", "") variant_name = doc.get("variant_name", "") # published_variant = doc.get("publish", "") published_variant = doc.get("__publish_hack__", "") if not published_variant: published_variant = None elif published_variant == "1": published_variant = 1 else: published_variant = 0 game_variant_id = existing_variant[2] if not game_variant_id: # variant is not in database database_cursor.execute( "INSERT INTO game_variant (uuid) VALUES (?)", (variant_uuid,), ) game_variant_id = database_cursor.lastrowid database_cursor.execute( "UPDATE game_variant SET name = ?, game_uuid = ?, have = ?, " "update_stamp = ?, database = ?, published = ? WHERE id = ?", ( variant_name, parent_uuid, have_variant, update_stamp, database_name, published_variant, game_variant_id, ), ) # ensure_updated_games.add(parent_uuid) for row in game_rows: if self.stop_check(): return game_id, game_uuid_bin = row game_uuid = binary_to_uuid(game_uuid_bin) update_stamp = game_id existing_game = helper.existing_games.get( game_uuid, (None, None, None) ) if update_stamp == existing_game[0]: # after the loop has run its course, games to be removed # are left in existing_games helper.game_seen(game_uuid) continue self.scan_count += 1 self.set_status( gettext("Scanning games ({count} scanned)").format( count=self.scan_count ), game_uuid, ) doc = game_database.get_game_values(game_id) entry_type = int(doc.get("_type", "0")) if (entry_type & GAME_ENTRY_TYPE_GAME) == 0: continue # after the loop has run its course, games to be removed # are left in existing_games try: del helper.existing_games[game_uuid] except KeyError: pass game_name = doc.get("game_name", "") game_subtitle = doc.get("game_subtitle", "") platform = doc.get("platform", "") tags = doc.get("tags", "") year = doc.get("year", "") publisher = doc.get("publisher", "") front_sha1 = doc.get("front_sha1", "") title_sha1 = doc.get("title_sha1", "") screen1_sha1 = doc.get("screen1_sha1", "") screen2_sha1 = doc.get("screen2_sha1", "") screen3_sha1 = doc.get("screen3_sha1", "") screen4_sha1 = doc.get("screen4_sha1", "") screen5_sha1 = doc.get("screen5_sha1", "") thumb_sha1 = doc.get("thumb_sha1", "") backdrop_sha1 = doc.get("backdrop_sha1", "") published = doc.get("publish", "") sort_key = doc.get("sort_key", "") if not sort_key: # FIXME: handle the/a (etc) sort_key = game_name.lower() game_id = existing_game[2] if not game_id: # game is not in database database_cursor.execute( "INSERT INTO game (uuid) VALUES (?)", (game_uuid,) ) game_id = database_cursor.lastrowid search_terms = set() for key in [ "game_name", "full_name", "game_name_alt", "search_terms", "game_subtitle", ]: value = doc.get(key, "") if value: search_terms.update( GameNameUtil.extract_index_terms(value) ) letter = "" if len(sort_key) > 0: letter = sort_key[0].lower() if letter in "abcdefghijklmnopqrstuvwxyz": pass elif letter in "0123456789": letter = "#" else: letter = "?" search_terms.add("l:" + letter) for tag in tags.split(","): tag = tag.strip().lower() search_terms.add("t:" + tag) if year: search_terms.add("y:" + str(year)) if platform: search_terms.add("s:" + platform.lower()) if thumb_sha1: search_terms.add("t:thumb") if backdrop_sha1: search_terms.add("t:backdrop") backdrop_image = "sha1:{}/{}/{}/{}/{}".format( backdrop_sha1, doc.get("backdrop_zoom", "1.0"), doc.get("backdrop_zoom", "1.0"), doc.get("backdrop_halign", "0.5"), doc.get("backdrop_valign", "0.5"), ) else: backdrop_image = "" # if published: # # search_terms.add("t:published") # pass # else: # search_terms.add("t:unpublished") min_players = 0 max_players = 0 sim_players = 0 players = doc.get("players", "") if players == "1": min_players = max_players = 1 search_terms.add("p:1") elif players: try: parts1 = players.split("-") parts2 = parts1[1].split("(") min_players = int(parts1[0].strip()) max_players = int(parts2[0].strip()) sim_players = int(parts2[1].strip(" )")) except Exception as e: print("error parsing players") print(repr(e)) if min_players > 0: if max_players > 0: # we ignore players = 1 here, that is reserved for games # with max 1 players for i in range(min_players + 1, max_players + 1): search_terms.add("p:{0}".format(i)) if sim_players > 0: # we ignore players = 1 here, that is reserved for games # with max 1 players for i in range(min_players + 1, sim_players + 1): search_terms.add("p:{0}s".format(i)) database_cursor.execute( "UPDATE game SET name = ?, update_stamp = ?, sort_key = ?, " "platform = ?, " "publisher = ?, year = ?, front_image = ?, title_image = ?, " "screen1_image = ?, screen2_image = ?, screen3_image = ?, " "screen4_image = ?, screen5_image = ?, " "thumb_image = ?, backdrop_image = ?, " "adult = ?, published = ?, subtitle = ? WHERE id = ?", ( game_name, update_stamp, sort_key, platform, publisher or "", year or 0, "sha1:" + front_sha1 if front_sha1 else "", "sha1:" + title_sha1 if title_sha1 else "", "sha1:" + screen1_sha1 if screen1_sha1 else "", "sha1:" + screen2_sha1 if screen2_sha1 else "", "sha1:" + screen3_sha1 if screen3_sha1 else "", "sha1:" + screen4_sha1 if screen4_sha1 else "", "sha1:" + screen5_sha1 if screen5_sha1 else "", "sha1:" + thumb_sha1 if thumb_sha1 else "", backdrop_image, 1 if "t:adult" in search_terms else 0, 1 if published == "1" else 0, game_subtitle, game_id, ), ) helper.database.update_game_search_terms(game_id, search_terms)
def create_search_terms(cls, name): search_terms = set() game_name = name.split("(", 1)[0] search_terms.update(GameNameUtil.extract_index_terms(game_name)) return search_terms
def screenshots_name(self): # FIXME: REMOVE? return GameNameUtil.create_fs_name(self.game_name())
def screenshots_base(self): return GameNameUtil.create_link_name(self.game_name())
def scan_game_database(self, helper, database_name, game_database): """ :type helper: ScanHelper :type database_name: str :type game_database: fsgs.GameDatabase.GameDatabase """ database_cursor = helper.database.cursor() # this holds a list of game entry UUIDs which must exist / be checked # after variants have been processed # ensure_updated_games = set() game_database_cursor = game_database.cursor() # this list will contain game entries which are not variants game_rows = [] game_database_cursor.execute( "SELECT id, uuid FROM game WHERE data != ''") for row in game_database_cursor: if self.stop_check(): return variant_id, variant_uuid_bin = row variant_uuid = binary_to_uuid(variant_uuid_bin) update_stamp = variant_id existing_variant = helper.existing_variants.get( variant_uuid, (None, None, None)) existing_game = helper.existing_games.get(variant_uuid, (None, None, None)) if update_stamp == existing_game[0]: # Game entry, not updated. game_rows.append(row) continue if update_stamp == existing_variant[0]: # entry was already updated and has not changed if existing_variant[1] and not helper.deleted_files: # have this entry already and no files have been deleted # since the last time # print("skipping variant (no deleted files)") helper.variant_seen(variant_uuid) continue if not existing_variant[1] and not helper.added_files: # do not have this entry, but no files have been added # since the last time # print("skipping variant (no added files)") helper.variant_seen(variant_uuid) continue else: # when the game entry has changed, we always check it # regardless of file database status, since file_list may # have been changed, or download status... (or other info # needs to be corrected) # print("[SCANNER] Changed: {}".format(variant_uuid)) pass self.scan_count += 1 self.set_status( gettext("Scanning game variants ({count} scanned)").format( count=self.scan_count), variant_uuid, ) try: doc = self.fsgs.game.get_game_values_for_id( game_database, variant_id) except IncompleteGameException as e: print("[SCANNER]", repr(e)) continue file_list_json = doc.get("file_list", "") if not file_list_json: # not a game variant... (parent game only probably) game_rows.append(row) continue entry_type = int(doc.get("_type", "0")) if (entry_type & GAME_ENTRY_TYPE_VARIANT) == 0: # game entry is not tagged with variant -- add to game list # instead game_rows.append(row) continue helper.variant_seen(variant_uuid) all_files_found = True try: file_list = json.loads(file_list_json) except Exception: # invalid JSON string # FIXME: log error all_files_found = False file_list = [] for file_item in file_list: if file_item["name"].endswith("/"): # skip directory entries: continue result = self.fsgs.file.check_sha1(file_item["sha1"]) if not result: all_files_found = False break if all_files_found: have_variant = 4 elif doc.get("download_file", ""): have_variant = 2 elif doc.get("download_page", ""): have_variant = 1 else: have_variant = 0 parent_uuid = doc.get("parent_uuid", "") variant_name = doc.get("variant_name", "") # published_variant = doc.get("publish", "") published_variant = doc.get("__publish_hack__", "") if not published_variant: published_variant = None elif published_variant == "1": published_variant = 1 else: published_variant = 0 game_variant_id = existing_variant[2] if not game_variant_id: # variant is not in database database_cursor.execute( "INSERT INTO game_variant (uuid) VALUES (?)", (variant_uuid, ), ) game_variant_id = database_cursor.lastrowid database_cursor.execute( "UPDATE game_variant SET name = ?, game_uuid = ?, have = ?, " "update_stamp = ?, database = ?, published = ? WHERE id = ?", ( variant_name, parent_uuid, have_variant, update_stamp, database_name, published_variant, game_variant_id, ), ) # ensure_updated_games.add(parent_uuid) for row in game_rows: if self.stop_check(): return game_id, game_uuid_bin = row game_uuid = binary_to_uuid(game_uuid_bin) update_stamp = game_id existing_game = helper.existing_games.get(game_uuid, (None, None, None)) if update_stamp == existing_game[0]: # after the loop has run its course, games to be removed # are left in existing_games helper.game_seen(game_uuid) continue self.scan_count += 1 self.set_status( gettext("Scanning games ({count} scanned)").format( count=self.scan_count), game_uuid, ) doc = game_database.get_game_values(game_id) entry_type = int(doc.get("_type", "0")) if (entry_type & GAME_ENTRY_TYPE_GAME) == 0: continue # after the loop has run its course, games to be removed # are left in existing_games try: del helper.existing_games[game_uuid] except KeyError: pass game_name = doc.get("game_name", "") game_subtitle = doc.get("game_subtitle", "") platform = doc.get("platform", "") tags = doc.get("tags", "") year = doc.get("year", "") publisher = doc.get("publisher", "") front_sha1 = doc.get("front_sha1", "") title_sha1 = doc.get("title_sha1", "") screen1_sha1 = doc.get("screen1_sha1", "") screen2_sha1 = doc.get("screen2_sha1", "") screen3_sha1 = doc.get("screen3_sha1", "") screen4_sha1 = doc.get("screen4_sha1", "") screen5_sha1 = doc.get("screen5_sha1", "") thumb_sha1 = doc.get("thumb_sha1", "") backdrop_sha1 = doc.get("backdrop_sha1", "") published = doc.get("publish", "") sort_key = doc.get("sort_key", "") if not sort_key: # FIXME: handle the/a (etc) sort_key = game_name.lower() game_id = existing_game[2] if not game_id: # game is not in database database_cursor.execute("INSERT INTO game (uuid) VALUES (?)", (game_uuid, )) game_id = database_cursor.lastrowid search_terms = set() for key in [ "game_name", "full_name", "game_name_alt", "search_terms", "game_subtitle", ]: value = doc.get(key, "") if value: search_terms.update( GameNameUtil.extract_index_terms(value)) letter = "" if len(sort_key) > 0: letter = sort_key[0].lower() if letter in "abcdefghijklmnopqrstuvwxyz": pass elif letter in "0123456789": letter = "#" else: letter = "?" search_terms.add("l:" + letter) for tag in tags.split(","): tag = tag.strip().lower() search_terms.add("t:" + tag) if year: search_terms.add("y:" + str(year)) if platform: search_terms.add("s:" + platform.lower()) if thumb_sha1: search_terms.add("t:thumb") if backdrop_sha1: search_terms.add("t:backdrop") backdrop_image = "sha1:{}/{}/{}/{}/{}".format( backdrop_sha1, doc.get("backdrop_zoom", "1.0"), doc.get("backdrop_zoom", "1.0"), doc.get("backdrop_halign", "0.5"), doc.get("backdrop_valign", "0.5"), ) else: backdrop_image = "" # if published: # # search_terms.add("t:published") # pass # else: # search_terms.add("t:unpublished") min_players = 0 max_players = 0 sim_players = 0 players = doc.get("players", "") if players == "1": min_players = max_players = 1 search_terms.add("p:1") elif players: try: parts1 = players.split("-") parts2 = parts1[1].split("(") min_players = int(parts1[0].strip()) max_players = int(parts2[0].strip()) sim_players = int(parts2[1].strip(" )")) except Exception as e: print("error parsing players") print(repr(e)) if min_players > 0: if max_players > 0: # we ignore players = 1 here, that is reserved for games # with max 1 players for i in range(min_players + 1, max_players + 1): search_terms.add("p:{0}".format(i)) if sim_players > 0: # we ignore players = 1 here, that is reserved for games # with max 1 players for i in range(min_players + 1, sim_players + 1): search_terms.add("p:{0}s".format(i)) database_cursor.execute( "UPDATE game SET name = ?, update_stamp = ?, sort_key = ?, " "platform = ?, " "publisher = ?, year = ?, front_image = ?, title_image = ?, " "screen1_image = ?, screen2_image = ?, screen3_image = ?, " "screen4_image = ?, screen5_image = ?, " "thumb_image = ?, backdrop_image = ?, " "adult = ?, published = ?, subtitle = ? WHERE id = ?", ( game_name, update_stamp, sort_key, platform, publisher or "", year or 0, "sha1:" + front_sha1 if front_sha1 else "", "sha1:" + title_sha1 if title_sha1 else "", "sha1:" + screen1_sha1 if screen1_sha1 else "", "sha1:" + screen2_sha1 if screen2_sha1 else "", "sha1:" + screen3_sha1 if screen3_sha1 else "", "sha1:" + screen4_sha1 if screen4_sha1 else "", "sha1:" + screen5_sha1 if screen5_sha1 else "", "sha1:" + thumb_sha1 if thumb_sha1 else "", backdrop_image, 1 if "t:adult" in search_terms else 0, 1 if published == "1" else 0, game_subtitle, game_id, ), ) helper.database.update_game_search_terms(game_id, search_terms)
def screenshots_name(self): return GameNameUtil.create_fs_name(self.get_name())
def find_disks( cls, path, base_names=None, script=None, file_list=None, black_list={} ): disks = [path] print("") print("FIRST DISK", path) print("") # disks = [] if script: use_name = script.rename_file(os.path.basename(path)) else: use_name = os.path.basename(path) number = GameNameUtil.find_number(use_name) disk_count = GameNameUtil.find_disk_count(use_name) first_without_number = GameNameUtil.strip_number(use_name) first_without_flags = GameNameUtil.strip_flags(first_without_number) if number is None: # only this disk return disks base_name = GameNameUtil.find_base_name(path) dir = os.path.dirname(path) candidates = {} items = [] if base_names: items = base_names[base_name] else: if file_list: all_items = file_list else: all_items = os.listdir(dir) for item in all_items: b = GameNameUtil.find_base_name(item) if base_name == b: items.append(item) # print("items is", items) for item in items: if script: use_name = script.rename_file(item) else: use_name = item # print(item) if GameNameUtil.is_bad_dump(use_name): continue if GameNameUtil.find_disk_count(use_name) != disk_count: continue n = GameNameUtil.find_number(use_name) if n == 0: n = 99 if n: candidates.setdefault(n, []).append( (use_name, os.path.join(dir, item)) ) # print(candidates) for n, items in candidates.items(): if n == 1: # already added first floppy continue print("") print("Candidates:") for item in items: print(item[0]) print("") print("FIND FLOPPY NUMBER", n) print("") matches = [] for use_name, p in items: without_number = GameNameUtil.strip_number(use_name) # print(without_number, "vs", first_without_number) if without_number == first_without_number: # print("perfect match:", p) # disks.append(p) matches.append((-1000, p)) continue # break without_flags = GameNameUtil.strip_flags(without_number) if without_flags == first_without_flags: flags_1 = extract_flags(first_without_number) cr_flag_1 = "" for flag in flags_1: if flag.startswith("cr"): cr_flag_1 = flag flags_n = extract_flags(without_number) cr_flag_n = "" for flag in flags_n: if flag.startswith("cr"): cr_flag_n = flag score = 0 # if cr_flag_n and cr_flag_1 != cr_flag_n: if cr_flag_1 and cr_flag_n and cr_flag_1 != cr_flag_n: # not same cracker score += 10000 if "[o" in without_number: score += 20000 flag_set_1 = set(flags_1) flag_set_n = set(flags_n) extra_flags_in_1 = flag_set_1.difference(flag_set_n) extra_flags_in_n = flag_set_n.difference(flag_set_1) # score += len(extra_flags_in_1) print(extra_flags_in_1) for flag in extra_flags_in_1: score += 10 - flags_1.index(flag) score += len(extra_flags_in_n) * 100 print(score, p) matches.append((score, p)) # if without_flags == without_number: # # there were no flags on this floppy # matches.append((1, p)) # else: # # slightly worse score since there were flags # # not matching floppy 1 # matches.append((100, p)) if len(matches) == 0: # raise Exception("no candidates for floppy " + num) # print("WARNING: choosing partial matching floppy", p, # "for floppy number", n) # disks.append(p) print("Did not find good match for floppy", n) print("candidates:") for item in items: print(" ", item) raise Exception( "Did not find good match for floppy {0}".format(n) ) matches.sort() print("") print("Matches:") for match in matches: print(match[0], match[1]) print("") score, p = matches[0] # if score == 2: disks.append(p) # TOSEC (x of y) disk number labelling format if " of {0})".format(n) in path: # found the correct number of disks break print("") print("Result:") for disk in disks: print(disk) print("") return disks
def find_disks(cls, path, base_names=None, script=None): disks = [path] print("") print("FIRST DISK", path) print("") # disks = [] use_name = script.rename_file(os.path.basename(path)) number = GameNameUtil.find_number(use_name) first_without_number = GameNameUtil.strip_number(use_name) first_without_flags = GameNameUtil.strip_flags(first_without_number) if number is None: # only this disk return disks base_name = GameNameUtil.find_base_name(path) dir = os.path.dirname(path) candidates = {} items = [] if base_names: items = base_names[base_name] else: all_items = os.listdir(dir) for item in all_items: b = GameNameUtil.find_base_name(item) if base_name == b: items.append(item) # print("items is", items) for item in items: use_name = script.rename_file(item) if GameNameUtil.is_bad_dump(use_name): continue n = GameNameUtil.find_number(use_name) if n == 0: n = 99 if n: candidates.setdefault(n, []).append( (use_name, os.path.join(dir, item))) # print(candidates) for n, items in candidates.items(): print("") print("FIND FLOPPIES FOR n", n, "=", items) print("") if n == 1: # already added first floppy continue print(" - floppy number", n) matches = [] for use_name, p in items: without_number = GameNameUtil.strip_number(use_name) # print(without_number, "vs", first_without_number) if without_number == first_without_number: print("perfect match") # disks.append(p) matches.append((0, p)) continue # break without_flags = GameNameUtil.strip_flags(without_number) if without_flags == first_without_flags: print("ok match") if without_flags == without_number: # there were no flags on this floppy matches.append((1, p)) else: # slightly worse score since there were flags # not matching floppy 1 matches.append((2, p)) # disks.append(p) # break # matches.append((2, p)) if len(matches) == 0: # raise Exception("no candidates for floppy " + num) # print("WARNING: choosing partial matching floppy", p, # "for floppy number", n) # disks.append(p) print("Did not find good match for floppy", n) print("candidates:") for item in items: print(" ", item) raise Exception( "Did not find good match for floppy {0}".format(n)) matches.sort() print(matches) score, p = matches[0] # if score == 2: disks.append(p) # TOSEC (x of y) disk number labelling format if " of {0})".format(n) in path: # found the correct number of disks break return disks
def find_disks(cls, path, base_names=None, script=None, file_list=None, black_list={}): disks = [path] print("") print("FIRST DISK", path) print("") # disks = [] if script: use_name = script.rename_file(os.path.basename(path)) else: use_name = os.path.basename(path) number = GameNameUtil.find_number(use_name) disk_count = GameNameUtil.find_disk_count(use_name) first_without_number = GameNameUtil.strip_number(use_name) first_without_flags = GameNameUtil.strip_flags(first_without_number) if number is None: # only this disk return disks base_name = GameNameUtil.find_base_name(path) dir = os.path.dirname(path) candidates = {} items = [] if base_names: items = base_names[base_name] else: if file_list: all_items = file_list else: all_items = os.listdir(dir) for item in all_items: b = GameNameUtil.find_base_name(item) if base_name == b: items.append(item) # print("items is", items) for item in items: if script: use_name = script.rename_file(item) else: use_name = item # print(item) if GameNameUtil.is_bad_dump(use_name): continue if GameNameUtil.find_disk_count(use_name) != disk_count: continue n = GameNameUtil.find_number(use_name) if n == 0: n = 99 if n: candidates.setdefault(n, []).append( (use_name, os.path.join(dir, item))) # print(candidates) for n, items in candidates.items(): if n == 1: # already added first floppy continue print("") print("Candidates:") for item in items: print(item[0]) print("") print("FIND FLOPPY NUMBER", n) print("") matches = [] for use_name, p in items: without_number = GameNameUtil.strip_number(use_name) # print(without_number, "vs", first_without_number) if without_number == first_without_number: # print("perfect match:", p) # disks.append(p) matches.append((-1000, p)) continue # break without_flags = GameNameUtil.strip_flags(without_number) if without_flags == first_without_flags: flags_1 = extract_flags(first_without_number) cr_flag_1 = "" for flag in flags_1: if flag.startswith("cr"): cr_flag_1 = flag flags_n = extract_flags(without_number) cr_flag_n = "" for flag in flags_n: if flag.startswith("cr"): cr_flag_n = flag score = 0 # if cr_flag_n and cr_flag_1 != cr_flag_n: if cr_flag_1 and cr_flag_n and cr_flag_1 != cr_flag_n: # not same cracker score += 10000 if "[o" in without_number: score += 20000 flag_set_1 = set(flags_1) flag_set_n = set(flags_n) extra_flags_in_1 = flag_set_1.difference(flag_set_n) extra_flags_in_n = flag_set_n.difference(flag_set_1) # score += len(extra_flags_in_1) print(extra_flags_in_1) for flag in extra_flags_in_1: score += (10 - flags_1.index(flag)) score += len(extra_flags_in_n) * 100 print(score, p) matches.append((score, p)) # if without_flags == without_number: # # there were no flags on this floppy # matches.append((1, p)) # else: # # slightly worse score since there were flags # # not matching floppy 1 # matches.append((100, p)) if len(matches) == 0: # raise Exception("no candidates for floppy " + num) # print("WARNING: choosing partial matching floppy", p, # "for floppy number", n) # disks.append(p) print("Did not find good match for floppy", n) print("candidates:") for item in items: print(" ", item) raise Exception( "Did not find good match for floppy {0}".format(n)) matches.sort() print("") print("Matches:") for match in matches: print(match[0], match[1]) print("") score, p = matches[0] # if score == 2: disks.append(p) # TOSEC (x of y) disk number labelling format if ' of {0})'.format(n) in path: # found the correct number of disks break print("") print("Result:") for disk in disks: print(disk) print("") return disks