diff --git a/APIs.py b/APIs.py deleted file mode 100644 index 5bb90646217004fb8bd40467ea8731e1e63d6d25..0000000000000000000000000000000000000000 --- a/APIs.py +++ /dev/null @@ -1,122 +0,0 @@ -import requests -from json import dumps, loads -from bs4 import BeautifulSoup - -class codemaoAPI(object): - def __init__(self,UA='Mozilla/5.0 (Windows NT 10.0; ) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36',debug=False): - self.debug = debug - self.ses = requests.session() - self.headers = {"Content-Type": "application/json", "User-Agent": UA} - self.log('Successfully creat a codemao user.') - - def login(self,identity,password): - self.log('getting pid...') - soup = BeautifulSoup(requests.get('https://shequ.codemao.cn', headers = self.headers).text, 'html.parser') - pid = loads(soup.find_all("script")[0].string.split("=")[1])['pid'] - self.log('Successfully get pid;pid=' + pid) - self.log('loginning...') - a = self.ses.post('https://api.codemao.cn/tiger/v3/web/accounts/login', headers = self.headers,data = dumps({"identity": identity, "password": password, "pid": pid})) - if a.status_code == 200: - self.log("Successfully login to codemao.cn") - else: - self.log('End of login to codemao.cn;response', a.status_code) - - def log(self, *msg): - if self.debug: - print(*msg) - - def send_post(self, board, title, message): - self.log('posting...') - a = self.ses.post(f'https://api.codemao.cn/web/forums/boards/{board}/posts', headers = self.headers,data = dumps({'title': title, 'content': message})) - self.log('End.response', a.status_code) - - def replies(self, postID, message): - self.log('replieing...') - a = self.ses.post(f'https://api.codemao.cn/web/forums/posts/{postID}/replies', headers = self.headers,data = dumps({'content': message})) - self.log('End.response', a.status_code) - - def __delete_work(self, workID): # BUG - self.log('deleting...') - a = self.ses.delete(f'https://api.codemao.cn/tiger/work/{workID}/temporarily', headers = self.headers) - self.log('End.response', a.status_code) - - def __recove_work(self, workID): # BUG - self.log('recoving...') - a = self.ses.patch(f'https://api.codemao.cn/tiger/work/{workID}/recover', headers = self.headers) - self.log('End.response', a.status_code) - - def __permanent_work(self, workID): # BUG - self.log('permanenting...') - a = self.ses.delete(f'https://api.codemao.cn/tiger/work/{workID}/permanently', headers = self.headers) - self.log('End.response', a.status_code) - - def delete_all_work(self): - self.log('All work are permanenting...') - a = self.ses.delete('https://api.codemao.cn/tiger/work/user/works/permanently', headers = self.headers) - self.log('End.response', a.status_code) - - def send_post_to_work_shop(self, work_shop_ID, message): - self.log('posting...') - a = self.ses.post(f'https://api.codemao.cn/web/discussions/{work_shop_ID}/comment', headers = self.headers,data = dumps({"content": message, "rich_content": message, "source": "WORK_SHOP"})) - self.log('End.response', a.status_code) - - def top_replies(self, repliesID): - self.log('On top...') - a = self.ses.put(f'https://api.codemao.cn/web/forums/replies/{repliesID}/top', headers = self.headers, - data = r'{}') - self.log('End.response', a.status_code) - - def untop_replies(self, repliesID): - self.log('Untop...') - a = self.ses.delete(f'https://api.codemao.cn/web/forums/replies/{repliesID}/top', headers = self.headers) - self.log('End.response', a.status_code) - - def like_replies(self, repliesID): - self.log('liking...') - self.ses.put(f'https://api.codemao.cn/web/forums/comments/{repliesID}/liked?source=REPLY',headers = self.headers, data = r'{}') - self.log('End.response', a.status_code) - - def unlike_replies(self, repliesID): - self.log('Unliking...') - self.ses.delete(f'https://api.codemao.cn/web/forums/comments/{repliesID}/liked?source=REPLY',headers = self.headers) - - def search_post(self,key,to):#同步执行,可能帖子太多会有点慢。。。。 - self.log('searching...') - res=[] - page=1 - keeprun=True - while keeprun: - resp=self.ses.get(f'https://api.codemao.cn/web/forums/posts/search?title={key}&limit=30&page={page}',headers=self.headers).json() - if resp['items']==[]: - break - for msg in resp['items']: - if (to!=None) and (len(res)>=to): - keeprun=False - break - res.append({'user':{'userid':msg['user']['id'],'username':msg['user']['nickname']},'id':msg['id'],'title':msg['title']}) - page+=1 - return res - - def logout(self): - self.log('logouting...') - a=self.ses.options('https://api.codemao.cn/tiger/v3/web/accounts/logout',headers=self.headers) - if a.status_code==204: - self.log('Successfully logout from codemao.cn') - else: - self.log('End of logout from codemao.cn;response', a.status_code) - - def like_work(self,workID): - self.log('liking...') - a=self.ses.post(f'https://api.codemao.cn/nemo/v2/works/{workID}/like',headers=self.headers,data='{}') - if a.status_code==200: - self.log('Successfully like work') - else: - self.log('End of liking;response', a.status_code) - - def unlike_work(self,workID): - self.log('unliking...') - a=self.ses.delete(f'https://api.codemao.cn/nemo/v2/works/{workID}/like',headers=self.headers) - if a.status_code==200: - self.log('Successfully unlike work') - else: - self.log('End of unliking;response', a.status_code) \ No newline at end of file diff --git a/README.md b/README.md deleted file mode 100644 index 2dffd800435bf0aad6670c569270b6df14b5f2e9..0000000000000000000000000000000000000000 --- a/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# **codemao-apis** -

                      ——编程猫的API

- -## 特点 -1. 包含大部分常用功能,使用更方便 -2. 面向对象式编程,代码清晰明了 -3. 封装到极致,写代码更精简 diff --git a/api.py b/api.py new file mode 100644 index 0000000000000000000000000000000000000000..d4cd648ccbdeafd21e4dcc30e00361c6ee1a4f9a --- /dev/null +++ b/api.py @@ -0,0 +1,191 @@ +from requests import * +from json import dumps, loads +from bs4 import BeautifulSoup +import os + + +class CodemaoApi(): + def __init__(self, UA='Mozilla/5.0 (Windows NT 10.0; ) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36', debug=False): + # New: api sets + self.apis = {'home': 'https://shequ.codemao.cn', + 'matomoApi': 'https://matomo.codemao.cn/piwik.js', + 'login': 'https://api.codemao.cn/tiger/v3/web/accounts/login', + 'postArticle': 'https://api.codemao.cn/web/forums/boards/{}/posts', + 'postReply': 'https://api.codemao.cn/web/forums/posts/{}/replies', + 'clearWork': 'https://api.codemao.cn/tiger/work/user/works/permanently', + 'requireWorkshop': 'https://api.codemao.cn/web/discussions/{}/comment', + 'topReply': 'https://api.codemao.cn/web/forums/replies/{}/top', + 'untopReply': 'https://api.codemao.cn/web/forums/replies/{}/top', + 'likeReply': 'https://api.codemao.cn/web/forums/comments/{}/liked?source=REPLY', + 'unlikeReply': 'https://api.codemao.cn/web/forums/comments/{}/liked?source=REPLY', + 'searchArticle': 'https://api.codemao.cn/web/forums/posts/search?title={}&limit=30&page={}', + 'logout': 'https://api.codemao.cn/tiger/v3/web/accounts/logout', + 'likeWork': 'https://api.codemao.cn/nemo/v2/works/{}/like', + 'unlikeWork': 'https://api.codemao.cn/nemo/v2/works/{}/like'} + self.debug = debug + # Use abs path to create in the root path, not cwd + self.logpath = os.path.split(__file__)[0] + os.sep + 'runtime.log' + self.ses = session() + self.headers = {"Content-Type": "application/json", "User-Agent": UA} + self.log('Successfully create the main session') + + def log(self, *msg): + if self.debug: + print(*msg) + # New: temp log file in the root dir + if not os.path.exists(self.logpath): + open(self.logpath, 'w', encoding='utf-8').close() + with open(self.logpath, 'a', encoding='utf-8') as log: + msg = [str(i) for i in msg] + text = ' '.join(msg) + '\n' # list -> str + log.write(text) + + def login(self, identity, password): + # Get PID + self.log('getting pid...') + text = get(self.apis['home'], headers = self.headers).text + soup = BeautifulSoup(text, 'html.parser') + json = soup.find('script').string.split("=")[1] + pid = loads(json)['pid'] + self.log('Successfully get pid; pid:' + pid) + # Log-in + self.log('logging in...') + res = self.ses.post(self.apis['login'], headers=self.headers, data=dumps({"identity": identity, "password": password, "pid": pid})) + if res.status_code == 200: + self.log("Successfully login to codemao.cn") + else: + self.log('End of logging in to codemao.cn; response', res.status_code) + return res.json() + + def logout(self): + self.log('logging out...') + res = self.ses.options(self.apis['logout'], headers=self.headers) + if res.status_code == 204: + self.log('Successfully log-out from codemao.cn') + else: + self.log('End of logout from codemao.cn; response', res.status_code) + return res.json() + + def postArticle(self, board, title, content): + self.log('posting...') + res = self.ses.post(self.apis['postArticle'].format(board), headers=self.headers, data=dumps({'title': title, 'content': content})) + if res.status_code == 201: + self.log("Successfully post article") + else: + self.log('End of posting; response', res.status_code) + return res.json() + + def postReply(self, arid, content): + self.log('posting...') + res = self.ses.post(self.apis['postReply'].format(arid), headers=self.headers, data=dumps({'content': content})) + if res.status_code == 200: + self.log("Successfully post reply") + else: + self.log('End of posting; response', res.status_code) + return res.json() + + # Not changed + def __delete_work(self, workID): # BUG + self.log('deleting...') + a = self.ses.delete(f'https://api.codemao.cn/tiger/work/{workID}/temporarily', headerss = self.headerss) + self.log('End.response', a.status_code) + + def __recove_work(self, workID): # BUG + self.log('recoving...') + a = self.ses.patch(f'https://api.codemao.cn/tiger/work/{workID}/recover', headerss = self.headerss) + self.log('End.response', a.status_code) + + def __permanent_work(self, workID): # BUG + self.log('permanenting...') + a = self.ses.delete(f'https://api.codemao.cn/tiger/work/{workID}/permanently', headerss = self.headerss) + self.log('End.response', a.status_code) + + def clearWork(self): + self.log('clearing...') + res = self.ses.delete(self.apis['clearWork'], headers=self.headers, data=dumps({'title': title, 'content': content})) + if res.status_code == 200: + self.log("Successfully send request to workshop") + else: + self.log('End of requiring; response', res.status_code) + return res.json() + + def requireWorkshop(self, wsid, content): + self.log('requiring...') + res = self.ses.post(self.apis['requireWorkshop'].format(wsid), headers=self.headers, data=dumps({'content': content, 'rich_content': content, 'source': 'WORK_SHOP'})) + if res.status_code == 200: + self.log("Successfully send request to workshop") + else: + self.log('End of requiring; response', res.status_code) + return res.json() + + def topReply(self, rpid): + self.log('Setting...') + res = self.ses.put(self.apis['topReply'].format(rpid), headers=self.headers, data=r'{}') + if res.status_code == 200: + self.log("Successfully set top reply") + else: + self.log('End of requiring; response', res.status_code) + return res.json() + + def untopReply(self, rpid): + self.log('Setting...') + res = self.ses.delete(self.apis['untopReply'].format(rpid), headers=self.headers) + if res.status_code == 200: + self.log("Successfully cancel top reply") + else: + self.log('End of requiring; response', res.status_code) + return res.json() + + def likeReply(self, rpid): + self.log('Setting...') + res = self.ses.put(self.apis['likeReply'].format(rpid), headers=self.headers, data=r'{}') + if res.status_code == 200: + self.log("Successfully set liked reply") + else: + self.log('End of setting; response', res.status_code) + return res.json() + + def unlikeReply(self, rpid): + self.log('Setting...') + res = self.ses.put(self.apis['unlikeReply'].format(rpid), headers=self.headers) + if res.status_code == 200: + self.log("Successfully cancel liked reply") + else: + self.log('End of setting; response', res.status_code) + return res.json() + + def searchArticle(self, key, to): + # Not changed + self.log('searching...') + res = [] + page = 1 + keeprun = True + while keeprun: + resp=self.ses.get(self.apis['searchArticle'].format(key, page), headers=self.headers).json() + if resp['items']==[]: + break + for msg in resp['items']: + if to != None and len(res) >= to: + keeprun = False + break + res.append({'user':{'userid':msg['user']['id'], 'username':msg['user']['nickname']},'id':msg['id'],'title':msg['title']}) + page+=1 + return res + + def likeWork(self, wkid): + self.log('setting...') + res = self.ses.post(self.apis['likeWork'].format(wkid), headers=self.headers, data=r'{}') + if res.status_code == 200: + self.log('Successfully set liked work') + else: + self.log('End of setting; response', res.status_code) + return res.json() + + def unlikeWork(self,workID): + self.log('setting...') + res = self.ses.delete(self.apis['unlikeWork'].format(wkid), headers=self.headers) + if res.status_code == 200: + self.log('Successfully cancel liked work') + else: + self.log('End of setting; response', res.status_code) + return res.json() \ No newline at end of file diff --git a/test.py b/test.py new file mode 100644 index 0000000000000000000000000000000000000000..eaf0c29212f0a7a89054879717d1e9088c746061 --- /dev/null +++ b/test.py @@ -0,0 +1,7 @@ +from api import * + +api = CodemaoApi(debug=True) +print(api.login('', '')) +print(api.postArticle('11', 'testing', '

testingtestingtesting

')) +print(api.postReply('388382', 'API回复')) +print(api.searchArticle('123', 10)) \ No newline at end of file diff --git "a/\351\241\266\345\270\226\347\245\236\345\231\250.py" "b/\351\241\266\345\270\226\347\245\236\345\231\250.py" deleted file mode 100644 index 18c0dc074eef1a8602ba8d07df9a5b0a2d9a9300..0000000000000000000000000000000000000000 --- "a/\351\241\266\345\270\226\347\245\236\345\231\250.py" +++ /dev/null @@ -1,25 +0,0 @@ -import requests -from guimaker import inputbox -from bs4 import BeautifulSoup -from json import loads,dumps - -identity=input("用户名/手机号/邮箱:") -password=input("密码:") - - -ses = requests.session() -headers = {"Content-Type": "application/json", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; ) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36"} -print('正在寻找登录密钥...') -soup = BeautifulSoup(requests.get('https://shequ.codemao.cn', headers = headers).text, 'html.parser') -pid = loads(soup.find_all("script")[0].string.split("=")[1])['pid'] -print('秘药为:',pid) -print('正在登录') -a = ses.post('https://api.codemao.cn/tiger/v3/web/accounts/login', headers = headers,data = dumps({"identity": identity, "password": password, "pid": pid})) -if a.status_code == 200: - print("登录成功") -else: - exit("不能登录编程猫") -print('正在顶帖') -postID = inputbox(type_ = int,text="ID?") -a = ses.post(f'https://api.codemao.cn/web/forums/posts/{postID}/replies', headers = headers,data = dumps({'content': "

dd

"})) -print("成功" if a.status_code == 201 else "失败") \ No newline at end of file