From 968b4b10647c3382ff6f49cbe6c37d6da0cb28b0 Mon Sep 17 00:00:00 2001 From: Yigit Colakoglu Date: Wed, 27 Oct 2021 20:58:16 +0200 Subject: [PATCH] Basic tool done --- __pycache__/vevoxqa.cpython-39.pyc | Bin 0 -> 3798 bytes crush.py | 194 +++++++---------------------- vevoxqa.py | 78 ++++++++++-- 3 files changed, 111 insertions(+), 161 deletions(-) create mode 100644 __pycache__/vevoxqa.cpython-39.pyc diff --git a/__pycache__/vevoxqa.cpython-39.pyc b/__pycache__/vevoxqa.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2e4a2f5d2d42dce43c12e04442ef0e94acb7f02c GIT binary patch literal 3798 zcmb_f%~Ko66`!8b$4CeRHnHQZlMvM=DQzKySZo#&JIlf*VPmsi{FO{Ra?a+r<{Ds@AZrXve(&4)wZhNyng+<`}MD1zt?id z$MXiti@$f=Z>|}}*VMRLEHpkwRiA)xgR`d5Vh&@(n@zK2IhN+FW~!BT(wa{-Gp($X zWybFep5~cX2G5+Dj?J@AjFNqUd5jW^veNar=Z9deT|u98GjO>AGgX(u4MnXU_`axz zUf|bh(A6?D>j9*~a2PinlTUDyTd$a7@f1(LGMp68@GQP*Zu1-rNyM=juVLPRk7n@h0jTs`?0ovz}1{8la3@ zpe9d&T0N43J4>G%;4(Z7n(dLE%?&J^*>wNI4CCaasDwQ7>Y}((Ox8{WuPAu1dGPJmwShHi01&jR2=Xl-pgTKMeA(LyXm82ic(Eqe z?>)S$q`Ut7p0gyKs`I>Y9}_f02ZMh5V&~!N(f((xXUi|Pec3`sxaUd!*p*@D84TLs z(4zGO*{WM7eYD+!gXcmj925Ghb4zn%GVr@9T=v}ZBr)?P=h{|e9g+g*yFVqco zb`;rOt}e{a7S(Zar8>W`0B*0ivand4EqZD-4291HUKb4!DhXd z2-?`uy?K<`q7;X1p+bV~!+yW}?~zk)2@%pBVmEl})YmoQ$-%Gc8v*l&=kC_)aFDft zlZOnBM4!+0{9>KEi`DYNf^f@=^X}cUdsi%$>tgwCb(;h0drR*)tmN`Nrn8cvCt`e6 zAj8ik7ZNM^fo!?W;v3to4z~NnaKDS#?^h%H<({gy6}imimdQgd9X;Oi`cUstd<7nQ z4e>Sr$uQdT2|*tmc=bV}i4l;K%Zwb$(9WTmGbh+e_n+U7p^pOaV~JLcHE}=F8j&+i!=gKDHr8D-wQprd90$sWf(;(LwMkuc2$F# z3b=Ya%GY*ODUg2{@&-Py=PG+aOH?}Et`}C| zG5d(xs*(iNHQ82sLRNG%J#^;|I+0zgk$tt=b&OV%AO_0}e|d1-$z=50K(&rYIV`kG zsyYV$1q^3>#?8LjGuMqTH~Us-a3q0Kv!Ci&Jl!zmLXU;4hqQ2NE*X7xSb#hO`4-7} zwwLxAEGuq&Jo-)7&pW%4?}?yveZ7iWt;-R9@{s$*|6knXmRTdxocm`&dpQG_^G}b zrlFI8uGO=E^c~=95~{b1p4Cg;Hf|x;-!g!kdH5jA0#`jZx6yCx6E%76uap6EXy?xI zpksO+`<$I)4J|F48wp4KqH(=A9{qv_=Tc2-zxiYgh%(*jRfH*OOJlmGO z;4{cFVOv2YZvxxb?0(n$)l4@Nr=ac)$~3>BqmAD&HILt?w@*C?8VIRQCLZo&Ra?jK z?#gh<4Z6Ug+nl)^ja7B9x?H{OCj)od%_v0)!I?-TNx)R{J=hgxlgJayjK( z-(zPiwgWFNE~4~-c0Ten%<0ub`BPFPztO%LnFt(+1U{EJts_PKNYXPhjtnW{enzAS zQp#vAkC@cckfYPy^}Ihuzhg_G4s;@*SaRv^gp$Us46&lA40a9fK5eG7)BlM5gxv&p z6Vd`MKnh%UVsHVHv30s|gF^ewqUxxz4Fj}e;NFS?#Sk-#^DF(v(SfIz|*Li+w{iEZbsPza_7BwCN&kx8Q7x%)A1w9 zC4)A2$(BE-zF!b25TTQa0jAI?HQv7jSF$wJj;*}}$u*wz4Oqtz`3DNC7^U9kB~NS)kJFaqfq zVfbB;T8AG0Rx}GV=>X0@jKFDXIHw12UR4|k$_O==e<&!%YsX_01a)9yn@Akw0#Ul& z43sFbIB$%etDJ+zGgPHro^{6u3+q9f7)8F1w*j&*JuPZAWc^wz;O!>yg<9>f?Ka~c z`2(oxd?QQ5%@Uz|s8_j?m$VH!IZv$jekH6tSG@25D4%y{|kZ>;iv!r literal 0 HcmV?d00001 diff --git a/crush.py b/crush.py index dca5d40..6f620f8 100644 --- a/crush.py +++ b/crush.py @@ -7,163 +7,55 @@ # Copyright 2021. Yigit Colakoglu. All rights reserved. # -from websocket import create_connection -import requests +import vevoxqa +from tqdm import tqdm import sys -import ssl +from concurrent.futures import ThreadPoolExecutor, as_completed -apiurl = "https://web1-httpapi.vevox.com" - -ciss = """f7311cdd-7c93-4cc2-a37b-6f60dc590bd9 -f152afaf-1104-43da-8f1c-5bc344922d81 -cd1a88ef-999e-4c9d-be5d-b5b1e56f5c48 -6ee5f89d-1912-48c8-bf6d-d2990269469d -52232dcf-68e2-47a7-b672-83b244eb1241 -f0895e68-15a0-478f-ad2b-ffefcc5705ce -fdf37fbc-ed8e-4c23-90cc-d272ed06585c -f43ef402-b4e2-4556-90e5-ac35535e3c1f -ed3fd857-5b90-4a46-8c1a-abba08258618 -02ef350b-0994-4c22-b7fc-849864a53642 -87c50bc1-eb38-4f57-87e6-b82ca2b1b8f0 -f7978990-bfa0-4a2c-809d-1de725472cfb -c8cb9238-119d-45eb-b436-312283f0ee66 -716fef4a-cd3e-4a68-aaca-02a991a8dcb5 -6f02e7b0-e27f-4215-952a-eb303fc1c5e9 -281d544a-de02-4ab4-9f27-ee773f1e396e -484063ad-fc14-4437-aa17-40cce5e0ac1f -af1b11f7-1942-4c28-8ffd-e7eec5555694 -c49c363a-3d29-486e-ba9a-2a409588087d -6410f54e-142a-4c1b-ae6c-0e53c790000b -320952ff-8a49-49d8-8ff4-ef93e168144c -65bf2796-74dd-4388-a122-dae3d279c545 -459063f7-6681-4e1f-9e99-c649dc62e213 -99bc9405-8064-48f6-890e-a36318e3c09f -4e79fc77-ebf9-447d-a8a7-712c3f455c80 -796d2460-45e6-4de0-9602-6409c82f7957 -df6d96b7-db9f-406c-a53b-ffa8c98fd1ad -d5ce58d4-88f4-42ce-b937-8c34ae63248b -538bca24-4f51-4ac9-a1a8-5cfa403d7240 -667a1b16-ce91-4f6a-ab37-30a6c3954d07 -2566f814-2121-45c2-b5fd-5b0e3fbfb326 -a672c800-68bc-4c9e-b6dc-12913d26e8ec -98c4d069-b9e4-4409-bf06-3a01313023ba -cb410cdc-7bb7-4196-a19e-743c6b08c1f8 -acb958cd-2628-410e-b0d9-8404767fa646 -3c098a63-7f9b-44f9-9b87-73385a90bb1f -6fbc49d3-9191-4cd2-9549-99db8446f3d2 -4a58d30a-7e8b-446c-be53-513fcde9e125 -202f066c-35b7-4e75-970b-ee438d237ff6 -d4025dbf-da22-4594-a37b-dfcce2cc3fd9 -c6f1bc75-d8ce-45aa-8dda-ed0523578612 -6a77db93-eb33-46ba-bcf6-c374578d5dc0 -6bd70847-12f5-4d79-8f80-eff43bae2e18 -7b401ed5-1722-4f42-b8f6-9537f31c31fc -9834866e-0e33-4536-a100-270d8a8692e4 -236fb156-2c86-4e19-89f5-ba42f8e3f873 -df33f43d-4209-4554-b686-8ba3be0bc6fe -8eb1ef43-9587-42d7-af22-267b80d929d9 -f9da3907-d4bd-452e-97ac-d6ca22d7c67f -1fab5eba-c366-4f94-997a-e3dd784ff306 -01dda5d7-4f50-481c-a7fc-f4e8ad6465ed -ae4d1505-23af-41b2-a539-093807b5b060 -0af23214-1009-4f87-bf72-67c6ac93d3dc -cd807405-6590-4077-8f4e-6f4a500253e0 -bbc393ff-a1e9-461c-8fe6-04f944e34199 -8e50612f-e9a0-4c25-9423-bee8f7fb8ddb -4876f0b4-ca3a-409c-99c5-32e5467e21bb -0a4e20b3-ebdb-4541-ab7c-45522a77da9b -7b4d4fe0-2b75-49bf-b93c-8630e4703d19 -fe73a6ee-c79c-4fe0-919e-6eb02d172603 -a38aaf18-2ba1-4285-83b4-8109519c3ca5 -09435a3f-e4ba-40f7-bd77-5664e3d8e043 -0eabbf76-2ada-4ee6-9751-aac2e21ff568 -d86dd315-465f-454e-aa44-2ec17e34e89a -dacb8d8c-e26c-44e7-ba44-ce190f23424d -7a3e6b79-d98e-4ed4-a11f-ac8297bfe6da -45d46ae4-5d05-462e-a95a-daed8363acc5 -d5c2f0ae-e002-42e0-80d4-fd7823655f74 -d0266250-2bbb-4a18-9fbe-8ed38720ac07 -1ff0eb16-435a-4713-9bac-62c8ed55e83c -487cee8f-dd8a-40f5-aa9d-5ba62537e1bd -fb0c1c48-b66f-43b2-8d80-fe2b331124fe -aef12b08-51bc-4291-8ce6-4912b1948fff -0ed13503-a48d-4a23-a022-1c258ddfaf95 -3dd501c9-4758-47e4-81ee-20620c3003c3 -32fa2a02-cc5e-45dd-991a-e2a0a407e36a -6b967a3c-82f9-4cf6-88ff-154baa81ab6a -be3724a1-2f57-47ed-b72e-da74a20542e9 -055def12-8452-4b29-b652-02e62fc419ca -dc876fa1-dae7-485d-9acb-c2e9e3e30d04 -aea2e4d3-7124-4e26-9205-77c0e61edbc3 -44e50283-9b0a-459d-b04b-a5b3653ef11a -4c24f961-3efe-4233-8ee6-669b65b8d6c6 -4ca70109-64e4-4562-a6df-1e8f8bd541dc -b03d8cb0-893a-40cc-9aae-23e3862086d9 -60105b65-fc68-4653-903c-480c9a03b17a -d3ead3be-e473-4e03-ad5c-a8f8c93c612f -ee56ab97-47bc-4e67-aceb-8cec8864a7cf -ab3df90b-5e6e-461b-bf82-1d1bad4306b9 -b8f93e14-76dc-4b54-8f0f-ddff7a873311 -d8dcefb8-913c-4f83-9e77-23b24e449082 -0025acc9-05ab-4348-8aa0-c1fe6c163c41 -f1c5f0fd-861e-48f4-be43-532cb96279c2 -434e00ff-eedd-489c-b6a3-0819b3dfb708 -a5c06c4d-33db-4186-ac6f-adc5b59670e2 -3715749b-e88e-4d57-8e89-17f7446c83d4 -4925f118-c47b-45d7-9203-62a3739280e2 -7e95a757-8185-4085-ae7f-efbc8053ed3c -c1bd06cc-bb5c-4c9d-929e-306e84c9076f -9d6c83ee-64e6-47b0-917c-2aacafb3517b""" - - -initialws = """{{"service":"httpapiservice-1_0","message":"SetConnectionInfo","data":{{"secret":"RIM2JSTSyk4Y/TXTwvh7nIWCrD6L5sraDV6Z7rZ1ZVk=","key":"FWfLAvjJmU9Wbnrm","thirdPartyUserId":"","deviceId":"{}","appVersion":"1.7.0","apiVersion":"1.23","tzid":"Europe/Amsterdam","tzoffset":-120,"sw":1022,"sh":241,"isAttendee":true,"gatewayMappings":{{"97":"wss://staging-httpapi.lumidev.net/api","98":"wss://qarel-httpapi.lumidev.net/api","99":"wss://qamaster-httpapi.lumidev.net/api"}}}},"timeout":60000,"requestId":3}}""" - -connectionws = """{{"service":"meetingservice-1_0","message":"DeviceConnectAction","data":{{"accessCode":"{}","appId":"b04cda41-22ea-40a5-a5e4-ce951bd12067","apiVersion":"1.23","connectProperties":{{"sortOrder":"normal"}}}},"timeout":10000,"reQquestId":4}}""" - -likews = """{{"service":"discussionservice-1_3","message":"DeviceDiscussionMessageLikeAction","data":{{"messageId":{},"topicId":219158,"liked":true}},"timeout":10000,"requestId": {}}}""" - - -try: - _create_unverified_https_context = ssl._create_unverified_context -except AttributeError: - # Legacy Python that doesn't verify HTTPS certificates by default - pass -else: - # Handle target environment that doesn't support HTTPS verification - ssl._create_default_https_context = _create_unverified_https_context def main(): - connection_ids = ciss.split('\n') - counter = 0 - rid = 5 - for i in range(int(sys.argv[1])): - r = requests.get(apiurl) - print("{}, {}".format(i, r.status_code)) - cookie = "" - cdict = dict(r.cookies) - for i in cdict: - cookie += i+"="+cdict[i]+"; " - cid = connection_ids[counter] - counter+= 1 - upvoteq(sys.argv[2], cookie, connection_ids[counter], sys.argv[3], rid) - rid += 1 + print("====Welcome to Vevox Crusher====") + if len(sys.argv) < 2: + sessionid = input("Please enter session id: ") + else: + sessionid = sys.argv[1] + cmd = "" -def upvoteq(qid, cookies, cid, sid, rid): - ws = create_connection("wss://web1-httpapi.vevox.com/api?connection_id=" + cid, cookies=cookies) - # print(ws.recv()) - test = initialws.format(cid) - ws.send(test) - ws.recv() - test2 = connectionws.format(sid) - ws.send(test2) - ws.recv() - test3 = likews.format(qid, rid) - print("LIKE") - print(test3) - ws.send(test3) - print(ws.recv()) - ws.close() + while cmd != "exit": + cmd = input(">>> ") + cmdparts = cmd.split(" ") + + if cmdparts[0] == "ask": + vq = vevoxqa.VevoxQA(sessionid) + vq.connect() + vq.askquestion(" ".join(cmdparts[1:])) + vq.close() + + elif cmdparts[0] == "upvote": + with tqdm(total=int(cmdparts[2]), bar_format='{l_bar}{bar:10}{r_bar}{bar:-10b}') as pbar: + with ThreadPoolExecutor(max_workers=int(cmdparts[3])) as ex: + futures = [ex.submit(upvote, sessionid, cmdparts[1]) for i in range(int(cmdparts[2]))] + for future in as_completed(futures): + pbar.update(1) + + elif cmdparts[0] == "questions": + vq = vevoxqa.VevoxQA(sessionid) + vq.connect() + + for i in vq.messages: + print("{} : {} [{} likes]".format(i["messageId"], i["text"], i["likesCount"])) + + vq.close() + + else: + print("Unknown comand >:(") + +def upvote(sessionid, questionid): + liker = vevoxqa.VevoxQA(sessionid) + liker.connect() + count = liker.likequestion(questionid) + liker.close() if __name__ == "__main__": diff --git a/vevoxqa.py b/vevoxqa.py index 37d552a..34f83ee 100644 --- a/vevoxqa.py +++ b/vevoxqa.py @@ -7,22 +7,80 @@ # Copyright 2021. Yigit Colakoglu. All rights reserved. # +from random import randint +from requests import get +from json import loads +from websocket import create_connection + class VevoxQA: - def __init__(self, sessid): + + + def __init__(self, sessid, host = "web1-httpapi.vevox.com"): + self.initialws = '{{"service":"httpapiservice-1_0","message":"SetConnectionInfo","data":{{"secret":"RIM2JSTSyk4Y/TXTwvh7nIWCrD6L5sraDV6Z7rZ1ZVk=","key":"FWfLAvjJmU9Wbnrm","thirdPartyUserId":"","deviceId":"{}","appVersion":"1.7.0","apiVersion":"1.23","tzid":"Europe/Amsterdam","tzoffset":-120,"sw":1022,"sh":241,"isAttendee":true,"gatewayMappings":{{"97":"wss://staging-httpapi.lumidev.net/api","98":"wss://qarel-httpapi.lumidev.net/api","99":"wss://qamaster-httpapi.lumidev.net/api"}}}},"timeout":60000,"requestId":3}}' + self.connectionws = '{{"service":"meetingservice-1_0","message":"DeviceConnectAction","data":{{"accessCode":"{}","appId":"b04cda41-22ea-40a5-a5e4-ce951bd12067","apiVersion":"1.23","connectProperties":{{"sortOrder":"normal"}}}},"timeout":10000,"reQquestId":4}}' + self.likews = '{{"service":"discussionservice-1_3","message":"DeviceDiscussionMessageLikeAction","data":{{"messageId":{},"topicId":{},"liked":true}},"timeout":10000,"requestId": {}}}' + self.askws = '{{"service":"discussionservice-1_3","message":"DeviceDiscussionMessagePostAction","data":{{"topicId":{},"message":"{}","anonymous":true,"nameHidden":false}},"timeout":10000,"requestId":{}}}' self.sessid = sessid + self.connid = self._genconnid() + self.requestid = 5 + self.host = host + + def _genconnid(self): + connid = "" + connformat = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx" + + for i in connformat: + rint = randint(0,15) + if i == "x": + connid += format(rint, 'x') + elif i == "y": + connid += format(3 & rint | 8, 'x') + else: + connid += i + + return connid + # Open a connection to Vevox Q&A Session def connect(self): - pass + r = get("https://"+self.host) + if r.status_code != 404: + print("[ERROR]: Connection to {} returned status {}".format(self.host, r.status_code)) + + cookies = "" + cookiedict = dict(r.cookies) + for i in cookiedict: + cookies += i+"="+cookiedict[i]+"; " + self.ws = create_connection("wss://" + self.host + "/api?connection_id=" + self.connid, cookies=cookies) + self.ws.send(self.initialws.format(self.connid)) + self.ws.recv() + self.ws.send(self.connectionws.format(self.sessid)) + response = loads(self.ws.recv()) + if response["status"] != "success": + print("[ERROR]: Initital connection request returned unsuccessful") + return + self.topicId = response["data"]["successMessages"][8]["topicId"] + self.messages = response["data"]["successMessages"][8]["messages"]["messages"] + + def askquestion(self, question): + self.ws.send(self.askws.format(self.topicId, question, self.requestid)) + data = loads(self.ws.recv()) + while "message" not in data or data["message"] != "DeviceDiscussionMessageList": + data = loads(self.ws.recv()) + + return data["data"]["messages"][0]["messageId"] - # Get the questions from Vevox Q&A Session - def getquestions(self): - pass # Like a question returns true if successful - def likequestion(self): - pass + def likequestion(self, qid): + self.ws.send(self.likews.format(qid, self.topicId, self.requestid)) + data = loads(self.ws.recv()) - # Unlike a question returns true if successful - def unlikequestion(self): - pass + while "message" not in data or data["message"] != "DeviceDiscussionMessageLikeCountList": + data = loads(self.ws.recv()) + + return data["data"]["likeCounts"][0]["likeCount"] + + + def close(self): + self.ws.close()