##// END OF EJS Templates
gist cli should convert given paths to basenames
marcink -
r3845:0a023c38 beta
parent child Browse files
Show More
@@ -1,159 +1,159
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.bin.gist
3 rhodecode.bin.gist
4 ~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~
5
5
6 Gist CLI client for RhodeCode
6 Gist CLI client for RhodeCode
7
7
8 :created_on: May 9, 2013
8 :created_on: May 9, 2013
9 :author: marcink
9 :author: marcink
10 :copyright: (C) 2010-2013 Marcin Kuzminski <marcin@python-works.com>
10 :copyright: (C) 2010-2013 Marcin Kuzminski <marcin@python-works.com>
11 :license: GPLv3, see COPYING for more details.
11 :license: GPLv3, see COPYING for more details.
12 """
12 """
13 # This program is free software: you can redistribute it and/or modify
13 # This program is free software: you can redistribute it and/or modify
14 # it under the terms of the GNU General Public License as published by
14 # it under the terms of the GNU General Public License as published by
15 # the Free Software Foundation, either version 3 of the License, or
15 # the Free Software Foundation, either version 3 of the License, or
16 # (at your option) any later version.
16 # (at your option) any later version.
17 #
17 #
18 # This program is distributed in the hope that it will be useful,
18 # This program is distributed in the hope that it will be useful,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # GNU General Public License for more details.
21 # GNU General Public License for more details.
22 #
22 #
23 # You should have received a copy of the GNU General Public License
23 # You should have received a copy of the GNU General Public License
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25
25
26 from __future__ import with_statement
26 from __future__ import with_statement
27 import os
27 import os
28 import sys
28 import sys
29 import stat
29 import stat
30 import argparse
30 import argparse
31 import fileinput
31 import fileinput
32
32
33 from rhodecode.bin.base import api_call, RcConf
33 from rhodecode.bin.base import api_call, RcConf
34
34
35
35
36 def argparser(argv):
36 def argparser(argv):
37 usage = (
37 usage = (
38 "rhodecode-gist [-h] [--format=FORMAT] [--apikey=APIKEY] [--apihost=APIHOST] "
38 "rhodecode-gist [-h] [--format=FORMAT] [--apikey=APIKEY] [--apihost=APIHOST] "
39 "[--config=CONFIG] [--save-config] "
39 "[--config=CONFIG] [--save-config] "
40 "[filename or stdin use - for terminal stdin ]\n"
40 "[filename or stdin use - for terminal stdin ]\n"
41 "Create config file: rhodecode-gist --apikey=<key> --apihost=http://rhodecode.server --save-config"
41 "Create config file: rhodecode-gist --apikey=<key> --apihost=http://rhodecode.server --save-config"
42 )
42 )
43
43
44 parser = argparse.ArgumentParser(description='RhodeCode Gist cli',
44 parser = argparse.ArgumentParser(description='RhodeCode Gist cli',
45 usage=usage)
45 usage=usage)
46
46
47 ## config
47 ## config
48 group = parser.add_argument_group('config')
48 group = parser.add_argument_group('config')
49 group.add_argument('--apikey', help='api access key')
49 group.add_argument('--apikey', help='api access key')
50 group.add_argument('--apihost', help='api host')
50 group.add_argument('--apihost', help='api host')
51 group.add_argument('--config', help='config file')
51 group.add_argument('--config', help='config file')
52 group.add_argument('--save-config', action='store_true',
52 group.add_argument('--save-config', action='store_true',
53 help='save the given config into a file')
53 help='save the given config into a file')
54
54
55 group = parser.add_argument_group('GIST')
55 group = parser.add_argument_group('GIST')
56 group.add_argument('-f', '--filename', help='set uploaded gist filename')
56 group.add_argument('-f', '--filename', help='set uploaded gist filename')
57 group.add_argument('-p', '--private', action='store_true',
57 group.add_argument('-p', '--private', action='store_true',
58 help='Create private Gist')
58 help='Create private Gist')
59 group.add_argument('-d', '--description', help='Gist description')
59 group.add_argument('-d', '--description', help='Gist description')
60 group.add_argument('-l', '--lifetime', metavar='MINUTES',
60 group.add_argument('-l', '--lifetime', metavar='MINUTES',
61 help='Gist lifetime in minutes, -1 (Default) is forever')
61 help='Gist lifetime in minutes, -1 (Default) is forever')
62
62
63 args, other = parser.parse_known_args()
63 args, other = parser.parse_known_args()
64 return parser, args, other
64 return parser, args, other
65
65
66
66
67 def _run(argv):
67 def _run(argv):
68 conf = None
68 conf = None
69 parser, args, other = argparser(argv)
69 parser, args, other = argparser(argv)
70
70
71 api_credentials_given = (args.apikey and args.apihost)
71 api_credentials_given = (args.apikey and args.apihost)
72 if args.save_config:
72 if args.save_config:
73 if not api_credentials_given:
73 if not api_credentials_given:
74 raise parser.error('--save-config requires --apikey and --apihost')
74 raise parser.error('--save-config requires --apikey and --apihost')
75 conf = RcConf(config_location=args.config,
75 conf = RcConf(config_location=args.config,
76 autocreate=True, config={'apikey': args.apikey,
76 autocreate=True, config={'apikey': args.apikey,
77 'apihost': args.apihost})
77 'apihost': args.apihost})
78 sys.exit()
78 sys.exit()
79
79
80 if not conf:
80 if not conf:
81 conf = RcConf(config_location=args.config, autoload=True)
81 conf = RcConf(config_location=args.config, autoload=True)
82 if not conf:
82 if not conf:
83 if not api_credentials_given:
83 if not api_credentials_given:
84 parser.error('Could not find config file and missing '
84 parser.error('Could not find config file and missing '
85 '--apikey or --apihost in params')
85 '--apikey or --apihost in params')
86
86
87 apikey = args.apikey or conf['apikey']
87 apikey = args.apikey or conf['apikey']
88 host = args.apihost or conf['apihost']
88 host = args.apihost or conf['apihost']
89 DEFAULT_FILENAME = 'gistfile1.txt'
89 DEFAULT_FILENAME = 'gistfile1.txt'
90 if other:
90 if other:
91 # skip multifiles for now
91 # skip multifiles for now
92 filename = other[0]
92 filename = other[0]
93 if filename == '-':
93 if filename == '-':
94 filename = DEFAULT_FILENAME
94 filename = DEFAULT_FILENAME
95 gist_content = ''
95 gist_content = ''
96 for line in fileinput.input():
96 for line in fileinput.input():
97 gist_content += line
97 gist_content += line
98 else:
98 else:
99 with open(filename, 'rb') as f:
99 with open(filename, 'rb') as f:
100 gist_content = f.read()
100 gist_content = f.read()
101
101
102 else:
102 else:
103 filename = DEFAULT_FILENAME
103 filename = DEFAULT_FILENAME
104 gist_content = None
104 gist_content = None
105 # little bit hacky but cross platform check where the
105 # little bit hacky but cross platform check where the
106 # stdin comes from we skip the terminal case it can be handled by '-'
106 # stdin comes from we skip the terminal case it can be handled by '-'
107 mode = os.fstat(0).st_mode
107 mode = os.fstat(0).st_mode
108 if stat.S_ISFIFO(mode):
108 if stat.S_ISFIFO(mode):
109 # "stdin is piped"
109 # "stdin is piped"
110 gist_content = sys.stdin.read()
110 gist_content = sys.stdin.read()
111 elif stat.S_ISREG(mode):
111 elif stat.S_ISREG(mode):
112 # "stdin is redirected"
112 # "stdin is redirected"
113 gist_content = sys.stdin.read()
113 gist_content = sys.stdin.read()
114 else:
114 else:
115 # "stdin is terminal"
115 # "stdin is terminal"
116 pass
116 pass
117
117
118 # make sure we don't upload binary stuff
118 # make sure we don't upload binary stuff
119 if gist_content and '\0' in gist_content:
119 if gist_content and '\0' in gist_content:
120 raise Exception('Error: binary files upload is not possible')
120 raise Exception('Error: binary files upload is not possible')
121
121
122 filename = args.filename or filename
122 filename = os.path.basename(args.filename or filename)
123 if gist_content:
123 if gist_content:
124 files = {
124 files = {
125 filename: {
125 filename: {
126 'content': gist_content,
126 'content': gist_content,
127 'lexer': None
127 'lexer': None
128 }
128 }
129 }
129 }
130
130
131 margs = dict(
131 margs = dict(
132 gist_lifetime=args.lifetime,
132 gist_lifetime=args.lifetime,
133 gist_description=args.description,
133 gist_description=args.description,
134 gist_type='private' if args.private else 'public',
134 gist_type='private' if args.private else 'public',
135 files=files
135 files=files
136 )
136 )
137
137
138 api_call(apikey, host, 'json', 'create_gist', **margs)
138 api_call(apikey, host, 'json', 'create_gist', **margs)
139 return 0
139 return 0
140
140
141
141
142 def main(argv=None):
142 def main(argv=None):
143 """
143 """
144 Main execution function for cli
144 Main execution function for cli
145
145
146 :param argv:
146 :param argv:
147 """
147 """
148 if argv is None:
148 if argv is None:
149 argv = sys.argv
149 argv = sys.argv
150
150
151 try:
151 try:
152 return _run(argv)
152 return _run(argv)
153 except Exception, e:
153 except Exception, e:
154 print e
154 print e
155 return 1
155 return 1
156
156
157
157
158 if __name__ == '__main__':
158 if __name__ == '__main__':
159 sys.exit(main(sys.argv))
159 sys.exit(main(sys.argv))
General Comments 0
You need to be logged in to leave comments. Login now