Skip to content

Commit

Permalink
Merge pull request #2142 from devos50/get_settings_endpoint
Browse files Browse the repository at this point in the history
READY: Implemented endpoint to fetch Tribler settings
  • Loading branch information
whirm committed Apr 28, 2016
2 parents 677ccac + 9b4c970 commit e46090b
Show file tree
Hide file tree
Showing 6 changed files with 151 additions and 6 deletions.
4 changes: 4 additions & 0 deletions Tribler/Core/Modules/restapi/root_endpoint.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from twisted.web import resource
from Tribler.Core.Modules.restapi.my_channel_endpoint import MyChannelEndpoint
from Tribler.Core.Modules.restapi.settings_endpoint import SettingsEndpoint


class RootEndpoint(resource.Resource):
Expand All @@ -14,3 +15,6 @@ def __init__(self, session):

self.my_channel_endpoint = MyChannelEndpoint(self.session)
self.putChild("mychannel", self.my_channel_endpoint)

self.settings_endpoint = SettingsEndpoint(self.session)
self.putChild("settings", self.settings_endpoint)
66 changes: 66 additions & 0 deletions Tribler/Core/Modules/restapi/settings_endpoint.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import json
import os

from twisted.web import resource

from Tribler.Core.Utilities.configparser import CallbackConfigParser
from Tribler.Core.defaults import tribler_defaults
from Tribler.Core.simpledefs import STATEDIR_GUICONFIG


class SettingsEndpoint(resource.Resource):
"""
This endpoint is reponsible for handing all requests regarding settings and configuration.
A GET request to this endpoint returns all the session settings that can be found in Tribler.
Please note that a port with a value of -1 means that the port is randomly assigned at startup.
Example GET response:
{
"settings": {
"barter_community": {
"enabled": false
},
"libtorrent": {
"anon_listen_port": -1,
...
},
...
}
}
"""

def __init__(self, session):
resource.Resource.__init__(self)
self.session = session

def render_GET(self, request):
"""
Return the settings present in Tribler in a JSON dictionary.
"""
libtribler_settings = self.session.sessconfig.get_config_as_json()

# Load the Tribler GUI configuration file.
configfilepath = os.path.join(self.session.get_state_dir(), STATEDIR_GUICONFIG)
tribler_config = CallbackConfigParser()
tribler_config.read_file(configfilepath, 'utf-8-sig')

def set_default_value(section, option):
if not tribler_config.has_option(section, option):
tribler_config.set(section, option, tribler_defaults.get('Tribler', {}).get(option, None))

# Make sure some default values are present in the JSON being returned
set_default_value('Tribler', 'showsaveas')
set_default_value('Tribler', 'default_number_hops')
set_default_value('Tribler', 'default_anonymity_enabled')
set_default_value('Tribler', 'default_safeseeding_enabled')
set_default_value('Tribler', 'maxuploadrate')
set_default_value('Tribler', 'maxdownloadrate')

tribler_settings = tribler_config.get_config_as_json()

# Merge the configuration of libtribler and the Tribler configuration
settings_dict = libtribler_settings.copy()
settings_dict.update(tribler_settings)

return json.dumps({"settings": settings_dict})
20 changes: 16 additions & 4 deletions Tribler/Core/Utilities/configparser.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,7 @@ def get(self, section, option, literal_eval=True):
value = RawConfigParser.get(self, section, option) if RawConfigParser.has_option(
self, section, option) else None
if literal_eval:
try:
value = ast.literal_eval(value)
except (ValueError, SyntaxError):
pass
return CallbackConfigParser.get_literal_value(value)
return value

def copy(self):
Expand Down Expand Up @@ -73,3 +70,18 @@ def write(self, fp):
if key != u"__name__":
fp.write(u"%s = %s\n" % (key, unicode(value).replace(u'\n', u'\n\t')))
fp.write(u"\n")

@staticmethod
def get_literal_value(value):
try:
return ast.literal_eval(value)
except (ValueError, SyntaxError):
return value

def get_config_as_json(self):
json_dict = {}
for section in self.sections():
json_dict[section] = {}
for option, value in self.items(section):
json_dict[section][option] = CallbackConfigParser.get_literal_value(value)
return json_dict
4 changes: 3 additions & 1 deletion Tribler/Test/Core/Modules/RestApi/base_api_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,17 @@ def __init__(self, *args, **kwargs):
super(AbstractApiTest, self).__init__(*args, **kwargs)
self.expected_response_code = 200
self.expected_response_json = None
self.should_check_equality = True

def setUpPreSession(self):
super(AbstractApiTest, self).setUpPreSession()
self.config.set_http_api_enabled(True)
self.config.set_megacache(True)

def parse_body(self, body):
if body is not None:
if body is not None and self.should_check_equality:
self.assertDictEqual(json.loads(body), self.expected_response_json)
return body

def parse_response(self, response):
self.assertEqual(response.code, self.expected_response_code)
Expand Down
34 changes: 34 additions & 0 deletions Tribler/Test/Core/Modules/RestApi/test_settings_endpoint.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import json
import os

from Tribler.Core.Utilities.configparser import CallbackConfigParser
from Tribler.Core.Utilities.twisted_thread import deferred
from Tribler.Test.Core.Modules.RestApi.base_api_test import AbstractApiTest


class TestSettingsEndpoint(AbstractApiTest):

def verify_settings(self, settings):
"""
Verify that the expected sections are present.
"""
check_section = ['barter_community', 'libtorrent', 'mainline_dht', 'torrent_store', 'general', 'Tribler',
'video', 'upgrader', 'torrent_checking', 'allchannel_community', 'tunnel_community',
'http_api', 'torrent_collecting', 'dispersy', 'multichain', 'watch_folder', 'search_community',
'metadata']
settings_json = json.loads(settings)
self.assertTrue(settings_json['settings'])
for section in check_section:
self.assertTrue(settings_json['settings'][section])

@deferred(timeout=10)
def test_get_settings(self):
"""
Testing whether the API returns a correct settings dictionary when the settings are requested
"""
self.should_check_equality = False
tribler_config = CallbackConfigParser()
tribler_config.add_section('Tribler')
tribler_config.write_file(os.path.join(self.session.get_state_dir(), 'tribler.conf'))

return self.do_request('settings', expected_code=200).addCallback(self.verify_settings)
29 changes: 28 additions & 1 deletion doc/Tribler REST API.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,13 @@ The API has been built using [Twisted Web](http://twistedmatrix.com/trac/wiki/Tw

| Endpoint | Description |
| ---- | --------------- |
| [GET /mychannel/overview](/v3_resources/blocks.md#get-usersloginblocks) | Get the name, description and identifier of your channel |
| GET /mychannel/overview | Get the name, description and identifier of your channel |

### Settings

| Endpoint | Description |
| ---- | --------------- |
| GET /settings | Get settings used by the current Tribler session |

## `GET /mychannel/overview`

Expand All @@ -29,3 +35,24 @@ Returns an overview of the channel of the user. This includes the name, descript
}
}
```

## `GET /settings`

Returns a dictionary with the settings that the current Tribler session is using. Note that the response below is not the complete settings dictionary returned since that would be too large to display here.

### Example response

```
{
"settings": {
"barter_community": {
"enabled": false
},
"libtorrent": {
"anon_listen_port": 55638,
...
},
...
}
}
```

0 comments on commit e46090b

Please sign in to comment.