Esempio n. 1
0
    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)
Esempio n. 2
0
 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
Esempio n. 3
0
    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