作者 lemon

初步测试部署服务器

... ... @@ -103,12 +103,12 @@ class CallBack():
body = {
"to": client.uid,
"msgId": mid,
"from": author_id,
"from": thread_id,
"timeInMillis": ts
}
if thread_type == ThreadType.GROUP:
body['roomSender'] = thread_id
body['roomSender'] = author_id
if message_object.text:
body['content'] = message_object.text
... ...
... ... @@ -6,10 +6,10 @@
# @Software: PyCharm
import os
import requests
from fbchat import ThreadType, EmojiSize
from lib import common
from lib.facebook import FacebookClient
import uuid
from base64 import b64decode
... ... @@ -33,6 +33,20 @@ def _send_msg(local_func, remote_func, to, content, thread_type, suffix):
return res
def _upload_binary(upload_func, set_func, image, setting):
if image.startswith("http"):
r = requests.get(image)
assert r.status_code == 200, '图片资源无法下载,link="{}"'.format(image)
temp_ = r.content
else:
temp_ = b64decode(image.encode('utf-8'))
fbid = upload_func(temp_)
if not setting:
return {"photo_id": fbid}
else:
return set_func(fbid)
class Executor():
def __init__(self, client):
... ... @@ -76,12 +90,58 @@ class Executor():
_type = getattr(ThreadType, thread_type.upper())
return self.client.sendPictureLink(link, thread_id=to, thread_type=_type)
def waveMsg(self, to, first=True, thread_type='USER'):
_type = getattr(ThreadType, thread_type.upper())
return self.client.wave(first, thread_id=to, thread_type=_type)
def searchForUsers(self, name, limit=5):
users = self.client.searchForUsers(name, limit)
keys = ['type', 'gender', 'is_friend', 'name', 'photo', 'uid', 'url']
result=[]
result = []
for u in users:
info = common.todict(u, keys)
info['type'] = info.get('type').name
result.append(info)
return result
\ No newline at end of file
return result
def uploadAvatar(self, image, setting=False):
return _upload_binary(
self.client.uploudAvatar,
self.client.setAvatar,
image,
setting
)
def uploadCover(self, image, setting=False):
return _upload_binary(
self.client.uploadCover,
self.client.setCover,
image,
setting
)
def pymkFriends(self, filter_ids: list = []):
result = self.client._pymk_request(filter_ids)
data = {
'size': len(result),
'detail': result,
}
return data
def friendRequests(self, next_url=None, require_gender=True):
result, next_url = self.client._friendRequest(next_url, require_gender=require_gender)
data = {
'size': len(result),
'detail': result,
'next_url': 'https://www.facebook.com' + next_url if next_url else None
}
return data
def sentRequests(self, next_url, require_gender):
result, next_url = self.client._outgoingRequest(next_url, require_gender=require_gender)
data = {
'size': len(result),
'detail': result,
'next_url': 'https://www.facebook.com' + next_url if next_url else None
}
return data
... ...
... ... @@ -128,6 +128,22 @@ class PostParam(Enum):
EVENT_INVITE_ONLY = 599950423437029
class RequestSource():
const = {
1: 'requests_page_pymk',
2: 'profile_button',
3: 'profile_friends',
4: 'group_member_list',
5: 'hovercard',
}
@classmethod
def get(cls, channel):
if isinstance(channel, str):
channel = int(channel)
return cls.const.get(channel, 'people_you_may_know')
class FacebookClient(Client):
def __init__(self,
user_obj,
... ... @@ -195,16 +211,21 @@ class FacebookClient(Client):
res = self._payload_post('/ajax/messenger/context_banner/?profile_id=%s' % fbid, {'__user': self.uid})
return res
def addFriend(self, friend_id):
data = {"to_friend": friend_id,
"action": "add_friend",
"how_found": "profile_button",
# "link_data[gt][profile_owner]": friend_id,
# "link_data[gt][ref]": "timeline:timeline",
# "no_flyout_on_click": "true",
# "floc": "profile_box"
}
res = self._payload_post("/ajax/add_friend/action.php", data)
def addFriend(self, fbid, channel=1):
how_found = RequestSource.get(channel)
data = {
"to_friend": fbid,
"action": "add_friend",
"how_found": how_found,
}
if how_found == 'profile_friends':
data['ref_param'] = 'friends_tab'
if channel == 2:
res = self._payload_post("/ajax/add_friend/action.php", data)
else:
res = self._payload_post("/ajax/add_friend/action?" + self._to_url_params(data), {})
return res
def previewName(self, primary_first, primary_middle, primary_last):
... ... @@ -241,12 +262,12 @@ class FacebookClient(Client):
except:
return None
def setAvatar(self, fbid):
def setAvatar(self, photo_id):
'''
设置头像
'''
data = {'x': '0', 'y': '0', 'width': '1', 'height': '1',
'photo_id': fbid, 'profile_id': self.uid,
'photo_id': photo_id, 'profile_id': self.uid,
'source': 'timeline'} # 'source': 'unknown', 'method': 'upload'
res = self._payload_post('/profile/picture/crop_profile_pic/?' + self._to_url_params(data), {})
... ... @@ -318,7 +339,31 @@ class FacebookClient(Client):
data = {'sex': sex, 'sex_preferred_pronouns': '1',
'privacy[237760973066217]': PostParam.ONLY_ME.value}
res = self._post('/profile/edit/infotab/save/gender/', data)
return res
html = parse_html.get_domops_3(res)
if 'Gender' in html:
return {"success": True}
else:
raise BaseException("未知错误:", html)
def setSexualOrientation(self, sex: int):
'''
设置性取向 1女性 2男性 3双性
'''
data = {
'privacy[8787590733]': PostParam.EVERYONE.value
}
if sex == 1 or sex == 3:
data['meeting_sex1'] = 'on'
if sex == 2 or sex == 3:
data['meeting_sex2'] = 'on'
res = self._post('/profile/edit/infotab/save/interested_in/', data)
html = parse_html.get_domops_3(res)
if 'interested_in' in html:
return {"success": True}
else:
raise BaseException("未知错误:", html)
def sendSticker(self, sticker_id, thread_id, thread_type=ThreadType.USER):
return self.send(
... ... @@ -364,16 +409,25 @@ class FacebookClient(Client):
sub = (ids.pop(0), names.pop(0))
yield sub
def _friendRequest(self, url=None):
def _friendRequest(self, url=None, require_gender=True):
if url:
j = self._post(url, params={})
else:
data = {'log_impressions': 'true', 'reloadcontent': 'false'}
j = self._post('/ajax/requests/loader/', data)
result, next_url = parse_html.friend_unit(j)
return parse_html.friend_unit(j)
if require_gender and result:
ids = [x['fbid'] for x in result]
users = self.fetchUserInfo(*ids)
for r in result:
gender = users.get(r['fbid']).gender
r['gender'] = 'boy' if 'male_singular' == gender else \
('girl' if 'female_singular' == gender else 'unknown')
def rejectRequest(self, fbid):
return result, next_url
def deleteRequest(self, fbid):
data = {'confirm': fbid,
'type': 'friend_connect',
'request_id': fbid,
... ... @@ -383,10 +437,13 @@ class FacebookClient(Client):
'ref': 'jewel',
'ego_log': '',
'actions[reject]': '1',
'nctr[_mod]': 'pagelet_bluebar'
# 'nctr[_mod]': 'pagelet_bluebar'
}
res = self._post('/ajax/reqs.php', data)
return res
detail = res['domops'][0]
if detail[0] == 'setContent' and detail[2]:
return {"success": True}
raise BaseException("未知错误:" + json.dumps(detail))
def pymkRequest(self) -> tuple:
'''
... ... @@ -406,26 +463,39 @@ class FacebookClient(Client):
yield sub
def _pymk_request(self, total_ids: list):
data = {
'''data = {
'how_found': 'people_you_may_know',
'page': 'pymk_jewel',
'instance_name': 'jewel',
'show_more': 'true'
}
'''
data = {
'how_found': 'requests_page_pymk',
'page': 'friends_center',
'instance_name': 'friend-browser',
'big_pics': 1,
'social_context': 1,
'network_context': 1,
'show_more': True
}
for index, id in enumerate(total_ids):
data['friend_browser_id[%d]' % index] = id
path = "/ajax/growth/friend_browser/checkbox.php" # 直接调用翻页接口
j = self._post(path, data)
ids, names, _ = parse_html.friend_unit(j)
gender = []
j = self._post("/ajax/growth/friend_browser/checkbox.php", data)
result, _ = parse_html.friend_unit(j)
if ids:
if result:
ids = [x['fbid'] for x in result]
users = self.fetchUserInfo(*ids)
for id in ids:
gender.append(users.get(id).gender)
for r in result:
id = r['fbid']
gender = users.get(id).gender
r['gender'] = 'boy' if 'male_singular' == gender else \
('girl' if 'female_singular' == gender else 'unknown')
return ids, names, gender
return result
def pymkRemove(self, fbid):
'''
... ... @@ -437,7 +507,9 @@ class FacebookClient(Client):
'how_found': 'people_you_may_know',
'nctr[_mod]': 'pagelet_bluebar'}
res = self._post('/friends/pymk/xout/', data)
return res
if res['payload'] == None:
return {"success": True}
raise BaseException("未知错误:" + json.dumps(res))
def _to_url_params(self, data: dict):
return '&'.join(["{}={}".format(k, v) for k, v in data.items()])
... ... @@ -474,7 +546,7 @@ class FacebookClient(Client):
sub = (ids.pop(0), names.pop(0))
yield sub
def _outgoingRequest(self, url=None):
def _outgoingRequest(self, url=None, require_gender=True):
if url:
j = self._get(url, {})
else:
... ... @@ -482,7 +554,31 @@ class FacebookClient(Client):
'pager_id': 'outgoing_reqs_pager_5e3a685eb1075' + os.urandom(5).hex()}
j = self._get("/friends/requests/outgoing/more/", data)
return parse_html.friend_unit(j)
result, next_url = parse_html.friend_unit(j)
if require_gender and result:
ids = [x['fbid'] for x in result]
users = self.fetchUserInfo(*ids)
for r in result:
gender = users.get(r['fbid']).gender
r['gender'] = 'boy' if 'male_singular' == gender else \
('girl' if 'female_singular' == gender else 'unknown')
return result, next_url
def cancelRequest(self, fbid):
'''
取消好友申请
:return
'''
data = {
'friend': fbid,
'cancel_ref': 'outgoing_requests',
}
res = self._post('/ajax/friends/requests/cancel.php', data)
detail = res['jsmods']['require'][0]
if 'FriendRequest/cancel' in json.dumps(detail[3]):
return {'success': True}
raise BaseException("未知错误:" + json.dumps(detail))
def searchForCity(self, city):
query = {
... ... @@ -573,21 +669,26 @@ class FacebookClient(Client):
}
data = {'target_id': self.uid, 'profile_id': self.uid, 'source': '10'}
res = self._post('https://upload.facebook.com/ajax/timeline/cover/upload/', data, files=files)
text = json.dumps(res)
try:
return re.findall(r'data-fbid=\\"(\d+)\\"', text)[0]
except:
return None
def setCover(self, fbid):
result = res['jsmods']['require'][0]
status = result[1]
detail = result[3]
if isinstance(detail[0], int):
return str(detail[0])
raise BaseException(status + ' ' + ':'.join(detail[3]))
def setCover(self, photo_id):
'''设置封面图片'''
data = {
'photo_id': fbid, 'profile_id': self.uid, 'photo_offset_y': '',
'photo_id': photo_id, 'profile_id': self.uid, 'photo_offset_y': '',
'photo_offset_x': '', 'save': '1',
'nctr[_mod]': 'pagelet_timeline_main_column'
}
res = self._post("/ajax/timeline/cover_photo_select.php?av=%s" % self.uid, data)
return res
html = parse_html.get_domops_3(res)
m = re.search(r'src="(.*?)"', html)
if m:
return {'src': m.group(1).replace('&', '&')}
raise BaseException("设置封面未知错误:" + json.dumps(res['jsmods']['require'][0]))
def info(self):
data = {
... ... @@ -596,4 +697,23 @@ class FacebookClient(Client):
'page_url': self._state.page_url,
'imageurl': self._state.imageurl
}
return data
\ No newline at end of file
return data
def followProfile(self, fbid, status=True):
'''关注个人主页'''
data = {
'profile_id': fbid,
'location': 1,
}
if status:
url_ = '/ajax/follow/follow_profile.php'
else:
url_ = '/ajax/follow/unfollow_profile.php'
res = self._post(url_, data)
if 'onload' not in res:
raise BaseException("未知错误:" + res)
onloads = json.dumps(res['onload'])
if 'Arbiter.inform' in onloads:
return {"success": True}
raise BaseException("未知错误:" + onloads)
... ...
... ... @@ -52,6 +52,9 @@ class Do():
def three(self, x, y, z):
print(locals())
def createGroup(self,message,user_ids):
print(locals())
if __name__ == '__main__':
d = Do()
... ... @@ -61,7 +64,8 @@ if __name__ == '__main__':
f1 = join(d.two, {"x": 'x1', "y": 'y2', 'z': 'z3'})
f2 = join(d.one, 'x2')
f3 = join(d.three, {"x": 'x1', "y": 'y2', 'z': 'z3'})
f3 = join(d.createGroup,{"message":"12333","user_ids":[1,2,3,4,5]})
t.submit(**f1)
t.submit(**f2)
... ...
... ... @@ -13,43 +13,51 @@ from bs4 import BeautifulSoup
def friend_unit(p: dict):
next_url = None
user_ids = list()
names = list()
result = list()
html = _unit_html(p)
bs = BeautifulSoup(html, "html.parser")
if 'objectListItem' in html:
for li in bs.select('.objectListItem'):
data = li.find_all('a', limit=2)[1].attrs
a_label = li.find_all('a', limit=2)
try:
src = a_label[0].find('img').attrs['src']
except:
src = None
data = a_label[1].attrs
thread_id = re.findall(r'user.php\?id=(\d+)&', data['data-hovercard'])[0]
title = data['title']
if thread_id and title:
user_ids.append(thread_id)
names.append(title)
if 'friendBrowserListUnit' in html:
result.append({'fbid': thread_id, 'name': title, 'src': src})
elif 'friendBrowserListUnit' in html:
for li in bs.select('.friendBrowserListUnit'):
data = li.find_all('a', limit=2)[1].attrs
a_label = li.find_all('a', limit=2)
try:
src = a_label[0].find('img').attrs['src']
except:
src = None
data = a_label[1].attrs
thread_id = re.findall(r'user.php\?id=(\d+)&', data['data-hovercard'])[0]
title = data['title']
if thread_id and title:
user_ids.append(thread_id)
names.append(title)
if 'friendBrowserContent' in html:
result.append({'fbid': thread_id, 'name': title, 'src': src})
elif 'friendBrowserContent' in html:
for li in bs.select('.friendBrowserContent'):
try:
src = li.parent.parent.parent.parent.find('img').attrs['src']
except:
src = None
data = li.find_all('a', limit=2)[0].attrs
if 'data-hovercard' in data:
thread_id = re.findall(r'user.php\?id=(\d+)&', data['data-hovercard'])[0]
title = data['title']
if thread_id and title:
user_ids.append(thread_id)
names.append(title)
result.append({'fbid': thread_id, 'name': title, 'src': src})
if 'uiMorePagerPrimary' in html:
atag = bs.find('a', attrs={'class': 'uiMorePagerPrimary'})
next_url = atag.get('ajaxify')
return user_ids, names, next_url
return result, next_url
def _unit_html(p):
... ...