Init du dépot sur une base de scorbot

This commit is contained in:
hadware
2018-05-24 03:24:06 +02:00
commit 0b2ed0e002
13 changed files with 566 additions and 0 deletions
View File
+58
View File
@@ -0,0 +1,58 @@
from typing import List
from .requests import LoginRequest, PostLoginRequest
import logging
class Interlocutor:
def __init__(self, nick: str, age:int, city: str, is_male: bool, conv_id: str):
self.nick = nick
self.age = age
self.is_male = is_male
self.city = city
self.id = conv_id
@classmethod
def from_string(cls, str):
# 47130922100412004Rastapopoulos
# 47 (age) 1 (sexe) 30922 (city id) 100412(conv id)
age = str[:2]
is_male = int(str[2:3]) in (1, 6)
city_id = str[3:8]
conv_id = str[8:14]
nick = str[17:]
return cls(nick, age, city_id, is_male, conv_id)
def __eq__(self, other):
return other.nick == self.nick
class CocoClient:
def __init__(self, nick: str, age: int, is_female: bool, zip_code: str):
self.nick = nick
self.age = age
self.is_female = is_female
self.zip_code = zip_code
self.interlocutors = [] # type: List[Interlocutor]
self.user_id = None # type:str
self.user_pass = None # type:str
def connect(self):
login_req = LoginRequest(self.nick, self.age, self.is_female, self.zip_code)
self.user_id, self.user_pass = login_req.retrieve()
logging.info("Logged in to coco as %s" % self.nick)
post_login_req = PostLoginRequest(self.user_id, self.user_pass)
post_login_req.retrieve()
logging.info("Post login successful")
def pulse(self):
pass
def send_msg(self):
pass
def switch_conv(self, nick: str=None):
pass
+99
View File
@@ -0,0 +1,99 @@
from urllib.request import Request, urlopen
from random import randint, choice, random
from string import ascii_uppercase
from .tools import get_city_id, coco_cipher, encode_msg
class BaseCocoRequest:
host = 'http://cloud.coco.fr/'
headers = {'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:59.0) Gecko/20100101 Firefox/59.0',
'Cookie': '_ga=GA1.2.795717920.1518381607',
'Host': 'cloud.coco.fr',
'Referer': 'http://www.coco.fr/chat/index.html'}
def _get_url(self):
pass
def _parse_response(self, response):
pass
def retrieve(self):
req = Request(self._get_url(), headers=self.headers)
response = urlopen(req).read()
cleaned = response.decode("utf-8")[len("process1('#"):-len("');")]
return self._parse_response(cleaned)
class LoginRequest(BaseCocoRequest):
def __init__(self, nick: str, age: int, is_female: bool, zip_code: str):
self.nick = nick
self.age = str(age)
self.sex = str('2' if is_female else '1')
self.city = get_city_id(zip_code)
def _get_url(self):
identifier = str(randint(100000000, 990000000)) + '0' + ''.join(choice(ascii_uppercase) for i in range(20))
return self.host + '40' + self.nick + '*' + self.age + self.sex + self.city + identifier
def _parse_response(self, response):
credentials = response[2:14]
return credentials[:6], credentials[6:] # user_id and password
class LoggedInRequest(BaseCocoRequest):
def __init__(self, user_id, password):
self.user_id = user_id
self.password = password
@property
def token(self):
return self.user_id + self.password
class PostLoginRequest(LoggedInRequest):
client_id_str = "3551366741*0*1aopiig*-940693579*192.168.0.14*0"
def _get_url(self):
return self.host + '52' + self.token + coco_cipher(self.client_id_str, self.password)
def _parse_response(self, response):
"""Checks if the post-login was successful"""
# TODO
pass
class PulseRequest(LoggedInRequest):
# typical response :
# process1('#669276787#30130916276787003HotelDiscret#salut_toi#47130922100412004Rastapopoulos#Mes_hommages,_Mademoiselle...#47130922100412004Rastapopoulos#Jamais_un_mari_ne_sera_si_bien_veng*r_que_par_l*8amant_de_sa_femme.#40636427396758003leo913#cam.!7w2738702leo913#396758#');
# process1('#669276787#30130916276787003HotelDiscret#chaude=#292223#32130926292223003HDirect#Salut,_te_faire_payer_pour_un_plan_sexe_ca_te_plairais_=#');
# process1('#66945630927183748003WolfiSoDentelle#en_manque_de_sommeil_peut_etre_=_#');
# ^ le type a 45 balais donc il doit falloir couper après 669
# process1('#66929630926396791003Clouds#bonsoir,_comment_vas-tu_=_que_cherches_tu_=#');
# idem avec lui, il a 29 ans
def _get_url(self):
return self.host + "95" + self.token + "?" + str(random())
def _parse_response(self, response):
"""Can either be a single message or several messages"""
# TODO
pass
class SendMsgRequest(LoggedInRequest):
def __init__(self, user_id, password, conv_id: str, msg: str):
super().__init__(user_id, password)
self.conv_id = conv_id
self.msg = msg
def _get_url(self):
return self.host + "99" + self.token + self.conv_id + encode_msg(self.msg)
def _parse_response(self, response):
"""Response to a send message request can either just be #97x or an
actual message (like in pulse request)"""
# TODO
pass
+88
View File
@@ -0,0 +1,88 @@
from urllib.request import urlopen
import re
doc = {0: 65, 1: 66, 2: 67, 3: 68, 4: 69, 5: 70, 6: 71, 7: 72, 8: 73, 9: 74, 10: 75, 11: 76, 12: 77, 13: 78, 14: 79,
15: 80, 16: 81, 17: 82, 18: 83, 19: 84, 20: 101, 21: 102, 22: 103, 23: 104, 24: 105, 25: 106, 26: 107,
27: 108, 28: 109, 29: 110, 30: 85, 31: 86, 32: 87, 33: 88, 34: 89, 35: 90, 36: 97, 37: 98, 38: 99, 39: 100,
40: 111, 41: 112, 42: 113, 43: 114, 44: 115, 45: 116, 46: 117, 47: 118, 48: 119, 49: 120, 50: 121, 51: 122,
52: 48, 53: 49, 54: 50, 55: 51, 56: 52, 57: 53, 58: 54, 59: 55, 60: 56, 61: 57, 62: 43, 63: 47, 64: 61}
def coco_cipher(str: str, key: str):
"""Implementation of coco's weird 'enxo' cipher. key has to be the user's password,
retrieved from a previous request"""
def none_int(var):
return var if var is not None else 0
def safe_get_charcode(s: str, idx: int):
try:
return ord(s[idx])
except IndexError:
return None
output, chr1, chr2, chr3 = "", 0, 0, 0
enc, revo = {}, {}
for j in range(65):
revo[doc[j]] = j
result = ""
for i, char_n in enumerate(str):
result += chr(ord(key[i % len(key)]) ^ ord(char_n))
i = 0
while i < len(str):
chr1 = safe_get_charcode(result, i)
i += 1
chr2 = safe_get_charcode(result, i)
i += 1
chr3 = safe_get_charcode(result, i)
i += 1
enc[0] = none_int(chr1) >> 2
enc[1] = ((none_int(chr1) & 3) << 4) | (none_int(chr2) >> 4)
enc[2] = ((none_int(chr2) & 15) << 2) | (none_int(chr3) >> 6)
enc[3] = none_int(chr3) & 63
if chr2 is None:
enc[2] = 64
enc[3] = 64
elif chr3 is None:
enc[3] = 64
for j in range(4):
output += chr(doc[enc[j]])
return output
def get_city_id(postal_code: str):
response = str(urlopen("http://www.coco.fr/cocoland/%s.js" % postal_code).read(), 'utf-8')
first_city_code = re.search(r'[0-9]+', response)
if first_city_code:
return first_city_code.group()
elif 'ERROR' in response:
raise ValueError('Invalid postal code')
else:
RuntimeError('Unexpected output')
smilies = [":)", ":(", ";)", ":d", ":-o", ":s", ":$", "*-)", "-)", "^o)", ":p", "(l)", "(v)", ":'(", "(h)", "(f)",
":@", "(y)", "(n)", "(k)", "gr$", "(a)", "(6)", "(yn)", "+o(", "na$", "oh$", "tr$", "(e)", "sh$", "fu$",
"nw$", "ba$", "ao$", "db$", "si$", "oo$", "co$", "bi$", "cc$", "ye$", "mo$", "aa$", "ci$", "uu$", "ff$",
"zz$", "gt$", "ah$", "mm$", "?$", "xx$"]
special_chars = {" ": "~", "!": "!", "\"": "*8", "$": "*7", "%": "*g", "'": "*8", "(": "(", ")": ")", "*": "*s", "=": "*h",
"?": "=", "@": "*m", "^": "*l", "_": "*0", "€": "*d", "à": "*a", "â": "*k", "ç": "*c", "è": "*e",
"é": "*r", "ê": "*b", "î": "*i", "ï": "*j", "ô": "*o", "ù": "*f", "û": "*u"}
def encode_msg(msg : str):
"""Encoding the message to coco's weird url-compatible format"""
for i in range(len(smilies)):
msg = msg.replace(smilies[i], ';' + str(i).zfill(2))
for char, replacement in special_chars.items():
msg = msg.replace(char, replacement)
return msg
def decode_msg(msg: str):
pass