[27267] in Source-Commits

home help back first fref pref prev next nref lref last post

python-discuss commit: Implement automatic meeting location

daemon@ATHENA.MIT.EDU (Victor Vasiliev)
Sat Sep 7 15:06:56 2013

Date: Sat, 7 Sep 2013 15:06:48 -0400
From: Victor Vasiliev <vasilvv@MIT.EDU>
Message-Id: <201309071906.r87J6moF002776@drugstore.mit.edu>
To: source-commits@MIT.EDU

https://github.com/mit-athena/python-discuss/commit/f3db06ee90eb422023f5e9a23457ebb128f5bd71
commit f3db06ee90eb422023f5e9a23457ebb128f5bd71
Author: Victor Vasiliev <vasilvv@mit.edu>
Date:   Sat Sep 7 03:32:05 2013 -0400

    Implement automatic meeting location
    
    This allows users not to care in particular on which server the meeting
    is located, which is helpful because there are not that many discuss
    servers in existence.

 discuss/__init__.py |    1 +
 discuss/client.py   |    5 +++
 discuss/locator.py  |   74 +++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 80 insertions(+), 0 deletions(-)

diff --git a/discuss/__init__.py b/discuss/__init__.py
index ea60e9e..1ccd01b 100644
--- a/discuss/__init__.py
+++ b/discuss/__init__.py
@@ -1,3 +1,4 @@
 from .client import *
 from .rcfile import *
+from .locator import *
 
diff --git a/discuss/client.py b/discuss/client.py
index 9599256..a137a2e 100644
--- a/discuss/client.py
+++ b/discuss/client.py
@@ -65,6 +65,11 @@ class Client(object):
         reply = self.rpc.request(request)
         return reply.read_string()
 
+    def close(self):
+        """Disconnect from the server."""
+
+        self.rpc.socket.close()
+
 class Meeting(object):
     """Discuss meeting."""
 
diff --git a/discuss/locator.py b/discuss/locator.py
new file mode 100644
index 0000000..f2a3045
--- /dev/null
+++ b/discuss/locator.py
@@ -0,0 +1,74 @@
+#
+# Python client for Project Athena forum system.
+# See LICENSE file for more details.
+#
+# The following file contains routine used to locate
+# a meeting my its name using the two sources for location
+# lists: /etc/discuss/servers and ~/.dsc_servers. Both
+# of those files are formatted as lists of hostnames
+# with both empty lines and comments prefixed by "#" sign.
+#
+
+from .client import Client, Meeting, DiscussError
+from .constants import NO_SUCH_MTG
+from functools import partial
+import errno
+import os
+import re
+
+def _read_server_list(filename):
+    """Parses the given list of discuss servers."""
+
+    try:
+        source = open(filename, "r")
+        lines = source.readlines()
+        source.close()
+
+        remove_comments = partial(re.sub, "#.*", "")
+
+        lines = map(remove_comments, lines)    # comments
+        lines = map(str.strip, lines)          # whitespace
+        lines = filter(lambda x: x, lines)     # empty lines
+
+        return lines
+    except IOError as err:
+        # File is allowed not to exist
+        if err.errno == errno.ENOENT:
+            return []
+        else:
+            raise err
+
+def get_servers():
+    global_list_path = "/etc/discuss/servers"
+    user_list_path = os.path.expanduser("~/.dsc_servers")
+
+    global_servers = _read_server_list(global_list_path)
+    user_servers  = _read_server_list(user_list_path)
+
+    return global_servers + [ server
+            for server in user_servers if server not in global_servers ]
+
+def locate(name):
+    """Attempts to locate the meeting by looking for it on known
+    discuss servers. If found, returns the meeting object with a live
+    connection."""
+
+    servers = get_servers()
+    for server in servers:
+        client = Client(server)
+        for prefix in ("/var/spool/discuss/", "/usr/spool/discuss/"):
+            mtg_path = prefix + name
+            mtg = Meeting(client, mtg_path)
+            try:
+                mtg.load_info()
+                return mtg
+            except DiscussError as err:
+                if err.code == NO_SUCH_MTG:
+                    continue
+                else:
+                    client.close()
+                    raise err
+
+        client.close()
+
+    return None

home help back first fref pref prev next nref lref last post