예제 #1
0
파일: loaddata.py 프로젝트: kling109/Smithy
def load_skills(sm: SmithyDB, filepath: str):
    """
    Loads skill information from a properly-formatted tsv file, then adds it to the
    database.

    :param sm: The database object to operate on.
    :param filepath: The path to the desired .csv file.
    :return:
    """
    if path.exists(filepath):
        with open(filepath) as skilltsv:
            columns = skilltsv.readline()
            data = skilltsv.readlines()

        skills = []
        skilldesc = []
        for entry in data:
            entry = entry.strip().split('\t')
            name = entry[0]
            skilllv = entry[2][0]
            skills.append((name, skilllv))

        #sm.add_skills(skills)

        for entry in data:
            entry = entry.strip().split('\t')
            name = entry[0]
            skillnu = sm.get_skills_by_name([(name, )])
            desc = entry[3]
            skilldesc.append((skillnu[0][0], desc))

        sm.add_skill_desc(skilldesc)

    else:
        print("The path to the .tsv file does not exist.")
예제 #2
0
def write_charms(charms: dict, filename: str):
    """
    Write a dictionary describing charms to a tsv file.

    :param charms: A dictionary specifying the charms
    :param filename: The name of the file to write to
    :return: None
    """
    sm = SmithyDB(PASSFILE)
    with open(filename, 'w') as testcharms:
        cols = "Name\tUserId\tSlots\tSkill1\tSkill2\tSkill3\tSkill4\n"
        testcharms.write(cols)
        for ch in charms.values():
            name = ch["name"]
            usr = ch["uid"]
            slots = (str(ch["sslots"])+str(ch["mslots"])+str(ch["lslots"])).replace("0", "-")
            skills = []
            for i in range(1, 5):
                if ch["skillnum"+str(i)] != None:
                    skilldet = sm.get_skill(ch["skillnum"+str(i)])[0]
                    skills.append(skilldet[1] + " Lv. " + str(ch["skillval"+str(i)]))
                else:
                    skills.append("")
            line = "{}\t{}\t{}\t{}\t{}\t{}\n".format(name, usr, slots, skills[0], skills[1], skills[2], skills[3]).strip()
            testcharms.write(line + "\n")
예제 #3
0
파일: loaddata.py 프로젝트: kling109/Smithy
def load_charms(sm: SmithyDB, filepath: str):
    """
    A method to add a set of charms given by a tsv file to the charm database.

    :param sm: The database object to operate on.
    :param filepath: a path to the charm tsv file
    :return:
    """
    if path.exists(filepath):
        with open(filepath) as charmtsv:
            columns = charmtsv.readline()
            data = charmtsv.readlines()

    charms = []
    for entry in data:
        entry = entry.strip().split('\t')
        name = entry[0]
        usrid = entry[1]
        slots = entry[2].replace('-', '0')
        slots1 = slots[0]
        slots2 = slots[1]
        slots3 = slots[2]
        skills = []
        if len(entry) > 3:
            for i in range(3, len(entry)):
                skni = entry[i].split('Lv.')[0].strip()
                skidi = sm.get_skills_by_name([(skni, )])
                skvi = entry[i].split('Lv.')[1].strip()
                skills.append((skidi[0][0], skvi))
        for i in range(7 - len(entry)):
            skills.append((None, 0))

        sm.add_charm(name, usrid, slots1, slots2, slots3, skills[0][0],
                     skills[0][1], skills[1][0], skills[1][1], skills[2][0],
                     skills[2][1], skills[3][0], skills[3][1])
예제 #4
0
def gen_charms(n: int):
    """
    Generate a set of n random valid charms.

    :param n: The number of charms to generate.
    :return: A dictionary of charms
    """
    sm = SmithyDB(PASSFILE)
    Faker.seed(0)
    fake = Faker()
    charms = {}
    for i in range(n):
        name = "test" + fake.pystr(min_chars=5, max_chars=10)
        uid = fake.pyint(min_value=pow(10, 17), max_value=pow(10, 18)) # Discord user Id's are 17 or 18 digits long
        sslots = fake.pyint(min_value=0, max_value=3)
        mslots = fake.pyint(min_value=0, max_value=3)
        lslots = fake.pyint(min_value=0, max_value=3)
        num_skills = fake.pyint(min_value=1, max_value=4)
        skills = []
        for _ in range(num_skills):
            skillnu = fake.pyint(min_value=1, max_value=104)
            skillva = fake.pyint(min_value=1, max_value=sm.get_skill(skillnu)[0][2])
            skills.append((skillnu, skillva))

        charms["Charm " + str(i)] = {}
        charms["Charm " + str(i)]["name"] = name
        charms["Charm " + str(i)]["uid"] = uid
        charms["Charm " + str(i)]["sslots"] = sslots
        charms["Charm " + str(i)]["mslots"] = mslots
        charms["Charm " + str(i)]["lslots"] = lslots
        for j in range(num_skills):
            charms["Charm " + str(i)]["skillnum" + str(j+1)] = skills[j][0]
            charms["Charm " + str(i)]["skillval" + str(j+1)] = skills[j][1]
        for k in range(num_skills, 4):
            charms["Charm " + str(i)]["skillnum" + str(k+1)] = None
            charms["Charm " + str(i)]["skillval" + str(k+1)] = 0

    return charms
예제 #5
0
파일: loaddata.py 프로젝트: kling109/Smithy
def load_decos(sm: SmithyDB, filepath: str):
    """
    A method to add a list of decorations from a given file into the deco table

    :param sm: The database object to operate on.
    :param filepath: a path to the file to use.
    :return: None
    """
    if path.exists(filepath):
        with open(filepath) as decotsv:
            columns = decotsv.readline()
            data = decotsv.readlines()

    decos = []
    for entry in data:
        entry = entry.strip().split('\t')
        name = entry[0]
        slotSize = entry[1]
        skni = entry[2].split('Lv.')[0].strip()
        skidi = sm.get_skills_by_name([(skni, )])[0][0]
        skvi = entry[2].split('Lv.')[1].strip()
        decos.append((name, slotSize, skidi, skvi))

    sm.add_deco(decos)
예제 #6
0
파일: loaddata.py 프로젝트: kling109/Smithy
def load_armor(sm: SmithyDB, filepath: str):
    """
    Loads in armor data from a tsv file.  Sorts loaded armors by type, then
    adds each to their repective tables.

    :param sm: The database object to operate on.
    :param filepath: a path to the armor tsv file
    :return: None
    """
    if path.exists(filepath):
        with open(filepath) as armortsv:
            columns = armortsv.readline()
            data = armortsv.readlines()

        helms = []
        chests = []
        vambraces = []
        faulds = []
        greaves = []
        for entry in data:
            entry = entry.strip().split('\t')
            name = entry[0]
            slots = entry[1].replace('-', '0')
            slots1 = slots[0]
            slots2 = slots[1]
            slots3 = slots[2]
            skills = []

            if len(entry) > 2:
                for i in range(2, len(entry)):
                    skni = entry[i].split('Lv.')[0].strip()
                    skidi = sm.get_skills_by_name([skni])
                    skvi = entry[i].split('Lv.')[1].strip()
                    skills.append((skidi[0][0], skvi))
            for i in range(6 - len(entry)):
                skills.append((None, 0))

            armtype = re.sub(r" \bS\b", "", name).strip().split(' ')[-1]
            if armtype in HELM_NAMES:
                helms.append(
                    (name, slots1, slots2, slots3, skills[0][0], skills[0][1],
                     skills[1][0], skills[1][1], skills[2][0], skills[2][1],
                     skills[3][0], skills[3][1]))
            elif armtype in CHEST_NAMES:
                chests.append(
                    (name, slots1, slots2, slots3, skills[0][0], skills[0][1],
                     skills[1][0], skills[1][1], skills[2][0], skills[2][1],
                     skills[3][0], skills[3][1]))
            elif armtype in VAMBRACE_NAMES:
                vambraces.append(
                    (name, slots1, slots2, slots3, skills[0][0], skills[0][1],
                     skills[1][0], skills[1][1], skills[2][0], skills[2][1],
                     skills[3][0], skills[3][1]))
            elif armtype in FAULD_NAMES:
                faulds.append(
                    (name, slots1, slots2, slots3, skills[0][0], skills[0][1],
                     skills[1][0], skills[1][1], skills[2][0], skills[2][1],
                     skills[3][0], skills[3][1]))
            elif armtype in GREAVE_NAMES:
                greaves.append(
                    (name, slots1, slots2, slots3, skills[0][0], skills[0][1],
                     skills[1][0], skills[1][1], skills[2][0], skills[2][1],
                     skills[3][0], skills[3][1]))
            else:
                print("This armor type is not yet handled: {}".format(armtype))
                return

        sm.add_armors('helm', helms)
        sm.add_armors('chest', chests)
        sm.add_armors('vambraces', vambraces)
        sm.add_armors('faulds', faulds)
        sm.add_armors('greaves', greaves)

    else:
        print("The path to the .tsv file does not exist.")
예제 #7
0
파일: loaddata.py 프로젝트: kling109/Smithy
    decos = []
    for entry in data:
        entry = entry.strip().split('\t')
        name = entry[0]
        slotSize = entry[1]
        skni = entry[2].split('Lv.')[0].strip()
        skidi = sm.get_skills_by_name([(skni, )])[0][0]
        skvi = entry[2].split('Lv.')[1].strip()
        decos.append((name, slotSize, skidi, skvi))

    sm.add_deco(decos)


if __name__ == "__main__":
    loadtype = sys.argv[1]
    loadpath = sys.argv[2]
    sm = SmithyDB(PASSFILE)
    if loadtype == "skill":
        load_skills(sm, loadpath)
    elif loadtype == "armor":
        load_armor(sm, loadpath)
    elif loadtype == "charm":
        load_charms(sm, loadpath)
    elif loadtype == "deco":
        load_decos(sm, loadpath)
    else:
        print("The given type of element cannot be loaded.")
        print("Input should be of the form, 'python loaddata.py [type] [path]")
        print("Available types: 'armor', 'skill', 'charm'")
    print("Program exited correctly.")
예제 #8
0
 def __init__(self, info: str):
     self.armordb = SmithyDB(info)
예제 #9
0
class QueryProcessor:
    armordb = None

    def __init__(self, info: str):
        self.armordb = SmithyDB(info)

    def __del__(self):
        pass

    def add_user_charm(self, charminfo: dict, uid: int):
        """
        Adds a charm to the database from the user's given skills and other info.
        :param charminfo: a dictionary of charm parameters
        :param uid: the user's Discord Id
        :return: None
        """
        try:
            skill_names = [charminfo["skill1Name"], charminfo["skill2Name"], charminfo["skill3Name"], charminfo["skill4Name"]]
            skill_data = self.armordb.get_skills_by_name(skill_names)
            skill_ids = [s[0] for s in skill_data] + [None for i in range(len(skill_data), 4)]
            self.armordb.add_charm(charminfo["name"], uid, charminfo["slot1"], charminfo["slot2"], charminfo["slot3"],
                                   skill_ids[0], charminfo["skill1Val"], skill_ids[1],
                                   charminfo["skill2Val"], skill_ids[2], charminfo["skill3Val"],
                                   skill_ids[3], charminfo["skill4Val"])
        except ValueError as err:
            print("Charm was unable to be added to the database.")

    def remove_user_charm(self, charm_name: str, uid: int):
        """
        Removes a given charm from the database of a user.

        :param charm_name: The name of the charm to remove
        :param uid: the user's Discord Id
        :return: None
        """
        try:
            self.armordb.delete_charm(charm_name, uid)
        except ValueError as err:
            print("The given charm was not removed from the database.")

    def modify_user_charm(self, charm_name: str, uid : int, value_to_modify: str, new_val):
        """
        Modifies an existing user charm.
        
        :param charm_name: The name of the charm to modify
        :param uid: The Discord User Id
        :param value_to_modify: the name of the column to modify
        :param new_val: the new value to place in the column
        :return: None.
        """
        try:
            if value_to_modify == 'slots':
                self.armordb.update_charm(charm_name, uid, 'slot1', new_val[0])
                self.armordb.update_charm(charm_name, uid, 'slot2', new_val[1])
                self.armordb.update_charm(charm_name, uid, 'slot3', new_val[2])
            elif value_to_modify == 'skill':
                skill_index = new_val[0]
                new_skill = new_val[1]
                skill_id = self.armordb.get_skills_by_name([new_skill])[0][0]
                new_skill_val = new_val[2]
                self.armordb.update_charm(charm_name, uid, 'skill'+str(skill_index)+'Id', skill_id)
                self.armordb.update_charm(charm_name, uid, 'skill'+str(skill_index)+'Val', new_skill_val)
        except ValueError as err:
            print("Charm was unable to be modified.")

    def search_armor_set(self, skills: dict, uid: int, num_results: int = 4, returned_results: int = 1):
        """
        Generates an optimized armor set for the given set of skills

        :param skills: a dictionary of skills to search for
        :param uid: the Discord user's Id.
        :param num_results: the number of elements to include in the search.  Default value is 4
        :param returned_results: the number of results to return.  default is 1.
        :return: armor_sets: A list of dictionaries specifying the armor set and its decorations.
        """
        try:
            skill_names = [k for k in skills.keys()]
            skill_data = self.armordb.get_skills_by_name(skill_names)
            skill_ids = [s[0] for s in skill_data]
            skill_max_vals = [v for v in skills.values()]
            results = self.armordb.get_armor_by_skills(skill_ids, skill_max_vals, uid, num_results)
            armor_sets = []
            for i in range(min(returned_results, len(results))):
                set_dict = {"helm": {}, "chest": {}, "vambraces": {}, "faulds": {}, "greaves": {}, "charm": {},
                            "totals": {}}
                set_res = results[i]
                set_dict["helm"]["name"] = set_res[0]
                set_dict["chest"]["name"] = set_res[1]
                set_dict["vambraces"]["name"] = set_res[2]
                set_dict["faulds"]["name"] = set_res[3]
                set_dict["greaves"]["name"] = set_res[4]
                set_dict["charm"]["name"] = set_res[5]
                set_dict["helm"]["decos"] = [x for x in set_res[6:9] if x is not None]
                set_dict["chest"]["decos"] = [x for x in set_res[9:12] if x is not None]
                set_dict["vambraces"]["decos"] = [x for x in set_res[12:15] if x is not None]
                set_dict["faulds"]["decos"] = [x for x in set_res[15:18] if x is not None]
                set_dict["greaves"]["decos"] = [x for x in set_res[18:21] if x is not None]
                set_dict["charm"]["decos"] = [x for x in set_res[21:24] if x is not None]
                for n in range(len(skill_names)):
                    set_dict["totals"][skill_names[n]] = int(set_res[24 + n])

                armor_sets.append(set_dict)

            return armor_sets
        except ValueError as err:
            print("Search could not be performed")
            return []

    def format_sets(self, unformatted_set: list):
        """
        Formats a set of objects from a query result.

        :param unformatted_set: The set of objects to format.
        :return: formatted_set: The set of proper dictionaries.
        """
        formatted_set = []
        for c in unformatted_set:
            item = {"name": c[0], "slot1": c[1], "slot2": c[2], "slot3": c[3], "skills": {}}
            if c[4] is not None:
                item["skills"][self.armordb.get_skill(c[4])[0][1]] = int(c[5])
            if c[6] is not None:
                item["skills"][self.armordb.get_skill(c[6])[0][1]] = int(c[7])
            if c[8] is not None:
                item["skills"][self.armordb.get_skill(c[8])[0][1]] = int(c[9])
            if c[10] is not None:
                item["skills"][self.armordb.get_skill(c[10])[0][1]] = int(c[11])
            formatted_set.append(item)

        return formatted_set

    def display(self, uid: int, armor_type: str, skill_name: str = None):
        """
        Returns and formats all charms for a given user.

        :param uid: the user's Discord Id
        :param armor_type: the type of armor to return.
        :param skill_name: The name of a skill to search for.
        :return: charm_set: list of dictionaries of the charms.
        """
        try:
            skillId = None
            if skill_name is not None:
                skillId = self.armordb.get_skills_by_name([skill_name])[0][0]

            if armor_type == "helms":
                unformatted_set = self.armordb.get_helms(skillId)
            elif armor_type == "chests":
                unformatted_set = self.armordb.get_chests(skillId)
            elif armor_type == "vambraces":
                unformatted_set = self.armordb.get_vambraces(skillId)
            elif armor_type == "faulds":
                unformatted_set = self.armordb.get_faulds(skillId)
            elif armor_type == "greaves":
                unformatted_set = self.armordb.get_greaves(skillId)
            elif armor_type == "charms":
                unformatted_set = self.armordb.get_charms(uid, skillId)
            else:
                raise ValueError

            return self.format_sets(unformatted_set)
        except ValueError as err:
            print("Unable to query the set.")
            return []

    def show_decorations(self):
        """
        Displays all the decorations in the given database.

        :return: list of dictionaries of decoration info, list of decorations by slot size
        """
        try:
            deco_set = []
            decos = self.armordb.get_all_decos()
            deco_counts = self.armordb.get_deco_counts()
            for d in decos:
                dec = {}
                dec["name"] = d[1]
                dec["slot"] = d[2]
                dec["skillName"] = self.armordb.get_skill(d[3])[0][1]
                dec["skillVal"] = d[4]
                deco_set.append(dec)
            return deco_set, deco_counts
        except ValueError as err:
            print("Unable to query the set.")
            return []

    def get_skill_desc(self, skill_name):
        try:
            skill_id = self.armordb.get_skills_by_name([skill_name])[0][0]
            skill_desc = self.armordb.get_skill_desc(skill_id)[0][0]
            return skill_desc
        except ValueError as err:
            print("Unable to get a skill description.")
            return ""