Erik Svensson avatar Erik Svensson committed b2cd245

Added mutators to Session.
Moved stuff around.

Comments (0)

Files changed (5)

doc/reference/transmissionrpc.rst

 Transmission RPC specification, but with underscore instead of hyphen.
 ``download-dir`` -> ``download_dir``.
 
+Mutators
+--------
+
+Some attributes can be changed, these are called mutators. These changes will be sent to the server when changed.
+To reload information from Transmission use ``update()``.
+
 Reference
 ---------
 

transmissionrpc/client.py

         elif user or password:
             LOGGER.warning('Either user or password missing, not using authentication.')
         self._sequence = 0
-        self.session = Session()
+        self.session = None
         self.session_id = 0
         self.server_version = None
         self.protocol_version = None
         """
         Update session data.
         """
-        self.session.update(data)
+        if self.session:
+            self.session.from_request(data)
+        else:
+            self.session = Session(self, data)
 
     def _update_server_version(self):
         if self.server_version is None:

transmissionrpc/session.py

 # Copyright (c) 2008-2011 Erik Svensson <erik.public@gmail.com>
 # Licensed under the MIT license.
 
+from transmissionrpc.utils import Field
+
 class Session(object):
     """
     Session is a class holding the session data for a Transmission daemon.
     ``download-dir`` -> ``download_dir``.
     """
 
-    def __init__(self, fields=None):
-        self.fields = {}
+    def __init__(self, client=None, fields=None):
+        self._client = client
+        self._fields = {}
         if fields is not None:
-            self.update(fields)
-
-    def update(self, other):
-        """Update the session data from a session arguments dictionary"""
-
-        fields = None
-        if isinstance(other, dict):
-            fields = other
-        elif isinstance(other, Session):
-            fields = other.fields
-        else:
-            raise ValueError('Cannot update with supplied data')
-
-        for key, value in fields.iteritems():
-            self.fields[key.replace('-', '_')] = value
+            self._update_fields(fields)
 
     def __getattr__(self, name):
         try:
-            return self.fields[name]
+            return self._fields[name].value
         except KeyError:
             raise AttributeError('No attribute %s' % name)
 
     def __str__(self):
         text = ''
-        for key in sorted(self.fields.keys()):
-            text += "% 32s: %s\n" % (key[-32:], self.fields[key])
+        for key in sorted(self._fields.keys()):
+            text += "% 32s: %s\n" % (key[-32:], self._fields[key].value)
         return text
+
+    def _update_fields(self, other):
+        """
+        Update the session data from a Transmission JSON-RPC arguments dictionary
+        """
+        fields = None
+        if isinstance(other, dict):
+            for key, value in other.iteritems():
+                self._fields[key.replace('-', '_')] = Field(value, False)
+        elif isinstance(other, Session):
+            for key in other._fields.keys():
+                self._fields[key] = Field(other._fields[key].value, False)
+        else:
+            raise ValueError('Cannot update with supplied data')
+
+    def _dirty_fields(self):
+        """Enumerate changed fields"""
+        outgoing_keys = ['peer_port', 'pex_enabled']
+        fields = []
+        for key in outgoing_keys:
+            if key in self._fields and self._fields[key].dirty:
+                fields.append(key)
+        return fields
+
+    def _push(self):
+        """Push changed fields to the server"""
+        dirty = self._dirty_fields()
+        args = {}
+        for key in dirty:
+            args[key] = self._fields[key].value
+            self._fields[key] = self._fields[key]._replace(dirty=False)
+        if len(args) > 0:
+            self._client.set_session(**args)
+
+    def update(self, timeout=None):
+        """Update the session information."""
+        self._push()
+        session = self._client.get_session(timeout=timeout)
+        self._update_fields(session)
+        session = self._client.session_stats(timeout=timeout)
+        self._update_fields(session)
+
+    def from_request(self, data):
+        """Update the session information."""
+        self._update_fields(data)
+
+    def _get_peer_port(self):
+        """
+        Get the peer port.
+        """
+        return self._fields['peer_port'].value
+
+    def _set_peer_port(self, port):
+        """
+        Set the peer port.
+        """
+        if isinstance(port, (int, long)):
+            self._fields['peer_port'] = Field(port, True)
+            self._push()
+        else:
+            raise ValueError("Not a valid limit")
+
+    peer_port = property(_get_peer_port, _set_peer_port, None, "Peer port. This is a mutator.")
+
+    def _get_pex_enabled(self):
+        return self._fields['pex_enabled'].value
+
+    def _set_pex_enabled(self, enabled):
+        if isinstance(enabled, bool):
+            self._fields['pex_enabled'] = Field(enabled, True)
+            self._push()
+        else:
+            raise TypeError("Not a valid type")
+
+    pex_enabled = property(_get_pex_enabled, _set_pex_enabled, None, "Enable PEX. This is a mutator.")

transmissionrpc/torrent.py

 # Licensed under the MIT license.
 
 import sys, datetime
-from collections import namedtuple
 
 from transmissionrpc.constants import PRIORITY, RATIO_LIMIT, IDLE_LIMIT
-from transmissionrpc.utils import format_timedelta
-
-Field = namedtuple('Field', ['value', 'dirty'])
+from transmissionrpc.utils import Field, format_timedelta
 
 class Torrent(object):
     """
     def __copy__(self):
         return Torrent(self._client, self._fields)
 
+    def __getattr__(self, name):
+        try:
+            return self._fields[name].value
+        except KeyError:
+            raise AttributeError('No attribute %s' % name)
+
     def _rpc_version(self):
         if self._client:
             return self._client.rpc_version
         return 2
+
+    def _dirty_fields(self):
+        """Enumerate changed fields"""
+        outgoing_keys = ['bandwidthPriority', 'downloadLimit', 'downloadLimited', 'peer_limit', 'queuePosition'
+            , 'seedIdleLimit', 'seedIdleMode', 'seedRatioLimit', 'seedRatioMode', 'uploadLimit', 'uploadLimited']
+        fields = []
+        for key in outgoing_keys:
+            if key in self._fields and self._fields[key].dirty:
+                fields.append(key)
+        return fields
+
+    def _push(self):
+        """Push changed fields to the server"""
+        dirty = self._dirty_fields()
+        args = {}
+        for key in dirty:
+            args[key] = self._fields[key].value
+            self._fields[key] = self._fields[key]._replace(dirty=False)
+        if len(args) > 0:
+            self._client.change_torrent(self.id, **args)
+
+    def _update_fields(self, other):
+        """
+        Update the torrent data from a Transmission JSON-RPC arguments dictionary
+        """
+        fields = None
+        if isinstance(other, dict):
+            for key, value in other.iteritems():
+                self._fields[key.replace('-', '_')] = Field(value, False)
+        elif isinstance(other, Torrent):
+            for key in other._fields.keys():
+                self._fields[key] = Field(other._fields[key].value, False)
+        else:
+            raise ValueError('Cannot update with supplied data')
+        self._incoming_pending = False
     
     def _status_old(self, code):
         mapping = {
         else:
             return self._status_old(code)
 
-    def _update_fields(self, other):
-        """
-        Update the torrent data from a Transmission JSON-RPC arguments dictionary
-        """
-        fields = None
-        if isinstance(other, dict):
-            for key, value in other.iteritems():
-                self._fields[key.replace('-', '_')] = Field(value, False)
-        elif isinstance(other, Torrent):
-            for key in other._fields.keys():
-                self._fields[key] = Field(other._fields[key].value, False)
-        else:
-            raise ValueError('Cannot update with supplied data')
-        self._incoming_pending = False
-
     def files(self):
         """
         Get list of files for this torrent.
                     'completed': item[1]['bytesCompleted']}
         return result
 
-    def __getattr__(self, name):
-        try:
-            return self._fields[name].value
-        except KeyError:
-            raise AttributeError('No attribute %s' % name)
-
     @property
     def status(self):
         """
 
     queue_position = property(_get_queue_position, _set_queue_position, None, "Queue position")
 
-    def _dirty_fields(self):
-        """Enumerate changed fields"""
-        outgoing_keys = ['bandwidthPriority', 'downloadLimit', 'downloadLimited', 'peer_limit', 'queuePosition'
-            , 'seedIdleLimit', 'seedIdleMode', 'seedRatioLimit', 'seedRatioMode', 'uploadLimit', 'uploadLimited']
-        fields = []
-        for key in outgoing_keys:
-            if key in self._fields and self._fields[key].dirty:
-                fields.append(key)
-        return fields
-
-    def _push(self):
-        """Push changed fields to the server"""
-        dirty = self._dirty_fields()
-        args = {}
-        for key in dirty:
-            args[key] = self._fields[key].value
-            self._fields[key] = self._fields[key]._replace(dirty=False)
-        if len(args) > 0:
-            self._client.change_torrent(self.id, **args)
-
     def update(self, timeout=None):
         """Update the torrent information."""
         self._push()

transmissionrpc/utils.py

 # Licensed under the MIT license.
 
 import socket, datetime, logging
+from collections import namedtuple
 import transmissionrpc.constants as constants
 from transmissionrpc.constants import LOGGER
 
         trpc_logger.setLevel(loglevel)
         loghandler.setLevel(loglevel)
     trpc_logger.addHandler(loghandler)
+
+Field = namedtuple('Field', ['value', 'dirty'])
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.