Commits

fab31 committed 9d9ecac

update docstrings

Comments (0)

Files changed (11)

zicbee_lib/commands/__init__.py

-# commands dict: <cmd name>:<request string OR handler_function>, <doc>, [extra dict]
-# in request string, you can use two forms: positional or named
-# in positional form, you should have as many %s as required parameters, they will be passed in given order
-# in named form, you have dict expansion for: args (a string containing all arguments separated by a space), db_host, player_host
-# if given an handler_function, this is executed to get the request string
-#
-# In both forms, you should return an uri, if it's a relative prefix, db_host or player_host is chose according to "/db/" pattern presence
-# the request result is print on the console
+"""
+commands dict: <cmd name>:<request string OR handler_function>, <doc>, [extra dict]
+in request string, you can use two forms: positional or named
+in positional form, you should have as many %s as required parameters, they will be passed in given order
+in named form, you have dict expansion for: args (a string containing all arguments separated by a space), db_host, player_host
+if given an handler_function, this is executed to get the request string
 
+In both forms, you should return an uri, if it's a relative prefix, db_host or player_host is chose according to "/db/" pattern presence
+the request result is print on the console
+"""
+
+
+#: allow asynchronous operations
 ALLOW_ASYNC = True
 
 from itertools import chain
 from .command_misc import random_command, show_random_result
 
 def complete_cd(cw, args):
+    """ completor function for "cd" command """
     a = ' '.join(args[1:])
     word = len(args)-2 # remove last (index starts to 0, and first item doesn't count)
     if not cw:
             return [' '.join(riri[0][word:])]
 
 def remember_ls_results(r):
+    """ stores results into memory """
     ret = []
     for res in r:
         if not res.startswith('http://'):
     memory['last_ls'] = ret
 
 def ls_command(out, *arg):
+    """ ls command implementation
+    Allow someone to list artists, albums and songs
+    """
     path = memory.get('path', [])
     arg = ' '.join(arg)
 
             return '/db/albums'
 
 def pwd_command(out):
+    """ shows the current working directory """
     path = memory.get('path', [])
     out(['/'+('/'.join(path))])
 
 def cd_command(out, *arg):
+    """ Changes the current directory """
     path = memory.get('path', [])
     arg = ' '.join(arg)
 
 remember_results = partial(memory.__setitem__, 'last_search')
 forget_results = lambda uri: memory.__delitem__('last_search')
 
+#: this dict stores all the available commands
 commands = {
 #        'freeze': (dump_home, 'Dumps a minimalistic python environment'),
         'play': ('/search?host=%(db_host)s&pattern=%(args)s', 'Play a song', dict(threaded=True)),
 possible_commands.extend(shortcuts.keys())
 
 def write_lines(lines):
+    """ write lines on stdout """
     sys.stdout.writelines(l+'\n' for l in lines)
 
 def execute(name=None, line=None, output=write_lines):
+    """ Executes any command
+
+    :param str name: the name of the command to execute
+    :param str line: the rest of the command arguments
+    :param callable output: the output function,
+        taking a `str` as the only parameter.
+
+    .. note:: `line` can be omitted, in that case, all informations must be passed to the `name` variable.
+    """
     # real alias support (not host alias, full command)
     if name in shortcuts:
         name = shortcuts[name]

zicbee_lib/config.py

 except ImportError: # sane environment ;)
     TMP_DIR=r"/tmp"
 
-# Dictionary with default configuration
+#: Dictionary with default configuration
 defaults_dict = {
         'streaming_file' : os.path.join(TMP_DIR, 'zsong'),
         'download_dir' : TMP_DIR,
 config_filename = os.path.join(DB_DIR, 'config.ini')
 
 class _ConfigObj(object):
+    """ Configuration object """
 
     _cfg = ConfigParser.ConfigParser(defaults_dict)
 

zicbee_lib/core.py

         dict.clear(self)
         self._tss.clear()
 
-#: persistant values, kept across cmdline calls 
+#: persistant values, kept across cmdline calls
 memory = _LostMemory()

zicbee_lib/debug.py

+""" Debug facilities """
 __all__ = ['DEBUG', 'debug_enabled', 'log', 'nop', 'set_trace']
 import os
 import logging
 from logging import getLogger
 from zicbee_lib.config import config
 
+#: general logger
 log = getLogger('zicbee')
+
 def nop(*args):
     """ Don't do anything """
     return
     """ Prints a traceback + exception,
     optionally breaks into a debugger.
 
-
-    Args:
-        trace (bool): if True, breaks into a debugger after showing infos.
-
-    Returns:
-        None.
+    :param bool trace: if True, breaks into a debugger after showing infos.
+    :returns: None
     """
     traceback.print_stack()
     traceback.print_exc()

zicbee_lib/downloader.py

 from weakref import WeakKeyDictionary
 
 def DownloadGenerator(uri):
+    """ Gets some uri
+
+    :param uri: uri and output filename
+    :type uri: tuple(str, str)
+    :returns: an iterator that will download the uri to the filename
+    """
     uri, filename = uri
 
     if os.path.exists(filename):
     just call :meth:`run` with a list of uris you want to fetch
     """
     def __init__(self, nb_dl=2):
-        """ Args:
-            nb_dl: number of downloads to do in parallel
+        """
+        :param int nb_dl: number of downloads to do in parallel
         """
         self._nb_dl = nb_dl
         self._last_display = time.time()
     def run(self, uri_list):
         """ Takes a list of uri and returns when they are downloaded
 
-        Args:
-            uri_list (iterable): a list of strings
-        Returns:
-            None
+        :param iterable uri_list: a list of uris (str)
+        :returns: None
         """
         downloaders = [] # Generators to handle
         in_queue = [] # List of "TODO" uris

zicbee_lib/formats.py

     """ Expands a path with variables & user alias
 
 
-    Args:
-        path (str): a path containing shell-like shortcuts
-    Returns:
-        str. A normalized path.
+    :param str path: a path containing shell-like shortcuts
+    :returns: A normalized path.
+    :rtype: str
     """
     return expanduser(abspath(expandvars(path)))
 
     """ Avoids path separators in the path
 
 
-    Args:
-        path (str): the possible unsafe path
-    Returns:
-        str. A string without separator
+    :param str path: the possible unsafe path
+    :returns: A string without separator
+    :rtype: str
     """
     return path.replace(os.path.sep, ' ')
 
 # int (de)compacter [int <> small str convertors]
 # convert to base62...
+#: conversion base
 base = 62
+#: available characters
 chars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
 
 def compact_int(ival):
     """ Makes an int compact
 
 
-    Args:
-        ival (int): the integer value you want to shorten
-    Returns:
-        str. A string equivalent to the integer but with a more compact representation
+    :param int ival: the integer value you want to shorten
+    :returns: A string equivalent to the integer but with a more compact representation
+    :rtype: str
     """
     result = []
     rest = ival
     """ Makes an int from a compact string
 
 
-    Args:
-        str_val (str): The string representing a compact integer value
-    Returns:
-        int. The integer value
+    :param str str_val: The string representing a compact integer value
+    :returns: The integer value
+    :rtype: int
     """
     # int(x, base) not used because it's limited to base 36
     unit = 1
     """ Converts a string representing an index into an int or a slice
 
 
-    Args:
-        val (str): string like ``4`` or ``1:10``
-    Raises:
-        :exc:`ValueError`
-    Returns:
-        :keyword:`int` or :keyword:`slice` corresponding to the given string
+    :param str val: string like ``4`` or ``1:10``
+    :raises:  :exc:`ValueError`
+    :returns: :keyword:`int` or :keyword:`slice` corresponding to the given string
     """
     try:
         i = int(val)
 def dump_data_as_text(d, format):
     """ Dumps simple types (dict, iterable, float, int, unicode)
     as: json or plain text (compromise between human readable and parsable form)
-    Returns an iterator returning text
+    :param str format: value in "html", "json" or "txt"
+    returns: an iterator returning text
     """
     if format == "json":
         if isinstance(d, GeneratorType):
     """ Pretty formats an integer duration
 
 
-    Args:
-        orig (int, float): the value you want to pretty-print
-    Returns:
-        str. A string representing the given duration
+    :param orig: the value you want to pretty-print
+    :type orig: int or float
+    :returns: A string representing the given duration
+    :rtype: :keyword:`str`
     """
     minutes, seconds = divmod(orig, 60)
     if minutes > 60:
     """
     Returns a pretty-string from a function.
 
-    Args:
-        cmd (method): a method
-    Returns:
-        a tuple (:keyword:`str` tidy doc, :keyword:`bool` is_remote) from a function
+    :arg callable cmd: the fonction/method you want to get documentation from
+    :Returns: (:keyword:`str` tidy doc, :keyword:`bool` is_remote) from a function
+    :rtype: :keyword:`tuple`
     """
     arg_names, not_used, neither, dflt_values = inspect.getargspec(cmd)
     is_remote = any(h for h in arg_names if h.startswith('host') or h.endswith('host'))

zicbee_lib/parser.py

 
 
 class VarCounter(object):
+    """ Variable counter, used to increment count and get variables name in an abstract way """
 
     @property
     def varname(self):
 
 
 class Node(object):
+    """ Any language keyword is a :class:`Node` """
 
     def __init__(self, name):
+        """ :arg str name: :class:`Node` name"""
         self.name = name
 
     def __repr__(self, *unused):
     python = __repr__
 
     def isa(self, other):
+        """ Test if that node is of the same type as another
+
+        :arg other: the other node to test
+        """
         return self.__class__ == other.__class__ and self.name == getattr(other, 'name', None)
 
     def __eq__(self, other):
 
 
 class Not(Node):
+    """ Negation node - like python's "not" """
 
     def python(self, cnt):
+        """ Returns python representation """
         return "not"
 
 
 class Tag(Node):
+    """ A generic tag node
+    """
 
     def __init__(self, name):
         Node.__init__(self, name)
         return self
 
     def from_name(self, name=None):
+        """ Returns a new node of the same type from a node name
+
+        :arg str name: :class:`Node` name
+        """
         return self.__class__(name or self.name)
 
     def is_sensitive(self):
+        """ Is that node case-sensitive ?
+
+        :rtype: bool
+        """
         return self.name[0].isupper()
 
     def python(self, cnt):
+        """ Python reprensentation of the :class:`Node` """
         name = self.name.strip(':').lower()
         if not self.is_sensitive():
             name += ".lower()"
 
 
 class NumTag(Tag):
+    """ Numeric node """
 
     def is_sensitive(self):
         return True
 
 
 class Index(Tag):
+    """ "id" node """
 
     def is_sensitive(self):
         return True
 
 
 class Special(Tag):
+    """ Special (no python meaning) node """
 
     def __eq__(self, other):
         return self.name == getattr(other, 'name', None) if other else False
 
 # Recognised infos is here:
 
+#: Regex for tags
 TAG_RE = re.compile(r'([A-Za-z][a-z_-]*:)')
+#: Regex for operators
 OP_RE = re.compile(r'(\W|^|(?<!\\))(and|or|!)(\W|$)')
+#: Regex for groups
 GRP_RE = re.compile(r'(?<!\\)([()])')
 
+#: Regex for (
 OPEN = Node('(')
+#: Regex for )
 CLOSE = Node(')')
-
+#: "or" node
 OR = Node('or')
+#: "and" node
 AND = Node('and')
+#: "not" node
 NOT = Not('!')
 
+#: "id": node
 ID = Index('id:')
+#: "artist" node
 ARTIST = Tag('artist:')
+#: "album" node
 ALBUM = Tag('album:')
+#: "title" node
 TITLE = Tag('title:')
+#: "tags" node
 TAG = Tag('tags:')
 
+#: "Artist" node
 CS_ARTIST = Tag('Artist:')
+#: "Album" node
 CS_ALBUM = Tag('Album:')
+#: "Title" node
 CS_TITLE = Tag('Title:')
-
+#: "length" node
 LENGTH = NumTag('length:')
+#: "score" node
 SCORE = NumTag('score:')
 
+#: "pls" node
 PLAYLIST = Special('pls:')
+#: "auto" node
 AUTO = Special('auto:')
-
+#: operators node list
 OPERATORS = (AND, OR, NOT)
+#: tags nodes list
 TAGS = (ARTIST, ALBUM, TITLE, LENGTH, SCORE, PLAYLIST, AUTO, ID,
         CS_ARTIST, CS_ALBUM, CS_TITLE)
 
 
 def parse_string(st):
+    """ Parses a string
+
+    :arg str st: The string you want to parse
+    """
     # minor sanity check, allowing people to use !artist: syntax (instead of ! artist:)
     st = re.sub('!(\S)', r'! \1', st)
     # handle ()
 
 
 def tokens2python(tokens):
+    """ Convert a list of tokens into python code
+
+    :arg tokens: the list of tokens you want to convert
+    :type tokens: (:keyword:`list` of :class:`Node`)
+    :returns: the python code + variables dictionnary
+    :rtype: :keyword:`tuple`(:keyword:`str`, :keyword:`dict`)
+    """
     with VarCounter() as vc:
         ret = []
         d = {}
 
 
 def tokens2string(tokens):
+    """ Convert a list of tokens to a simple string
+
+    :arg tokens: the list of tokens you want to convert
+    :type tokens: (:keyword:`list` of :class:`Node`)
+
+    :rtype: str
+    """
     return ' '.join(str(t) for t in tokens)
 
 
 def string2python(st):
+    """ Converts a string into python code
+
+    :arg str st: the string (pattern) you want to convert
+    :returns: the same as :func:`tokens2python`
+    """
     toks = parse_string(st)
     if AUTO in toks:
         max_vals = int(toks[toks.index(AUTO)].value or 10)
     to("artist: (björk or foobar) auto:")
     to("auto: artist: (björk or foobar)")
     to("auto: 20 artist: (toto or björk or foobar)")
-    
+
     raise SystemExit()
-    
+
     tst_str = [
         'artist: Björk or artist: toto',
         'artist: metallica album: black',

zicbee_lib/remote_apis.py

     """ AudioScrobbler Artist object """
 
     def __init__(self, name):
+        """ :arg str name: the name of the artist """
         self.name = name.encode('utf8')
         self._base_url = 'http://ws.audioscrobbler.com/1.0/artist'
 
     def getSimilar(self):
+        """ Get similar artists list
+
+        :returns: the list of matching artists
+        :rtype: list(str, str, ...)
+        """
         ret = []
         infos = urllib.urlopen(self._base_url+'/%s/similar.txt'%urllib.quote(self.name))
         while True:
         return ret
 
     def getTop(self):
+        """ Get the artists top's tracks
+
+        :returns: the list of track names
+        :rtype: list(str, str, str)
+        """
         ret = []
         xmlpage = urllib.urlopen(self._base_url+'/%s/toptracks.xml'%urllib.quote(self.name)).read()
         xmlpage = ET.fromstring(xmlpage)

zicbee_lib/resources.py

     return iter_entry_points("zicbee.player")
 
 def set_proc_title(name):
+    """ Sets the process name on the OS
+
+    :arg str name: the name we would like
+    """
     try:
         import setproctitle
         setproctitle.setproctitle(name)

zicbee_lib/wasp/__init__.py

 def startup():
+    """ Startup function, used to start wasp"""
     import sys
     from .core import Shell
     from zicbee_lib import commands, __version__ as VERSION

zicbee_lib/wasp/core.py

 
 
 def complete_command(name, completer, cur_var, line, s, e):
+    """ Generic completion helper """
     ret = completer(cur_var, line.split())
     return [cur_var+h[e-s:] for h in ret if h.startswith(cur_var)]
 
 class Shell(Cmd):
+    """ Wasp shell :) """
+
+    #: default prompt
     prompt = "Wasp> "
+
     def __init__(self):
         self._history = os.path.join(DB_DIR, 'wasp_history.txt')
         self._last_line = None
         set_proc_title('wasp')
 
     def onecmd(self, line):
+        """ Executes one line """
         try:
             cmd, arg, line = self.parseline(line)
             if not line: