Example #1
0
    def __init__(self, session):
        BaseChannelsEndpoint.__init__(self, session)

        child_handler_dict = {"subscribed": ChannelsSubscribedEndpoint, "discovered": ChannelsDiscoveredEndpoint,
                              "popular": ChannelsPopularEndpoint}
        for path, child_cls in child_handler_dict.iteritems():
            self.putChild(path, child_cls(self.session))
    def render_POST(self, request):
        """
        .. http:post:: /channels/discovered/(string: channelid)/playlists/(int: playlistid)

        Edit a specific playlist. The new name and description should be passed as parameter.

            **Example request**:

            .. sourcecode:: none

                curl -X POST http://localhost:8085/channels/discovered/abcd/playlists/3
                --data "name=test&description=my test description"

            **Example response**:

            .. sourcecode:: javascript

                {
                    "modified": True
                }

            :statuscode 404: if the specified channel (community) or playlist does not exist or if the
            name and description parameters are missing.
        """
        parameters = http.parse_qs(request.content.read(), 1)

        if 'name' not in parameters or len(parameters['name']) == 0:
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": "name parameter missing"})

        if 'description' not in parameters or len(
                parameters['description']) == 0:
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": "description parameter missing"})

        channel_info = self.get_channel_from_db(self.cid)
        if channel_info is None:
            return ChannelsPlaylistsEndpoint.return_404(request)

        playlist = self.channel_db_handler.getPlaylist(self.playlist_id,
                                                       ['Playlists.id'])
        if playlist is None:
            return BaseChannelsEndpoint.return_404(
                request, message="this playlist cannot be found")

        channel_community = self.get_community_for_channel_id(channel_info[0])
        if channel_community is None:
            return BaseChannelsEndpoint.return_404(
                request,
                message="the community for the specific channel cannot be found"
            )

        channel_community.modifyPlaylist(
            playlist[0], {
                'name': parameters['name'][0],
                'description': parameters['description'][0]
            })

        return json.dumps({"modified": True})
    def __init__(self, session, cid):
        BaseChannelsEndpoint.__init__(self, session)
        self.cid = bytes(cid.decode('hex'))

        child_handler_dict = {"torrents": ChannelsTorrentsEndpoint, "rssfeeds": ChannelsRssFeedsEndpoint,
                              "playlists": ChannelsPlaylistsEndpoint, "recheckfeeds": ChannelsRecheckFeedsEndpoint}
        for path, child_cls in child_handler_dict.iteritems():
            self.putChild(path, child_cls(session, self.cid))
    def render_DELETE(self, request):
        """
        .. http:delete:: /channels/discovered/(string: channelid)/playlists/(int: playlistid)/(string: infohash)

        Remove a torrent with a specified infohash from a specified playlist.

            **Example request**:

            .. sourcecode:: none

                curl -X DELETE http://localhost:8085/channels/discovered/abcd/playlists/3/abcdef

            **Example response**:

            .. sourcecode:: javascript

                {
                    "removed": True
                }

            :statuscode 404: if the specified channel/playlist/torrent does not exist.
        """
        channel_info = self.get_channel_from_db(self.cid)
        if channel_info is None:
            return ChannelsPlaylistsEndpoint.return_404(request)

        playlist = self.channel_db_handler.getPlaylist(
            self.playlist_id, ['Playlists.dispersy_id'])
        if playlist is None:
            return BaseChannelsEndpoint.return_404(
                request, message="this playlist cannot be found")

        channel_community = self.get_community_for_channel_id(channel_info[0])
        if channel_community is None:
            return BaseChannelsEndpoint.return_404(
                request,
                message="the community for the specific channel cannot be found"
            )

        # Check whether this torrent is present in this playlist and if so, get the dispersy ID
        torrent_dispersy_id = -1
        for torrent in self.channel_db_handler.getTorrentsFromPlaylist(
                self.playlist_id,
            ["infohash", "PlaylistTorrents.dispersy_id"]):
            if torrent[0] == self.infohash:
                torrent_dispersy_id = torrent[1]
                break

        if torrent_dispersy_id == -1:
            request.setResponseCode(http.NOT_FOUND)
            return json.dumps(
                {"error": "this torrent is not in your playlist"})

        channel_community.remove_playlist_torrents(int(self.playlist_id),
                                                   [torrent_dispersy_id])

        return json.dumps({"removed": True})
    def __init__(self, session, cid):
        BaseChannelsEndpoint.__init__(self, session)
        self.cid = bytes(cid.decode('hex'))

        child_handler_dict = {"torrents": ChannelsTorrentsEndpoint, "rssfeeds": ChannelsRssFeedsEndpoint,
                              "playlists": ChannelsPlaylistsEndpoint, "recheckfeeds": ChannelsRecheckFeedsEndpoint,
                              "mdblob": ChannelsDiscoveredExportEndpoint}
        for path, child_cls in child_handler_dict.iteritems():
            self.putChild(path, child_cls(session, self.cid))
Example #6
0
    def render_PUT(self, request):
        """
        .. http:put:: /channels/discovered/(string: channelid)/playlists/(int: playlistid)/(string: infohash)

        Add a torrent with a specified infohash to a specified playlist. The torrent that is added to the playlist,
        should be present in the channel.

            **Example request**:

            .. sourcecode:: none

                curl -X PUT http://localhost:8085/channels/discovered/abcd/playlists/3/abcdef

            **Example response**:

            .. sourcecode:: javascript

                {
                    "added": True
                }

            :statuscode 404: if the specified channel/playlist/torrent does not exist.
            :statuscode 409: if the specified torrent is already in the specified playlist.
        """
        channel_info = self.get_channel_from_db(self.cid)
        if channel_info is None:
            return ChannelsPlaylistsEndpoint.return_404(request)

        channel_community = self.get_community_for_channel_id(channel_info[0])
        if channel_community is None:
            return BaseChannelsEndpoint.return_404(request,
                                                   message="the community for the specific channel cannot be found")

        playlist = self.channel_db_handler.getPlaylist(self.playlist_id, ['Playlists.dispersy_id'])
        if playlist is None:
            return BaseChannelsEndpoint.return_404(request, message="this playlist cannot be found")

        # Check whether this torrent is present in your channel
        torrent_in_channel = False
        for torrent in self.channel_db_handler.getTorrentsFromChannelId(channel_info[0], True, ["infohash"]):
            if torrent[0] == self.infohash:
                torrent_in_channel = True
                break

        if not torrent_in_channel:
            return BaseChannelsEndpoint.return_404(request, message="this torrent is not available in your channel")

        # Check whether this torrent is not already present in this playlist
        for torrent in self.channel_db_handler.getTorrentsFromPlaylist(self.playlist_id, ["infohash"]):
            if torrent[0] == self.infohash:
                request.setResponseCode(http.CONFLICT)
                return json.dumps({"error": "this torrent is already in your playlist"})

        channel_community.create_playlist_torrents(int(self.playlist_id), [self.infohash])

        return json.dumps({"added": True})
    def render_PUT(self, request):
        """
        .. http:put:: /channels/discovered/(string: channelid)/playlists/(int: playlistid)/(string: infohash)

        Add a torrent with a specified infohash to a specified playlist. The torrent that is added to the playlist,
        should be present in the channel.

            **Example request**:

            .. sourcecode:: none

                curl -X PUT http://localhost:8085/channels/discovered/abcd/playlists/3/abcdef

            **Example response**:

            .. sourcecode:: javascript

                {
                    "added": True
                }

            :statuscode 404: if the specified channel/playlist/torrent does not exist.
            :statuscode 409: if the specified torrent is already in the specified playlist.
        """
        channel_info = self.get_channel_from_db(self.cid)
        if channel_info is None:
            return ChannelsPlaylistsEndpoint.return_404(request)

        channel_community = self.get_community_for_channel_id(channel_info[0])
        if channel_community is None:
            return BaseChannelsEndpoint.return_404(request,
                                                   message="the community for the specific channel cannot be found")

        playlist = self.channel_db_handler.getPlaylist(self.playlist_id, ['Playlists.dispersy_id'])
        if playlist is None:
            return BaseChannelsEndpoint.return_404(request, message="this playlist cannot be found")

        # Check whether this torrent is present in your channel
        torrent_in_channel = False
        for torrent in self.channel_db_handler.getTorrentsFromChannelId(channel_info[0], True, ["infohash"]):
            if torrent[0] == self.infohash:
                torrent_in_channel = True
                break

        if not torrent_in_channel:
            return BaseChannelsEndpoint.return_404(request, message="this torrent is not available in your channel")

        # Check whether this torrent is not already present in this playlist
        for torrent in self.channel_db_handler.getTorrentsFromPlaylist(self.playlist_id, ["infohash"]):
            if torrent[0] == self.infohash:
                request.setResponseCode(http.CONFLICT)
                return json.dumps({"error": "this torrent is already in your playlist"})

        channel_community.create_playlist_torrents(int(self.playlist_id), [self.infohash])

        return json.dumps({"added": True})
Example #8
0
    def __init__(self, session):
        BaseChannelsEndpoint.__init__(self, session)

        child_handler_dict = {
            "subscribed": ChannelsSubscribedEndpoint,
            "discovered": ChannelsDiscoveredEndpoint,
            "popular": ChannelsPopularEndpoint
        }
        for path, child_cls in child_handler_dict.iteritems():
            self.putChild(path, child_cls(self.session))
    def render_POST(self, request):
        """
        .. http:post:: /channels/discovered/(string: channelid)/playlists/(int: playlistid)

        Edit a specific playlist. The new name and description should be passed as parameter.

            **Example request**:

            .. sourcecode:: none

                curl -X POST http://localhost:8085/channels/discovered/abcd/playlists/3
                --data "name=test&description=my test description"

            **Example response**:

            .. sourcecode:: javascript

                {
                    "modified": True
                }

            :statuscode 404: if the specified channel (community) or playlist does not exist or if the
            name and description parameters are missing.
        """
        parameters = http.parse_qs(request.content.read(), 1)

        if 'name' not in parameters or len(parameters['name']) == 0:
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": "name parameter missing"})

        if 'description' not in parameters or len(parameters['description']) == 0:
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": "description parameter missing"})

        channel_info = self.get_channel_from_db(self.cid)
        if channel_info is None:
            return ChannelsPlaylistsEndpoint.return_404(request)

        playlist = self.channel_db_handler.getPlaylist(self.playlist_id, ['Playlists.id'])
        if playlist is None:
            return BaseChannelsEndpoint.return_404(request, message="this playlist cannot be found")

        channel_community = self.get_community_for_channel_id(channel_info[0])
        if channel_community is None:
            return BaseChannelsEndpoint.return_404(request,
                                                   message="the community for the specific channel cannot be found")

        channel_community.modifyPlaylist(playlist[0], {'name': parameters['name'][0],
                                                       'description': parameters['description'][0]})

        return json.dumps({"modified": True})
    def render_DELETE(self, request):
        """
        .. http:delete:: /channels/discovered/(string: channelid)/playlists/(int: playlistid)/(string: infohash)

        Remove a torrent with a specified infohash from a specified playlist.

            **Example request**:

            .. sourcecode:: none

                curl -X DELETE http://localhost:8085/channels/discovered/abcd/playlists/3/abcdef

            **Example response**:

            .. sourcecode:: javascript

                {
                    "removed": True
                }

            :statuscode 404: if the specified channel/playlist/torrent does not exist.
        """
        channel_info = self.get_channel_from_db(self.cid)
        if channel_info is None:
            return ChannelsPlaylistsEndpoint.return_404(request)

        playlist = self.channel_db_handler.getPlaylist(self.playlist_id, ['Playlists.dispersy_id'])
        if playlist is None:
            return BaseChannelsEndpoint.return_404(request, message="this playlist cannot be found")

        channel_community = self.get_community_for_channel_id(channel_info[0])
        if channel_community is None:
            return BaseChannelsEndpoint.return_404(request,
                                                   message="the community for the specific channel cannot be found")

        # Check whether this torrent is present in this playlist and if so, get the dispersy ID
        torrent_dispersy_id = -1
        for torrent in self.channel_db_handler.getTorrentsFromPlaylist(self.playlist_id,
                                                                       ["infohash", "PlaylistTorrents.dispersy_id"]):
            if torrent[0] == self.infohash:
                torrent_dispersy_id = torrent[1]
                break

        if torrent_dispersy_id == -1:
            request.setResponseCode(http.NOT_FOUND)
            return json.dumps({"error": "this torrent is not in your playlist"})

        channel_community.remove_playlist_torrents(int(self.playlist_id), [torrent_dispersy_id])

        return json.dumps({"removed": True})
    def render_DELETE(self, request):
        """
        .. http:delete:: /channels/discovered/(string: channelid)/playlists/(int: playlistid)

        Remove a playlist with a specified playlist id.

            **Example request**:

            .. sourcecode:: none

                curl -X DELETE http://localhost:8085/channels/discovered/abcd/playlists/3

            **Example response**:

            .. sourcecode:: javascript

                {
                    "removed": True
                }

            :statuscode 404: if the specified channel (community) or playlist does not exist
        """
        channel_info = self.get_channel_from_db(self.cid)
        if channel_info is None:
            return ChannelsPlaylistsEndpoint.return_404(request)

        playlist = self.channel_db_handler.getPlaylist(
            self.playlist_id, ['Playlists.dispersy_id', 'Playlists.id'])
        if playlist is None:
            return BaseChannelsEndpoint.return_404(
                request, message="this playlist cannot be found")

        channel_community = self.get_community_for_channel_id(channel_info[0])
        if channel_community is None:
            return BaseChannelsEndpoint.return_404(
                request,
                message="the community for the specific channel cannot be found"
            )

        # Remove all torrents from this playlist
        playlist_torrents = self.channel_db_handler.get_torrent_ids_from_playlist(
            playlist[1])
        channel_community.remove_playlist_torrents(
            playlist[0], [dispersy_id for dispersy_id, in playlist_torrents])

        # Remove the playlist itself
        channel_community.remove_playlists([playlist[0]])

        return json.dumps({"removed": True})
    def render_DELETE(self, request):
        """
        .. http:delete:: /channels/discovered/(string: channelid)/torrents/(string: torrent infohash)

        Remove a torrent with a given infohash from a given channel.

            **Example request**:

            .. sourcecode:: none

                curl -X DELETE http://localhost:8085/channels/discovered/abcdefg/torrents/
                97d2d8f5d37e56cfaeaae151d55f05b077074779

            **Example response**:

            .. sourcecode:: javascript

                {
                    "removed": True
                }

            :statuscode 404: if the channel is not found or if the torrent is not found in the specified channel
        """
        channel_info = self.get_channel_from_db(self.cid)
        if channel_info is None:
            return ChannelsTorrentsEndpoint.return_404(request)

        torrent_db_columns = [
            'Torrent.torrent_id', 'infohash', 'Torrent.name', 'length',
            'Torrent.category', 'num_seeders', 'num_leechers',
            'last_tracker_check', 'ChannelTorrents.dispersy_id'
        ]
        torrent_info = self.channel_db_handler.getTorrentFromChannelId(
            channel_info[0], self.path.decode('hex'), torrent_db_columns)

        if torrent_info is None:
            return BaseChannelsEndpoint.return_404(request,
                                                   message=UNKNOWN_TORRENT_MSG)

        channel_community = self.get_community_for_channel_id(channel_info[0])
        if channel_community is None:
            return BaseChannelsEndpoint.return_404(
                request, message=UNKNOWN_COMMUNITY_MSG)

        channel_community.remove_torrents([
            torrent_info[8]
        ])  # the 8th index is the dispersy id of the channel torrent

        return json.dumps({"removed": True})
Example #13
0
 def _on_add_failed(failure):
     failure.trap(ValueError, DuplicateTorrentFileError,
                  SchemeNotSupported)
     self._logger.exception(failure.value)
     request.write(
         BaseChannelsEndpoint.return_500(self, request, failure.value))
     request.finish()
    def render_DELETE(self, request):
        """
        .. http:delete:: /channels/discovered/(string: channelid)/playlists/(int: playlistid)

        Remove a playlist with a specified playlist id.

            **Example request**:

            .. sourcecode:: none

                curl -X DELETE http://localhost:8085/channels/discovered/abcd/playlists/3

            **Example response**:

            .. sourcecode:: javascript

                {
                    "removed": True
                }

            :statuscode 404: if the specified channel (community) or playlist does not exist
        """
        channel_info = self.get_channel_from_db(self.cid)
        if channel_info is None:
            return ChannelsPlaylistsEndpoint.return_404(request)

        playlist = self.channel_db_handler.getPlaylist(self.playlist_id, ['Playlists.dispersy_id', 'Playlists.id'])
        if playlist is None:
            return BaseChannelsEndpoint.return_404(request, message="this playlist cannot be found")

        channel_community = self.get_community_for_channel_id(channel_info[0])
        if channel_community is None:
            return BaseChannelsEndpoint.return_404(request,
                                                   message="the community for the specific channel cannot be found")

        # Remove all torrents from this playlist
        playlist_torrents = self.channel_db_handler.get_torrent_ids_from_playlist(playlist[1])
        channel_community.remove_playlist_torrents(playlist[0], [dispersy_id for dispersy_id, in playlist_torrents])

        # Remove the playlist itself
        channel_community.remove_playlists([playlist[0]])

        return json.dumps({"removed": True})
    def render_PUT(self, request):
        """
        .. http:put:: /channels/discovered/(string: channelid)/torrents

        Add a torrent file to your own channel. Returns error 500 if something is wrong with the torrent file
        and DuplicateTorrentFileError if already added to your channel. The torrent data is passed as base-64 encoded
        string. The description is optional.

            **Example request**:

            .. sourcecode:: none

                curl -X PUT http://localhost:8085/channels/discovered/abcd/torrents
                --data "torrent=...&description=funny video"

            **Example response**:

            .. sourcecode:: javascript

                {
                    "added": True
                }

            :statuscode 404: if your channel does not exist.
            :statuscode 500: if the passed torrent data is corrupt.
        """
        channel = self.get_channel_from_db(self.cid)
        if channel is None:
            return ChannelsTorrentsEndpoint.return_404(request)

        parameters = http.parse_qs(request.content.read(), 1)

        if 'torrent' not in parameters or len(parameters['torrent']) == 0:
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": "torrent parameter missing"})

        if 'description' not in parameters or len(
                parameters['description']) == 0:
            extra_info = {}
        else:
            extra_info = {'description': parameters['description'][0]}

        try:
            torrent = base64.b64decode(parameters['torrent'][0])
            torrent_def = TorrentDef.load_from_memory(torrent)
            self.session.add_torrent_def_to_channel(channel[0],
                                                    torrent_def,
                                                    extra_info,
                                                    forward=True)

        except (DuplicateTorrentFileError, ValueError) as ex:
            return BaseChannelsEndpoint.return_500(self, request, ex)

        return json.dumps({"added": True})
Example #16
0
    def render_POST(self, request):
        """
        .. http:post:: /mychannel

        Modify the name and/or the description of your channel.
        This endpoint returns a 404 HTTP response if you have not created a channel (yet).

            **Example request**:

            .. sourcecode:: none

                curl -X POST http://localhost:8085/mychannel
                --data "name=My fancy playlist&description=This playlist contains some random movies"

            **Example response**:

            .. sourcecode:: javascript

                {
                    "modified": True
                }

            :statuscode 404: if your channel has not been created (yet).
        """
        my_channel_id = self.channel_db_handler.getMyChannelId()
        if my_channel_id is None:
            request.setResponseCode(http.NOT_FOUND)
            return json.dumps({"error": NO_CHANNEL_CREATED_RESPONSE_MSG})

        channel_community = self.get_community_for_channel_id(my_channel_id)
        if channel_community is None:
            return BaseChannelsEndpoint.return_404(
                request,
                message="the community for the your channel cannot be found")

        parameters = http.parse_qs(request.content.read(), 1)
        my_channel = self.channel_db_handler.getChannel(my_channel_id)

        if not get_parameter(parameters, 'name'):
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": 'channel name cannot be empty'})

        changes = {}
        if my_channel[2] != get_parameter(parameters, 'name'):
            changes['name'] = unicode(get_parameter(parameters, 'name'),
                                      'utf-8')
        if my_channel[3] != get_parameter(parameters, 'description'):
            changes['description'] = unicode(
                get_parameter(parameters, 'description'), 'utf-8')

        channel_community.modifyChannel(changes)

        return json.dumps({'modified': True})
    def render_PUT(self, request):
        """
        .. http:put:: /channels/discovered/(string: channelid)/playlists

        Create a new empty playlist with a given name and description. The name and description parameters are
        mandatory.

            **Example request**:

            .. sourcecode:: none

                curl -X PUT http://localhost:8085/channels/discovered/abcd/playlists
                --data "name=My fancy playlist&description=This playlist contains some random movies"

            **Example response**:

            .. sourcecode:: javascript

                {
                    "created": True
                }

            :statuscode 400: if you are missing the name and/or description parameter
            :statuscode 404: if the specified channel does not exist
        """
        parameters = http.parse_qs(request.content.read(), 1)

        if 'name' not in parameters or len(parameters['name']) == 0:
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": "name parameter missing"})

        if 'description' not in parameters or len(
                parameters['description']) == 0:
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": "description parameter missing"})

        channel_info = self.get_channel_from_db(self.cid)
        if channel_info is None:
            return ChannelsPlaylistsEndpoint.return_404(request)

        channel_community = self.get_community_for_channel_id(channel_info[0])
        if channel_community is None:
            return BaseChannelsEndpoint.return_404(
                request,
                message="the community for the specific channel cannot be found"
            )

        channel_community.create_playlist(
            unicode(parameters['name'][0], 'utf-8'),
            unicode(parameters['description'][0], 'utf-8'), [])

        return json.dumps({"created": True})
Example #18
0
    def render_PUT(self, request):
        """
        .. http:put:: /channels/discovered

        Create your own new channel. The passed mode and descriptions are optional.
        Valid modes include: 'open', 'semi-open' or 'closed'. By default, the mode of the new channel is 'closed'.

            **Example request**:

            .. sourcecode:: none

                curl -X PUT http://localhost:8085/channels/discovered
                --data "name=fancy name&description=fancy description&mode=open"

            **Example response**:

            .. sourcecode:: javascript

                {
                    "added": 23
                }

            :statuscode 500: if a channel with the specified name already exists.
        """
        parameters = http.parse_qs(request.content.read(), 1)

        if 'name' not in parameters or len(parameters['name']) == 0 or len(
                parameters['name'][0]) == 0:
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": "channel name cannot be empty"})

        if 'description' not in parameters or len(
                parameters['description']) == 0:
            description = u''
        else:
            description = unicode(parameters['description'][0], 'utf-8')

        if 'mode' not in parameters or len(parameters['mode']) == 0:
            # By default, the mode of the new channel is closed.
            mode = u'closed'
        else:
            mode = unicode(parameters['mode'][0], 'utf-8')

        try:
            channel_id = self.session.create_channel(
                unicode(parameters['name'][0], 'utf-8'), description, mode)
        except DuplicateChannelNameError as ex:
            return BaseChannelsEndpoint.return_500(self, request, ex)

        return json.dumps({"added": channel_id})
    def render_PUT(self, request):
        """
        .. http:put:: /channels/discovered/(string: channelid)/playlists

        Create a new empty playlist with a given name and description. The name and description parameters are
        mandatory.

            **Example request**:

            .. sourcecode:: none

                curl -X PUT http://localhost:8085/channels/discovered/abcd/playlists
                --data "name=My fancy playlist&description=This playlist contains some random movies"

            **Example response**:

            .. sourcecode:: javascript

                {
                    "created": True
                }

            :statuscode 400: if you are missing the name and/or description parameter
            :statuscode 404: if the specified channel does not exist
        """
        parameters = http.parse_qs(request.content.read(), 1)

        if 'name' not in parameters or len(parameters['name']) == 0:
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": "name parameter missing"})

        if 'description' not in parameters or len(parameters['description']) == 0:
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": "description parameter missing"})

        channel_info = self.get_channel_from_db(self.cid)
        if channel_info is None:
            return ChannelsPlaylistsEndpoint.return_404(request)

        channel_community = self.get_community_for_channel_id(channel_info[0])
        if channel_community is None:
            return BaseChannelsEndpoint.return_404(request,
                                                   message="the community for the specific channel cannot be found")

        channel_community.create_playlist(unicode(parameters['name'][0], 'utf-8'),
                                          unicode(parameters['description'][0], 'utf-8'), [])

        return json.dumps({"created": True})
Example #20
0
 def __init__(self, session, cid, playlist_id):
     BaseChannelsEndpoint.__init__(self, session)
     self.cid = cid
     self.playlist_id = playlist_id
Example #21
0
    def render_DELETE(self, request):
        """
        .. http:delete:: /channels/discovered/(string: channelid)/torrents/(string: comma separated torrent infohashes)

        Remove a single or multiple torrents with the given comma separated infohashes from a given channel.

            **Example request**:

            .. sourcecode:: none

                curl -X DELETE http://localhost:8085/channels/discovered/abcdefg/torrents/
                97d2d8f5d37e56cfaeaae151d55f05b077074779,971d55f05b077074779d2d8f5d37e56cfaeaae15

            **Example response**:

            .. sourcecode:: javascript

                {
                    "removed": True
                }

            .. sourcecode:: javascript

                {
                    "removed": False, "failed_torrents":["97d2d8f5d37e56cfaeaae151d55f05b077074779"]
                }

            :statuscode 404: if the channel is not found
        """
        if self.is_chant_channel:
            with db_session:
                my_key = self.session.trustchain_keypair
                my_channel_id = my_key.pub().key_to_bin()
                failed_torrents = []

                if my_channel_id != self.cid:
                    request.setResponseCode(http.NOT_ALLOWED)
                    return json.dumps({
                        "error":
                        "you can only remove torrents from your own chant channel"
                    })

                my_channel = self.session.lm.mds.get_my_channel()
                if not my_channel:
                    return ChannelsTorrentsEndpoint.return_404(request)

                for torrent_path in self.path.split(","):
                    infohash = torrent_path.decode('hex')
                    if not my_channel.delete_torrent_from_channel(infohash):
                        failed_torrents.append(torrent_path)

                if failed_torrents:
                    return json.dumps({
                        "removed": False,
                        "failed_torrents": failed_torrents
                    })
                return json.dumps({"removed": True})
        else:
            channel_info = self.get_channel_from_db(self.cid)
            if channel_info is None:
                return ChannelsTorrentsEndpoint.return_404(request)

            channel_community = self.get_community_for_channel_id(
                channel_info[0])
            if channel_community is None:
                return BaseChannelsEndpoint.return_404(
                    request, message=UNKNOWN_COMMUNITY_MSG)

            torrent_db_columns = [
                'Torrent.torrent_id', 'infohash', 'Torrent.name', 'length',
                'Torrent.category', 'num_seeders', 'num_leechers',
                'last_tracker_check', 'ChannelTorrents.dispersy_id'
            ]

            failed_torrents = []
            for torrent_path in self.path.split(","):
                torrent_info = self.channel_db_handler.getTorrentFromChannelId(
                    channel_info[0], torrent_path.decode('hex'),
                    torrent_db_columns)
                if torrent_info is None:
                    failed_torrents.append(torrent_path)
                else:
                    # the 8th index is the dispersy id of the channel torrent
                    channel_community.remove_torrents([torrent_info[8]])

            if failed_torrents:
                return json.dumps({
                    "removed": False,
                    "failed_torrents": failed_torrents
                })

            return json.dumps({"removed": True})
Example #22
0
    def render_PUT(self, request):
        """
        .. http:put:: /channels/discovered/(string: channelid)/torrents/http%3A%2F%2Ftest.com%2Ftest.torrent

        Add a torrent by magnet or url to your channel. Returns error 500 if something is wrong with the torrent file
        and DuplicateTorrentFileError if already added to your channel (except with magnet links).

            **Example request**:

            .. sourcecode:: none

                curl -X PUT http://localhost:8085/channels/discovered/abcdefg/torrents/
                http%3A%2F%2Ftest.com%2Ftest.torrent --data "description=nice video"

            **Example response**:

            .. sourcecode:: javascript

                {
                    "added": "http://test.com/test.torrent"
                }

            :statuscode 404: if your channel does not exist.
            :statuscode 500: if the specified torrent is already in your channel.
        """
        my_key = self.session.trustchain_keypair
        my_channel_id = my_key.pub().key_to_bin()

        if self.is_chant_channel:
            if my_channel_id != self.cid:
                request.setResponseCode(http.NOT_ALLOWED)
                return json.dumps({
                    "error":
                    "you can only add torrents to your own chant channel"
                })
            channel = self.session.lm.mds.ChannelMetadata.get_channel_with_id(
                my_channel_id)
        else:
            channel = self.get_channel_from_db(self.cid)

        if channel is None:
            return BaseChannelsEndpoint.return_404(request)

        parameters = http.parse_qs(request.content.read(), 1)

        if 'description' not in parameters or len(
                parameters['description']) == 0:
            extra_info = {}
        else:
            extra_info = {'description': parameters['description'][0]}

        def _on_url_fetched(data):
            return TorrentDef.load_from_memory(data)

        def _on_magnet_fetched(meta_info):
            return TorrentDef.load_from_dict(meta_info)

        def _on_torrent_def_loaded(torrent_def):
            if self.is_chant_channel:
                # We have to get my channel again since we are in a different database session now
                with db_session:
                    channel = self.session.lm.mds.get_my_channel()
                    channel.add_torrent_to_channel(torrent_def, extra_info)
            else:
                channel = self.get_channel_from_db(self.cid)
                self.session.add_torrent_def_to_channel(channel[0],
                                                        torrent_def,
                                                        extra_info,
                                                        forward=True)
            return self.path

        def _on_added(added):
            request.write(json.dumps({"added": added}))
            request.finish()

        def _on_add_failed(failure):
            failure.trap(ValueError, DuplicateTorrentFileError,
                         SchemeNotSupported)
            self._logger.exception(failure.value)
            request.write(
                BaseChannelsEndpoint.return_500(self, request, failure.value))
            request.finish()

        def _on_timeout(_):
            request.write(
                BaseChannelsEndpoint.return_500(
                    self, request, RuntimeError("Metainfo timeout")))
            request.finish()

        if self.path.startswith("http:") or self.path.startswith("https:"):
            self.deferred = http_get(self.path)
            self.deferred.addCallback(_on_url_fetched)

        if self.path.startswith("magnet:"):
            try:
                self.session.lm.ltmgr.get_metainfo(
                    self.path,
                    callback=self.deferred.callback,
                    timeout=30,
                    timeout_callback=_on_timeout,
                    notify=True)
            except Exception as ex:
                self.deferred.errback(ex)

            self.deferred.addCallback(_on_magnet_fetched)

        self.deferred.addCallback(_on_torrent_def_loaded)
        self.deferred.addCallback(_on_added)
        self.deferred.addErrback(_on_add_failed)
        return NOT_DONE_YET
Example #23
0
    def render_PUT(self, request):
        """
        .. http:put:: /channels/discovered/(string: channelid)/torrents

        Add a torrent file to your own channel. Returns error 500 if something is wrong with the torrent file
        and DuplicateTorrentFileError if already added to your channel. The torrent data is passed as base-64 encoded
        string. The description is optional.

            **Example request**:

            .. sourcecode:: none

                curl -X PUT http://localhost:8085/channels/discovered/abcd/torrents
                --data "torrent=...&description=funny video"

            **Example response**:

            .. sourcecode:: javascript

                {
                    "added": True
                }

            :statuscode 404: if your channel does not exist.
            :statuscode 500: if the passed torrent data is corrupt.
        """
        key = self.session.trustchain_keypair
        my_channel_id = key.pub().key_to_bin()

        # First check whether the channel actually exists
        if self.is_chant_channel:
            if my_channel_id != self.cid:
                request.setResponseCode(http.NOT_ALLOWED)
                return json.dumps({
                    "error":
                    "you can only add torrents to your own chant channel"
                })

            channel = self.session.lm.mds.ChannelMetadata.get_channel_with_id(
                my_channel_id)
            if not channel:
                return ChannelsTorrentsEndpoint.return_404(request)
        else:
            channel = self.get_channel_from_db(self.cid)
            if channel is None:
                return ChannelsTorrentsEndpoint.return_404(request)

        parameters = http.parse_qs(request.content.read(), 1)

        if 'torrent' not in parameters or len(parameters['torrent']) == 0:
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": "torrent parameter missing"})

        if 'description' not in parameters or len(
                parameters['description']) == 0:
            extra_info = {}
        else:
            extra_info = {'description': parameters['description'][0]}

        # Try to parse the torrent data
        try:
            torrent = base64.b64decode(parameters['torrent'][0])
            torrent_def = TorrentDef.load_from_memory(torrent)
        except ValueError as exc:
            return BaseChannelsEndpoint.return_500(self, request, exc)

        if self.is_chant_channel:
            try:
                channel.add_torrent_to_channel(torrent_def, extra_info)
            except DuplicateTorrentFileError as exc:
                return BaseChannelsEndpoint.return_500(self, request, exc)
        else:
            try:
                self.session.add_torrent_def_to_channel(channel[0],
                                                        torrent_def,
                                                        extra_info,
                                                        forward=True)
            except (DuplicateTorrentFileError, HttpError) as ex:
                return BaseChannelsEndpoint.return_500(self, request, ex)

        return json.dumps({"added": True})
    def render_PUT(self, request):
        """
        .. http:put:: /channels/discovered/(string: channelid)/torrents/http%3A%2F%2Ftest.com%2Ftest.torrent

        Add a torrent by magnet or url to your channel. Returns error 500 if something is wrong with the torrent file
        and DuplicateTorrentFileError if already added to your channel (except with magnet links).

            **Example request**:

            .. sourcecode:: none

                curl -X PUT http://localhost:8085/channels/discovered/abcdefg/torrents/
                http%3A%2F%2Ftest.com%2Ftest.torrent --data "description=nice video"

            **Example response**:

            .. sourcecode:: javascript

                {
                    "added": "http://test.com/test.torrent"
                }

            :statuscode 404: if your channel does not exist.
            :statuscode 500: if the specified torrent is already in your channel.
        """
        channel = self.get_channel_from_db(self.cid)
        if channel is None:
            return BaseChannelsEndpoint.return_404(request)

        parameters = http.parse_qs(request.content.read(), 1)

        if 'description' not in parameters or len(parameters['description']) == 0:
            extra_info = {}
        else:
            extra_info = {'description': parameters['description'][0]}

        def _on_url_fetched(data):
            return TorrentDef.load_from_memory(data)

        def _on_magnet_fetched(meta_info):
            return TorrentDef.load_from_dict(meta_info)

        @blocking_call_on_reactor_thread
        def _on_torrent_def_loaded(torrent_def):
            self.session.add_torrent_def_to_channel(channel[0], torrent_def, extra_info, forward=True)
            return self.path

        def _on_added(added):
            request.write(json.dumps({"added": added}))
            request.finish()

        def _on_add_failed(failure):
            failure.trap(ValueError, DuplicateTorrentFileError)
            self._logger.exception(failure.value)
            request.write(BaseChannelsEndpoint.return_500(self, request, failure.value))
            request.finish()

        if self.path.startswith("http:") or self.path.startswith("https:"):
            self.deferred = http_get(self.path)
            self.deferred.addCallback(_on_url_fetched)

        if self.path.startswith("magnet:"):
            try:
                self.session.lm.ltmgr.get_metainfo(self.path, callback=self.deferred.callback,
                                                   timeout=30, timeout_callback=self.deferred.errback, notify=True)
            except Exception as ex:
                self.deferred.errback(ex)

            self.deferred.addCallback(_on_magnet_fetched)

        self.deferred.addCallback(_on_torrent_def_loaded)
        self.deferred.addCallback(_on_added)
        self.deferred.addErrback(_on_add_failed)
        return NOT_DONE_YET
 def __init__(self, session, cid, playlist_id):
     BaseChannelsEndpoint.__init__(self, session)
     self.cid = cid
     self.playlist_id = playlist_id
 def __init__(self, session, cid):
     BaseChannelsEndpoint.__init__(self, session)
     self.cid = bytes(cid.decode('hex'))
    def render_DELETE(self, request):
        """
        .. http:delete:: /channels/discovered/(string: channelid)/torrents/(string: comma separated torrent infohashes)

        Remove a single or multiple torrents with the given comma separated infohashes from a given channel.

            **Example request**:

            .. sourcecode:: none

                curl -X DELETE http://localhost:8085/channels/discovered/abcdefg/torrents/
                97d2d8f5d37e56cfaeaae151d55f05b077074779,971d55f05b077074779d2d8f5d37e56cfaeaae15

            **Example response**:

            .. sourcecode:: javascript

                {
                    "removed": True
                }

            .. sourcecode:: javascript

                {
                    "removed": False, "failed_torrents":["97d2d8f5d37e56cfaeaae151d55f05b077074779"]
                }

            :statuscode 404: if the channel is not found
        """
        if self.is_chant_channel:
            with db_session:
                my_key = self.session.trustchain_keypair
                my_channel_id = my_key.pub().key_to_bin()
                failed_torrents = []

                if my_channel_id != self.cid:
                    request.setResponseCode(http.NOT_ALLOWED)
                    return json.dumps({"error": "you can only remove torrents from your own chant channel"})

                my_channel = self.session.lm.mds.get_my_channel()
                if not my_channel:
                    return ChannelsTorrentsEndpoint.return_404(request)

                for torrent_path in self.path.split(","):
                    infohash = torrent_path.decode('hex')
                    if not my_channel.delete_torrent_from_channel(infohash):
                        failed_torrents.append(torrent_path)

                if failed_torrents:
                    return json.dumps({"removed": False, "failed_torrents": failed_torrents})
                return json.dumps({"removed": True})
        else:
            channel_info = self.get_channel_from_db(self.cid)
            if channel_info is None:
                return ChannelsTorrentsEndpoint.return_404(request)

            channel_community = self.get_community_for_channel_id(channel_info[0])
            if channel_community is None:
                return BaseChannelsEndpoint.return_404(request, message=UNKNOWN_COMMUNITY_MSG)

            torrent_db_columns = ['Torrent.torrent_id', 'infohash', 'Torrent.name', 'length', 'Torrent.category',
                                  'num_seeders', 'num_leechers', 'last_tracker_check', 'ChannelTorrents.dispersy_id']

            failed_torrents = []
            for torrent_path in self.path.split(","):
                torrent_info = self.channel_db_handler.getTorrentFromChannelId(channel_info[0],
                                                                               torrent_path.decode('hex'),
                                                                               torrent_db_columns)
                if torrent_info is None:
                    failed_torrents.append(torrent_path)
                else:
                    # the 8th index is the dispersy id of the channel torrent
                    channel_community.remove_torrents([torrent_info[8]])

            if failed_torrents:
                return json.dumps({"removed": False, "failed_torrents": failed_torrents})

            return json.dumps({"removed": True})
 def on_refresh_error(failure):
     self._logger.exception(failure.value)
     request.write(BaseChannelsEndpoint.return_500(self, request, failure.value))
     request.finish()
 def __init__(self, session, cid, path):
     BaseChannelsEndpoint.__init__(self, session)
     self.cid = cid
     self.path = path
     self.deferred = Deferred()
Example #30
0
 def __init__(self, session, cid):
     BaseChannelsEndpoint.__init__(self, session)
     self.cid = cid
 def __init__(self, session, cid):
     BaseChannelsEndpoint.__init__(self, session)
     self.cid = bytes(cid.decode('hex'))
    def render_PUT(self, request):
        """
        .. http:put:: /channels/discovered/(string: channelid)/torrents

        Add a torrent file to your own channel. Returns error 500 if something is wrong with the torrent file
        and DuplicateTorrentFileError if already added to your channel. The torrent data is passed as base-64 encoded
        string. The description is optional.

            **Example request**:

            .. sourcecode:: none

                curl -X PUT http://localhost:8085/channels/discovered/abcd/torrents
                --data "torrent=...&description=funny video"

            **Example response**:

            .. sourcecode:: javascript

                {
                    "added": True
                }

            :statuscode 404: if your channel does not exist.
            :statuscode 500: if the passed torrent data is corrupt.
        """
        key = self.session.trustchain_keypair
        my_channel_id = key.pub().key_to_bin()

        # First check whether the channel actually exists
        if self.is_chant_channel:
            if my_channel_id != self.cid:
                request.setResponseCode(http.NOT_ALLOWED)
                return json.dumps({"error": "you can only add torrents to your own chant channel"})

            channel = self.session.lm.mds.ChannelMetadata.get_channel_with_id(my_channel_id)
            if not channel:
                return ChannelsTorrentsEndpoint.return_404(request)
        else:
            channel = self.get_channel_from_db(self.cid)
            if channel is None:
                return ChannelsTorrentsEndpoint.return_404(request)

        parameters = http.parse_qs(request.content.read(), 1)

        if 'torrent' not in parameters or len(parameters['torrent']) == 0:
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": "torrent parameter missing"})

        if 'description' not in parameters or len(parameters['description']) == 0:
            extra_info = {}
        else:
            extra_info = {'description': parameters['description'][0]}

        # Try to parse the torrent data
        try:
            torrent = base64.b64decode(parameters['torrent'][0])
            torrent_def = TorrentDef.load_from_memory(torrent)
        except ValueError as exc:
            return BaseChannelsEndpoint.return_500(self, request, exc)

        if self.is_chant_channel:
            try:
                channel.add_torrent_to_channel(torrent_def, extra_info)
            except DuplicateTorrentFileError as exc:
                return BaseChannelsEndpoint.return_500(self, request, exc)
        else:
            try:
                self.session.add_torrent_def_to_channel(channel[0], torrent_def, extra_info, forward=True)
            except (DuplicateTorrentFileError, HttpError) as ex:
                return BaseChannelsEndpoint.return_500(self, request, ex)

        return json.dumps({"added": True})
Example #33
0
 def __init__(self, session, cid, path):
     BaseChannelsEndpoint.__init__(self, session)
     self.cid = cid
     self.path = path
     self.deferred = Deferred()
     self.is_chant_channel = (len(cid) == 74)
Example #34
0
 def __init__(self, session, cid):
     BaseChannelsEndpoint.__init__(self, session)
     self.cid = cid
Example #35
0
 def __init__(self, session, cid):
     BaseChannelsEndpoint.__init__(self, session)
     self.cid = cid
     self.is_chant_channel = (len(cid) == 74)
Example #36
0
    def render_PUT(self, request):
        """
        .. http:put:: /channels/discovered

        Create your own new channel. The passed mode and descriptions are optional.
        Valid modes include: 'open', 'semi-open' or 'closed'. By default, the mode of the new channel is 'closed'.

            **Example request**:

            .. sourcecode:: none

                curl -X PUT http://localhost:8085/channels/discovered
                --data "name=fancy name&description=fancy description&mode=open"

            **Example response**:

            .. sourcecode:: javascript

                {
                    "added": 23
                }

            :statuscode 500: if a channel with the specified name already exists.
        """
        parameters = http.parse_qs(request.content.read(), 1)

        if 'name' not in parameters or len(parameters['name']) == 0 or len(
                parameters['name'][0]) == 0:
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": "channel name cannot be empty"})

        if 'description' not in parameters or len(
                parameters['description']) == 0:
            description = u''
        else:
            description = unicode(parameters['description'][0], 'utf-8')

        if self.session.config.get_chant_channel_edit():
            my_key = self.session.trustchain_keypair
            my_channel_id = my_key.pub().key_to_bin()

            # Do not allow to add a channel twice
            if self.session.lm.mds.get_my_channel():
                request.setResponseCode(http.INTERNAL_SERVER_ERROR)
                return json.dumps({"error": "channel already exists"})

            title = unicode(parameters['name'][0], 'utf-8')
            self.session.lm.mds.ChannelMetadata.create_channel(
                title, description)
            return json.dumps({
                "added": str(my_channel_id).encode("hex"),
            })

        if 'mode' not in parameters or len(parameters['mode']) == 0:
            # By default, the mode of the new channel is closed.
            mode = u'closed'
        else:
            mode = unicode(parameters['mode'][0], 'utf-8')

        try:
            channel_id = self.session.create_channel(
                unicode(parameters['name'][0], 'utf-8'), description, mode)
        except DuplicateChannelNameError as ex:
            return BaseChannelsEndpoint.return_500(self, request, ex)

        return json.dumps({"added": channel_id})
Example #37
0
 def _on_timeout(_):
     request.write(
         BaseChannelsEndpoint.return_500(
             self, request, RuntimeError("Metainfo timeout")))
     request.finish()
 def __init__(self, session, cid):
     BaseChannelsEndpoint.__init__(self, session)
     self.cid = cid
     self.is_chant_channel = (len(cid) == 74)
    def render_PUT(self, request):
        """
        .. http:put:: /channels/discovered

        Create your own new channel. The passed mode and descriptions are optional.
        Valid modes include: 'open', 'semi-open' or 'closed'. By default, the mode of the new channel is 'closed'.

            **Example request**:

            .. sourcecode:: none

                curl -X PUT http://localhost:8085/channels/discovered
                --data "name=fancy name&description=fancy description&mode=open"

            **Example response**:

            .. sourcecode:: javascript

                {
                    "added": 23
                }

            :statuscode 500: if a channel with the specified name already exists.
        """
        parameters = http.parse_qs(request.content.read(), 1)

        if 'name' not in parameters or len(parameters['name']) == 0 or len(parameters['name'][0]) == 0:
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": "channel name cannot be empty"})

        if 'description' not in parameters or len(parameters['description']) == 0:
            description = u''
        else:
            description = unicode(parameters['description'][0], 'utf-8')

        if self.session.config.get_chant_channel_edit():
            my_key = self.session.trustchain_keypair
            my_channel_id = my_key.pub().key_to_bin()

            # Do not allow to add a channel twice
            if self.session.lm.mds.get_my_channel():
                request.setResponseCode(http.INTERNAL_SERVER_ERROR)
                return json.dumps({"error": "channel already exists"})

            title = unicode(parameters['name'][0], 'utf-8')
            self.session.lm.mds.ChannelMetadata.create_channel(title, description)
            return json.dumps({
                "added": str(my_channel_id).encode("hex"),
            })

        if 'mode' not in parameters or len(parameters['mode']) == 0:
            # By default, the mode of the new channel is closed.
            mode = u'closed'
        else:
            mode = unicode(parameters['mode'][0], 'utf-8')

        try:
            channel_id = self.session.create_channel(unicode(parameters['name'][0], 'utf-8'), description, mode)
        except DuplicateChannelNameError as ex:
            return BaseChannelsEndpoint.return_500(self, request, ex)

        return json.dumps({"added": channel_id})
 def _on_add_failed(failure):
     failure.trap(ValueError, DuplicateTorrentFileError, SchemeNotSupported)
     self._logger.exception(failure.value)
     request.write(BaseChannelsEndpoint.return_500(self, request, failure.value))
     request.finish()
Example #41
0
 def __init__(self, session, cid, playlist_id, infohash):
     BaseChannelsEndpoint.__init__(self, session)
     self.cid = cid
     self.playlist_id = playlist_id
     self.infohash = infohash.decode('hex')
 def _on_timeout(_):
     request.write(BaseChannelsEndpoint.return_500(self, request, RuntimeError("Metainfo timeout")))
     request.finish()
 def __init__(self, session, cid, path):
     BaseChannelsEndpoint.__init__(self, session)
     self.cid = cid
     self.path = path
     self.deferred = Deferred()
     self.is_chant_channel = (len(cid) == 74)
 def __init__(self, session, cid, playlist_id, infohash):
     BaseChannelsEndpoint.__init__(self, session)
     self.cid = cid
     self.playlist_id = playlist_id
     self.infohash = infohash.decode('hex')
    def render_PUT(self, request):
        """
        .. http:put:: /channels/discovered/(string: channelid)/torrents/http%3A%2F%2Ftest.com%2Ftest.torrent

        Add a torrent by magnet or url to your channel. Returns error 500 if something is wrong with the torrent file
        and DuplicateTorrentFileError if already added to your channel (except with magnet links).

            **Example request**:

            .. sourcecode:: none

                curl -X PUT http://localhost:8085/channels/discovered/abcdefg/torrents/
                http%3A%2F%2Ftest.com%2Ftest.torrent --data "description=nice video"

            **Example response**:

            .. sourcecode:: javascript

                {
                    "added": "http://test.com/test.torrent"
                }

            :statuscode 404: if your channel does not exist.
            :statuscode 500: if the specified torrent is already in your channel.
        """
        my_key = self.session.trustchain_keypair
        my_channel_id = my_key.pub().key_to_bin()

        if self.is_chant_channel:
            if my_channel_id != self.cid:
                request.setResponseCode(http.NOT_ALLOWED)
                return json.dumps({"error": "you can only add torrents to your own chant channel"})
            channel = self.session.lm.mds.ChannelMetadata.get_channel_with_id(my_channel_id)
        else:
            channel = self.get_channel_from_db(self.cid)

        if channel is None:
            return BaseChannelsEndpoint.return_404(request)

        parameters = http.parse_qs(request.content.read(), 1)

        if 'description' not in parameters or len(parameters['description']) == 0:
            extra_info = {}
        else:
            extra_info = {'description': parameters['description'][0]}

        def _on_url_fetched(data):
            return TorrentDef.load_from_memory(data)

        def _on_magnet_fetched(meta_info):
            return TorrentDef.load_from_dict(meta_info)

        def _on_torrent_def_loaded(torrent_def):
            if self.is_chant_channel:
                # We have to get my channel again since we are in a different database session now
                with db_session:
                    channel = self.session.lm.mds.get_my_channel()
                    channel.add_torrent_to_channel(torrent_def, extra_info)
            else:
                channel = self.get_channel_from_db(self.cid)
                self.session.add_torrent_def_to_channel(channel[0], torrent_def, extra_info, forward=True)
            return self.path

        def _on_added(added):
            request.write(json.dumps({"added": added}))
            request.finish()

        def _on_add_failed(failure):
            failure.trap(ValueError, DuplicateTorrentFileError, SchemeNotSupported)
            self._logger.exception(failure.value)
            request.write(BaseChannelsEndpoint.return_500(self, request, failure.value))
            request.finish()

        def _on_timeout(_):
            request.write(BaseChannelsEndpoint.return_500(self, request, RuntimeError("Metainfo timeout")))
            request.finish()

        if self.path.startswith("http:") or self.path.startswith("https:"):
            self.deferred = http_get(self.path)
            self.deferred.addCallback(_on_url_fetched)

        if self.path.startswith("magnet:"):
            try:
                self.session.lm.ltmgr.get_metainfo(self.path, callback=self.deferred.callback,
                                                   timeout=30, timeout_callback=_on_timeout, notify=True)
            except Exception as ex:
                self.deferred.errback(ex)

            self.deferred.addCallback(_on_magnet_fetched)

        self.deferred.addCallback(_on_torrent_def_loaded)
        self.deferred.addCallback(_on_added)
        self.deferred.addErrback(_on_add_failed)
        return NOT_DONE_YET
Example #46
0
    def render_POST(self, request):
        """
        .. http:post:: /mychannel

        Modify the name and/or the description of your channel.
        This endpoint returns a 404 HTTP response if you have not created a channel (yet).

            **Example request**:

            .. sourcecode:: none

                curl -X POST http://localhost:8085/mychannel
                --data "name=My fancy playlist&description=This playlist contains some random movies"

            **Example response**:

            .. sourcecode:: javascript

                {
                    "modified": True
                }

            :statuscode 404: if your channel has not been created (yet).
        """
        parameters = http.parse_qs(request.content.read(), 1)

        if not get_parameter(parameters, 'name') and not get_parameter(parameters, 'commit_changes'):
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": 'channel name cannot be empty'})

        if self.session.config.get_chant_channel_edit():
            with db_session:
                modified = False
                my_key = self.session.trustchain_keypair
                my_channel_id = my_key.pub().key_to_bin()
                my_channel = self.session.lm.mds.ChannelMetadata.get_channel_with_id(my_channel_id)

                if not my_channel:
                    request.setResponseCode(http.NOT_FOUND)
                    return json.dumps({"error": NO_CHANNEL_CREATED_RESPONSE_MSG})

                if get_parameter(parameters, 'name'):
                    my_channel.update_metadata(update_dict={
                        "tags": unicode(get_parameter(parameters, 'description'), 'utf-8'),
                        "title": unicode(get_parameter(parameters, 'name'), 'utf-8')
                    })
                    modified = True

                if get_parameter(parameters, 'commit_changes') and my_channel.staged_entries_list:
                    # Update torrent if we have uncommitted content in the channel
                    my_channel.commit_channel_torrent()
                    torrent_path = os.path.join(self.session.lm.mds.channels_dir, my_channel.dir_name + ".torrent")
                    self.session.lm.updated_my_channel(torrent_path)
                    modified = True

            return json.dumps({'modified': modified})
        else:
            my_channel_id = self.channel_db_handler.getMyChannelId()
            if my_channel_id is None:
                request.setResponseCode(http.NOT_FOUND)
                return json.dumps({"error": NO_CHANNEL_CREATED_RESPONSE_MSG})

            channel_community = self.get_community_for_channel_id(my_channel_id)
            if channel_community is None:
                return BaseChannelsEndpoint.return_404(request,
                                                       message="the community for the your channel cannot be found")

            my_channel = self.channel_db_handler.getChannel(my_channel_id)
            changes = {}
            if my_channel[2] != get_parameter(parameters, 'name'):
                changes['name'] = unicode(get_parameter(parameters, 'name'), 'utf-8')
            if my_channel[3] != get_parameter(parameters, 'description'):
                changes['description'] = unicode(get_parameter(parameters, 'description'), 'utf-8')

            channel_community.modifyChannel(changes)

            return json.dumps({'modified': True})