diff --git a/README.md b/README.md index 83fdda8..7ac2116 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,8 @@ pip install git+https://github.com/thedtvn/zingmp3py.git from zingmp3py import ZingMp3 zi = ZingMp3() +# login is not required +zi.login("zpsid cookies") zi.getDetailPlaylist("67ZFO8DZ") zi.getDetailArtist("Cammie") zi.getRadioInfo("IWZ979CW") @@ -37,6 +39,8 @@ from zingmp3py import ZingMp3Async async def main(): zi = ZingMp3Async() + # login is not required + await zi.login("zpsid cookies") await zi.getDetailPlaylist("67ZFO8DZ") await zi.getDetailArtist("Cammie") await zi.getSongInfo("ZWAF6UFD") @@ -47,6 +51,12 @@ async def main(): asyncio.run(main()) ``` +## how to get zpsid cookies + +go to https://id.zalo.me/account/logininfo then check f12 go to tab application go to cookies and check for cookie name zpsid + +note: please check check you are login or not by check key `logged` in json return in that url is `true` + ## Get Type And ID ```py diff --git a/setup.py b/setup.py index ad4eaaa..188ed85 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setup( name='zingmp3py', - version="0.3.2", + version="0.3.3", long_description=ld, long_description_content_type='text/markdown', description='A light weight Python library for the ZingMp3 API', diff --git a/test/zasync_test.py b/test/zasync_test.py index 3940d5f..bf788d8 100644 --- a/test/zasync_test.py +++ b/test/zasync_test.py @@ -3,10 +3,11 @@ async def main(): zi = ZingMp3Async() + await zi.login("zpsid cookies") (await zi.getDetailPlaylist("ZB08FIBW")).songs await zi.getDetailArtist("Cammie") await zi.getSongInfo("ZWAF6UFD") - await zi.getSongStreaming("ZWAF6UFD") + await zi.getSongStreaming("ZWDB08FB") await zi.getTop100() await zi.search("rick roll") diff --git a/test/zsync_test.py b/test/zsync_test.py index 4ad80d3..66bde49 100644 --- a/test/zsync_test.py +++ b/test/zsync_test.py @@ -2,10 +2,11 @@ getUrlTypeAndID("https://zingmp3.vn/liveradio/IWZ979CW.html") zi = ZingMp3() +zi.login("zpsid cookies") zi.getDetailPlaylist("ZB08FIBW").songs zi.getDetailArtist("Cammie") zi.getRadioInfo("IWZ979UB") zi.getSongInfo("ZWAF6UFD") -zi.getSongStreaming("ZWAF6UFD") +zi.getSongStreaming("ZWDB08FB") zi.getTop100() zi.search("rick roll") \ No newline at end of file diff --git a/zingmp3py/__init__.py b/zingmp3py/__init__.py index 512e0ef..223a219 100644 --- a/zingmp3py/__init__.py +++ b/zingmp3py/__init__.py @@ -3,4 +3,4 @@ from .util import getUrlTypeAndID from .sobj import Song, Artist, Search, Playlist, LiveRadio, Stream -__version__ = '0.3.2' \ No newline at end of file +__version__ = '0.3.3' \ No newline at end of file diff --git a/zingmp3py/zasync.py b/zingmp3py/zasync.py index 7a56dee..b7428de 100644 --- a/zingmp3py/zasync.py +++ b/zingmp3py/zasync.py @@ -1,5 +1,8 @@ import aiohttp import re + +from yarl import URL + from .util import * from .zsync import ZingMp3 from .sobj import * @@ -38,15 +41,27 @@ def songs(self): return [Song(song, self.client) for song in self.indata['song']["items"]] class ZingMp3Async(ZingMp3): + cooke = aiohttp.CookieJar() + apikey = {} + zpsid = None + last_updated = 0 async def get_ck(self, request: aiohttp.ClientSession): - if int(self.cooke["last_updated"] + 60) < int(time.time()): + if int(self.last_updated + 60) < int(time.time()): + if self.zpsid: + ck = {"zpsid": self.zpsid} + async with request.get("https://id.zalo.me/account?continue=https%3A%2F%2Fzingmp3.vn", cookies=ck) as r: + if str(r.url) != "https://zingmp3.vn": + raise Exception("zpsid is invalid cookie") async with request.get("https://zingmp3.vn") as r: - self.cooke["cookies"] = r.cookies - self.cooke["last_updated"] = int(time.time()) - return self.cooke["cookies"] + pass + for i in list(request.cookie_jar): + self.cooke.update_cookies({i.key: i}) + request.cookie_jar.update_cookies({i.key: i}) + self.last_updated = int(time.time()) else: - return self.cooke["cookies"] + for i in list(self.cooke): + request.cookie_jar.update_cookies({i.key: i}) async def get_key(self): if not self.apikey: @@ -64,9 +79,7 @@ async def get_key(self): else: return self.apikey["data"] - async def requestZing(self, path, qs=None, haveParam=0): - if qs is None: - qs = {} + async def requestZing(self, path, qs={}, haveParam=0): apikey, skey = await self.get_key() param = "&".join([f"{i}={k}" for i, k in qs.items()]) sig = hashParam(skey, path, param, haveParam) @@ -75,13 +88,23 @@ async def requestZing(self, path, qs=None, haveParam=0): qs.update({"sig": sig[0]}) url = "https://zingmp3.vn" + path async with aiohttp.ClientSession() as s: - ck = await self.get_ck(s) - async with s.get(url, params=qs, cookies=ck) as r: + await self.get_ck(s) + async with s.get(url, params=qs) as r: data = await r.json() if data['err'] != 0: raise ZingMp3Error(data) return data + async def login(self, zpsid): + async with aiohttp.ClientSession() as s: + async with s.get("https://id.zalo.me/account/logininfo", cookies={"zpsid": zpsid}) as r: + out = await r.json() + if out["error_code"] != 0: + raise ZingMp3Error({"msg": f"Login Error: {out['error_message']}"}) + elif not out["data"]["logged"]: + raise ZingMp3Error({"msg": f"zpsid is invalid"}) + self.zpsid = zpsid + async def getDetailPlaylist(self, id): data = await self.requestZing("/api/v2/page/get/playlist", {"id": id}) return Playlist(data["data"], client=self) diff --git a/zingmp3py/zsync.py b/zingmp3py/zsync.py index c7bc7fa..4f19b07 100644 --- a/zingmp3py/zsync.py +++ b/zingmp3py/zsync.py @@ -1,21 +1,32 @@ import re +from requests.cookies import RequestsCookieJar from .util import * from .sobj import * class ZingMp3: + cooke = RequestsCookieJar() + apikey = {} + zpsid = None + last_updated = 0 + def __init__(self): - self.apikey = {} - self.cooke = {"cookies": {}, "last_updated": 0} + pass def get_ck(self, request: requests.Session): - if int(self.cooke["last_updated"] - 60) < int(time.time()): + if int(self.last_updated - 60) < int(time.time()): + if self.zpsid: + ck = {"zpsid": self.zpsid} + with request.get("https://id.zalo.me/account?continue=https%3A%2F%2Fzingmp3.vn", cookies=ck) as r: + if str(r.url) != "https://zingmp3.vn": + raise Exception("zpsid is invalid cookie") with request.get("https://zingmp3.vn") as r: - self.cooke["cookies"] = r.cookies - self.cooke["last_updated"] = int(time.time()) - return self.cooke["cookies"] + pass + self.cooke.update(r.cookies) + self.last_updated = int(time.time()) + request.cookies.update(self.cooke) else: - return self.cooke["cookies"] + request.cookies.update(self.cooke) def get_key(self): if not self.apikey: @@ -42,12 +53,23 @@ def requestZing(self, path, qs={}, haveParam=0): qs.update({"sig": sig[0]}) url = "https://zingmp3.vn" + path with requests.Session() as s: - with s.get(url, params=qs, cookies=self.get_ck(s)) as r: + self.get_ck(s) + with s.get(url, params=qs) as r: data = r.json() if data['err'] != 0: raise ZingMp3Error(data) return data + def login(self, zpsid): + with requests.Session() as s: + with s.get("https://id.zalo.me/account/logininfo", cookies={"zpsid": zpsid}) as r: + out = r.json() + if out["error_code"] != 0: + raise ZingMp3Error({"msg": f"Login Error: {out['error_message']}"}) + elif not out["data"]["logged"]: + raise ZingMp3Error({"msg": f"zpsid is invalid"}) + self.zpsid = zpsid + def getDetailPlaylist(self, id): data = self.requestZing("/api/v2/page/get/playlist", {"id": id}) return Playlist(data["data"], client=self)