HDmario: fix registrazione automatica (supporto a captcha e verifica mail)

This commit is contained in:
marco
2020-10-07 20:54:03 +02:00
parent ca6c75f711
commit 3f8af5efc8
5 changed files with 406 additions and 106 deletions
+131
View File
@@ -0,0 +1,131 @@
import random
import string
import time
from core import httptools, support
from platformcode import platformtools, config, logger
class Mailbox:
def __init__(self):
self.address = self.new()
if '@' in self.address:
self.user, self.domain = self.address.split('@')
else:
self.user = None
self.domain = None
def new(self):
return 'test@ciao.it'
def inbox(self):
pass
def readLast(self):
pass
def waitForMail(self, timeout=50):
info = 'verifica tramite mail richiesta dal sito, sono in attesa di nuove mail sulla casella ' + self.address
# info += '\nTimeout tra ' + str(timeout) + ' secondi'
dialog = platformtools.dialog_progress(config.get_localized_string(20000), info)
secs = 0
while secs < timeout:
msg = self.readLast()
logger.debug('Checked mail ' + self.address)
if msg:
dialog.close()
logger.debug(msg)
return msg
else:
time.sleep(1)
secs += 1
dialog.update(0, info + '\nTimeout tra ' + str(timeout-secs) + ' secondi')
if dialog.iscanceled():
break
logger.debug('No mail found, timeout reached or dialog canceled')
return None
class Email:
def __init__(self, subject='', body='', sender='', date=''):
self.subject = subject
self.body = body
self.sender = sender
self.date = date
def __repr__(self):
r = "Date: " + self.date + '\n'
r += "Subject: " + self.subject + '\n'
r += "Sender: " + self.sender + '\n\n'
r += self.body
return r
class OneSecMailbox(Mailbox):
def __init__(self):
self.defDomain = '1secmail.com'
self.baseUrl = 'https://www.1secmail.com/api/v1/'
Mailbox.__init__(self)
if not self.domain:
self.domain = self.defDomain
self.user = self.address
def inbox(self):
"""
:return: json containing inbox id and subjects
"""
apiUrl = self.baseUrl + '?action=getMessages&login=' + self.user + '&domain=' + self.domain
return httptools.downloadpage(apiUrl).json
def readLast(self):
try:
id = self.inbox()[0]['id']
except:
return None
apiUrl = self.baseUrl + '?action=readMessage&login=' + self.user + '&domain=' + self.domain + '&id=' + str(id)
j = httptools.downloadpage(apiUrl).json
return Email(j['subject'], j['htmlBody'], j['from'], j['date'])
def new(self, len=10):
letters = string.ascii_lowercase
return ''.join(random.choice(letters) for i in range(len)) + '@' + self.defDomain
class Gmailnator(Mailbox):
def __init__(self, domains=('.gmail',)):
self.baseUrl = 'https://gmailnator.com/'
self.genDomains = {
'gmailnator': 1,
'+gmail': 2,
'.gmail': 3
}
self.data = [self.genDomains[d] for d in domains]
Mailbox.__init__(self)
def new(self):
self.csrf = support.match(self.baseUrl, patron='csrf-token" content="([a-z0-9]+)').match
logger.debug(self.csrf)
e = httptools.downloadpage(self.baseUrl + 'index/indexquery', post={'csrf_gmailnator_token': self.csrf, 'action': 'GenerateEmail', 'data[]': self.data})
if e.success:
return e.data
else:
platformtools.dialog_ok(config.get_localized_string(20000), 'Impossibile ottenere una mail temporanea')
def inbox(self):
#[{"content":"\n\t\t\t\t<a href=\"https:\/\/gmailnator.com\/jonathanmichaeltmp\/messageid\/#174f933a17b5f625\">\n\t\t\t\t\t<table class=\"message_container\">\n\t\t\t\t\t\t<tbody>\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<td>dsds<\/td>\n\t\t\t\t\t\t\t\t<td>body<\/td>\n\t\t\t\t\t\t\t\t<td class=\"text-right\">one minute ago<\/td>\n\t\t\t\t\t\t\t<\/tr>\n\t\t\t\t\t\t<\/tbody>\n\t\t\t\t\t<\/table>\n\t\t\t\t<\/a>"}]
return httptools.downloadpage(self.baseUrl + 'mailbox/mailboxquery', post={'csrf_gmailnator_token': self.csrf, 'action': 'LoadMailList', 'Email_address': self.address}).json
def readLast(self):
inbox = self.inbox()
if inbox:
self.user, id = support.match(inbox[0]['content'], patron='([^\/]+)\/messageid\/#([a-z0-9]+)').match
#<b>subject</b><div>2 minutes ago</div><hr /><div dir="ltr">body</div>
html = httptools.downloadpage(self.baseUrl + 'mailbox/get_single_message/', post={'csrf_gmailnator_token': self.csrf, 'action': 'get_message', 'message_id': id, 'email': self.user}).data
logger.debug(html)
m = Email()
m.subject, m.date, m.body = support.match(html, patron='<b>([^<]+)<\/b><div>([^<]+)<\/div><hr \/>(.*)').match
return m
return inbox
-56
View File
@@ -1,56 +0,0 @@
import random
import string
import time
from core import httptools
from platformcode import platformtools, config
baseUrl = 'https://www.1secmail.com/api/v1/'
defDomain = '1secmail.com'
def splitMail(mail):
if '@' in mail:
user, domain = mail.split('@')
else:
user = mail
domain = defDomain
return user, domain
def getMessages(mail):
"""
:param user: user@1secmail.com
:return: json containing inbox id and subjects
"""
user, domain = splitMail(mail)
apiUrl = baseUrl + '?action=getMessages&login=' + user + '&domain=' + domain
return httptools.downloadpage(apiUrl).json
def readLastMessage(mail):
user, domain = splitMail(mail)
try:
id = getMessages(mail)[0]['id']
except:
return None
apiUrl = baseUrl + '?action=readMessage&login=' + user + '&domain=' + domain + '&id=' + str(id)
return httptools.downloadpage(apiUrl).json
def waitForMail(mail, timeout=50):
dialog = platformtools.dialog_progress(config.get_localized_string(20000), 'verifica tramite mail richiesta dal sito, sono in attesa di nuove mail sulla casella ' + mail)
secs = 0
while secs < timeout:
msg = readLastMessage(mail)
if msg:
dialog.close()
return msg
else:
time.sleep(1)
secs += 1
if dialog.iscanceled():
break
return None
def getRandom(len=10):
letters = string.ascii_lowercase
return ''.join(random.choice(letters) for i in range(len)) + '@' + defDomain
+71 -1
View File
@@ -110,6 +110,11 @@ def dialog_browse(_type, heading, shares="files", mask="", useThumbs=False, trea
return d return d
def dialog_register(heading, user=False, email=False, password=False, user_default='', email_default='', password_default='', captcha_img=''):
dialog = Register('Register.xml', config.get_runtime_path()).Start(heading, user, email, password, user_default, email_default, password_default, captcha_img)
return dialog
def itemlist_refresh(): def itemlist_refresh():
# pos = Item().fromurl(xbmc.getInfoLabel('ListItem.FileNameAndPath')).itemlistPosition # pos = Item().fromurl(xbmc.getInfoLabel('ListItem.FileNameAndPath')).itemlistPosition
# logger.info('Current position: ' + str(pos)) # logger.info('Current position: ' + str(pos))
@@ -136,7 +141,7 @@ def render_items(itemlist, parent_item):
logger.info('START render_items') logger.info('START render_items')
thumb_type = config.get_setting('video_thumbnail_type') thumb_type = config.get_setting('video_thumbnail_type')
from platformcode import shortcuts from platformcode import shortcuts
from core import httptools # from core import httptools
_handle = int(sys.argv[1]) _handle = int(sys.argv[1])
default_fanart = config.get_fanart() default_fanart = config.get_fanart()
def_context_commands = shortcuts.context() def_context_commands = shortcuts.context()
@@ -1269,3 +1274,68 @@ def get_platform():
ret["arch"] = "arm" ret["arch"] = "arm"
return ret return ret
class Register(xbmcgui.WindowXMLDialog):
def Start(self, heading, user, email, password, user_default, email_default, password_default, captcha_img):
self.result = {}
self.heading = heading
self.user = user
self.email = email
self.password = password
self.user_default = user_default
self.email_default = email_default
self.password_default = password_default
self.captcha_img = captcha_img
self.doModal()
return self.result
def __init__(self, *args, **kwargs):
self.mensaje = kwargs.get("mensaje")
self.imagen = kwargs.get("imagen")
def onInit(self):
#### Kodi 18 compatibility ####
if config.get_platform(True)['num_version'] < 18:
self.setCoordinateResolution(2)
height = 90
self.getControl(10002).setText(self.heading)
if self.user:
self.getControl(10003).setText(self.user_default)
height+=70
else:
self.getControl(10003).setVisible(False)
if self.email:
self.getControl(10004).setText(self.email_default)
height+=70
else:
self.getControl(10004).setVisible(False)
if self.password:
self.getControl(10005).setText(self.password_default)
height+=70
else:
self.getControl(10005).setVisible(False)
if self.captcha_img:
self.getControl(10007).setImage(self.captcha_img)
height+=240
else:
self.getControl(10005).setVisible(False)
height +=40
if height < 250: height = 250
self.getControl(10000).setHeight(height)
self.getControl(10001).setHeight(height)
self.getControl(10000).setPosition(255, (720-height)/2)
self.setFocusId(30000)
def onClick(self, control):
if control in [10010]:
self.close()
elif control in [10009]:
if self.user: self.result['user'] = self.getControl(10003).getText()
if self.email: self.result['email'] = self.getControl(10004).getText()
if self.password: self.result['password'] = self.getControl(10005).getText()
if self.captcha_img: self.result['captcha'] = self.getControl(10006).getText()
self.close()
+125
View File
@@ -0,0 +1,125 @@
<?xml version="1.0" encoding="utf-8"?>
<window>
<allowoverlays>false</allowoverlays>
<animation type="WindowOpen" reversible="false">
<effect type="zoom" start="80" end="100" center="640,225" delay="160" tween="back" time="240" />
<effect type="fade" delay="160" end="100" time="240" />
</animation>
<animation type="WindowClose" reversible="false">
<effect type="zoom" start="100" end="80" center="640,225" easing="in" tween="back" time="240" />
<effect type="fade" start="100" end="0" time="240" />
</animation>
<controls>
<control type="group" id="10000">
<width>790</width>
<!-- Background -->
<control type="image" id='10001'>
<width>790</width>
<texture colordiffuse="FF232323">white.png</texture>
</control>
<!-- Header -->
<control type="textbox" id="10002">
<height>60</height>
<width>600</width>
<textcolor>FFFFFFFF</textcolor>
<wrapmultiline>true</wrapmultiline>
<align>center</align>
<aligny>center</aligny>
<label></label>
</control>
<!-- User -->
<control type="grouplist" id="30000">
<top>90</top>
<left>40</left>
<itemgap>20</itemgap>
<onright>10009</onright>
<control type="edit" id="10003">
<height>50</height>
<width>560</width>
<textcolor>FFFFFFFF</textcolor>
<texturefocus colordiffuse="FF0082C2">white.png</texturefocus>
<texturenofocus colordiffuse="FF232323">white.png</texturenofocus>
<aligny>center</aligny>
<label>username</label>
</control>
<!-- Email -->
<control type="edit" id="10004">
<height>50</height>
<width>560</width>
<textcolor>FFFFFFFF</textcolor>
<texturefocus colordiffuse="FF0082C2">white.png</texturefocus>
<texturenofocus colordiffuse="FF232323">white.png</texturenofocus>
<aligny>center</aligny>
<label>email</label>
</control>
<!-- Password -->
<control type="edit" id="10005">
<height>50</height>
<width>560</width>
<textcolor>FFFFFFFF</textcolor>
<texturefocus colordiffuse="FF0082C2">white.png</texturefocus>
<texturenofocus colordiffuse="FF232323">white.png</texturenofocus>
<aligny>center</aligny>
<label>password</label>
</control>
<!-- Captcha -->
<control type="edit" id="10006">
<height>50</height>
<width>560</width>
<textcolor>FFFFFFFF</textcolor>
<texturefocus colordiffuse="FF0082C2">white.png</texturefocus>
<texturenofocus colordiffuse="FF232323">white.png</texturenofocus>
<aligny>center</aligny>
<label>captcha</label>
</control>
<!-- Captchaimg -->
<control type="image" id="10007">
<width>560</width>
<height>170</height>
<left>20</left>
<aspectratio>keep</aspectratio>
</control>
</control>
<control type="group" id='10008'>
<top>90</top>
<left>620</left>
<control type="button" id="10009">
<top>0</top>
<left>0</left>
<width>150</width>
<height>50</height>
<textwidth>110</textwidth>
<textcolor>FFFFFFFF</textcolor>
<focusedcolor>FFFFFFFF</focusedcolor>
<texturefocus colordiffuse="FF0082C2">white.png</texturefocus>
<texturenofocus colordiffuse="000082C2">white.png</texturenofocus>
<align>center</align>
<aligny>center</aligny>
<label>$ADDON[plugin.video.kod 70007]</label>
<onup>10010</onup>
<ondown>10010</ondown>
<onleft>10003</onleft>
<onright>10003</onright>
</control>
<control type="button" id="10010">
<top>70</top>
<left>0</left>
<width>150</width>
<height>50</height>
<textwidth>110</textwidth>
<textcolor>FFFFFFFF</textcolor>
<focusedcolor>FFFFFFFF</focusedcolor>
<texturefocus colordiffuse="FF0082C2">white.png</texturefocus>
<texturenofocus colordiffuse="000082C2">white.png</texturenofocus>
<align>center</align>
<aligny>center</aligny>
<label>$ADDON[plugin.video.kod 707433]</label>
<onup>10009</onup>
<ondown>10009</ondown>
<onleft>10003</onleft>
<onright>10003</onright>
</control>
</control>
</control>
</controls>
</window>
+78 -48
View File
@@ -3,6 +3,7 @@ import xbmc
from core import httptools, scrapertools, filetools from core import httptools, scrapertools, filetools
from platformcode import logger, config, platformtools from platformcode import logger, config, platformtools
from lib.fakeMail import Gmailnator
baseUrl = 'https://hdmario.live' baseUrl = 'https://hdmario.live'
@@ -20,49 +21,78 @@ def test_video_exists(page_url):
def login(): def login():
httptools.downloadpage(page.url.replace('/unauthorized', '/login'), r = httptools.downloadpage(page.url.replace('/unauthorized', '/login'),
post={'email': config.get_setting('username', server='hdmario'), post={'email': config.get_setting('username', server='hdmario'),
'password': config.get_setting('password', server='hdmario')}) 'password': config.get_setting('password', server='hdmario')})
if not r.success or 'Email o Password non validi' in r.data:
platformtools.dialog_ok('HDmario', 'Username/password non validi')
return False
return True
def registerOrLogin(page_url, forced=False): def registerOrLogin(page_url):
if not forced and config.get_setting('username', server='hdmario') and config.get_setting('password', server='hdmario'): if config.get_setting('username', server='hdmario') and config.get_setting('password', server='hdmario'):
login() if login():
else: return True
if platformtools.dialog_yesno('HDmario',
'Questo server necessita di un account, ne hai già uno oppure vuoi tentare una registrazione automatica?', if platformtools.dialog_yesno('HDmario',
yeslabel='Accedi', nolabel='Tenta registrazione'): 'Questo server necessita di un account, ne hai già uno oppure vuoi tentare una registrazione automatica?',
from specials import setting yeslabel='Accedi', nolabel='Tenta registrazione'):
from core.item import Item from specials import setting
setting.server_config(Item(config='hdmario')) from core.item import Item
login() user_pre = config.get_setting('username', server='hdmario')
password_pre = config.get_setting('password', server='hdmario')
setting.server_config(Item(config='hdmario'))
user_post = config.get_setting('username', server='hdmario')
password_post = config.get_setting('password', server='hdmario')
if user_pre != user_post or password_pre != password_post:
return registerOrLogin(page_url)
else: else:
logger.info('Registrazione automatica in corso') return False
import random else:
import string import random
randEmail = ''.join(random.choice(string.ascii_letters + string.digits) for i in range(random.randint(9, 14))) + '@gmail.com' import string
randPsw = ''.join(random.choice(string.ascii_letters + string.digits) for i in range(10)) logger.info('Registrazione automatica in corso')
logger.info('email: ' + randEmail) mailbox = Gmailnator()
logger.info('pass: ' + randPsw) randPsw = ''.join(random.choice(string.ascii_letters + string.digits) for i in range(10))
nTry = 0 captcha = httptools.downloadpage(baseUrl + '/captchaInfo').json
while nTry < 5: logger.info('email: ' + mailbox.address)
nTry += 1 logger.info('pass: ' + randPsw)
rq = 'loggedin' in httptools.downloadpage(baseUrl + '/register/', reg = platformtools.dialog_register(baseUrl + '/register/', email=True, password=True, email_default=mailbox.address, password_default=randPsw, captcha_img=captcha['captchaUrl'])
post={'email': randEmail, 'email_confirmation': randEmail, if not reg:
'password': randPsw, return False
'password_confirmation': randPsw}).url regPost = httptools.downloadpage(baseUrl + '/register/',
if rq: post={'email': reg['email'], 'email_confirmation': reg['email'],
config.set_setting('username', randEmail, server='hdmario') 'password': reg['password'],
config.set_setting('password', randPsw, server='hdmario') 'password_confirmation': reg['password'],
platformtools.dialog_ok('HDmario', 'captchaUuid': captcha['captchaUuid'],
'Registrato automaticamente con queste credenziali:\nemail:' + randEmail + '\npass: ' + randPsw) 'captcha': reg['captcha']})
break if '/register' in regPost.url:
error = scrapertools.htmlclean(scrapertools.find_single_match(regPost.data, 'Impossibile proseguire.*?</div>'))
error = scrapertools.unescape(scrapertools.re.sub('\n\s+', ' ', error))
platformtools.dialog_ok('HDmario', error)
return False
if reg['email'] == mailbox.address:
mail = mailbox.waitForMail()
if mail:
checkUrl = scrapertools.find_single_match(mail.body, 'href="([^"]+)">Premi qui')
httptools.downloadpage(checkUrl)
config.set_setting('username', mailbox.address, server='hdmario')
config.set_setting('password', randPsw, server='hdmario')
platformtools.dialog_ok('HDmario',
'Registrato automaticamente con queste credenziali:\nemail:' + mailbox.address + '\npass: ' + randPsw)
else: else:
platformtools.dialog_ok('HDmario', 'Impossibile registrarsi automaticamente') platformtools.dialog_ok('HDmario', 'Impossibile registrarsi automaticamente')
logger.info('Registrazione completata') return False
global page, data else:
page = httptools.downloadpage(page_url) platformtools.dialog_ok('HDmario', 'Hai modificato la mail quindi KoD non sarà in grado di effettuare la verifica in autonomia, apri la casella ' + reg['email']
data = page.data + ' e clicca sul link. Premi ok quando fatto')
logger.info('Registrazione completata')
return True
def get_video_url(page_url, premium=False, user="", password="", video_password=""): def get_video_url(page_url, premium=False, user="", password="", video_password=""):
global page, data global page, data
@@ -70,27 +100,27 @@ def get_video_url(page_url, premium=False, user="", password="", video_password=
logger.info("url=" + page_url) logger.info("url=" + page_url)
if 'unconfirmed' in page.url: if 'unconfirmed' in page.url:
from lib import onesecmail
id = page_url.split('/')[-1] id = page_url.split('/')[-1]
mail = onesecmail.getRandom() mailbox = Gmailnator()
postData = { postData = {
'email': mail, 'email': mailbox.address,
'hls_video_id': id 'hls_video_id': id
} }
httptools.downloadpage(page.url, post=postData) httptools.downloadpage(page.url, post=postData)
jsonMail = onesecmail.waitForMail(mail) mail = mailbox.waitForMail()
logger.info(jsonMail) logger.info(mail)
if jsonMail: if mail:
code = jsonMail['subject'].split(' - ')[0] code = mail.subject.split(' - ')[0]
page = httptools.downloadpage(page_url + '?code=' + code) page = httptools.downloadpage(page_url + '?code=' + code)
data = page.data data = page.data
if '/unauthorized' in page.url: if '/unauthorized' in page.url or '/not-active' in page.url:
registerOrLogin(page_url) httptools.set_cookies({}, True) # clear cookies
if not registerOrLogin(page_url):
return []
page = httptools.downloadpage(page_url)
data = page.data
if 'Registrati' in data:
platformtools.dialog_ok('HDmario', 'Username/password non validi')
registerOrLogin(page_url, True)
logger.info(data) logger.info(data)
from lib import jsunpack_js2py from lib import jsunpack_js2py
unpacked = jsunpack_js2py.unpack(scrapertools.find_single_match(data, '<script type="text/javascript">\n*\s*\n*(eval.*)')) unpacked = jsunpack_js2py.unpack(scrapertools.find_single_match(data, '<script type="text/javascript">\n*\s*\n*(eval.*)'))