Skip to content

Commit

Permalink
Merge pull request #2146 from devos50/my_channel_torrents_endpoint
Browse files Browse the repository at this point in the history
Implemented my channel torrents endpoint
  • Loading branch information
whirm committed Apr 29, 2016
2 parents b27f763 + 3dabacb commit 70839ac
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 28 deletions.
79 changes: 57 additions & 22 deletions Tribler/Core/Modules/restapi/my_channel_endpoint.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,45 @@
import json
from twisted.web import server, resource
from twisted.web import http, server, resource
from Tribler.Core.simpledefs import NTFY_CHANNELCAST


class MyChannelEndpoint(resource.Resource):
class MyChannelBaseEndpoint(resource.Resource):
"""
This endpoint is reponsible for handing all requests regarding your channel such as getting and updating
torrents, playlists and rss-feeds.
Base class for all endpoints related to fetching information about my channel.
"""

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

@staticmethod
def return_404(request):
"""
Returns a 404 response code if your channel has not been created.
"""
request.setResponseCode(http.NOT_FOUND)
return "your channel has not been created"


class MyChannelEndpoint(MyChannelBaseEndpoint):
"""
This endpoint is reponsible for handing all requests regarding your channel such as getting and updating
torrents, playlists and rss-feeds.
"""

def getChild(self, path, request):
if path == "overview":
return MyChannelOverviewEndpoint(self.session)
child_handler_dict = {"overview": MyChannelOverviewEndpoint, "torrents": MyChannelTorrentsEndpoint}
if path not in child_handler_dict:
return None

return child_handler_dict[path](self.session)

class MyChannelOverviewEndpoint(resource.Resource):

class MyChannelOverviewEndpoint(MyChannelBaseEndpoint):
"""
Return the name, description and identifier of your channel.
This endpoint returns a 404 HTTP response if you have not created a channel (yet).
Otherwise, it returns the name, description and identifier of your channel.
Example response:
{
Expand All @@ -33,25 +51,42 @@ class MyChannelOverviewEndpoint(resource.Resource):
}
"""

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

def return_404(self, request):
"""
Returns a 404 response code if your channel has not been created.
"""
request.setResponseCode(404)
request.finish()

def render_GET(self, request):
my_channel_id = self.channel_db_handler.getMyChannelId()
if my_channel_id is None:
self.return_404(request)
return server.NOT_DONE_YET
return MyChannelBaseEndpoint.return_404(request)

my_channel = self.channel_db_handler.getChannel(my_channel_id)
request.setHeader('Content-Type', 'text/json')
return json.dumps({'overview': {'identifier': my_channel[1].encode('hex'), 'name': my_channel[2],
'description': my_channel[3]}})


class MyChannelTorrentsEndpoint(MyChannelBaseEndpoint):
"""
Return the torrents in your channel. For each torrent item, the infohash, name and timestamp added is included.
This endpoint returns a 404 HTTP response if you have not created a channel (yet).
Example response:
{
"torrents": [{
"name": "ubuntu-15.04.iso",
"added": 1461840601,
"infohash": "e940a7a57294e4c98f62514b32611e38181b6cae"
}, ...]
}
"""

def render_GET(self, request):
my_channel_id = self.channel_db_handler.getMyChannelId()
if my_channel_id is None:
return MyChannelBaseEndpoint.return_404(request)

req_columns = ['ChannelTorrents.name', 'infohash', 'ChannelTorrents.inserted']
torrents = self.channel_db_handler.getTorrentsFromChannelId(my_channel_id, True, req_columns)

request.setHeader('Content-Type', 'text/json')
torrent_list = []
for torrent in torrents:
torrent_list.append({'name': torrent[0], 'infohash': torrent[1].encode('hex'), 'added': torrent[2]})
return json.dumps({'torrents': torrent_list})
47 changes: 41 additions & 6 deletions Tribler/Test/Core/Modules/RestApi/test_my_channel_endpoints.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,26 @@
import json
from Tribler.Core.Utilities.twisted_thread import deferred
from Tribler.Core.simpledefs import NTFY_CHANNELCAST
from Tribler.Test.Core.Modules.RestApi.base_api_test import AbstractApiTest


class TestMyChannelEndpoints(AbstractApiTest):

def setUp(self, autoload_discovery=True):
super(TestMyChannelEndpoints, self).setUp(autoload_discovery)
self.channel_db_handler = self.session.open_dbhandler(NTFY_CHANNELCAST)

def create_my_channel(self, name, description):
"""
Utility method to create your channel
"""
self.channel_db_handler._get_my_dispersy_cid = lambda: "myfakedispersyid"
self.channel_db_handler.on_channel_from_dispersy('fakedispersyid', None, name, description)
return self.channel_db_handler.getMyChannelId()

def insert_torrents_into_my_channel(self, torrent_list):
self.channel_db_handler.on_torrents_from_dispersy(torrent_list)

@deferred(timeout=10)
def test_my_channel_overview_endpoint_no_my_channel(self):
"""
Expand All @@ -17,13 +33,32 @@ def test_my_channel_overview_endpoint_with_channel(self):
"""
Testing whether the API returns the right JSON data if a channel overview is requested
"""
channel_db_handler = self.session.open_dbhandler(NTFY_CHANNELCAST)

channel_json = {u'overview': {u'name': u'testname', u'description': u'testdescription',
u'identifier': 'fakedispersyid'.encode('hex')}}
channel_db_handler._get_my_dispersy_cid = lambda: "myfakedispersyid"
channel_db_handler.on_channel_from_dispersy('fakedispersyid', None,
channel_json['overview']['name'],
channel_json['overview']['description'])
self.create_my_channel(channel_json[u'overview'][u'name'], channel_json[u'overview'][u'description'])

return self.do_request('mychannel/overview', expected_code=200, expected_json=channel_json)

@deferred(timeout=10)
def test_my_channel_torrents_endpoint_no_my_channel(self):
"""
Testing whether the API returns response code 404 if no channel has been created when fetching torrents
"""
return self.do_request('mychannel/torrents', expected_code=404)

def verify_torrents_json(self, body):
torrents_dict = json.loads(body)
self.assertTrue(torrents_dict["torrents"])
self.assertEqual(len(torrents_dict["torrents"]), 1)

@deferred(timeout=10)
def test_torrents_endpoint_with_channel(self):
"""
Testing whether the API returns the right JSON data if a torrents from a channel are fetched
"""
self.should_check_equality = False
my_channel_id = self.create_my_channel("my channel", "this is a short description")
torrent_list = [[my_channel_id, 1, 1, ('a' * 40).decode('hex'), 1460000000, "ubuntu-torrent.iso", [], []]]
self.insert_torrents_into_my_channel(torrent_list)

return self.do_request('mychannel/torrents', expected_code=200).addCallback(self.verify_torrents_json)
17 changes: 17 additions & 0 deletions doc/Tribler REST API.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ The API has been built using [Twisted Web](http://twistedmatrix.com/trac/wiki/Tw
| Endpoint | Description |
| ---- | --------------- |
| GET /mychannel/overview | Get the name, description and identifier of your channel |
| GET /mychannel/torrents | Get a list of torrents in your channel |

### Settings

Expand All @@ -36,6 +37,22 @@ Returns an overview of the channel of the user. This includes the name, descript
}
```

## `GET /mychannel/torrents`

Returns a list of torrents in your channel. Each torrent item in the list contains the infohash, name and the timestamp of addition of the torrent.

### Example response

```json
{
"torrents": [{
"name": "ubuntu-15.04.iso",
"added": 1461840601,
"infohash": "e940a7a57294e4c98f62514b32611e38181b6cae"
}, ...]
}
```

## `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.
Expand Down

0 comments on commit 70839ac

Please sign in to comment.