astrXbian/.install/.kodi/addons/plugin.video.vstream/resources/lib/librecaptcha/__main__.py

263 lines
6.9 KiB
Python

# Copyright (C) 2017, 2019 nickolas360 <contact@nickolas360.com>
#
# This file is part of librecaptcha.
#
# librecaptcha is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# librecaptcha is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with librecaptcha. If not, see <http://www.gnu.org/licenses/>.
from __future__ import absolute_import
from .errors import UserError, UserExit
from .librecaptcha import get_token, __version__
from .user_agents import random_user_agent
import os
import re
import sys
def get_cmd():
if not sys.argv:
return "librecaptcha"
if sys.argv[0].startswith("./"):
return sys.argv[0]
return os.path.basename(sys.argv[0])
CMD = get_cmd()
USAGE = """\
Usage:
{0} [options] [--] <api-key> <site-url> [<user-agent>]
{0} -h | --help | --version
Arguments:
<api-key> The reCAPTCHA API key to use. This is usually the value of the
"data-sitekey" HTML attribute.
<site-url> The URL of the site that contains the reCAPTCHA challenge.
Should start with http:// or https://. Everything after the
hostname is optional. For example: https://example.com
<user-agent> A user-agent string. The client that will use the obtained
reCAPTCHA token should have this user-agent string. If not
provided, a random user-agent string will be chosen and shown.
Options:
-g --gui Use the GTK 3 GUI (as opposed to the CLI).
--debug Show debugging information while running.
-h --help Show this help message.
--version Show the program version.
""".format(CMD)
def usage(file=sys.stdout):
print (USAGE)
def usage_error(exit=True):
usage(sys.stderr)
if exit:
sys.exit(1)
class ParsedArgs(object):
def __init__(self):
self.parse_error = None
self.api_key = None
self.site_url = None
self.user_agent = None
self.gui = False
self.debug = False
self.help = False
self.version = False
class ArgParser(object):
def __init__(self, args):
self.args = args
self.index = 0
self.positional_index = 0
self.parsed = ParsedArgs()
self.options_done = False
self.end_early = False
@property
def arg(self):
try:
return self.args[self.index]
except IndexError:
return None
@property
def done(self):
return self.end_early or self.index >= len(self.args)
def advance(self):
self.index += 1
def error(self, message):
self.parsed.parse_error = message
self.end_early = True
def parse_long_option(self, arg):
body = arg[len("--"):]
if body == "debug":
self.parsed.debug = True
return
if body == "help":
self.parsed.help = True
self.end_early = True
return
if body == "version":
self.parsed.version = True
self.end_early = True
return
if body == "gui":
self.parsed.gui = True
return
self.error("Unrecognized option: {}".format(arg))
def parse_short_option_char(self, char):
if char == "h":
self.parsed.help = True
self.end_early = True
return
if char == "g":
self.parsed.gui = True
return
self.error("Unrecognized option: -{}".format(char))
def parse_short_option(self, arg):
body = arg[len("-"):]
for char in body:
self.parse_short_option_char(char)
def try_parse_option(self):
arg = self.arg
if arg == "--":
self.options_done = True
return True
if re.match("--[^-]", arg):
self.parse_long_option(arg)
return True
if re.match("-[^-]", arg):
self.parse_short_option(arg)
return True
return False
def parse_positional(self):
arg = self.arg
if self.positional_index == 0:
self.parsed.api_key = arg
return
if self.positional_index == 1:
self.parsed.site_url = arg
return
if self.positional_index == 2:
self.parsed.user_agent = arg
return
self.error("Unexpected positional argument: {}".format(arg))
def parse_single(self):
if not self.options_done and self.try_parse_option():
return
self.parse_positional()
self.positional_index += 1
def handle_end(self):
if self.end_early:
return
if self.positional_index < 1:
self.error("Missing positional argument: <api-key>")
return
if self.positional_index < 2:
self.error("Missing positional argument: <site-url>")
return
def parse(self):
while not self.done:
self.parse_single()
self.advance()
self.handle_end()
return self.parsed
GOT_TOKEN_MSG = """\
Received token. This token should usually be submitted with the form as the
value of the "g-recaptcha-response" field.
"""
def run(args):
random_ua = False
user_agent = args.user_agent
if args.user_agent is None:
random_ua = True
user_agent = random_user_agent()
if args.debug:
print ("User-agent string: {}".format(user_agent))
uvtoken = get_token(
args.api_key, args.site_url, user_agent,
gui=args.gui, debug=args.debug,
)
print (GOT_TOKEN_MSG)
if random_ua:
print ("Note: The following user-agent string was used:")
print (user_agent)
print ("Token:")
print (uvtoken)
UNEXPECTED_ERR_MSG = """\
An unexpected error occurred. The exception traceback is shown below:
"""
def run_or_exit(args):
if args.debug:
return run(args)
try:
return run(args)
except UserExit:
sys.exit(2)
except UserError:
sys.exit(1)
except KeyboardInterrupt:
sys.exit(2)
except Exception:
print (UNEXPECTED_ERR_MSG)
raise
def main():
args = sys.argv[1:]
parsed = ArgParser(args).parse()
error = parsed.parse_error
if error is not None:
print (error)
print ("For usage information, run: {} --help".format(CMD))
sys.exit(1)
if parsed.help:
usage()
return
if parsed.version:
print (__version__)
return
run_or_exit(parsed)
if __name__ == "__main__":
main()