2 # -*- coding: utf-8 -*-
5 # gPodder - A media aggregator and podcast client
6 # Copyright (c) 2005-2018 The gPodder Team
8 # gPodder is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 3 of the License, or
11 # (at your option) any later version.
13 # gPodder is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License
19 # along with this program. If not, see <http://www.gnu.org/licenses/>.
23 gPodder enables you to subscribe to media feeds (RSS, Atom, YouTube,
24 Soundcloud and Vimeo) and automatically download new content.
26 This is the gPodder GUI. See gpo(1) for the command-line interface.
36 from optparse import OptionGroup, OptionParser
38 logger = logging.getLogger(__name__)
42 from dbus.mainloop.glib import DBusGMainLoop
46 Warning: python-dbus not found. Disabling D-Bus support.
52 # Paths to important files
53 gpodder_script = sys.argv[0]
54 gpodder_script = os.path.realpath(gpodder_script)
55 gpodder_dir = os.path.join(os.path.dirname(gpodder_script), '..')
56 prefix = os.path.abspath(os.path.normpath(gpodder_dir))
58 src_dir = os.path.join(prefix, 'src')
59 locale_dir = os.path.join(prefix, 'share', 'locale')
60 ui_folder = os.path.join(prefix, 'share', 'gpodder', 'ui')
61 images_folder = os.path.join(prefix, 'share', 'gpodder', 'images')
62 icon_file = os.path.join(prefix, 'share', 'icons', 'hicolor', 'scalable', 'apps', 'gpodder.svg')
64 if os.path.exists(os.path.join(src_dir, 'gpodder', '__init__.py')):
65 # Run gPodder from local source folder (not installed)
66 sys.path.insert(0, src_dir)
68 # on Mac OS X, read from the defaults database the locale of the user
69 if platform.system() == 'Darwin' and 'LANG' not in os.environ:
70 locale_cmd = ('defaults', 'read', 'NSGlobalDomain', 'AppleLocale')
71 process = subprocess.Popen(locale_cmd, stdout=subprocess.PIPE)
72 output, error_output = process.communicate()
73 # the output is a string like 'fr_FR', and we need 'fr_FR.utf-8'
74 user_locale = output.decode('utf-8').strip() + '.UTF-8'
75 os.environ['LANG'] = user_locale
76 print('Setting locale to', user_locale, file=sys.stderr)
78 # Set up the path to translation files
79 gettext.bindtextdomain('gpodder', locale_dir)
81 import gpodder # isort:skip
83 gpodder.prefix = prefix
85 # Package managers can install the empty file {prefix}/share/gpodder/no-update-check to disable update checks
86 gpodder.no_update_check_file = os.path.join(prefix, 'share', 'gpodder', 'no-update-check')
88 # Enable i18n for gPodder translations
91 # Set up paths to folder with GtkBuilder files and gpodder.svg
92 gpodder.ui_folders.append(ui_folder)
93 gpodder.images_folder = images_folder
94 gpodder.icon_file = icon_file
96 s_usage = 'usage: %%prog [options]\n\n%s' % (__doc__.strip())
97 s_version = '%%prog %s' % (gpodder.__version__)
99 parser = OptionParser(usage=s_usage, version=s_version)
101 grp_subscriptions = OptionGroup(parser, "Subscriptions")
102 parser.add_option_group(grp_subscriptions)
104 grp_subscriptions.add_option('-s', '--subscribe', dest='subscribe',
106 help=_('subscribe to the feed at URL'))
108 grp_logging = OptionGroup(parser, "Logging")
109 parser.add_option_group(grp_logging)
111 grp_logging.add_option("-v", "--verbose",
112 action="store_true", dest="verbose", default=False,
113 help=_("print logging output on the console"))
115 grp_logging.add_option("-q", "--quiet",
116 action="store_true", dest="quiet", default=False,
117 help=_("reduce warnings on the console"))
119 grp_advanced = OptionGroup(parser, "Advanced")
120 parser.add_option_group(grp_advanced)
122 grp_advanced.add_option("--close-after-startup", action="store_true",
123 help=_("exit once started up (for profiling)"))
125 # On Mac OS X, support the "psn" parameter for compatibility (bug 939)
127 grp_advanced.add_option('-p', '--psn', dest='macpsn', metavar='PSN',
128 help=_('Mac OS X application process number'))
130 options, args = parser.parse_args(sys.argv)
132 gpodder.ui.gtk = True
133 gpodder.ui.python3 = True
135 desktop_session = os.environ.get('DESKTOP_SESSION', 'unknown').lower()
136 xdg_current_desktop = os.environ.get('XDG_CURRENT_DESKTOP', 'unknown').lower()
137 gpodder.ui.unity = (desktop_session in ('ubuntu', 'ubuntu-2d', 'unity')
138 and xdg_current_desktop in ('unity', 'unity:unity7:ubuntu'))
140 from gpodder import log
141 log.setup(options.verbose, options.quiet)
143 if (not (gpodder.ui.win32 or gpodder.ui.osx) and
144 os.environ.get('DISPLAY', '') == '' and
145 os.environ.get('WAYLAND_DISPLAY', '') == ''):
146 logger.error('Cannot start gPodder: $DISPLAY or $WAYLAND_DISPLAY is not set.')
150 # Try to find an already-running instance of gPodder
151 session_bus = dbus.SessionBus()
153 # Obtain a reference to an existing instance; don't call get_object if
154 # such an instance doesn't exist as it *will* create a new instance
155 if session_bus.name_has_owner(gpodder.dbus_bus_name):
157 remote_object = session_bus.get_object(
158 gpodder.dbus_bus_name,
159 gpodder.dbus_gui_object_path)
161 # An instance of GUI is already running
162 logger.info('Activating existing instance via D-Bus.')
163 remote_object.show_gui_window(
164 dbus_interface=gpodder.dbus_interface)
166 if options.subscribe:
167 remote_object.subscribe_to_url(options.subscribe)
170 except dbus.exceptions.DBusException as dbus_exception:
171 logger.info('Cannot connect to remote object.', exc_info=True)
174 from gpodder.gtkui import app
175 gpodder.ui_folders.insert(0, os.path.join(ui_folder, 'gtk'))
178 logger.error('No GUI selected.')
181 if __name__ == '__main__':