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__)
45 Warning: python-dbus not found. Disabling D-Bus support.
51 # Paths to important files
52 gpodder_script = sys.argv[0]
53 gpodder_script = os.path.realpath(gpodder_script)
54 gpodder_dir = os.path.join(os.path.dirname(gpodder_script), '..')
55 prefix = os.path.abspath(os.path.normpath(gpodder_dir))
57 src_dir = os.path.join(prefix, 'src')
58 locale_dir = os.path.join(prefix, 'share', 'locale')
59 ui_folder = os.path.join(prefix, 'share', 'gpodder', 'ui')
60 images_folder = os.path.join(prefix, 'share', 'gpodder', 'images')
61 icon_file = os.path.join(prefix, 'share', 'icons', 'hicolor', 'scalable', 'apps', 'gpodder.svg')
63 if os.path.exists(os.path.join(src_dir, 'gpodder', '__init__.py')):
64 # Run gPodder from local source folder (not installed)
65 sys.path.insert(0, src_dir)
67 # on Mac OS X, read from the defaults database the locale of the user
68 if platform.system() == 'Darwin' and 'LANG' not in os.environ:
69 locale_cmd = ('defaults', 'read', 'NSGlobalDomain', 'AppleLocale')
70 process = subprocess.Popen(locale_cmd, stdout=subprocess.PIPE)
71 output, error_output = process.communicate()
72 # the output is a string like 'fr_FR', and we need 'fr_FR.utf-8'
73 user_locale = output.decode('utf-8').strip() + '.UTF-8'
74 os.environ['LANG'] = user_locale
75 print('Setting locale to', user_locale, file=sys.stderr)
77 # Set up the path to translation files
78 gettext.bindtextdomain('gpodder', locale_dir)
80 import gpodder # isort:skip
82 gpodder.prefix = prefix
84 # Package managers can install the empty file {prefix}/share/gpodder/no-update-check to disable update checks
85 gpodder.no_update_check_file = os.path.join(prefix, 'share', 'gpodder', 'no-update-check')
87 # Enable i18n for gPodder translations
90 # Set up paths to folder with GtkBuilder files and gpodder.svg
91 gpodder.ui_folders.append(ui_folder)
92 gpodder.images_folder = images_folder
93 gpodder.icon_file = icon_file
95 s_usage = 'usage: %%prog [options]\n\n%s' % (__doc__.strip())
96 s_version = '%%prog %s' % (gpodder.__version__)
98 parser = OptionParser(usage=s_usage, version=s_version)
100 grp_subscriptions = OptionGroup(parser, "Subscriptions")
101 parser.add_option_group(grp_subscriptions)
103 grp_subscriptions.add_option('-s', '--subscribe', dest='subscribe',
105 help=_('subscribe to the feed at URL'))
107 grp_logging = OptionGroup(parser, "Logging")
108 parser.add_option_group(grp_logging)
110 grp_logging.add_option("-v", "--verbose",
111 action="store_true", dest="verbose", default=False,
112 help=_("print logging output on the console"))
114 grp_logging.add_option("-q", "--quiet",
115 action="store_true", dest="quiet", default=False,
116 help=_("reduce warnings on the console"))
118 grp_advanced = OptionGroup(parser, "Advanced")
119 parser.add_option_group(grp_advanced)
121 grp_advanced.add_option("--close-after-startup", action="store_true",
122 help=_("exit once started up (for profiling)"))
124 # On Mac OS X, support the "psn" parameter for compatibility (bug 939)
126 grp_advanced.add_option('-p', '--psn', dest='macpsn', metavar='PSN',
127 help=_('Mac OS X application process number'))
129 options, args = parser.parse_args(sys.argv)
131 gpodder.ui.gtk = True
132 gpodder.ui.python3 = True
134 desktop_session = os.environ.get('DESKTOP_SESSION', 'unknown').lower()
135 xdg_current_desktop = os.environ.get('XDG_CURRENT_DESKTOP', 'unknown').lower()
136 gpodder.ui.unity = (desktop_session in ('ubuntu', 'ubuntu-2d', 'unity')
137 and xdg_current_desktop in ('unity', 'unity:unity7:ubuntu'))
139 from gpodder import log
140 log.setup(options.verbose, options.quiet)
142 if (not (gpodder.ui.win32 or gpodder.ui.osx)
143 and os.environ.get('DISPLAY', '') == ''
144 and os.environ.get('WAYLAND_DISPLAY', '') == ''):
145 logger.error('Cannot start gPodder: $DISPLAY or $WAYLAND_DISPLAY is not set.')
149 # Try to find an already-running instance of gPodder
150 session_bus = dbus.SessionBus()
152 # Obtain a reference to an existing instance; don't call get_object if
153 # such an instance doesn't exist as it *will* create a new instance
154 if session_bus.name_has_owner(gpodder.dbus_bus_name):
156 remote_object = session_bus.get_object(
157 gpodder.dbus_bus_name,
158 gpodder.dbus_gui_object_path)
160 # An instance of GUI is already running
161 logger.info('Activating existing instance via D-Bus.')
162 remote_object.show_gui_window(
163 dbus_interface=gpodder.dbus_interface)
165 if options.subscribe:
166 remote_object.subscribe_to_url(options.subscribe)
169 except dbus.exceptions.DBusException as dbus_exception:
170 logger.info('Cannot connect to remote object.', exc_info=True)
173 from gpodder.gtkui import app
174 gpodder.ui_folders.insert(0, os.path.join(ui_folder, 'gtk'))
177 logger.error('No GUI selected.')
180 if __name__ == '__main__':