##// END OF EJS Templates
Change command line tool config location to .config/kallithea
Bradley M. Kuhn -
r4181:e5cb0a4e kallithea-2.2.5-r...
parent child Browse files
Show More
@@ -1,27 +1,26 b''
1 1 syntax: glob
2 2 *.pyc
3 3 *.swp
4 4 *.sqlite
5 5 *.tox
6 6 *.egg-info
7 7 *.egg
8 8
9 9 syntax: regexp
10 10 ^rcextensions
11 11 ^build
12 12 ^dist/
13 13 ^docs/build/
14 14 ^docs/_build/
15 15 ^data$
16 16 ^sql_dumps/
17 17 ^\.settings$
18 18 ^\.project$
19 19 ^\.pydevproject$
20 20 ^\.coverage$
21 21 ^rhodecode\.db$
22 22 ^test\.db$
23 23 ^RhodeCode\.egg-info$
24 24 ^rc.*\.ini$
25 25 ^fabfile.py
26 ^\.rhodecode$
27 26 ^\.idea$
@@ -1,167 +1,167 b''
1 1 # -*- coding: utf-8 -*-
2 2 # This program is free software: you can redistribute it and/or modify
3 3 # it under the terms of the GNU General Public License as published by
4 4 # the Free Software Foundation, either version 3 of the License, or
5 5 # (at your option) any later version.
6 6 #
7 7 # This program is distributed in the hope that it will be useful,
8 8 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 10 # GNU General Public License for more details.
11 11 #
12 12 # You should have received a copy of the GNU General Public License
13 13 # along with this program. If not, see <http://www.gnu.org/licenses/>.
14 14 """
15 15 rhodecode.bin.base
16 16 ~~~~~~~~~~~~~~~~~~
17 17
18 18 Base utils for shell scripts
19 19
20 20 :created_on: May 09, 2013
21 21 :author: marcink
22 22 :copyright: (c) 2013 RhodeCode GmbH.
23 23 :license: GPLv3, see LICENSE for more details.
24 24 """
25 25
26 26 import os
27 27 import sys
28 28 import random
29 29 import urllib2
30 30 import pprint
31 31
32 32 try:
33 33 from rhodecode.lib.ext_json import json
34 34 except ImportError:
35 35 try:
36 36 import simplejson as json
37 37 except ImportError:
38 38 import json
39 39
40 CONFIG_NAME = '.rhodecode'
40 CONFIG_NAME = '.config/kallithea'
41 41 FORMAT_PRETTY = 'pretty'
42 42 FORMAT_JSON = 'json'
43 43
44 44
45 45 def api_call(apikey, apihost, method=None, **kw):
46 46 """
47 47 Api_call wrapper for RhodeCode.
48 48
49 49 :param apikey:
50 50 :param apihost:
51 51 :param format: formatting, pretty means prints and pprint of json
52 52 json returns unparsed json
53 53 :param method:
54 54 :returns: json response from server
55 55 """
56 56 def _build_data(random_id):
57 57 """
58 58 Builds API data with given random ID
59 59
60 60 :param random_id:
61 61 """
62 62 return {
63 63 "id": random_id,
64 64 "api_key": apikey,
65 65 "method": method,
66 66 "args": kw
67 67 }
68 68
69 69 if not method:
70 70 raise Exception('please specify method name !')
71 71 apihost = apihost.rstrip('/')
72 72 id_ = random.randrange(1, 9999)
73 73 req = urllib2.Request('%s/_admin/api' % apihost,
74 74 data=json.dumps(_build_data(id_)),
75 75 headers={'content-type': 'text/plain'})
76 76 ret = urllib2.urlopen(req)
77 77 raw_json = ret.read()
78 78 json_data = json.loads(raw_json)
79 79 id_ret = json_data['id']
80 80 if id_ret == id_:
81 81 return json_data
82 82
83 83 else:
84 84 _formatted_json = pprint.pformat(json_data)
85 85 raise Exception('something went wrong. '
86 86 'ID mismatch got %s, expected %s | %s' % (
87 87 id_ret, id_, _formatted_json))
88 88
89 89
90 90 class RcConf(object):
91 91 """
92 92 RhodeCode config for API
93 93
94 94 conf = RcConf()
95 95 conf['key']
96 96
97 97 """
98 98
99 99 def __init__(self, config_location=None, autoload=True, autocreate=False,
100 100 config=None):
101 101 HOME = os.getenv('HOME', os.getenv('USERPROFILE')) or ''
102 102 HOME_CONF = os.path.abspath(os.path.join(HOME, CONFIG_NAME))
103 103 self._conf_name = HOME_CONF if not config_location else config_location
104 104 self._conf = {}
105 105 if autocreate:
106 106 self.make_config(config)
107 107 if autoload:
108 108 self._conf = self.load_config()
109 109
110 110 def __getitem__(self, key):
111 111 return self._conf[key]
112 112
113 113 def __nonzero__(self):
114 114 if self._conf:
115 115 return True
116 116 return False
117 117
118 118 def __eq__(self):
119 119 return self._conf.__eq__()
120 120
121 121 def __repr__(self):
122 122 return 'RcConf<%s>' % self._conf.__repr__()
123 123
124 124 def make_config(self, config):
125 125 """
126 126 Saves given config as a JSON dump in the _conf_name location
127 127
128 128 :param config:
129 129 """
130 130 update = False
131 131 if os.path.exists(self._conf_name):
132 132 update = True
133 133 with open(self._conf_name, 'wb') as f:
134 134 json.dump(config, f, indent=4)
135 135
136 136 if update:
137 137 sys.stdout.write('Updated config in %s\n' % self._conf_name)
138 138 else:
139 139 sys.stdout.write('Created new config in %s\n' % self._conf_name)
140 140
141 141 def update_config(self, new_config):
142 142 """
143 143 Reads the JSON config updates it's values with new_config and
144 144 saves it back as JSON dump
145 145
146 146 :param new_config:
147 147 """
148 148 config = {}
149 149 try:
150 150 with open(self._conf_name, 'rb') as conf:
151 151 config = json.load(conf)
152 152 except IOError, e:
153 153 sys.stderr.write(str(e) + '\n')
154 154
155 155 config.update(new_config)
156 156 self.make_config(config)
157 157
158 158 def load_config(self):
159 159 """
160 160 Loads config from file and returns loaded JSON object
161 161 """
162 162 try:
163 163 with open(self._conf_name, 'rb') as conf:
164 164 return json.load(conf)
165 165 except IOError, e:
166 166 #sys.stderr.write(str(e) + '\n')
167 167 pass
@@ -1,171 +1,171 b''
1 1 # -*- coding: utf-8 -*-
2 2 # This program is free software: you can redistribute it and/or modify
3 3 # it under the terms of the GNU General Public License as published by
4 4 # the Free Software Foundation, either version 3 of the License, or
5 5 # (at your option) any later version.
6 6 #
7 7 # This program is distributed in the hope that it will be useful,
8 8 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 10 # GNU General Public License for more details.
11 11 #
12 12 # You should have received a copy of the GNU General Public License
13 13 # along with this program. If not, see <http://www.gnu.org/licenses/>.
14 14 """
15 15 rhodecode.bin.rhodecode_gist
16 16 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
17 17
18 18 Gist CLI client for RhodeCode
19 19
20 20 :created_on: May 9, 2013
21 21 :author: marcink
22 22 :copyright: (c) 2013 RhodeCode GmbH.
23 23 :license: GPLv3, see LICENSE for more details.
24 24 """
25 25
26 26 from __future__ import with_statement
27 27 import os
28 28 import sys
29 29 import stat
30 30 import argparse
31 31 import fileinput
32 32
33 33 from rhodecode.bin.base import json, api_call, RcConf, FORMAT_JSON, FORMAT_PRETTY
34 34
35 35
36 36 def argparser(argv):
37 37 usage = (
38 38 "rhodecode-gist [-h] [--format=FORMAT] [--apikey=APIKEY] [--apihost=APIHOST] "
39 39 "[--config=CONFIG] [--save-config] [GIST OPTIONS] "
40 40 "[filename or stdin use - for terminal stdin ]\n"
41 41 "Create config file: rhodecode-gist --apikey=<key> --apihost=http://rhodecode.server --save-config"
42 42 )
43 43
44 44 parser = argparse.ArgumentParser(description='RhodeCode Gist cli',
45 45 usage=usage)
46 46
47 47 ## config
48 48 group = parser.add_argument_group('config')
49 49 group.add_argument('--apikey', help='api access key')
50 50 group.add_argument('--apihost', help='api host')
51 group.add_argument('--config', help='config file path DEFAULT: ~/.rhodecode')
51 group.add_argument('--config', help='config file path DEFAULT: ~/.config/kallithea')
52 52 group.add_argument('--save-config', action='store_true',
53 53 help='save the given config into a file')
54 54
55 55 group = parser.add_argument_group('GIST')
56 56 group.add_argument('-p', '--private', action='store_true',
57 57 help='create private Gist')
58 58 group.add_argument('-f', '--filename',
59 59 help='set uploaded gist filename, '
60 60 'also defines syntax highlighting')
61 61 group.add_argument('-d', '--description', help='Gist description')
62 62 group.add_argument('-l', '--lifetime', metavar='MINUTES',
63 63 help='gist lifetime in minutes, -1 (DEFAULT) is forever')
64 64 group.add_argument('--format', dest='format', type=str,
65 65 help='output format DEFAULT: `%s` can '
66 66 'be also `%s`' % (FORMAT_PRETTY, FORMAT_JSON),
67 67 default=FORMAT_PRETTY
68 68 )
69 69 args, other = parser.parse_known_args()
70 70 return parser, args, other
71 71
72 72
73 73 def _run(argv):
74 74 conf = None
75 75 parser, args, other = argparser(argv)
76 76
77 77 api_credentials_given = (args.apikey and args.apihost)
78 78 if args.save_config:
79 79 if not api_credentials_given:
80 80 raise parser.error('--save-config requires --apikey and --apihost')
81 81 conf = RcConf(config_location=args.config,
82 82 autocreate=True, config={'apikey': args.apikey,
83 83 'apihost': args.apihost})
84 84 sys.exit()
85 85
86 86 if not conf:
87 87 conf = RcConf(config_location=args.config, autoload=True)
88 88 if not conf:
89 89 if not api_credentials_given:
90 90 parser.error('Could not find config file and missing '
91 91 '--apikey or --apihost in params')
92 92
93 93 apikey = args.apikey or conf['apikey']
94 94 host = args.apihost or conf['apihost']
95 95 DEFAULT_FILENAME = 'gistfile1.txt'
96 96 if other:
97 97 # skip multifiles for now
98 98 filename = other[0]
99 99 if filename == '-':
100 100 filename = DEFAULT_FILENAME
101 101 gist_content = ''
102 102 for line in fileinput.input('-'):
103 103 gist_content += line
104 104 else:
105 105 with open(filename, 'rb') as f:
106 106 gist_content = f.read()
107 107
108 108 else:
109 109 filename = DEFAULT_FILENAME
110 110 gist_content = None
111 111 # little bit hacky but cross platform check where the
112 112 # stdin comes from we skip the terminal case it can be handled by '-'
113 113 mode = os.fstat(0).st_mode
114 114 if stat.S_ISFIFO(mode):
115 115 # "stdin is piped"
116 116 gist_content = sys.stdin.read()
117 117 elif stat.S_ISREG(mode):
118 118 # "stdin is redirected"
119 119 gist_content = sys.stdin.read()
120 120 else:
121 121 # "stdin is terminal"
122 122 pass
123 123
124 124 # make sure we don't upload binary stuff
125 125 if gist_content and '\0' in gist_content:
126 126 raise Exception('Error: binary files upload is not possible')
127 127
128 128 filename = os.path.basename(args.filename or filename)
129 129 if gist_content:
130 130 files = {
131 131 filename: {
132 132 'content': gist_content,
133 133 'lexer': None
134 134 }
135 135 }
136 136
137 137 margs = dict(
138 138 lifetime=args.lifetime,
139 139 description=args.description,
140 140 gist_type='private' if args.private else 'public',
141 141 files=files
142 142 )
143 143
144 144 json_data = api_call(apikey, host, 'create_gist', **margs)['result']
145 145 if args.format == FORMAT_JSON:
146 146 print json.dumps(json_data)
147 147 elif args.format == FORMAT_PRETTY:
148 148 print json_data
149 149 print 'Created %s gist %s' % (json_data['gist']['type'],
150 150 json_data['gist']['url'])
151 151 return 0
152 152
153 153
154 154 def main(argv=None):
155 155 """
156 156 Main execution function for cli
157 157
158 158 :param argv:
159 159 """
160 160 if argv is None:
161 161 argv = sys.argv
162 162
163 163 try:
164 164 return _run(argv)
165 165 except Exception, e:
166 166 print e
167 167 return 1
168 168
169 169
170 170 if __name__ == '__main__':
171 171 sys.exit(main(sys.argv))
General Comments 0
You need to be logged in to leave comments. Login now