changeset 3833:5055dd385118 beta

api: decouple some parts from api CLI script - also change how we save config file - method should be always API method - now we use --save-config for saving api config
author Marcin Kuzminski <marcin@python-works.com>
date Thu, 09 May 2013 21:44:15 +0200
parents 07f8039ef090
children 2ad55d8ba11d
files rhodecode/bin/base.py rhodecode/bin/rhodecode_api.py
diffstat 2 files changed, 160 insertions(+), 154 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rhodecode/bin/base.py	Thu May 09 21:44:15 2013 +0200
@@ -0,0 +1,148 @@
+"""
+Base utils for shell scripts
+"""
+import os
+import sys
+import random
+import urllib2
+import pprint
+
+try:
+    from rhodecode.lib.ext_json import json
+except ImportError:
+    try:
+        import simplejson as json
+    except ImportError:
+        import json
+
+CONFIG_NAME = '.rhodecode'
+FORMAT_PRETTY = 'pretty'
+FORMAT_JSON = 'json'
+
+
+def api_call(apikey, apihost, format, method=None, **kw):
+    """
+    Api_call wrapper for RhodeCode
+
+    :param apikey:
+    :param apihost:
+    :param format: formatting, pretty means prints and pprint of json
+     json returns unparsed json
+    :param method:
+    """
+    def _build_data(random_id):
+        """
+        Builds API data with given random ID
+
+        :param random_id:
+        :type random_id:
+        """
+        return {
+            "id": random_id,
+            "api_key": apikey,
+            "method": method,
+            "args": kw
+        }
+
+    if not method:
+        raise Exception('please specify method name !')
+    id_ = random.randrange(1, 9999)
+    req = urllib2.Request('%s/_admin/api' % apihost,
+                      data=json.dumps(_build_data(id_)),
+                      headers={'content-type': 'text/plain'})
+    if format == FORMAT_PRETTY:
+        sys.stdout.write('calling %s to %s \n' % (req.get_data(), apihost))
+    ret = urllib2.urlopen(req)
+    raw_json = ret.read()
+    json_data = json.loads(raw_json)
+    id_ret = json_data['id']
+    _formatted_json = pprint.pformat(json_data)
+    if id_ret == id_:
+        if format == FORMAT_JSON:
+            sys.stdout.write(str(raw_json))
+        else:
+            sys.stdout.write('rhodecode returned:\n%s\n' % (_formatted_json))
+
+    else:
+        raise Exception('something went wrong. '
+                        'ID mismatch got %s, expected %s | %s' % (
+                                            id_ret, id_, _formatted_json))
+
+
+class RcConf(object):
+    """
+    RhodeCode config for API
+
+    conf = RcConf()
+    conf['key']
+
+    """
+
+    def __init__(self, config_location=None, autoload=True, autocreate=False,
+                 config=None):
+        self._conf_name = CONFIG_NAME if not config_location else config_location
+        self._conf = {}
+        if autocreate:
+            self.make_config(config)
+        if autoload:
+            self._conf = self.load_config()
+
+    def __getitem__(self, key):
+        return self._conf[key]
+
+    def __nonzero__(self):
+        if self._conf:
+            return True
+        return False
+
+    def __eq__(self):
+        return self._conf.__eq__()
+
+    def __repr__(self):
+        return 'RcConf<%s>' % self._conf.__repr__()
+
+    def make_config(self, config):
+        """
+        Saves given config as a JSON dump in the _conf_name location
+
+        :param config:
+        :type config:
+        """
+        update = False
+        if os.path.exists(self._conf_name):
+            update = True
+        with open(self._conf_name, 'wb') as f:
+            json.dump(config, f, indent=4)
+
+        if update:
+            sys.stdout.write('Updated config in %s\n' % self._conf_name)
+        else:
+            sys.stdout.write('Created new config in %s\n' % self._conf_name)
+
+    def update_config(self, new_config):
+        """
+        Reads the JSON config updates it's values with new_config and
+        saves it back as JSON dump
+
+        :param new_config:
+        """
+        config = {}
+        try:
+            with open(self._conf_name, 'rb') as conf:
+                config = json.load(conf)
+        except IOError, e:
+            sys.stderr.write(str(e) + '\n')
+
+        config.update(new_config)
+        self.make_config(config)
+
+    def load_config(self):
+        """
+        Loads config from file and returns loaded JSON object
+        """
+        try:
+            with open(self._conf_name, 'rb') as conf:
+                return  json.load(conf)
+        except IOError, e:
+            #sys.stderr.write(str(e) + '\n')
+            pass
--- a/rhodecode/bin/rhodecode_api.py	Thu May 09 14:52:05 2013 +0200
+++ b/rhodecode/bin/rhodecode_api.py	Thu May 09 21:44:15 2013 +0200
@@ -1,7 +1,7 @@
 # -*- coding: utf-8 -*-
 """
-    rhodecode.bin.backup_manager
-    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+    rhodecode.bin.api
+    ~~~~~~~~~~~~~~~~~
 
     Api CLI client for RhodeCode
 
@@ -24,160 +24,18 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 from __future__ import with_statement
-import os
 import sys
-import random
-import urllib2
-import pprint
 import argparse
 
-try:
-    from rhodecode.lib.ext_json import json
-except ImportError:
-    try:
-        import simplejson as json
-    except ImportError:
-        import json
-
-
-CONFIG_NAME = '.rhodecode'
-FORMAT_PRETTY = 'pretty'
-FORMAT_JSON = 'json'
-
-
-class RcConf(object):
-    """
-    RhodeCode config for API
-
-    conf = RcConf()
-    conf['key']
-
-    """
-
-    def __init__(self, config_location=None, autoload=True, autocreate=False,
-                 config=None):
-        self._conf_name = CONFIG_NAME if not config_location else config_location
-        self._conf = {}
-        if autocreate:
-            self.make_config(config)
-        if autoload:
-            self._conf = self.load_config()
-
-    def __getitem__(self, key):
-        return self._conf[key]
-
-    def __nonzero__(self):
-        if self._conf:
-            return True
-        return False
-
-    def __eq__(self):
-        return self._conf.__eq__()
-
-    def __repr__(self):
-        return 'RcConf<%s>' % self._conf.__repr__()
-
-    def make_config(self, config):
-        """
-        Saves given config as a JSON dump in the _conf_name location
-
-        :param config:
-        :type config:
-        """
-        update = False
-        if os.path.exists(self._conf_name):
-            update = True
-        with open(self._conf_name, 'wb') as f:
-            json.dump(config, f, indent=4)
-
-        if update:
-            sys.stdout.write('Updated config in %s\n' % self._conf_name)
-        else:
-            sys.stdout.write('Created new config in %s\n' % self._conf_name)
-
-    def update_config(self, new_config):
-        """
-        Reads the JSON config updates it's values with new_config and
-        saves it back as JSON dump
-
-        :param new_config:
-        """
-        config = {}
-        try:
-            with open(self._conf_name, 'rb') as conf:
-                config = json.load(conf)
-        except IOError, e:
-            sys.stderr.write(str(e) + '\n')
-
-        config.update(new_config)
-        self.make_config(config)
-
-    def load_config(self):
-        """
-        Loads config from file and returns loaded JSON object
-        """
-        try:
-            with open(self._conf_name, 'rb') as conf:
-                return  json.load(conf)
-        except IOError, e:
-            #sys.stderr.write(str(e) + '\n')
-            pass
-
-
-def api_call(apikey, apihost, format, method=None, **kw):
-    """
-    Api_call wrapper for RhodeCode
-
-    :param apikey:
-    :param apihost:
-    :param format: formatting, pretty means prints and pprint of json
-     json returns unparsed json
-    :param method:
-    """
-    def _build_data(random_id):
-        """
-        Builds API data with given random ID
-
-        :param random_id:
-        :type random_id:
-        """
-        return {
-            "id": random_id,
-            "api_key": apikey,
-            "method": method,
-            "args": kw
-        }
-
-    if not method:
-        raise Exception('please specify method name !')
-    id_ = random.randrange(1, 9999)
-    req = urllib2.Request('%s/_admin/api' % apihost,
-                      data=json.dumps(_build_data(id_)),
-                      headers={'content-type': 'text/plain'})
-    if format == FORMAT_PRETTY:
-        sys.stdout.write('calling %s to %s \n' % (req.get_data(), apihost))
-    ret = urllib2.urlopen(req)
-    raw_json = ret.read()
-    json_data = json.loads(raw_json)
-    id_ret = json_data['id']
-    _formatted_json = pprint.pformat(json_data)
-    if id_ret == id_:
-        if format == FORMAT_JSON:
-            sys.stdout.write(str(raw_json))
-        else:
-            sys.stdout.write('rhodecode returned:\n%s\n' % (_formatted_json))
-
-    else:
-        raise Exception('something went wrong. '
-                        'ID mismatch got %s, expected %s | %s' % (
-                                            id_ret, id_, _formatted_json))
+from rhodecode.bin.base import api_call, RcConf, FORMAT_JSON, FORMAT_PRETTY
 
 
 def argparser(argv):
     usage = (
-      "rhodecode_api [-h] [--format=FORMAT] [--apikey=APIKEY] [--apihost=APIHOST] "
-      " [--config=CONFIG] "
-      "_create_config or METHOD <key:val> <key2:val> ..."
+      "rhodecode-api [-h] [--format=FORMAT] [--apikey=APIKEY] [--apihost=APIHOST] "
+      "[--config=CONFIG] [--save-config] "
+      "METHOD <key:val> <key2:val> ...\n"
+      "Create config file: rhodecode-gist --apikey=<key> --apihost=http://rhodecode.server --save-config"
     )
 
     parser = argparse.ArgumentParser(description='RhodeCode API cli',
@@ -188,9 +46,10 @@
     group.add_argument('--apikey', help='api access key')
     group.add_argument('--apihost', help='api host')
     group.add_argument('--config', help='config file')
+    group.add_argument('--save-config', action='store_true', help='save the given config into a file')
 
     group = parser.add_argument_group('API')
-    group.add_argument('method', metavar='METHOD', type=str,
+    group.add_argument('method', metavar='METHOD', nargs='?', type=str, default=None,
             help='API method name to call followed by key:value attributes',
     )
     group.add_argument('--format', dest='format', type=str,
@@ -216,12 +75,13 @@
     parser, args, other = argparser(argv)
 
     api_credentials_given = (args.apikey and args.apihost)
-    if args.method == '_create_config':
+    if args.save_config:
         if not api_credentials_given:
-            raise parser.error('_create_config requires --apikey and --apihost')
+            raise parser.error('--save-config requires --apikey and --apihost')
         conf = RcConf(config_location=args.config,
                       autocreate=True, config={'apikey': args.apikey,
                                                'apihost': args.apihost})
+        sys.exit()
 
     if not conf:
         conf = RcConf(config_location=args.config, autoload=True)
@@ -233,8 +93,6 @@
     apikey = args.apikey or conf['apikey']
     host = args.apihost or conf['apihost']
     method = args.method
-    if method == '_create_config':
-        sys.exit()
 
     try:
         margs = dict(map(lambda s: s.split(':', 1), other))