XDM icon indicating copy to clipboard operation
XDM copied to clipboard

Captcha in plugin config

Open Torf opened this issue 11 years ago • 3 comments

Hi,

I want to create an Indexer Plugin that requires :

  • to enter Username and password
  • to get a captcha image (get request a .jpg)
  • to enter the captcha value (what letters I can see in the captcha)
  • to connect in order to get a unlimited time cookie (so this operation will be never do again)

Do you have any idea of how to do this please ?

Torf avatar Nov 24 '13 01:11 Torf

oh okay its a like a "do you want to give this thing permission to your account" thing ?

there is a function that lets you inject javascript/html into the settings page getConfigHtml

https://github.com/lad1337/XDM-main-plugin-repo/blob/master/Newznab/Newznab.py#L174

technically you can do whatever you want with this... like if the cookie data is not set

  1. create some html and js with the image from the other server (maybe encode the image into bas64)
  2. return that html
  3. call a ajax function on your plugin with the user input
  4. save the response / cookie in a config value OR save it in a hidden config value

hidden config fields are defined with _hidden_config https://github.com/lad1337/XDM/blob/master/corePlugins/system/System.py#L66 and accesed with e.g. self.hc.cookie https://github.com/lad1337/XDM/blob/master/xdm/web/wizard.py#L62

or open an iframe and get the data with javascript

but i noticed that the html you send is hidden ... either unhide it with javascript for now or wait until i make is visible by default :P

                 <div style="display: none;">
                {{plugin.getConfigHtml()}}
                </div>

https://github.com/lad1337/XDM/blob/master/html/templates/settings.html#L44

also note that you can have multiple instances of your plugin and you dont want to set it on the wrong instance what i did was the function is a specific function only for that instance ->

function newsznab_""" + self.instance + """_spreadCategories(data){`

https://github.com/lad1337/XDM-main-plugin-repo/blob/master/Newznab/Newznab.py#L176

and to get the correct fields

$('#""" + helper.idSafe(self.name) + """ input[name$="'+k+'"]').val(i)

https://github.com/lad1337/XDM-main-plugin-repo/blob/master/Newznab/Newznab.py#L179

the helper.idSafe(self.name)is used during rendering on the plugin settings pane https://github.com/lad1337/XDM/blob/master/html/templates/settings.html#L37

also interesting to know is that you can define a function that should be called if an ajax function was called https://github.com/lad1337/XDM-main-plugin-repo/blob/master/Newznab/Newznab.py#L168-171

your whole procedure might just work like the gather categories (in the newsnab plugin) with the exception of getting an image first .. displaying that and then sending the captcha text with ajax to the plugin and then calling some hide function on the image and populating the values in the fields (e.g. cookie_info)

as i said you could generate this html with the image dynamically meaning only if the cookie info is not given or does not work making it a one time thing

how you can use this cookie information i have no idea ...

edit: sometimes i am surprised what is implemented ... i need a documentation :/

lad1337 avatar Nov 25 '13 17:11 lad1337

Whoah, it's so great ! Yes, a few documentation could help :P

Thanks you for your answer, it will help me a lot :)

I think I can use a .js file with getConfigHtml ?

def getConfigHtml(self):
    with open("config.js", "r") as f:
        js = f.read()
    return js

edit: Oops, it's a HTML file, not a JS one.

edit2: oh no i can't, cause' I need python functions as idSafe :/

Torf avatar Nov 25 '13 17:11 Torf

sure you can but keep in mind that this is not plain javascript but rather html(@edit1) and you can embed javascript you could inject a script tag with an url ... you know you can access the files

you could also use a jinja template i use this in the TV plugin https://github.com/lad1337/XDM-main-plugin-repo/blob/develop/TV/TV.py#L63-66 but i expect to get a teplate string there you would need to render it

something like this


from jinja2.environment import Environment
from jinja2.loaders import FileSystemLoader, DictLoader

def getConfigHtml(self):
    with open("config.ji2", "r") as f: # the filename does not matter
        tpl = f.read()
    env = Environment(loader=DictLoader({'this': tpl}), extensions=['jinja2.ext.i18n'])
    env.install_gettext_callables(_, ngettext, newstyle=True) # might not need this
    env.filters['relativeTime'] = helper.reltime # might not need this
    env.filters['idSafe'] = helper.idSafe  # this looks good
    env.filters['derefMe'] = helper.dereferMe # might want this for external links
    env.filters['derefMeText'] = helper.dereferMeText # or this for external links that are in a bunch of text
    elementTemplate = env.get_template('this') # now you have the template

    return elementTemplate.render(plugin_name=self.name, # pass some variables
                                                 plugin=self # or why not the whole plugin instance
                                                 )

as you can see that is a lot ... well its just creating a jinja2 enviroment and rending the template string its also a bit fish since you read the file and but that contens into a dict and use the dict loader to get the current template ... might be easier to use the FileSystemLoader

fyi this code is used in the render method of each element (the core data structure in XDM) edit: removed unneeded code

lad1337 avatar Nov 25 '13 18:11 lad1337