Author: adc
Date: Sun May  4 23:52:48 2014
New Revision: 1592432

URL: http://svn.apache.org/r1592432
Log:
Handy WSGI script for ezmlm access

Added:
    labs/panopticon/bin/ezmlm.wsgi   (contents, props changed)
      - copied, changed from r1592426, labs/panopticon/src/asf/utils/rest.py
    labs/panopticon/src/asf/utils/wsgi.py
      - copied, changed from r1592426, labs/panopticon/src/asf/utils/rest.py
    labs/panopticon/src/asf/wsgi/
    labs/panopticon/src/asf/wsgi/__init__.py
      - copied, changed from r1592426, labs/panopticon/src/asf/utils/rest.py
    labs/panopticon/src/asf/wsgi/ezmlm.py
Removed:
    labs/panopticon/src/asf/utils/rest.py
Modified:
    labs/panopticon/setup.py

Copied: labs/panopticon/bin/ezmlm.wsgi (from r1592426, 
labs/panopticon/src/asf/utils/rest.py)
URL: 
http://svn.apache.org/viewvc/labs/panopticon/bin/ezmlm.wsgi?p2=labs/panopticon/bin/ezmlm.wsgi&p1=labs/panopticon/src/asf/utils/rest.py&r1=1592426&r2=1592432&rev=1592432&view=diff
==============================================================================
--- labs/panopticon/src/asf/utils/rest.py (original)
+++ labs/panopticon/bin/ezmlm.wsgi Sun May  4 23:52:48 2014
@@ -1,3 +1,4 @@
+# !/usr/bin/env python
 #
 # Licensed to the Apache Software Foundation (ASF) under one
 # or more contributor license agreements.  See the NOTICE file
@@ -16,20 +17,14 @@
 # specific language governing permissions and limitations
 # under the License.
 #
-""" Flask decorators and utilities
 """
-from json import dumps
-
-from flask import current_app, request
+CGI based WSGI API to mailing lists.
+"""
+import os
 
 
-def json_result(f):
-    def wrapper(*args, **kwargs):
-        indent = None
-        if current_app.config['JSONIFY_PRETTYPRINT_REGULAR'] and not 
request.is_xhr:
-            indent = 2
-        return current_app.response_class(dumps(f(*args, **kwargs),
-                                                indent=indent),
-                                          mimetype='application/json')
+def application(environ, start_response):
+    os.environ['EZMLM_FLASK_CONFIG'] = environ['EZMLM_FLASK_CONFIG']
+    from asf.wsgi.ezmlm import app
 
-    return wrapper
\ No newline at end of file
+    return app.wsgi_app(environ, start_response)

Propchange: labs/panopticon/bin/ezmlm.wsgi
------------------------------------------------------------------------------
    svn:executable = *

Modified: labs/panopticon/setup.py
URL: 
http://svn.apache.org/viewvc/labs/panopticon/setup.py?rev=1592432&r1=1592431&r2=1592432&view=diff
==============================================================================
--- labs/panopticon/setup.py (original)
+++ labs/panopticon/setup.py Sun May  4 23:52:48 2014
@@ -102,7 +102,7 @@ setup(
     # don't ever depend on refcounting to close files anywhere else
     long_description=open('README.rst', encoding='utf-8').read(),
 
-    scripts=['bin/moderator'],
+    scripts=['bin/moderator', 'bin/ezmlm.wsgi'],
 
     namespace_packages=['asf'],
     package_dir={'': 'src'},

Copied: labs/panopticon/src/asf/utils/wsgi.py (from r1592426, 
labs/panopticon/src/asf/utils/rest.py)
URL: 
http://svn.apache.org/viewvc/labs/panopticon/src/asf/utils/wsgi.py?p2=labs/panopticon/src/asf/utils/wsgi.py&p1=labs/panopticon/src/asf/utils/rest.py&r1=1592426&r2=1592432&rev=1592432&view=diff
==============================================================================
--- labs/panopticon/src/asf/utils/rest.py (original)
+++ labs/panopticon/src/asf/utils/wsgi.py Sun May  4 23:52:48 2014
@@ -18,12 +18,14 @@
 #
 """ Flask decorators and utilities
 """
+from functools import wraps
 from json import dumps
 
 from flask import current_app, request
 
 
 def json_result(f):
+    @wraps(f)
     def wrapper(*args, **kwargs):
         indent = None
         if current_app.config['JSONIFY_PRETTYPRINT_REGULAR'] and not 
request.is_xhr:

Copied: labs/panopticon/src/asf/wsgi/__init__.py (from r1592426, 
labs/panopticon/src/asf/utils/rest.py)
URL: 
http://svn.apache.org/viewvc/labs/panopticon/src/asf/wsgi/__init__.py?p2=labs/panopticon/src/asf/wsgi/__init__.py&p1=labs/panopticon/src/asf/utils/rest.py&r1=1592426&r2=1592432&rev=1592432&view=diff
==============================================================================
--- labs/panopticon/src/asf/utils/rest.py (original)
+++ labs/panopticon/src/asf/wsgi/__init__.py Sun May  4 23:52:48 2014
@@ -7,7 +7,7 @@
 # "License"); you may not use this file except in compliance
 # with the License.  You may obtain a copy of the License at
 #
-# http://www.apache.org/licenses/LICENSE-2.0
+#   http://www.apache.org/licenses/LICENSE-2.0
 #
 # Unless required by applicable law or agreed to in writing,
 # software distributed under the License is distributed on an
@@ -16,20 +16,6 @@
 # specific language governing permissions and limitations
 # under the License.
 #
-""" Flask decorators and utilities
 """
-from json import dumps
-
-from flask import current_app, request
-
-
-def json_result(f):
-    def wrapper(*args, **kwargs):
-        indent = None
-        if current_app.config['JSONIFY_PRETTYPRINT_REGULAR'] and not 
request.is_xhr:
-            indent = 2
-        return current_app.response_class(dumps(f(*args, **kwargs),
-                                                indent=indent),
-                                          mimetype='application/json')
-
-    return wrapper
\ No newline at end of file
+Various WSGI based API scripts.
+"""
\ No newline at end of file

Added: labs/panopticon/src/asf/wsgi/ezmlm.py
URL: 
http://svn.apache.org/viewvc/labs/panopticon/src/asf/wsgi/ezmlm.py?rev=1592432&view=auto
==============================================================================
--- labs/panopticon/src/asf/wsgi/ezmlm.py (added)
+++ labs/panopticon/src/asf/wsgi/ezmlm.py Sun May  4 23:52:48 2014
@@ -0,0 +1,264 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+"""
+CGI based WSGI API to mailing lists.
+"""
+from logging import getLogger
+import os
+
+import flask
+
+from asf.utils.ezmlm import Ezmlm
+from asf.utils.wsgi import json_result
+
+
+log = getLogger(__name__)
+
+app = flask.Flask(__name__)
+app.config.from_envvar('EZMLM_FLASK_CONFIG')
+
+
+@app.route('/foo')
+@json_result
+def foo():
+    return {'foo': 'bar'}
+
+
+@app.route('/v1/public/lists')
+@json_result
+def public_lists():
+    list_root_path = app.config['LIST_ROOT_PATH']
+
+    if not os.path.exists(list_root_path):
+        flask.abort(500)
+
+    return ezmlm_list_groups(list_root_path)
+
+
+@app.route('/v1/committer/lists')
+@json_result
+def committer_lists():
+    list_path = app.config['LIST_ROOT_PATH']
+
+    if not os.path.exists(list_path):
+        flask.abort(500)
+
+    return ezmlm_list_groups(list_path)
+
+
+@app.route('/v1/asf/lists')
+@json_result
+def asf_lists():
+    list_path = app.config['LIST_ROOT_PATH']
+
+    if not os.path.exists(list_path):
+        flask.abort(500)
+
+    return ezmlm_list_groups(list_path)
+
+
+# noinspection PyUnusedLocal
+@app.route('/v1/public/lists/<mailing_list>/subscribers')
+@json_result
+def public_list_subscribers(mailing_list):
+    flask.abort(401)
+
+
+# noinspection PyUnusedLocal
+@app.route('/v1/committer/lists/<mailing_list>/subscribers')
+@json_result
+def committer_list_subscribers(mailing_list):
+    flask.abort(401)
+
+
+@app.route('/v1/asf/lists/<mailing_list>/subscribers')
+@json_result
+def asf_list_subscribers(mailing_list):
+    list_path = path_from_root_and_list(app.config['LIST_ROOT_PATH'], 
mailing_list)
+
+    if not os.path.exists(list_path):
+        flask.abort(500)
+
+    return ezmlm_list_subscribers(list_path)
+
+
+# noinspection PyUnusedLocal
+@app.route('/v1/public/lists/<mailing_list>/moderators')
+@json_result
+def public_list_moderators(mailing_list):
+    flask.abort(401)
+
+
+# noinspection PyUnusedLocal
+@app.route('/v1/committer/lists/<mailing_list>/moderators')
+@json_result
+def committer_list_moderators(mailing_list):
+    flask.abort(401)
+
+
+@app.route('/v1/asf/lists/<mailing_list>/moderators')
+@json_result
+def asf_list_moderators(mailing_list):
+    list_path = path_from_root_and_list(app.config['LIST_ROOT_PATH'], 
mailing_list)
+
+    if not os.path.exists(list_path):
+        flask.abort(500)
+
+    return ezmlm_list_moderators(list_path)
+
+
+# noinspection PyUnusedLocal
+@app.route('/v1/public/lists/<mailing_list>/subscribers/<subscriber>', 
methods=['PUT', 'DELETE'])
+@json_result
+def public_manage_subscribers(mailing_list, subscriber):
+    flask.abort(401)
+
+
+# noinspection PyUnusedLocal
+@app.route('/v1/committer/lists/<mailing_list>/subscribers/<subscriber>', 
methods=['PUT', 'DELETE'])
+@json_result
+def committer_manage_subscribers(mailing_list, subscriber):
+    flask.abort(401)
+
+
+@app.route('/v1/asf/lists/<mailing_list>/subscribers/<subscriber>', 
methods=['PUT'])
+@json_result
+def asf_add_subscriber(mailing_list, subscriber):
+    list_path = path_from_root_and_list(app.config['LIST_ROOT_PATH'], 
mailing_list)
+
+    if not os.path.exists(list_path):
+        flask.abort(500)
+
+    return ezmlm_add_subscriber(list_path, subscriber)
+
+
+@app.route('/v1/asf/lists/<mailing_list>/subscribers/<subscriber>', 
methods=['DELETE'])
+@json_result
+def asf_remove_subscriber(mailing_list, subscriber):
+    list_path = path_from_root_and_list(app.config['LIST_ROOT_PATH'], 
mailing_list)
+
+    if not os.path.exists(list_path):
+        flask.abort(500)
+
+    return ezmlm_remove_subscriber(list_path, subscriber)
+
+
+# noinspection PyUnusedLocal
+@app.route('/v1/public/lists/<mailing_list>/moderators/<moderator>', 
methods=['PUT', 'DELETE'])
+@json_result
+def public_manage_moderators(mailing_list, moderator):
+    flask.abort(401)
+
+
+# noinspection PyUnusedLocal
+@app.route('/v1/committer/lists/<mailing_list>/moderators/<moderator>', 
methods=['PUT', 'DELETE'])
+@json_result
+def committer_manage_moderators(mailing_list, moderator):
+    flask.abort(401)
+
+
+@app.route('/v1/asf/lists/<mailing_list>/moderators/<moderator>', 
methods=['PUT'])
+@json_result
+def asf_add_moderator(mailing_list, moderator):
+    list_path = path_from_root_and_list(app.config['LIST_ROOT_PATH'], 
mailing_list)
+
+    if not os.path.exists(list_path):
+        flask.abort(500)
+
+    return ezmlm_add_moderator(list_path, moderator)
+
+
+@app.route('/v1/asf/lists/<mailing_list>/moderators/<moderator>', 
methods=['DELETE'])
+@json_result
+def asf_remove_moderator(mailing_list, moderator):
+    list_path = path_from_root_and_list(app.config['LIST_ROOT_PATH'], 
mailing_list)
+
+    if not os.path.exists(list_path):
+        flask.abort(500)
+
+    return ezmlm_remove_moderator(list_path, moderator)
+
+
+def path_from_root_and_list(list_root_path, mailing_list):
+    local, domain = mailing_list.split('@')
+
+    list_groups = ezmlm_list_groups(list_root_path)
+
+    if domain not in list_groups:
+        flask.abort(400)
+
+    if local not in list_groups[domain]:
+        flask.abort(400)
+
+    return os.path.join(list_root_path, domain, local)
+
+
+def ezmlm_list_groups(list_root_path):
+    groups = {}
+    for domain in [o for o in os.listdir(list_root_path) if 
os.path.isdir(os.path.join(list_root_path, o)) and o.endswith('.apache.org')]:
+        groups[domain] = []
+        domain_path = os.path.join(list_root_path, domain)
+        for mailing_list in os.listdir(domain_path):
+            groups[domain].append(mailing_list)
+
+    return groups
+
+
+def ezmlm_list_subscribers(list_path):
+    ezmlm = Ezmlm(list_path)
+
+    subscribers = []
+    for subscriber in sorted(ezmlm.subscribers):
+        subscribers.append(subscriber)
+
+    return {'subscribers': subscribers}
+
+
+def ezmlm_list_moderators(list_path):
+    ezmlm = Ezmlm(list_path)
+
+    moderators = []
+    for moderator in sorted(ezmlm.moderators):
+        moderators.append(moderator)
+
+    return {'moderators': moderators}
+
+
+def ezmlm_add_subscriber(list_path, subscriber):
+    ezmlm = Ezmlm(list_path)
+
+    ezmlm.add_subscriber(subscriber)
+
+
+def ezmlm_add_moderator(list_path, moderator):
+    ezmlm = Ezmlm(list_path)
+
+    ezmlm.add_moderator(moderator)
+
+
+def ezmlm_remove_subscriber(list_path, subscriber):
+    ezmlm = Ezmlm(list_path)
+
+    ezmlm.remove_subscriber(subscriber)
+
+
+def ezmlm_remove_moderator(list_path, moderator):
+    ezmlm = Ezmlm(list_path)
+
+    ezmlm.remove_moderator(moderator)



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@labs.apache.org
For additional commands, e-mail: commits-h...@labs.apache.org

Reply via email to