42
49
from gtk import gdk
43
51
if gtk.pygtk_version < (2, 8):
44
die_cli('PIDA requires PyGTK >= 2.8. It only found %s.%s'
45
% gtk.pygtk_version[:2])
47
die_cli('PIDA requires Python GTK bindings. They were not found.')
52
die_cli(_('PIDA requires PyGTK >= 2.8. It only found %(major)s.%(minor)s')
53
% {'major':gtk.pygtk_version[:2][0], 'minor':gtk.pygtk_version[:2][1]})
54
except ImportError, e:
55
die_cli(_('PIDA requires Python GTK bindings. They were not found.'), e)
59
from kiwi.ui.dialogs import error
60
def die_gui(message, exception):
52
61
"""Die in a GUI way."""
53
hig.error("Fatal error, cannot start PIDA",
62
error(_('Fatal error, cannot start PIDA'),
63
long='%s\n%s' % (message, exception))
66
except ImportError, e:
67
die_cli(_('Kiwi needs to be installed to run PIDA'), e)
61
71
if sys.version_info < (2,4):
62
die_gui('Python 2.4 is required to run PIDA. Only %s.%s was found.' %
66
# Setuptools is needed to run PIDA
70
pkg_resources.require('pida')
72
die_gui('PIDA requires <i>setuptools</i> module to be installed.')
72
die_gui(_('Python 2.4 is required to run PIDA. Only %(major)s.%(minor)s was found.') %
73
{'major':sys.version_info[:2][0], 'minor':sys.version_info[:2][1]})
75
76
# This can test if PIDA is installed
77
from pida.core import boss
78
from pida.pidagtk import debugwindow
79
from pida.model import model
81
die_gui('PIDA is not correctly install, the <i>pida</i> module was not found.')
85
# Start lock threads here because an exception may be raised
86
# and the dialog would be frozen
89
atexit.register(gdk.threads_leave)
91
# Now we can use a gui exception hook
92
old_excepthook = sys.excepthook
93
sys.excepthook = debugwindow.show
97
from pkg_resources import resource_string
78
from pida.core.environment import Environment
79
from pida.core.boss import Boss
80
from pida import PIDA_VERSION
81
except ImportError, e:
82
die_gui(_('The pida package could not be found.'), e)
86
print _('PIDA, version %s') % PIDA_VERSION
99
version_file = resource_string('pida', 'data/version')
101
version_file = 'unversioned'
105
pida_version = get_version()
108
class environment(object):
109
"""Handle environment variable and command line arguments"""
111
self.__editorname = None
114
def __parseargs(self):
115
home_dir_option = None
116
default_home = os.path.join(os.path.expanduser('~'), '.pida')
118
if default_home == os.path.join('~', '.pida') \
119
and sys.platform == "win32":
122
from win32com.shell import shell, shellcon
123
default_home = shell.SHGetSpecialFolderLocation(
125
shellcon.CSIDL_APPDATA
127
default_home = shell.SHGetPathFromIDList(default_home)
128
default_home = os.path.join(default_home, "Pida")
132
op = optparse.OptionParser()
133
op.add_option('-d', '--home-directory', type='string', nargs=1,
135
help=('The location of the pida home directory. '
136
'If this directory does not exist, it will be created. '
137
'Default: %s' % default_home),
138
default=default_home)
139
op.add_option('-o', '--option', type='string', nargs=1,
141
help=('Set an option. Options should be in the form: '
142
'servicename/group/name=value. '
143
'For example (without quotes): '
144
'"pida -o editormanager/general/editor_type=Vim". '
145
'More than one option can be set by repeated use of -o.'))
146
op.add_option('-v', '--version', action='store_true',
147
help='Print version information and exit.')
148
op.add_option('-D', '--debug', action='store_true',
149
help=('Run PIDA with added debug information. '
150
'This merely sets the environment variables: '
151
'PIDA_DEBUG=1 and PIDA_LOG_STDERR=1, '
152
'and so the same effect may be achieved by setting them.'))
153
op.add_option('-r', '--remote', action='store_true',
154
help=('Run PIDA remotely to open a file in an existing instance '
155
'of PIDA. Usage pida -r <filename>.'))
156
op.add_option('-F', '--first-run-wizard', action='store_true',
157
help='Run the PIDA first time wizard')
158
op.add_option('-t', '--testing-mode', action='store_true',
159
help='Run te PIDA self test')
160
opts, args = op.parse_args()
161
envhome = self.__parseenv()
162
if envhome is not None:
163
home_dir_option = envhome
165
home_dir_option = opts.home_directory
166
self.__home_dir = home_dir_option
167
self.__create_home_tree(self.__home_dir)
171
def __parseenv(self):
172
if 'PIDA_HOME' in os.environ:
173
return os.environ['PIDA_HOME']
175
def __create_home_tree(self, root):
178
for name in ['conf', 'log', 'run', 'vcs', 'sockets', 'data',
179
'projects', 'library']:
180
path = os.path.join(root, name)
185
def __mkdir(self, path):
186
if not os.path.exists(path):
189
def get_positional_args(self):
191
positional_args = property(get_positional_args)
193
def get_home_dir(self):
194
return self.__home_dir
195
home_dir = property(get_home_dir)
197
def get_version(self):
199
version = property(get_version)
201
def override_configuration_system(self, services):
202
if self.__editorname:
203
svc = services.get('editormanager')
204
svc.opts.general__type = self.__editorname
205
if not self.opts.option:
207
for opt in self.opts.option:
209
name, value = opt.split('=', 1)
211
parts = name.split('/', 3)
213
service, group, option = parts
215
svc = services.get(service)
216
optname = '%s__%s' % (group, option)
217
model.property_evading_setattr(svc.opts,
220
print ('failed to set an option %s %s' %
221
(service, group, option))
223
def override_editor_option(self, editorname):
224
self.__editorname = editorname
226
class PosixSignalHandler(object):
228
def __init__(self, app):
230
signal.signal(signal.SIGTERM, self.handle_SIGTERM)
232
def handle_SIGTERM(self, signum):
233
self.log.error('PIDA stopped by SIGTERM')
234
self._app.boss.stop()
237
class application(object):
238
"""The PIDA Application."""
243
mainstop=gtk.main_quit,
244
environment=environment()):
245
self._signal_handler = PosixSignalHandler(self)
246
self.__mainloop = mainloop
247
self.__mainstop = mainstop
248
self.__env = environment
249
self.__boss = bosstype(application=self, env=self.__env)
250
self.boss = self.__boss
251
self.env = self.__env
263
def run_pida(env, bosstype, mainloop, mainstop):
264
app = application(bosstype, mainloop, mainstop, env)
265
if run_firstrun(env, app.boss):
94
start_success = b.start()
272
def run_version(env, *args):
273
print 'PIDA, version %s' % pida_version
277
def run_remote(env, *args):
278
import pida.utils.pidaremote as pidaremote
279
pidaremote.main(env.home_dir, env.positional_args)
283
def run_firstrun(env, boss):
284
first_filaname = os.path.join(env.home_dir, '.firstrun')
286
if not os.path.exists(first_filaname) or env.opts.first_run_wizard:
287
import pida.utils.firstrun as firstrun
288
ftw = firstrun.FirstTimeWindow(boss.editors)
289
response, editor = ftw.run(first_filaname)
290
if response == gtk.RESPONSE_ACCEPT:
292
raise RuntimeError('No Working Editors')
294
env.override_editor_option(editor)
302
def main(bosstype=boss.boss, mainloop=gtk.main, mainstop=gtk.main_quit):
303
warnings.filterwarnings("ignore", category=DeprecationWarning)
106
def force_quit(signum, frame):
107
os.kill(os.getpid(), 9)
109
# Set the signal handler and a 5-second alarm
113
def traceit(frame, event, arg):
114
ss = frame.f_code.co_stacksize
115
fn = frame.f_code.co_filename
117
co = linecache.getline(fn, ln).strip()
118
print '%s %s:%s %s' % (ss * '>', fn, ln, co)
119
for k, i in frame.f_locals.items():
121
print '%s=%s' % (k, i)
123
print k, 'unable to print value'
125
sys.settrace(traceit)
128
env = Environment(sys.argv)
129
sys.argv = sys.argv[:1]
306
131
os.environ['PIDA_DEBUG'] = '1'
307
132
os.environ['PIDA_LOG_STDERR'] = '1'
308
if env.opts.testing_mode:
309
sys.excepthook = old_excepthook
310
if env.opts.version is not None:
134
warnings.filterwarnings("ignore")
311
138
run_func = run_version
312
elif env.opts.remote:
313
run_func = run_remote
315
140
run_func = run_pida
317
exit_val = run_func(env, bosstype, mainloop, mainstop)
141
exit_val = run_func(env)
142
signal.signal(signal.SIGALRM, force_quit)
318
144
sys.exit(exit_val)
321
if __name__ == '__main__':
147
# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79: