diff --git a/CursesDownload.py b/CursesDownload.py deleted file mode 100644 index ba31106..0000000 --- a/CursesDownload.py +++ /dev/null @@ -1,70 +0,0 @@ -import curses -import Common - - -widths = [ - (126, 1), (159, 0), (687, 1), (710, 0), (711, 1), - (727, 0), (733, 1), (879, 0), (1154, 1), (1161, 0), - (4347, 1), (4447, 2), (7467, 1), (7521, 0), (8369, 1), - (8426, 0), (9000, 1), (9002, 2), (11021, 1), (12350, 2), - (12351, 1), (12438, 2), (12442, 0), (19893, 2), (19967, 1), - (55203, 2), (63743, 1), (64106, 2), (65039, 1), (65059, 0), - (65131, 2), (65279, 1), (65376, 2), (65500, 1), (65510, 2), - (120831, 1), (262141, 2), (1114109, 1), -] - - -def get_width(o): - global widths - if o == 0xe or o == 0xf: - return 0 - for num, wid in widths: - if o <= num: - return wid - return 1 - - -def c_print(handle, y, x, string, style=curses.A_NORMAL): - if type(string) != str: - string = str(string) - for _i in string: - _w = get_width(ord(_i)) - if(_w>1): - handle.addch(y, x+1, " ", style) - handle.addch(y, x, ord(_i), style) - x += _w - - -def render(screen): - _style = curses.A_DIM - if Common.api.isLive: - _style = curses.A_BOLD | curses.A_BLINK | curses.A_ITALIC | curses.A_UNDERLINE - c_print(screen, 1, 3, Common.api.roomLiver, _style) - screen.refresh() - -def main(stdscr): - global screen - screen = stdscr.subwin(23, 79, 0, 0) - screen.timeout(2000) - screen.box() - screen.hline(2, 1, curses.ACS_HLINE, 77) - c_print(screen, 1, 2, " "*45 + " 西瓜录播助手 -- by JerryYan ", curses.A_STANDOUT) - render(screen) - while True: - c = stdscr.getch() - if c == ord("q"): - break - elif c == ord("f"): - render(screen) - - -stdscr = curses.initscr() -curses.noecho() -curses.cbreak() -stdscr.keypad(1) -curses.wrapper(main) -stdscr.keypad(0) -curses.echo() -curses.nocbreak() -curses.endwin() - diff --git a/CursesMain.py b/CursesMain.py deleted file mode 100644 index 4a1f513..0000000 --- a/CursesMain.py +++ /dev/null @@ -1,107 +0,0 @@ -import curses - -from Struct.Chat import Chat -from Struct.Gift import Gift -from Struct.MemberMsg import MemberMsg -from Struct.User import User -from api import XiGuaLiveApi - - -class Api(XiGuaLiveApi): - danmakuList = [] - def onAd(self, i): - pass - def onChat(self, chat: Chat): - self.danmakuList.append(str(chat)) - def onLike(self, user: User): - pass - def onEnter(self, msg: MemberMsg): - pass - def onJoin(self, user: User): - self.danmakuList.append(str(user)) - def onSubscribe(self, user: User): - self.danmakuList.append(str(user)) - def onPresent(self, gift: Gift): - pass - def onPresentEnd(self, gift: Gift): - self.danmakuList.append(str(gift)) - - -api = Api() -widths = [ - (126, 1), (159, 0), (687, 1), (710, 0), (711, 1), - (727, 0), (733, 1), (879, 0), (1154, 1), (1161, 0), - (4347, 1), (4447, 2), (7467, 1), (7521, 0), (8369, 1), - (8426, 0), (9000, 1), (9002, 2), (11021, 1), (12350, 2), - (12351, 1), (12438, 2), (12442, 0), (19893, 2), (19967, 1), - (55203, 2), (63743, 1), (64106, 2), (65039, 1), (65059, 0), - (65131, 2), (65279, 1), (65376, 2), (65500, 1), (65510, 2), - (120831, 1), (262141, 2), (1114109, 1), -] - - -def get_width(o): - global widths - if o == 0xe or o == 0xf: - return 0 - for num, wid in widths: - if o <= num: - return wid - return 1 - - -def c_print(handle, y, x, string, style=curses.A_NORMAL): - if type(string) != str: - string = str(string) - for _i in string: - _w = get_width(ord(_i)) - if(_w>1): - handle.addch(y, x+1, " ", style) - if _i != " " or style!=curses.A_NORMAL: - handle.addch(y, x, ord(_i), style) - else: - handle.addch(y, x, 0, style) - x += _w - - - - -def render(screen): - screen.erase() - screen.box() - screen.hline(2, 1, curses.ACS_HLINE, 77) - c_print(screen, 1, 2, " "*45 + " 西瓜弹幕助手 -- by JerryYan ", curses.A_STANDOUT) - _style = curses.A_DIM - if api.isLive: - _style = curses.A_BOLD | curses.A_BLINK | curses.A_ITALIC - c_print(screen, 1, 3, api.roomLiver, _style) - _y = 3 - api.getDanmaku() - for i in api.danmakuList[-10:]: - c_print(screen, _y, 2, i) - _y += 1 - screen.move(0,0) - screen.refresh() - -def main(stdscr): - global screen - screen = stdscr.subwin(23, 79, 0, 0) - screen.timeout(2000) - render(screen) - while True: - c = screen.getch() - if c == ord("q"): - break - render(screen) - - -stdscr = curses.initscr() -curses.noecho() -curses.cbreak() -stdscr.keypad(1) -curses.wrapper(main) -stdscr.keypad(0) -curses.echo() -curses.nocbreak() -curses.endwin() - diff --git a/WinMain.py b/WinMain.py index c932523..1fd95d7 100644 --- a/WinMain.py +++ b/WinMain.py @@ -112,7 +112,7 @@ class WinMain(Api): if self._tmp > 10: self._tmp = 0 if self._tmp < 5: - return "{} 的直播间 --弹幕助手 by JerryYan".format(self.roomLiver) + return "{} 的直播间 --弹幕助手 by JerryYan".format(self.broadcaster) else: if self.roomPopularity == 0: self._tmp = 0 @@ -190,13 +190,13 @@ if __name__ == "__main__": else: name = readInput("请输入主播用户名,默认为", name, 3) api = WinMain(name) - while not api.isValidRoom: + while not api.isValidUser: set_cmd_text_color(FOREGROUND_RED) print("未找到对应房间或未开播,等待1分钟后重试") resetColor() time.sleep(60) api.updRoomInfo() - print("进入", api.roomLiver, "的直播间") + print("进入", api.broadcaster, "的直播间") os.system("title {}".format(api.getTitle())) print("=" * 30) while True: diff --git a/api.py b/api.py index 1159cef..dae99ae 100644 --- a/api.py +++ b/api.py @@ -26,7 +26,7 @@ SEARCH_USER_API = ( "https://security.snssdk.com/video/app/search/live/?format=json&search_sug=0&forum=0&m_tab=live&is_native_req=0" "&offset=0&from=live&en_qc=1&pd=xigua_live&ssmix=a{COMMON}&keyword={keyword}") USER_INFO_API = "https://is.snssdk.com/video/app/user/home/v7/?to_user_id={userId}{COMMON}" -PING_ROOM_API = "https://webcast3.ixigua.com/webcast/room/ping/audience/?room_id={roomId}{COMMON}" +ROOM_INFO_API = "https://webcast3.ixigua.com/webcast/room/enter/?room_id={roomId}&pack_level=4{COMMON}" COMMON_HEADERS = { "sdk-version": '1', "User-Agent": "Dalvik/2.1.0 (Linux; U; Android 9) VideoArticle/8.1.6 cronet/TTNetVersion:b97574c0 2019-09-24", @@ -44,17 +44,17 @@ class XiGuaLiveApi: """ if name is None: name = "永恒de草薙" - self.roomLiver = None + self.broadcaster = None if type(name) == User: - self.roomLiver = name + self.broadcaster = name self.name = name.name elif str(name).isdigit(): - self.roomLiver = User() - self.roomLiver.ID = int(name) + self.broadcaster = User() + self.broadcaster.ID = int(name) else: self.name = str(name) self.isLive = False - self.isValidRoom = False + self.isValidUser = False self._rawRoomInfo = {} self.roomID = 0 self.roomPopularity = 0 @@ -220,46 +220,62 @@ class XiGuaLiveApi: """ print("中奖消息 :", i) - def _checkUsernameIsMatched(self): + def _checkUsernameIsMatched(self, compare=None): """ 验证主播名字是自己想要的那个 Check name matched :return: bool: 是否匹配 """ return True - if self.name is None or self.roomLiver is None: + if compare is None: + compare = self.broadcaster + if self.name is None or compare is None: return False - return self.name == self.roomLiver.__str__() or self.roomLiver.__str__() in self.name or self.name in self.roomLiver.__str__() + return self.name == compare.__str__() or compare.__str__() in self.name or self.name in compare.__str__() def _forceSearchUser(self): """ 搜索主播名 :return: """ - _results = self.searchUser(self.name) - if len(_results) > 0: - self.isValidRoom = True - self.roomLiver = _results[0] - return self._updateUserOnly() + _formatData = {"COMMON": COMMON_GET_PARAM, "TIMESTAMP": time.time() * 1000, "keyword": self.name} + _url = SEARCH_USER_API.format_map(_formatData).format_map(_formatData) + d = self.getJson(_url) + if d is None: + print("搜索接口请求失败") + return False + if "data" in d and d["data"] is not None: + for i in d["data"]: + if i["block_type"] != 0: + continue + if "cells" not in i or len(i["cells"]) == 0: + break + for _j in i["cells"]: + _user = User(_j) + if self._checkUsernameIsMatched(_user): + self.isValidUser = True + self.broadcaster = _user + break + return self._updateUserInfo() - def _updateUserOnly(self): + def _updateUserInfo(self): """ 获取用户信息 :return: """ - if self.roomLiver is None: + if self.broadcaster is None: return False - _formatData = {"COMMON": COMMON_GET_PARAM, "TIMESTAMP": time.time() * 1000, "userId": self.roomLiver.ID} + _formatData = {"COMMON": COMMON_GET_PARAM, "TIMESTAMP": time.time() * 1000, "userId": self.broadcaster.ID} _url = USER_INFO_API.format_map(_formatData).format_map(_formatData) d = self.getJson(_url) if d is None: print("获取用户信息失败") return False - self.isValidRoom = d["status"] == 0 + self.isValidUser = d["status"] == 0 if "user_info" not in d and d["user_info"] is None: self.apiChangedError("Api发生改变,请及时联系我", d) return False - self.roomLiver = User(d) + self.broadcaster = User(d) if not self._checkUsernameIsMatched(): self.isLive = False return False @@ -274,55 +290,30 @@ class XiGuaLiveApi: self.lottery = l return True - def _checkRoom(self): - if self.roomID == 0: - return False + def _getRoomInfo(self): _formatData = {"COMMON": COMMON_GET_PARAM, "TIMESTAMP": time.time() * 1000, "roomId": self.roomID} - _url = PING_ROOM_API.format_map(_formatData).format_map(_formatData) + _url = ROOM_INFO_API.format_map(_formatData).format_map(_formatData) d = self.getJson(_url) if d is None: - print("检查房间失败") + print("获取房间信息接口请求失败") return False - self.isLive = d["data"]["room_status"] == 0 - return self.isLive + if d["status_code"] != 0: + print("接口提示:【{}】".format(d["data"]["message"])) + return False + self._rawRoomInfo = d["data"] + return True def updRoomInfo(self): """ 更新房间信息 :return: """ - if not self.isValidRoom: + if not self.isValidUser: return self._forceSearchUser() elif not self.isLive: - return self._updateUserOnly() + return self._updateUserInfo() else: - return self._checkRoom() - - @staticmethod - def searchUser(keyword): - """ - 通过关键词搜索主播 - :param keyword: 关键词 - :return: array: 搜索结果 - """ - ret = [] - _formatData = {"COMMON": COMMON_GET_PARAM, "TIMESTAMP": time.time() * 1000, "keyword": keyword} - _url = SEARCH_USER_API.format_map(_formatData).format_map(_formatData) - try: - p = requests.get(_url) - d = p.json() - except json.decoder.JSONDecodeError as e: - XiGuaLiveApi.apiChangedError("搜索接口错误", e.__str__()) - return ret - if "data" in d and d["data"] is not None: - for i in d["data"]: - if i["block_type"] != 0: - continue - if "cells" not in i or len(i["cells"]) == 0: - break - for _j in i["cells"]: - ret.append(User(_j)) - return ret + return self._getRoomInfo() def getDanmaku(self): """ @@ -390,10 +381,10 @@ if __name__ == "__main__": name = sys.argv[1] print("西瓜直播弹幕助手 by JerryYan") api = XiGuaLiveApi(name) - if not api.isValidRoom: + if not api.isValidUser: input("房间不存在") sys.exit() - print("进入", api.roomLiver, "的直播间") + print("进入", api.broadcaster, "的直播间") print("=" * 30) while True: if api.isLive: