chore:update publish.yml

This commit is contained in:
2061360308 2023-12-20 00:50:12 +08:00
parent f34639a9ce
commit fb1d5fa298
14 changed files with 327 additions and 75 deletions

View File

@ -1,5 +1,5 @@
[bumpversion]
current_version = 0.1.8
current_version = 0.1.7
commit = True
tag = True

View File

@ -46,7 +46,7 @@ jobs:
- name: Build a binary wheel and a source tarball
run: |
cd package
python setup.py build
python setup.py upload
ls ./dist/
- name: Publish distribution 📦 to PyPI

View File

@ -17,6 +17,7 @@ Description-Content-Type: text/markdown
License-File: LICENSE
# NeteaseCloudMusic_PythonSDK
> 基于 [ NeteaseCloudMusicApi](https://github.com/Binaryify/NeteaseCloudMusicApi) 封装的 Python SDK。
> 网易云API Python版本。
@ -54,15 +55,48 @@ print(api_list())
> 注意: request(self, name, query=None) 的第一个参数为API名称第二个参数为API参数具体API名称和参数请参考 [NeteaseCloudMusicApi文档](https://docs.neteasecloudmusicapi.binaryify.com)name支持`/song/url/v1`和`song_url_v1`两种写法。
> api已加入自动缓存在测试接口时如果频繁调用获取结果在query里应该加上timestamp参数来区分例如
> ```python
> response = netease_cloud_music_api.request("song_url_v1", {"id": 33894312, "level": "exhigh", "timestamp": time.time()})
> ```
### 开发
- 克隆项目 `git clone git@github.com:2061360308/NeteaseCloudMusic_PythonSDK.git`
- 安装依赖 `pip install -r requirements.txt`
- 目录/文件说明
```
├── package 项目包根目录
├── test_gender 生成测试代码的脚本
├── test.py 手动测试/ 使用示例
```
### 更新
项目使用towncrier自动生成更新日志
在 newsfragments 目录下,创建一个新的文本文件。这个文件的名字应该是一个唯一的编号,后缀是 .rst。
例如,如果你正在处理编号为 123 的问题,你可以创建一个名为 123.feature.rst 的文件。
注意在 towncrier 中,新闻片段的类型通常由文件名的后缀决定。以下是一些常见的新闻片段类型:
- .feature: 用于描述新的特性或者功能。
- .bugfix: 用于描述一个 bug 修复。
- .doc: 用于描述文档的更改。
- .removal: 用于描述移除的特性或者功能。
- .misc: 用于描述其他类型的更改。
-
在这个文件中,写下你的更改的描述。这个描述应该是简短的,通常只有一到两句话。
例如`Added support for the XYZ feature.`
### 发布新版本
使用bumpversion自动更新版本号提交并发布标签
你需要安装bumpversion然后执行
```bash
bumpversion patch # for a patch level increase (e.g., 1.0.0 to 1.0.1)
bumpversion minor # for a minor level increase (e.g., 1.0.0 to 1.1.0)
bumpversion major # for a major level increase (e.g., 1.0.0 to 2.0.0)
```
接下来会自动更新版本号并提交到远程仓库,然后发布一个新的标签
workflow会依据标签自动发布相应资源并且发布到pypi
### 改进
> 下列API未支持
@ -107,3 +141,8 @@ print(api_list())
- /fm_trash
### 欢迎提交PR
更正request库返回多个cookie时自动用分号拼接导致后续cookie不好解析的问题
添加了对cookie中Max-Age为0的处理
改进判断cookie是否过期的逻辑
添加了自动处理cookie的更新操作

View File

@ -7,6 +7,7 @@ NeteaseCloudMusic/__init__.py
NeteaseCloudMusic/config.json
NeteaseCloudMusic/help.py
NeteaseCloudMusic/main.py
NeteaseCloudMusic/utils.py
NeteaseCloudMusic.egg-info/PKG-INFO
NeteaseCloudMusic.egg-info/SOURCES.txt
NeteaseCloudMusic.egg-info/dependency_links.txt

View File

@ -1,2 +1,3 @@
py_mini_racer
requests
diskcache

View File

@ -2,4 +2,4 @@ from .main import NeteaseCloudMusicApi
from .help import api_help, api_list
from .utils import format_cookie_str, prase_cookie_str
__version__ = '0.1.8'
__version__ = '0.1.7'

View File

@ -35,15 +35,48 @@ print(api_list())
> 注意: request(self, name, query=None) 的第一个参数为API名称第二个参数为API参数具体API名称和参数请参考 [NeteaseCloudMusicApi文档](https://docs.neteasecloudmusicapi.binaryify.com)name支持`/song/url/v1`和`song_url_v1`两种写法。
> api已加入自动缓存在测试接口时如果频繁调用获取结果在query里应该加上timestamp参数来区分例如
> ```python
> response = netease_cloud_music_api.request("song_url_v1", {"id": 33894312, "level": "exhigh", "timestamp": time.time()})
> ```
### 开发
- 克隆项目 `git clone git@github.com:2061360308/NeteaseCloudMusic_PythonSDK.git`
- 安装依赖 `pip install -r requirements.txt`
- 目录/文件说明
```
├── package 项目包根目录
├── test_gender 生成测试代码的脚本
├── test.py 手动测试/ 使用示例
```
### 更新
项目使用towncrier自动生成更新日志
在 newsfragments 目录下,创建一个新的文本文件。这个文件的名字应该是一个唯一的编号,后缀是 .rst。
例如,如果你正在处理编号为 123 的问题,你可以创建一个名为 123.feature.rst 的文件。
注意在 towncrier 中,新闻片段的类型通常由文件名的后缀决定。以下是一些常见的新闻片段类型:
- .feature: 用于描述新的特性或者功能。
- .bugfix: 用于描述一个 bug 修复。
- .doc: 用于描述文档的更改。
- .removal: 用于描述移除的特性或者功能。
- .misc: 用于描述其他类型的更改。
-
在这个文件中,写下你的更改的描述。这个描述应该是简短的,通常只有一到两句话。
例如`Added support for the XYZ feature.`
### 发布新版本
使用bumpversion自动更新版本号提交并发布标签
你需要安装bumpversion然后执行
```bash
bumpversion patch # for a patch level increase (e.g., 1.0.0 to 1.0.1)
bumpversion minor # for a minor level increase (e.g., 1.0.0 to 1.1.0)
bumpversion major # for a major level increase (e.g., 1.0.0 to 2.0.0)
```
接下来会自动更新版本号并提交到远程仓库,然后发布一个新的标签
workflow会依据标签自动发布相应资源并且发布到pypi
### 改进
> 下列API未支持
@ -88,3 +121,8 @@ print(api_list())
- /fm_trash
### 欢迎提交PR
更正request库返回多个cookie时自动用分号拼接导致后续cookie不好解析的问题
添加了对cookie中Max-Age为0的处理
改进判断cookie是否过期的逻辑
添加了自动处理cookie的更新操作

View File

@ -44,6 +44,7 @@ if (typeof window === "undefined") {
}
function encodeURIComponent(str) {
str = String(str); // 将输入转换为字符串 以免TrueFalse等非字符无法转换
var result = "";
if (str !== undefined && str !== null) {
@ -37928,7 +37929,7 @@ const hug_comment_resourceTypeMap = config_namespaceObject.A;
});
;// CONCATENATED MODULE: ./package.json
const package_namespaceObject = {"i8":"0.1.1"};
const package_namespaceObject = {"i8":"0.1.2"};
;// CONCATENATED MODULE: ./module/inner_version.js
/* harmony default export */ const inner_version = ((query, request) => {
@ -38338,30 +38339,19 @@ var crypto_js = __webpack_require__(1292);
;// CONCATENATED MODULE: ./module/login_refresh.js
// 登录刷新
/* harmony default export */ const login_refresh = (async (query, request) => {
let result = await request(
'POST',
/* harmony default export */ const login_refresh = ((query, request) => {
return request(
"POST",
`https://music.163.com/weapi/login/token/refresh`,
{},
{
crypto: 'weapi',
ua: 'pc',
crypto: "weapi",
ua: "pc",
cookie: query.cookie,
proxy: query.proxy,
realIP: query.realIP,
},
)
if (result.body.code === 200) {
result = {
status: 200,
body: {
...result.body,
cookie: result.cookie.join(';'),
},
cookie: result.cookie,
}
}
return result
);
});
;// CONCATENATED MODULE: ./module/login_status.js
@ -42852,6 +42842,7 @@ const weapi = (object) => {
for (let i = 0; i < 16; i++) {
secretKey += base62.charAt(Math.round(Math.random() * 61))
}
return {
params: aesEncrypt(
aesEncrypt(text, 'cbc', presetKey, iv),
@ -43181,6 +43172,27 @@ function beforeRequest(name, query) {
return response;
});
;// CONCATENATED MODULE: ./afterRequest/login_refresh.js
/* harmony default export */ const afterRequest_login_refresh = ((response) => {
response = JSON.parse(response);
let cookie = response.cookie;
if (Array.isArray(cookie)) {
cookie = cookie.join(";");
}
if (response.body.code === 200) {
response = {
status: 200,
body: {
...response.body,
cookie: cookie,
},
cookie: cookie,
};
}
return response;
});
;// CONCATENATED MODULE: ./afterRequest/login_status.js
/* harmony default export */ const afterRequest_login_status = ((response) => {
response = JSON.parse(response);
@ -43255,9 +43267,11 @@ function beforeRequest(name, query) {
/* harmony default export */ const afterRequestApi = ({
'check_music':afterRequest_check_music,
'login_cellphone':afterRequest_login_cellphone,
'login_refresh':afterRequest_login_refresh,
'login_status':afterRequest_login_status,
'related_playlist':afterRequest_related_playlist,
'top_playlist':afterRequest_top_playlist,

View File

@ -1,2 +1,5 @@
from .main import NeteaseCloudMusicApi
from .help import api_help, api_list
from .utils import format_cookie_str, prase_cookie_str
__version__ = '0.1.7'

View File

@ -1,26 +1,36 @@
import json
import os.path
import socket
import time
from pprint import pprint
import http.cookies
import datetime
from diskcache import Cache
import pkg_resources
import requests
from py_mini_racer import py_mini_racer
from .help import api_list
from .utils import format_cookie_str, prase_cookie_str
import urllib.parse
class NeteaseCloudMusicApi:
__cookie = None
__ip = None
def __init__(self, debug=False):
cache = Cache('cache', timeout=120) # 设置缓存目录和过期时间
# cache = TTLCache(maxsize=100, ttl=120) # 设置缓存大小为100缓存项的生存时间为120秒
def __init__(self, debug=False, cache=False):
self.DEBUG = debug # 是否开启调试模式
self.CACHE = cache # 是否开启缓存
self.special_api = {"/playlist/track/all": self.playlist_track_all,
"/login/cellphone": self.login_cellphone,
"/inner/version": self.inner_version}
"/inner/version": self.inner_version,
"/login/refresh": self.login_refresh}
# 载入js代码
resource_path = pkg_resources.resource_filename(__name__, 'NeteaseCloudMusicApi.js')
@ -66,8 +76,21 @@ class NeteaseCloudMusicApi:
if name not in yubei_special.values():
raise Exception(f"apiName: {name} not foundplease use ”api_list()“ to view the interface list")
# 生成一个唯一的键,用于在缓存中查找结果
cache_key = (name, frozenset(query.items()) if query else None)
if self.CACHE:
# 检查缓存中是否已经有了结果
if self.cache.get(cache_key):
return self.cache.get(cache_key)
if query is None:
query = {}
else:
# 如果存在timestamp参数那么删除它
if query.get("timestamp"):
del query["timestamp"]
if query.get("cookie") is None:
query["cookie"] = self.cookie
@ -82,7 +105,9 @@ class NeteaseCloudMusicApi:
else:
result = self.call_api(name, query)
#
if self.CACHE:
# 将结果存入缓存
self.cache.set(cache_key, result)
return result
@ -105,46 +130,47 @@ class NeteaseCloudMusicApi:
if self.__cookie is None:
if os.path.isfile("cookie_storage"):
with open("cookie_storage", "r", encoding='utf-8') as f:
self.cookie = f.read()
content = f.read()
try:
cookie_storage = json.loads(content)
# 验证cookie是否过期
create_time_stamp = cookie_storage['create_time_stamp']
if time.time() - create_time_stamp > 1296010:
# cookie过期了
self.__cookie = ""
else:
# 判断cookie生成时间是否超过1天
if time.time() - create_time_stamp > 86400:
# 更新cookie
# Todo login_refresh接口返回cookie好像少一些值
# self.request("/login/refresh", {"cookie": cookie_storage['cookie'], "timestamp": time.time()})
self.cookie = cookie_storage['cookie']
else:
self.__cookie = cookie_storage['cookie']
except json.JSONDecodeError and KeyError:
self.__cookie = ""
else:
self.__cookie = "" # 如果没有cookie文件就设置为空
return self.__cookie
@cookie.setter
def cookie(self, cookie):
if cookie is None:
cookie = ""
def cookie(self, value):
if value is None:
self.__cookie = ""
return
_cookie = cookie
"判断cookie是否合法, 简单检查一下关键的键"
necessary_keys = ["__csrf", "MUSIC_A_T", "MUSIC_R_T"]
cookie_dict = prase_cookie_str(value)
for key in necessary_keys:
if cookie_dict.get(key) is None:
raise Exception(f"cookie is illegal, missing key: {key}.")
'''判断cookie是否过期'''
# 创建一个Morsel对象它可以解析cookie字符串
morsel = http.cookies.SimpleCookie(cookie)
# 获取当前时间
now = datetime.datetime.now()
# 只判断 __csrf 是否过期
if not morsel.get('__csrf'):
# __csrf 不存在不是有效cookie
_cookie = ""
else:
# 将过期时间字符串转换为datetime对象
expires = morsel.get('__csrf')['expires']
expires_datetime = datetime.datetime.strptime(expires, "%a, %d %b %Y %H:%M:%S GMT")
# 判断cookie是否过期
if now > expires_datetime:
# 过期了
_cookie = ""
else:
# 未过期
pass
self.__cookie = _cookie
self.__cookie = value
with open("cookie_storage", "w+", encoding='utf-8') as f:
f.write(_cookie)
f.write(json.dumps({"cookie": value, "create_time_stamp": time.time()}, indent=2, ensure_ascii=False))
@property
def ip(self):
@ -155,18 +181,17 @@ class NeteaseCloudMusicApi:
def call_api(self, name, query):
request_param = self.ctx.call('NeteaseCloudMusicApi.beforeRequest', name, query) # 拿到请求头和请求参数
# Todo 了解 py_mini_racer 返回没有自动编码 而 node可以
param_data = {}
if request_param["data"] != "":
for item in request_param["data"].split("&"):
# param_data[item.split("=")[0]] = urllib.parse.quote(item.split("=")[1], safe='') # 不需要编码后反而出错
param_data[item.split("=")[0]] = item.split("=")[1]
# print("url", request_param["url"], "data", param_data, "headers\n", json.dumps(request_param["headers"], indent=2, ensure_ascii=False))
if request_param.get("method") == "GET":
response = requests.get(request_param["url"], params=param_data, headers=request_param["headers"])
else:
response = requests.post(request_param["url"], data=param_data, headers=request_param["headers"])
# response = requests.post(request_param["url"], data=param_data, headers=request_param["headers"])
try:
data = json.loads(response.text)
@ -179,12 +204,6 @@ class NeteaseCloudMusicApi:
"status": response.status_code,
}
# print("headers", response.headers)
# print("headers_dict", dict(response.headers))
# with open("response_result.json", "w+", encoding='utf-8') as f:
# f.write(json.dumps(response_result, indent=2, ensure_ascii=False))
result = self.ctx.call('NeteaseCloudMusicApi.afterRequest',
json.dumps(response_result),
request_param.get('crypto', None),
@ -230,8 +249,29 @@ class NeteaseCloudMusicApi:
"""
result = self.call_api("/login/cellphone", query)
# 自动 填充cookie
# 自动 更新cookie
if result["code"] == 200:
if result.get("data").get("cookie"):
self.cookie = result.get("data").get("cookie")
# cookie_str = format_cookie_str(result.get("data").get("cookie"))
cookie_str = result.get("data").get("cookie")
result["data"]["cookie"] = cookie_str
self.cookie = cookie_str
return result
def login_refresh(self, query):
"""
刷新登录状态
:param query:
:return:
"""
result = self.call_api("/login/refresh", query)
# 自动 更新cookie
# if result["code"] == 200:
# if result.get("data").get("cookie"):
# # cookie_str = format_cookie_str(result.get("data").get("cookie"))
# cookie_str = result.get("data").get("cookie")
# result["data"]["cookie"] = cookie_str
# pprint(cookie_str)
# self.cookie = cookie_str
return result

View File

@ -0,0 +1,124 @@
from pprint import pprint
def format_cookie_str(cookie_str: str) -> str:
"""
格式化cookie字符串
功能
处理以逗号分割的cookie字符串
删除max-age为0的cookie
注意
传入cookie字符串必须是以 逗号+空格 分号+空格 分割的规范cookie字符串
:param cookie_str:
:return: 格式化后的cookie str
"""
if not cookie_str:
return ""
# 解析cookie字符串
cookie_dict = prase_cookie_str(cookie_str)
cookie_valid_dict = {}
# 删除max-age为0的cookie
for item in cookie_dict.keys():
max_age = cookie_dict[item].get("Max-Age")
if max_age:
max_age = int(max_age)
if max_age != 0:
cookie_valid_dict[item] = cookie_dict[item]
# 重新拼接cookie字符串
cookie = ""
for item in cookie_valid_dict.keys():
cookie += item + "=" + cookie_valid_dict[item]["value"] + "; "
for key in cookie_valid_dict[item].keys():
if key != "value":
cookie += key + "=" + cookie_valid_dict[item][key] + "; "
return cookie[: -2]
def prase_cookie_str(cookie_str: str) -> dict:
"""
解析cookie字符串
功能
处理以逗号分割的cookie字符串
注意
传入cookie字符串必须是以 逗号+空格 分号+空格 分割的规范cookie字符串
:param cookie_str:
:return: cookie dict
"""
if not cookie_str:
return {}
# 解决用逗号分割的问题
cookie_part = []
for item in cookie_str.split(", "):
cookie_part.extend(item.split("; "))
cookies = []
for item in cookie_part:
if "=" not in item:
# 属于上一个cookie的一部分
cookies[-1] = cookies[-1] + item
else:
cookies.append(item)
cookie_dict = {}
current_name = ""
for cookie in cookies:
# print(cookie)
if cookie[-1] == "=":
name = cookie[:-1]
value = ""
else:
part = cookie.split("=")
name = part[0]
value = part[1]
if name in ["Max-Age", "Expires", "Path", "Domain"]:
cookie_dict[current_name][name] = value
else:
cookie_dict[name] = {"value": value}
current_name = name
return cookie_dict
if __name__ == '__main__':
cookie = ("MUSIC_R_T=1579622000495; Max-Age=2147483647; Expires=Wed, 02 Jan 2092 11:39:38 GMT; "
"Path=/openapi/clientlog; Domain=.music.163.com, MUSIC_A_T=1579621885297; Max-Age=2147483647; Expires=Wed, "
"02 Jan 2092 11:39:38 GMT; Path=/wapi/feedback; Domain=.music.163.com, __remember_me=true; "
"Max-Age=2147483647; Expires=Wed, 02 Jan 2092 11:39:38 GMT; Path=/; Domain=.music.163.com, "
"MUSIC_A_T=1579621885297; Max-Age=2147483647; Expires=Wed, 02 Jan 2092 11:39:38 GMT; Path=/api/feedback; "
"Domain=.music.163.com, MUSIC_A_T=1579621885297; Max-Age=2147483647; Expires=Wed, 02 Jan 2092 11:39:38 GMT; "
"Path=/eapi/clientlog; Domain=.music.163.com, MUSIC_A_T=1579621885297; Max-Age=2147483647; Expires=Wed, "
"02 Jan 2092 11:39:38 GMT; Path=/api/clientlog; Domain=.music.163.com, MUSIC_R_T=1579622000495; "
"Max-Age=2147483647; Expires=Wed, 02 Jan 2092 11:39:38 GMT; Path=/wapi/feedback; Domain=.music.163.com, "
"MUSIC_A_T=1579621885297; Max-Age=2147483647; Expires=Wed, 02 Jan 2092 11:39:38 GMT; Path=/weapi/clientlog; "
"Domain=.music.163.com, MUSIC_R_T=1579622000495; Max-Age=2147483647; Expires=Wed, 02 Jan 2092 11:39:38 GMT; "
"Path=/neapi/feedback; Domain=.music.163.com, MUSIC_R_T=1579622000495; Max-Age=2147483647; Expires=Wed, "
"02 Jan 2092 11:39:38 GMT; Path=/eapi/clientlog; Domain=.music.163.com, MUSIC_R_T=1579622000495; "
"Max-Age=2147483647; Expires=Wed, 02 Jan 2092 11:39:38 GMT; Path=/api/feedback; Domain=.music.163.com, "
"MUSIC_A_T=1579621885297; Max-Age=2147483647; Expires=Wed, 02 Jan 2092 11:39:38 GMT; Path=/weapi/feedback; "
"Domain=.music.163.com, MUSIC_R_T=1579622000495; Max-Age=2147483647; Expires=Wed, 02 Jan 2092 11:39:38 GMT; "
"Path=/eapi/feedback; Domain=.music.163.com, MUSIC_A_T=1579621885297; Max-Age=2147483647; Expires=Wed, "
"02 Jan 2092 11:39:38 GMT; Path=/neapi/clientlog; Domain=.music.163.com, MUSIC_R_T=1579622000495; "
"Max-Age=2147483647; Expires=Wed, 02 Jan 2092 11:39:38 GMT; Path=/wapi/clientlog; Domain=.music.163.com, "
"MUSIC_A_T=1579621885297; Max-Age=2147483647; Expires=Wed, 02 Jan 2092 11:39:38 GMT; Path=/wapi/clientlog; "
"Domain=.music.163.com, MUSIC_R_T=1579622000495; Max-Age=2147483647; Expires=Wed, 02 Jan 2092 11:39:38 GMT; "
"Path=/weapi/feedback; Domain=.music.163.com, NMTID=00OLqRn-wykrFFXdElLpZA3_-aaQtIAAAGMbJSp9A; "
"Max-Age=315360000; Expires=Mon, 12 Dec 2033 08:25:31 GMT; Path=/; Domain=music.163.com, "
"__csrf=4d5e515015723fd3d7edaa5b05f35b4d; Max-Age=1296010; Expires=Sat, 30 Dec 2023 08:25:41 GMT; Path=/; "
"Domain=.music.163.com, MUSIC_R_T=1579622000495; Max-Age=2147483647; Expires=Wed, 02 Jan 2092 11:39:38 GMT; "
"Path=/neapi/clientlog; Domain=.music.163.com, MUSIC_A_T=1579621885297; Max-Age=2147483647; Expires=Wed, "
"02 Jan 2092 11:39:38 GMT; Path=/openapi/clientlog; Domain=.music.163.com, MUSIC_A_T=1579621885297; "
"Max-Age=2147483647; Expires=Wed, 02 Jan 2092 11:39:38 GMT; Path=/eapi/feedback; Domain=.music.163.com, "
"MUSIC_R_T=1579622000495; Max-Age=2147483647; Expires=Wed, 02 Jan 2092 11:39:38 GMT; Path=/weapi/clientlog; "
"Domain=.music.163.com, MUSIC_R_T=1579622000495; Max-Age=2147483647; Expires=Wed, 02 Jan 2092 11:39:38 GMT; "
"Path=/api/clientlog; Domain=.music.163.com, MUSIC_SNS=; Max-Age=0; Expires=Fri, 15 Dec 2023 08:25:31 GMT; "
"Path=/, "
"MUSIC_U=00CCEEF2F7A9825637C9869A455B5CA8E009D905415134A7EDAC2E404A940B2D58BFF7129A413193E9A8FD6D1D497E1E8E9023611BA91D2CB28FA94B53DBE4C42699A30FF1448C8EFAF5B00E73ADD353C52F2E004C094AEAC4BA4D83C6FFBB4CD532DEEAEA8D5584E69AC78110BBA682829C263DA72F5AA290AD826A47F640CA3903AC652E4DDE946ACC4EB8A63E5853FA695B480A919CF84498B7084C5CA9A91297F2CF5AF45C2D545AC0D5C03A1641306BAC0FB6FFD57BC653A91F2483FB52BFE85DE39280B012BC036DF244883D9700480E5FDDCD5A417C60241AE08CD6AA84BFC1C8890AE4A08286144D9D1146E33C67CF7797CDB5A961C85DB5AC492B232601D80D4DB07E4F170F635ABC01E080B4D32408FA0698DAD95AD80CDB99F2F672638048F5116214319175B596BF68B2A7A0269746EABFD919D62C165353725E6B1253A7C5D6774D453DDDCC28524D3378; Max-Age=2147483647; Expires=Wed, 02 Jan 2092 11:39:38 GMT; Path=/; Domain=.music.163.com, MUSIC_A_T=1579621885297; Max-Age=2147483647; Expires=Wed, 02 Jan 2092 11:39:38 GMT; Path=/neapi/feedback; Domain=.music.163.com")
pprint(prase_cookie_str(cookie))

Binary file not shown.

View File

@ -19,7 +19,7 @@ URL = 'https://github.com/2061360308/NeteaseCloudMusic_PythonSDK'
EMAIL = '2061360308@qq.com'
AUTHOR = '盧瞳'
REQUIRES_PYTHON = '>=3.6.0'
VERSION = '0.1.8'
VERSION = '0.1.7'
UPDATA_INFO = ('修复了初次使用时没有cookie导致的一系列问题\n'
'修复了NeteaseCloudMusicApi.js没有更新的问题\n'
'添加了对于cookie的判断现在可以正常判断cookie是否过期了')
@ -114,13 +114,6 @@ class UploadCommand(Command):
self.status('Building Source and Wheel (universal) distribution…')
os.system('{0} setup.py sdist bdist_wheel --universal'.format(sys.executable))
self.status('Uploading the package to PyPI via Twine…')
os.system('twine upload dist/*')
self.status('Pushing git tags…')
os.system(f'git tag -a {about["__version__"]} -m {UPDATA_INFO}')
os.system('git push --tags')
sys.exit()
@ -193,6 +186,5 @@ setup(
# $ setup.py publish support.
cmdclass={
'upload': UploadCommand,
'build': BuildCommand,
},
)