Welcome to the LimeSurvey Community Forum

Ask the community, share ideas, and connect with other LimeSurvey users!

Exporting survey, participants and responses using Remote Control

  • cacorns
  • cacorns's Avatar Topic Author
  • Offline
  • New Member
  • New Member
More
5 years 3 weeks ago #182416 by cacorns
I'd like to use only Remote Control API to export all Survey information, including participant response. I know that we cannot export all/import all with Remote Control using only export_xxx and import_xxx methods. So I want to know if using the other methods I can do that.

Thanks in advance!
The topic has been locked.
  • tpartner
  • tpartner's Avatar
  • Online
  • LimeSurvey Community Team
  • LimeSurvey Community Team
More
5 years 3 weeks ago - 5 years 3 weeks ago #182420 by tpartner
All core remote control methods are listed here - api.limesurvey.org/classes/remotecontrol_handle.html

Denis has written a sample plugin to show how to extend the remote control API - extensions.sondages.pro/development-and-...d-remotecontrol-api/

Cheers,
Tony Partner

Solutions, code and workarounds presented in these forums are given without any warranty, implied or otherwise.
Last edit: 5 years 3 weeks ago by tpartner.
The following user(s) said Thank You: DenisChenu, cacorns
The topic has been locked.
  • cacorns
  • cacorns's Avatar Topic Author
  • Offline
  • New Member
  • New Member
More
5 years 3 weeks ago - 5 years 3 weeks ago #182710 by cacorns
Ok. It appears being promising. I've cloned repository into
Code:
plugins
subdir, but I can't call functions of RemoteControlHandler class, like
Code:
get_me
. Is it necessary to take any other measure?
Last edit: 5 years 3 weeks ago by cacorns.
The topic has been locked.
  • DenisChenu
  • DenisChenu's Avatar
  • Offline
  • LimeSurvey Community Team
  • LimeSurvey Community Team
More
5 years 3 weeks ago #182717 by DenisChenu
You need to use a different url (the url for the plugins) for the new function.

It's a reason why i think remote_control must have a way to add function, and all existing function must move to new plugins (exe: rcSurveyData_rc, rcUserManagement, rcSurveyManagment etc …) offering some functions.

Assistance on LimeSurvey forum and LimeSurvey core development are on my free time.
I'm not a LimeSurvey GmbH member, professional service on demand , plugin development .
I don't answer to private message.
The topic has been locked.
  • cacorns
  • cacorns's Avatar Topic Author
  • Offline
  • New Member
  • New Member
More
5 years 2 weeks ago #182767 by cacorns
I've changed the URL for the url for the plugins and the function is called now but can't instantiate the session key. Is it possible to use the url for the plugins only when calling the plugins functions? By the way I've put the code
Code:
'request' => array(
      'class'=>'LSHttpRequest',
      'noCsrfValidationRoutes'=>array(
        'remotecontrol',
        'plugins/direct'
      ),  
    ),

in config.php but it not works.

Only to clarify, I'm using LimeSurvey version 2.7.
The topic has been locked.
  • DenisChenu
  • DenisChenu's Avatar
  • Offline
  • LimeSurvey Community Team
  • LimeSurvey Community Team
More
5 years 2 weeks ago #182770 by DenisChenu
With 2.72 : it must work with /plugins/unsecure?plugin=extendRemoteControl&function=action no need to hack request.

What do you have for error ? Did you activated global json rpc ?
And yes : same function is used : then you can create the key with core link and use updated link for new function.

Assistance on LimeSurvey forum and LimeSurvey core development are on my free time.
I'm not a LimeSurvey GmbH member, professional service on demand , plugin development .
I don't answer to private message.
The following user(s) said Thank You: cacorns
The topic has been locked.
  • cacorns
  • cacorns's Avatar Topic Author
  • Offline
  • New Member
  • New Member
More
5 years 2 weeks ago #182790 by cacorns
Thanks for new response Denis. I still can make extendRemoteControl works. So I decided put a bit of code on this discussion.

I'm going step by step.

First of all I'm using python jsonrpc_requests package, to execute transactions with RemoteControl.

What I do is initialize a connection with the server with
Code:
s = Server('limesurvey_installation/index.php/admin/remotecontrol')

and then, define session_key variable with
Code:
session_key = s.get_session_key(<user>,  <password>)

After that I already can call RemoteControl functions. Ok.

Now, following your tips, I'm trying to redefine the url to
Code:
limesurvey_installation/index.php/plugins/unsecure?plugin=extendRemoteControl&amp;function=action

in order to access RemoteControlHandler functions.

Hacking Server class the line that defines s.request attribute is
Code:
self.request = functools.partial(self.session.post, url, **requests_kwargs)

so I'm trying to define a new url with
Code:
s.request = functools.partial(s.session.post, url='limesurvey_installation/index.php/plugins/unsecure?plugin=extendRemoteControl&amp;function=action')

and then calling the function get_me of RemoteControlHandler, with
Code:
s.get_me(s.session_key)

Now I receive this error:
Code:
File "python3.5/site-packages/jsonrpc_requests/jsonrpc.py", line 104, in __call__
    return self.__request_method(self.__method_name, args, kwargs)
  File "python3.5/site-packages/jsonrpc_requests/jsonrpc.py", line 88, in __request
    return self.send_request(method_name, is_notification, args or kwargs)
  File "python3.5/site-packages/jsonrpc_requests/jsonrpc.py", line 47, in send_request
    raise TransportError('Cannot deserialize response body', value_error)
jsonrpc_requests.jsonrpc.TransportError: ('Cannot deserialize response body', JSONDecodeError('Expecting value: line 1 column 1 (char 0)',))

---

Below is the Server class constructor:
Code:
class Server(object):
    """A connection to a HTTP JSON-RPC server, backed by requests"""
 
    def __init__(self, url, session=None, **requests_kwargs):
        self.session = session or requests.Session()
        self.session.headers.update({
            'Content-Type': 'application/json',
            'Accept': 'application/json-rpc',
        })
        self.request = functools.partial(self.session.post, url, **requests_kwargs)
The topic has been locked.
  • cacorns
  • cacorns's Avatar Topic Author
  • Offline
  • New Member
  • New Member
More
5 years 2 weeks ago #182863 by cacorns
I think the last post was a bit confusing. I'm going to try put another way. Now in a different approach, following the Python 2 example code for calling RPC API in official example codes .

Firstly I get the session key, logging in API:
Code:
req = urllib2.Request(url='https://myurl/index.php/admin/remotecontrol',\
                          data='{\"method\":\"get_session_key\",\"params\":[\"admin\",\"mypassword\"],\"id\":1}')
req.add_header('content-type', 'application/json')
req.add_header('connection', 'Keep-Alive')
 
f = urllib2.urlopen(req)
myreturn = f.read()
j=json.loads(myreturn)
session_key = j['result']

After that, I tested calling a function of RPC core and that works.

So what I understood that I have to do instantiate a new Request, now with the new url, but with the same session_key as of the last request.
Code:
req = urllib2.Request(url='http://myurl/index.php/plugins/unsecure?plugin=extendRemoteControl&amp;function=get_me', data='{\"method\":\"get_me\",\"params\":[\"<session_key>\"],\"id\":1}')
req.add_header('content-type', 'application/json')
req.add_header('connection', 'Keep-Alive')
 
f = urllib2.urlopen(req)
myreturn = f.read()

Here myreturn is empty. And whe trying to json loads with
Code:
j=json.loads(myreturn)
get error:
Code:
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/json/__init__.py", line 339, in loads
    return _default_decoder.decode(s)
  File "/usr/lib/python2.7/json/decoder.py", line 364, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/lib/python2.7/json/decoder.py", line 382, in raw_decode
    raise ValueError("No JSON object could be decoded")
ValueError: No JSON object could be decoded

So, calling with a new request, with new url, but same session_key seems doesn't work. Is there some missing part I'm not doing?
The topic has been locked.
  • DenisChenu
  • DenisChenu's Avatar
  • Offline
  • LimeSurvey Community Team
  • LimeSurvey Community Team
More
5 years 2 weeks ago #182913 by DenisChenu

cacorns wrote: So, calling with a new request, with new url, but same session_key seems doesn't work. Is there some missing part I'm not doing?

Last time i tested (with php script) : it work …
With updating url betwwen each call or not …

But using get_session_key with the new URL MUST work too.

Best way to track done
1. Show public API to true (in global setttings)
2. Go to plugin configuration : you muts have the link to the public API
3. Click on the link after «The API was published on:»
4. You must see something like this

Assistance on LimeSurvey forum and LimeSurvey core development are on my free time.
I'm not a LimeSurvey GmbH member, professional service on demand , plugin development .
I don't answer to private message.
The following user(s) said Thank You: cacorns
The topic has been locked.
  • cacorns
  • cacorns's Avatar Topic Author
  • Offline
  • New Member
  • New Member
More
5 years 2 weeks ago #182927 by cacorns
Thanks again Denis.

To clarify more, the RPC interface enabled in global sessions was already set to JSON-RPC.
I already have published API too, to list functions.
The extendRemoteControl plugin is in path /plugins/extendRemoteControl.

Only installing the plugin, the new functions should appear when displaying API functions in the site? This is not working.

I have to introduce the link
Code:
/plugins/unsecure?plugin=extendRemoteControl&amp;function=action

in some part of the files (extendRemoteControl.php/RemoteControlHandler.php)?

Maybe in getPluginSettings function?
Code:
   /**
     * Update the information content to show the good link
     * @params getValues
     */
    public function getPluginSettings($getValues=true)
    {
        $this->settings['information']['content']="";
        /* test if plugins/unsecure is in noCsrfValidationRoutes : in internal for compatible LimeSurvey version */
        if(in_array('plugins/unsecure',App()->request->noCsrfValidationRoutes))
        {
            $url=$this->api->createUrl('plugins/unsecure', array('plugin' => $this->getName(), 'function' => 'action'));
        }
        else
        {
            $this->settings['information']['content'].="<p class='alert alert-warning'>You need to add 'plugins/direct' to noCsrfValidationRoutes in your config file</p>";
            $url=$this->api->createUrl('plugins/direct', array('plugin' => $this->getName(), 'function' => 'action'));
        }
        if(Yii::app()->getConfig("RPCInterface")=='json')
        {
            $this->settings['information']['content'].="<p class='alert alert-info'>".sprintf(gT("The remote url was <code>%s</code>",'unescaped'),$url)."</p>";
            if(Yii::app()->getConfig("rpc_publish_api") == true)
            {
                if(floatval(Yii::app()->getConfig("versionnumber"))>=2.5)
                {
                    $url=$this->api->createUrl('admin/pluginhelper', array('plugin' => $this->getName(), 'sa'=>'sidebody','method'=>'actionIndex','surveyId'=>0));
                }
                $this->settings['information']['content'].="<p class='alert alert-warning'>".sprintf(gT("The API was published on <a href='%s'>%s</a>",'unescaped'),$url,$url)."</p>";
            }
        }
        else
        {
            $this->settings['information']['content']="<p class='alert alert-danger'>".gT("JSON RPC is not active.")."</p>";
        }
        return parent::getPluginSettings($getValues);
    }
The topic has been locked.
  • DenisChenu
  • DenisChenu's Avatar
  • Offline
  • LimeSurvey Community Team
  • LimeSurvey Community Team
More
5 years 2 weeks ago #182932 by DenisChenu
In the configure part : you must have



If not : there are an issue.
If yes : click on the link

Assistance on LimeSurvey forum and LimeSurvey core development are on my free time.
I'm not a LimeSurvey GmbH member, professional service on demand , plugin development .
I don't answer to private message.
The following user(s) said Thank You: cacorns
The topic has been locked.
  • cacorns
  • cacorns's Avatar Topic Author
  • Offline
  • New Member
  • New Member
More
5 years 2 weeks ago - 5 years 2 weeks ago #182938 by cacorns
Oh guy, shame on me. It was only configuring the plugin. And I hacking the code like a crazy. Sorry. But many thanks to take this discussion until the end.
Last edit: 5 years 2 weeks ago by cacorns.
The topic has been locked.

Lime-years ahead

Online-surveys for every purse and purpose