Exemple #1
0
    def StartSearchName(self,name:str=""):
        """
        开始一轮搜索。
        """
        global current_thread_set
        if name=="":
            name = self.EdtName.text()
        #检查这是否是一个合适的name
        name = name.strip(" \n\"\'“”‘’")
        if name == "":
            self.statusBar().showMessage("错误:没有输入名字")
            return - 1
        #如果是一个zkb链接
        fetch = re.search(r"https://zkillboard\.com/character/([0-9]*)/", name)
        if fetch != None:
            log("导入zkb链接"+fetch.group(0))
            self.RefreshLabelList({"LoadFromzkbLink": [TMsgEntry(
                "导入zkb链接 " + fetch.group(0),
                style_str=MDStyleStr(color=settings["clHint"], font_size=settings["labelFontSize"])
            ),TMsgEntry(
                "正在搜索...",
                style_str=MDStyleStr(color=settings["clHint"], font_size=settings["labelFontSize"])
            )]})
            self.MultiThreadRun(func=SearchName, args=(None, int(fetch.group(1))))
        else:
            name=re.search(r"^[a-zA-Z0-9 '\-_]*$", name)
            if name==None:
                #名字中含有非法字符
                self.statusBar().showMessage("错误:名字中含有非法字符")
                return - 1
            else:
                name=name.group(0)

            self.MsgEntryList = {}
            current_thread_set = set()
            log("搜索"+name)
            self.RefreshLabelList({"SearchName": {
                "Searching": [name,
                    TMsgEntry("正在搜索名字包含" + name + '的角色...',
                        style_str=MDStyleStr(
                            color=settings["clHint"],
                            font_size=settings["labelFontSize"]
                        )
                    ),
                ]
            }})
            self.MultiThreadRun(func=SearchName, args=(name,))
        return 0
Exemple #2
0
    def mousePressEvent(self, e):  # 单击
        global current_thread_set
        self.on_events = True
        self.parent().parent().LabelList_click_no = self.no
        if self.MsgEntry.ClickEvent != None:
            log("label:"+self.text()+",ClickEvent="+str(self.MsgEntry.ClickEvent)+",ClickArgs="+str(self.MsgEntry.ClickArgs))
            current_thread_set=set()
            self.parent().parent().EndSearchEvent()
            if self.MsgEntry.ClickEvent == SearchName:
                self.parent().parent().RefreshLabelList({"Searching": TMsgEntry(
                    text="正在搜索角色{name}...".format(name=str(self.MsgEntry.ClickArgs[0])),
                    style_str=MDStyleStr(
                            color=settings["clHint"],
                            font_size=settings["labelFontSize"]
                        ))})
                self.MsgEntry.ClickReturn = self.parent().parent().MultiThreadRun(func=self.MsgEntry.ClickEvent, args=self.MsgEntry.ClickArgs)
            elif self.MsgEntry.ClickEvent == SearchKM:
                #TODO:增加一个判断,如果已经获取了km则不重复获取
                if self.MsgEntry.ClickReturn == None:
                    self.parent().parent().StatusBar.showMessage("正在获取km...")
                    self.MsgEntry.ClickReturn = self.parent().parent().MultiThreadRun(func=self.MsgEntry.ClickEvent, args=self.MsgEntry.ClickArgs)
                # else:
                #     self.MsgEntry.enable = not self.MsgEntry.enable
                #     self.parent().parent().RefreshLabelList()


        self.on_events=False
Exemple #3
0
    def __init__(self, m=TMsgEntry(),no=-1,):
        super(TMsgLabel, self).__init__()
        self.no = no #在LabelList中的序号
        self.on_events = False  #正在响应事件
        self.MsgEntry=m

        left, top = self.MsgEntry.left, self.MsgEntry.top + (self.no * settings["labelFontSize"] * 6)
        self.move(left,top)
        self.setScaledContents = True  #自动拉伸
        self.setWordWrap = True
        self.setFont(QFont(font_path[settings["lang"]]))
        self.setTextFormat(Qt.MarkdownText)
        self.setText(font_path[settings["lang"]])
        if self.MsgEntry.style_str != "":
            #将html标签形式的font包装成text
            l= re.findall(r"<([a-zA-Z0-9\-_]*)([a-zA-Z0-9\-_#= ]*)>",self.MsgEntry.style_str)
            self.setText(self.MsgEntry.style_str + self.MsgEntry.text + ''.join(["</" + i[0] + ">" for i in l]))
        # 添加阴影
        self.effect_shadow = QGraphicsDropShadowEffect(self)
        text_color = re.search(r"color=(#[0-9A-F]*)", self.text())
        text_color = RGB2Hex((8,8,160,127)) if text_color == None else text_color.group(1)
        self.effect_shadow.setOffset(0,0)  # 偏移
        self.effect_shadow.setColor(QColor(text_color))  # 阴影颜色
        self.effect_shadow.setBlurRadius(10)  # 阴影半径
        self.setGraphicsEffect(self.effect_shadow)  # 将设置套用到widget窗口中
Exemple #4
0
def addName(ID: int, no: int = 0):
    """
    为characterID获取name。
    ID(int):要搜索name的ID。
    no(int):第no个搜索项。
    """
    url = r"https://esi.evetech.net/latest/characters/" + str(
        ID) + r"/?datasource=tranquility"
    Msg = {"addName": []}
    try:
        with rq.get(url, timeout=5) as ret:
            ret = loads(ret.content)
    except Exception as e:
        log("addName:" + str(e), level="error")
        return Msg

    log("addName:ID={ID}已获取到".format(ID=ID))
    if "name" in ret:
        history.update({ret["name"]: {"characterID": ID}})
        Msg["addName"].append([
            ID,
            TMsgEntry(ret["name"],
                      ClickEvent=SearchName,
                      ClickArgs=(ret["name"], ID),
                      style_str=MDStyleStr(
                          color=settings["claddName"],
                          font_size=settings["labelFontSize"]))
        ])
    return Msg
Exemple #5
0
    def EndSearchEvent(self,e=None):
        """
        搜索结束事件。
        将传递信息的线程传来的
        """
        if isinstance(self.sender(), TThread):
            log("EndSearch:"+str(self.sender().__name__))
            MutEndSearch.lock()
            Msg = self.sender().Msg
            log("Msg="+str(Msg))

            if id(self.sender()) not in current_thread_set:
                #说明不是此次搜索的返回线程,直接丢弃
                MutEndSearch.unlock()
                return - 1

            #由SearchName返回
            if "getKMList" in Msg:#完成了一轮完整的搜索流程
                self.MsgEntryList = {}
                self.MsgEntryList.update(Msg)
                self.statusBar().showMessage("搜索完成")
                self.EdtName.setStyleSheet("""
                    TEdtName{
                        border: 2px groove white;
                        border-radius: 3px;
                        padding:2px 3px;
                        color:rgb(255,0,0);
                        background-color:rgba(0,0,0,0)
                    }
                    TEdtName:focus{
                        color:rgb(0,255,0);
                        background-color: rgb(0,0,0)
                    } """)
            elif "Error" in Msg:  #SearchName返回错误
                self.MsgEntryList = {}
                self.MsgEntryList.update(Msg)
                if Msg["Error"] == "getKMListError":
                    self.MsgEntryList.update({"ErrorLabel": TMsgEntry("获取KM列表失败",style_str=MDStyleStr(color=settings["clFailed"],font_size=settings["labelFontSize"]))})
                elif Msg["Error"] == "zkbError":
                    self.MsgEntryList.update({"ErrorLabel": TMsgEntry("zkb查询失败",style_str=MDStyleStr(color=settings["clFailed"],font_size=settings["labelFontSize"]))})
                elif Msg["Error"] == "esiError":
                    self.MsgEntryList.update({"ErrorLabel": TMsgEntry("查询角色ID失败", style_str=MDStyleStr(color=settings["clFailed"], font_size=settings["labelFontSize"]))})
                elif Msg["Error"] == "SearchKMError":
                    self.MsgEntryList.update({"ErrorLabel": TMsgEntry("查询KM失败", style_str=MDStyleStr(color=settings["clFailed"], font_size=settings["labelFontSize"]))})
                elif Msg["Error"] == "NoSuchCharacterError":
                    self.MsgEntryList.update({"ErrorLabel": TMsgEntry("无此角色", style_str=MDStyleStr(color=settings["clFailed"], font_size=settings["labelFontSize"]))})
                elif Msg["Error"] == "PlayerNoPVPData":
                    self.MsgEntryList.update({"ErrorLabel": TMsgEntry("没有该角色的统计数据",style_str=MDStyleStr(color=settings["clHint"],font_size=settings["labelFontSize"]))})

            elif "NameList" in Msg:  #多个搜索结果命中
                self.MsgEntryList.update({"MultipleHits": TMsgEntry("命中" + str(len(Msg["NameList"])) + "条搜索结果...",style_str=MDStyleStr(color=settings["clHint"],font_size=settings["labelFontSize"]))})
                NameList = Msg["NameList"][:]
                no=0
                for c in NameList:
                    no+=1
                    self.MultiThreadRun(func=addName, args=(c, no))
            elif "TooManyResults" in Msg:  #搜索结果命中数超过ResultCountLimit
                self.MsgEntryList.update(Msg)
                self.MultiThreadRun(func=SearchName,args=(Msg["name"],-1,True))

            #由addName返回
            elif "addName" in Msg:
                #处理addName返回的情况
                #addName会多并发调用EndSearchEvent,因此需要QMutex
                #addName会返回成对的name和characterID,每个返回都应被添加至self.MsgEntryList["addName"]
                if "addName" not in self.MsgEntryList:
                    self.MsgEntryList["addName"]=[]
                self.MsgEntryList["addName"] += Msg["addName"]

            #由SearchKM返回
            elif "SearchKM" in Msg:
                if self.LabelList_click_no != -1:
                    #需要找到被单击的Label在self.MsgEntryList中的位置
                    for i in range(len(self.MsgEntryList["getKMList"])):
                        #如果getKMList中记录的killmail_id==LabelList中记录的killmail_id
                        if (self.MsgEntryList["getKMList"][i][0][0]==self.LabelList[self.LabelList_click_no].MsgEntry.ClickArgs[1]):
                            self.MsgEntryList["getKMList"][i][2]=Msg
                            break
                self.statusBar().showMessage("KM已获取")
            MutEndSearch.unlock()
            self.RefreshLabelList()
Exemple #6
0
def SearchName(name: str = '', ID: int = -1, is_strict=False):
    """
    获取角色ID与zkb统计信息。
    name(str):角色名
    ID(int):如果已有角色ID则跳过搜索characterID的步骤
    is_strict(bool):严格模式,只搜索与name完全一致的角色名
    """
    global MutSearchName
    MutSearchName.lock()
    Msg = {}
    log("SearchName:name={name},ID={ID},is_strict={is_strict}".format(
        name=name, ID=ID, is_strict=is_strict))
    #characterID
    if ID < 0:  #如果没有给出characterID
        name = name.strip(" \n")
        for i in history:
            if i.upper() == name.upper():
                name = i
                ID = history[name]["characterID"]
                break
        if ID < 0:  #搜索历史记录未命中
            log("SearchName:历史记录未命中")
            strict = "&strict=true" if is_strict else "&strict=false"
            url = r"https://esi.evetech.net/latest/search/?categories=character&datasource=tranquility&language=en-us&search=" + name.replace(
                " ", "+") + strict
            try:

                with rq.get(url, timeout=5) as ret:
                    ret = loads(ret.content)
            except Exception as e:
                log("SearchName:" + str(e), level="error")
                Msg.update({"Error": "esiError"})
                MutSearchName.unlock()
                return Msg
            if "character" in ret:
                ID = ret["character"]
                if (len(ID) > 1):
                    log("SearchName:命中{l}/{lmax}个结果".format(
                        l=len(ID), lmax=settings["ResultCountLimit"]))
                    #有多个命中结果
                    if len(ID) < settings["ResultCountLimit"]:
                        Msg.update({"NameList": ID})
                        MutSearchName.unlock()
                        return Msg
                    else:
                        #结果过多
                        Msg.update({
                            "TooManyResults": TMsgEntry("搜索结果数量超过" + \
                                str(settings["ResultCountLimit"]) + "个,改为严格模式...",
                                style_str=MDStyleStr(
                                    color=settings["clHint"],
                                    font_size=settings["labelFontSize"]
                            )),
                            "name": name
                            })
                        MutSearchName.unlock()
                        return Msg
                else:
                    ID = ID[0]
            else:
                Msg.update({"Error": "NoSuchCharacterError"})
                log("SearchName:esi查询失败:{name}".format(name=name),
                    level="warning")
                MutSearchName.unlock()
                return Msg
        Msg.update({"SearchName": [name, ID]})

    #zkb
    url = r"https://zkillboard.com/api/stats/characterID/" + str(ID) + r"/"
    try:
        with rq.get(url, timeout=5) as ret:
            ret = loads(ret.content)
    except Exception as e:
        Msg.update({"Error": "zkbError"})
        MutSearchName.unlock()
        return Msg

    #角色信息为None
    if (ret == {}) or (ret["info"] == None):
        Msg.update({"Error": "PlayerNoPVPData"})
        MutSearchName.unlock()
        return Msg

    if "dangerRatio" not in ret:
        ret["dangerRatio"] = 0
    danger_ratio_color = (int(ret["dangerRatio"] / 100 * 255),
                          int((1 - (ret["dangerRatio"] / 100)) * 255), 0)

    if "gangRatio" not in ret:
        ret["gangRatio"] = 100
    solo_ratio_color = (int((1 - (ret["gangRatio"] / 100)) * 255),
                        int(ret["gangRatio"] / 100 * 255), 0)

    Msg.update({
        "SearchKB": {
            "name": [
                ret["info"]["name"],
                TMsgEntry(
                    r"<a href='https://zkillboard.com/character/" + str(ID) +
                    r"' style='color:blue'>" + ret["info"]["name"] + "</a>",
                    style_str=MDStyleStr(color=settings["clURL"],
                                         font_size=settings["labelFontSize"]))
            ],
            "dangerRatio": [
                ret["dangerRatio"],
                TMsgEntry("危险度:" + str(ret["dangerRatio"]) + "%",
                          style_str=MDStyleStr(
                              color=danger_ratio_color,
                              font_size=settings["labelFontSize"]))
            ],
            "soloRatio": [
                ret["gangRatio"],
                TMsgEntry("solo率:" + str(100 - ret["gangRatio"]) + "%",
                          style_str=MDStyleStr(
                              color=solo_ratio_color,
                              font_size=settings["labelFontSize"]))
            ],
            "topShips":
            [[i["shipTypeID"] for i in ret["topLists"][3]["values"][:3]],
             TMsgEntry("最高击杀舰船:" + ','.join([
                 getNamebyID(i["shipTypeID"]) + "(" + str(i["kills"]) + "次)"
                 for i in ret["topLists"][3]["values"][:3]
                 if i["shipName"] != "Capsule"
             ]),
                       style_str=MDStyleStr(
                           color=settings["cltopShips"],
                           font_size=settings["labelFontSize"]))],
            "topSolarSystem":
            [[i["solarSystemName"] for i in ret["topLists"][4]["values"][:3]],
             TMsgEntry("最常出没:" + ','.join([
                 i["solarSystemName"] + "(" + str(i["kills"]) + "次)"
                 for i in ret["topLists"][4]["values"][:3]
             ]),
                       style_str=MDStyleStr(
                           color=settings["cltopSolarSystem"],
                           font_size=settings["labelFontSize"]))]
        }
    })

    history.update({ret["info"]["name"]: {"characterID": ID}})
    SaveFile(history, settings["workingDir"] + "history.json")

    #getKMList
    url = r"https://zkillboard.com/api/kills/characterID/" + str(ID) + r"/"
    try:
        with rq.get(url, timeout=5) as ret:
            ret = loads(ret.content)
    except Exception as e:
        log("getKMList:" + str(e), level="error")
        Msg.update({"Error": "getKMListError"})
        MutSearchName.unlock()
        return Msg

    #玩家可能没有击杀km
    if ret == []:
        Msg.update({"getKMList": []})
        MutSearchName.unlock()
        return Msg

    km_count = min(settings["KMCounts"], len(ret))
    killmail_pairs = [(ret[i]["killmail_id"], ret[i]["zkb"]["hash"])
                      for i in range(km_count)]
    remap = []
    label_list = [
        TMsgEntry(str(i + 1) + ".最近km(" +
                  Valuable(ret[i]["zkb"]["totalValue"]) + ' isk)',
                  style_str=MDStyleStr(color=settings["clKM"],
                                       font_size=settings["labelFontSize"]),
                  ClickEvent=SearchKM,
                  ClickArgs=(ID, killmail_pairs[i][0], killmail_pairs[i][1]))
        for i in range(len(killmail_pairs))
    ]
    for i in killmail_pairs:
        remap.append([i, label_list[0], {}])
        label_list = label_list[1:]
    Msg.update({"getKMList": remap})
    log("getKMList:完成")
    MutSearchName.unlock()
    return Msg
Exemple #7
0
def SearchKM(character_id: int, killmail_id: int = 0, killmail_hash: str = ''):
    """
    获取一个特定的km
    character_id(int):角色id
    killmail_id(int):该killmail的id
    killmail_hash(str):由ccp给出的km哈希值
    """
    global MutSearchKM
    MutSearchKM.lock()
    Msg = {}
    log("SearchKM:character_id={character_id},killmail_id={killmail_id},killmail_hash={killmail_hash}"
        .format(character_id=character_id,
                killmail_id=killmail_id,
                killmail_hash=killmail_hash))
    url = r"https://esi.evetech.net/latest/killmails/"\
            + str(killmail_id)\
            + r"/" + killmail_hash + r"/?datasource=tranquility"
    try:
        with rq.get(url, timeout=5) as ret:
            ret = loads(ret.content)
    except Exception as e:
        log("SearchKM:" + str(e), level="error")
        Msg.update({"Error": "SearchKMError"})
        MutSearchKM.unlock()
        return -1

    Msg = {
        "SearchKM": {
            "time": [
                ret["killmail_time"].replace('T', ' ').replace('Z', ''),
                TMsgEntry(
                    "  (" + ret["killmail_time"].replace('T', ' ').replace(
                        'Z', '' + ")"),
                    style_str=MDStyleStr(color=settings["clHint"],
                                         font_size=settings["labelFontSize"]))
            ],
            "victimShip": [
                ret["victim"]["ship_type_id"],
                TMsgEntry(
                    r"&nbsp;&nbsp;<a href='https://zkillboard.com/kill/" +
                    str(killmail_id) + r"/' style='color:blue'>击毁:" +
                    getNamebyID(ret["victim"]["ship_type_id"]) + r"</a>",
                    style_str=MDStyleStr(color=settings["clURL"],
                                         font_size=settings["labelFontSize"]))
            ]
        }
    }
    for i in ret["attackers"]:
        if ("character_id" in i) and (i["character_id"] == character_id):
            ship = getNamebyID(
                i["ship_type_id"]) if "ship_type_id" in i else "(?)"
            weapon = getNamebyID(
                i["weapon_type_id"]) if "weapon_type_id" in i else "(?)"
            if ship == weapon:
                weapon = "(混合)"
            Msg["SearchKM"].update({
                "shipType": [
                    ship,
                    TMsgEntry("   · " + ship,
                              style_str=MDStyleStr(
                                  color=settings["clshipType"],
                                  font_size=settings["labelFontSize"]))
                ],
                "weaponType": [
                    weapon,
                    TMsgEntry("   · " + weapon,
                              style_str=MDStyleStr(
                                  color=settings["clweaponType"],
                                  font_size=settings["labelFontSize"]))
                ]
            })
            break
    log("SearchKM:完成")
    MutSearchKM.unlock()
    return Msg