-
Notifications
You must be signed in to change notification settings - Fork 1
/
glader.py
executable file
·205 lines (170 loc) · 6.25 KB
/
glader.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
""" glader.py
...Writes GTK boilerplate code based on a Glade file.
-Christopher Welborn 09-14-2014
"""
import os
import sys
import traceback
from glader_core import (
VERSIONSTR,
import_fail,
)
from glader_util import GladeFile
from glader_ui import gui_main
try:
from docopt import docopt
except ImportError as eximp:
import_fail(eximp)
try:
from pygments import highlight as pyg_highlight
from pygments.lexers import get_lexer_by_name
from pygments.formatters import Terminal256Formatter
except ImportError:
highlight_warn = 'You must `pip install pygments`.'
has_pygments = False
def highlight_code(code):
return code
else:
# For the --highlight option, when pygments is available.
pyg_lexer = get_lexer_by_name('python3')
pyg_formatter = Terminal256Formatter(bg='dark', style='monokai')
highlight_warn = ''
has_pygments = True
def highlight_code(code):
return pyg_highlight(code, pyg_lexer, pyg_formatter).rstrip()
SCRIPT = os.path.split(os.path.abspath(sys.argv[0]))[1]
SCRIPTDIR = os.path.abspath(sys.path[0])
USAGESTR = f"""{VERSIONSTR}
Usage:
{SCRIPT} -h | -v
{SCRIPT} [FILE] [OUTFILE] [-D] [-d] [-g] [-l]
{SCRIPT} FILE OUTFILE -o [-D] [-d] [-l]
{SCRIPT} FILE [-H | -L] [-D] [-d] [-l]
Options:
FILE : Glade file to parse.
OUTFILE : File name for output.
If - is given, output will be printed to stdout.
-D,--debug : Show more info on errors.
-d,--dynamic : Use dynamic object initialization method.
-g,--gui : Force use of a GUI, even when an output file is given.
You still have to use the 'Save' button to apply
changes.
-H,--highlight : Syntax highlight the generated code and print to
stdout. {highlight_warn}
-h,--help : Show this help message.
-L,--layout : Show Glader layout for the file.
-l,--lib : Generate a usable Gtk.Window class only, not a
script.
-o,--overwrite : Overwrite existing files without confirmation.
-v,--version : Show version.
"""
DEBUG = ('-D' in sys.argv) or ('--debug' in sys.argv)
def main(argd):
""" Main entry point, expects doctopt arg dict as argd """
filepath = argd['FILE']
if filepath and (not os.path.exists(filepath)):
print('\nFile does not exist: {}'.format(filepath))
return 1
cmdline_cmds = argd['--layout'] or argd['--highlight']
outfile = '-' if cmdline_cmds else argd['OUTFILE']
# Automatic command line when outputfile is given, unless --gui is used.
if (cmdline_cmds or outfile) and not argd['--gui']:
# Cmdline version.
return do_cmdline(
filepath,
outputfile=outfile,
dynamic_init=argd['--dynamic'],
lib_mode=argd['--lib'],
overwrite=argd['--overwrite'],
highlight=argd['--highlight'],
layout=argd['--layout'],
)
# Full gui. Function exits the program when finished.
if outfile == '-':
# No stdout is used for gui mode.
outfile = None
do_gui(
filepath,
outputfile=outfile,
dynamic_init=argd['--dynamic'],
lib_mode=argd['--lib'],
)
def confirm(question):
""" Confirm an action with a yes/no question. """
ans = input('{} (y/N): '.format(question)).strip().lower()
return ans.startswith('y')
def do_cmdline(
filepath, outputfile=None, dynamic_init=False, lib_mode=False,
overwrite=False, highlight=False, layout=False):
""" Just run the cmdline version. """
if not filepath:
print_err('\nNo filepath provided!')
return 1
if outputfile and os.path.exists(outputfile) and (not overwrite):
msg = '\nFile exists: {}\n\nOverwrite it?'.format(outputfile)
if not confirm(msg):
print('\nUser cancelled.\n')
return 1
fileinfo = get_gladeinfo(filepath, dynamic_init)
if not fileinfo:
print('\nNo usable info was found for this file: {}'.format(filepath))
return 1
if layout:
print(repr(fileinfo))
return 0
content = fileinfo.get_content(lib_mode=lib_mode)
if outputfile.startswith('-'):
# User wants stdout.
print(highlight_code(content) if highlight else content)
else:
try:
with open(outputfile, 'w')as f:
f.write(content)
print('File was generated: {}'.format(outputfile))
except (PermissionError, EnvironmentError) as ex:
print_err('\nError writing file: {}\n{}'.format(outputfile, ex))
return 1
try:
fileinfo.make_executable(outputfile)
print('Mode +rwx (774) was set to make it executable.')
except (PermissionError, EnvironmentError) as experm:
print_err('Unable to make it executable:\n {}'.format(experm))
warnings = fileinfo.warning_msgs()
if warnings:
print_err(f'\n{warnings}')
return 0 if content else 1
def do_gui(
filepath=None, outputfile=None, dynamic_init=False, lib_mode=False):
""" Run the full gui. """
# This function will exit the program when finished.
gui_main(
filepath=filepath,
outputfile=outputfile,
dynamic_init=dynamic_init,
lib_mode=lib_mode,
)
def get_gladeinfo(filepath, dynamic_init=False):
""" Retrieve widget/object info from a glade file. """
try:
gladeinfo = GladeFile(
filepath,
dynamic_init=dynamic_init,
)
except Exception as ex:
print('\nError parsing glade file!: {}\n{}'.format(filepath, ex))
if DEBUG:
print_exc()
return None
return gladeinfo
def print_err(*args, **kwargs):
kwargs['file'] = kwargs.get('file', sys.stderr)
print(*args, **kwargs)
def print_exc():
etype, evalue, etraceback = sys.exc_info()
lines = traceback.format_exception(etype, evalue, etraceback)
print(''.join(lines), file=sys.stderr)
if __name__ == '__main__':
mainret = main(docopt(USAGESTR, version=VERSIONSTR))
sys.exit(mainret)