trivial: Catch bug if package candidate is None
[appstream:software-center.git] / software-center
1 #!/usr/bin/python
2 # Copyright (C) 2009-2011 Canonical
3 #
4 # Authors:
5 #  Michael Vogt
6 #
7 # This program is free software; you can redistribute it and/or modify it under
8 # the terms of the GNU General Public License as published by the Free Software
9 # Foundation; version 3.
10 #
11 # This program is distributed in the hope that it will be useful, but WITHOUT
12 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 # FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
14 # details.
15 #
16 # You should have received a copy of the GNU General Public License along with
17 # this program; if not, write to the Free Software Foundation, Inc.,
18 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
20 # take time stamp as early as python allows this
21 import time
22 time_entering_main = time.time()
23
24
25 from gi.repository import Gtk, GObject
26
27 import gettext
28 import glob
29 import logging
30 import os
31 import time
32 import sys
33
34 from softwarecenter.enums import *
35 from softwarecenter.paths import XAPIAN_BASE_PATH
36 from softwarecenter.utils import (
37     ExecutionTime, mangle_paths_if_running_in_local_checkout)
38 from softwarecenter.version import *
39
40 import softwarecenter.log
41 import softwarecenter.paths
42
43 from softwarecenter.distro import get_distro
44
45 from optparse import OptionParser
46
47 # Enable Xapian's CJK tokenizer (see LP: #745243)
48 os.environ['XAPIAN_CJK_NGRAM'] = '1'
49
50 LOG = logging.getLogger("softwarecenter")
51
52 if __name__ == "__main__":
53
54     parser = OptionParser("usage: %prog [options] [package-name | apturl | deb-file]",
55                           version="%prog "+VERSION)
56     parser.add_option("--debug", action="store_true",
57                       help="enable debug mode", default=False)
58     parser.add_option("--debug-filter",
59                       help="show only specific messages. supported currently: "
60                            "'softwarecenter.performance'")
61     parser.add_option("--force-rtl", action="store_true",
62                       help="force rtl mode (useful for debugging)",
63                       default=False)
64     parser.add_option("--display-navlog", action="store_true",
65                       help="display a navigation history log (useful for debugging)",
66                       default=False)
67     # FIXME:  REMOVE THIS option once launchpad integration is enabled
68     #         by default
69     parser.add_option("--enable-lp", action="store_true",
70                       help="enable launchpad integration (for development use)",
71                       default=False)
72     parser.add_option("--disable-buy", action="store_true",
73                       help="disable support to buy software",
74                       default=False)
75     parser.add_option("--disable-apt-xapian-index", action="store_true",
76                       help="disable support for apt-xapian-index (technical items)",
77                       default=False)
78     parser.add_option("--measure-startup-time", action="store_true",
79                       help="open and wait until the window is visible, then close, only useful for profiling",
80                       default=False)
81     parser.add_option("--dummy-backend", action="store_true",
82                       help="run with a dummy backend, this will not actually install or remove anything and is useful for testing",
83                       default=False)
84     parser.add_option("--aptd-backend", action="store_true",
85                       help="use APTDaemon backend)",
86                       default=False)
87
88     (options, args) = parser.parse_args()
89
90     # statup time measure implies "performance" in debug filters
91     if options.measure_startup_time:
92         options.debug_filter = "performance,traceback"
93
94     if options.debug_filter:
95         softwarecenter.log.add_filters_from_string(options.debug_filter)
96         # implies general debug
97         options.debug = True
98
99     if options.debug:
100         softwarecenter.log.root.setLevel(level=logging.DEBUG)
101     else:
102         softwarecenter.log.root.setLevel(level=logging.INFO)
103
104     # Enable the PackageKit backend by default
105     softwarecenter.enums.USE_PACKAGEKIT_BACKEND = True
106
107     # Aptdaemon
108     if options.aptd_backend:
109         softwarecenter.enums.USE_PACKAGEKIT_BACKEND = False
110
111     if softwarecenter.enums.USE_PACKAGEKIT_BACKEND:
112         logging.info("Using PackageKit backend")
113     else:
114         logging.info("Using Aptdaemon backend")
115
116     # dummy backend
117     if options.dummy_backend:
118         import atexit
119         from softwarecenter.testutils import start_dummy_backend, stop_dummy_backend
120         start_dummy_backend()
121         atexit.register(stop_dummy_backend)
122
123     # Use AXI only on Debian & Ubuntu
124     distro = get_distro()
125     options.disable_apt_xapian_index = not distro.USE_AXI
126
127     # override text direction for testing purposes
128     if options.force_rtl:
129         Gtk.Widget.set_default_direction(Gtk.TextDirection.RTL)
130
131     # check if running locally
132     (datadir, xapian_base_path) = mangle_paths_if_running_in_local_checkout()
133
134     # ensure we can actually run
135     Gtk.init_check(sys.argv)
136
137     # set default ssl-ca-file here because it needs only be set once, but
138     # it can not be set in the global context as this will cause segfaults
139     # on exit. However its IMPORTANT to set it as libsoup is *not* secure
140     # by default (see bugzilla #666280 and #666276)
141     from gi.repository import WebKit as webkit
142     # enable certificates validation in webkit views unless specified otherwise
143     if not "SOFTWARE_CENTER_FORCE_DISABLE_CERTS_CHECK" in os.environ:
144         session = webkit.get_default_session()
145         if os.path.exists("/etc/ssl/certs/ca-certificates.crt"):
146             session.set_property("ssl-ca-file", "/etc/ssl/certs/ca-certificates.crt")
147         else:
148             session.set_property("ssl-ca-file", "/etc/ssl/ca-bundle.pem")
149     else:
150         # WARN the user!! Do not remove this
151         LOG.warning("SOFTWARE_CENTER_FORCE_DISABLE_CERTS_CHECK " +
152                     "has been specified, all purchase transactions " +
153                     "are now INSECURE and UNENCRYPTED!!")
154
155     # create the app
156     from softwarecenter.ui.gtk3.app import SoftwareCenterAppGtk3
157     with ExecutionTime("create SoftwareCenterApp"):
158         app = SoftwareCenterAppGtk3(datadir, xapian_base_path, options, args)
159
160     # DEBUG/PROFILE mode
161     if options.measure_startup_time:
162         logger = logging.getLogger("softwarecenter.performance")
163         with ExecutionTime("show() & gtk events until visible"):
164             def are_we_there_yet():
165                 """ small helper that monitors the main window appearance """
166                 global main_visible
167                 # useful to check how often this is run - not often :/
168                 print time.time()
169                 if not main_visible and app.window_main.get_visible():
170                     logger.debug("** main window visible after: %s seconds" % (
171                             time.time() - time_entering_main))
172                     main_visible = True
173                     return False
174                 return True
175
176             # run watcher for main window
177             main_visible = False
178             GObject.timeout_add(100, are_we_there_yet)
179             app.run(args)
180
181             # keep monitoring the loop
182             while not (app.available_pane.cat_view and
183                        app.available_pane.cat_view.get_visible()):
184                 Gtk.main_iteration_do(True)
185
186         time_to_ready = time.time() - time_entering_main
187         print(time_to_ready)
188         logger.debug("** main window fully ready after: %s seconds" % time_to_ready)
189         sys.exit(0)
190
191     # run it normally
192     app.run(args)
193     Gtk.main()
194