2007-08-29 20:30:26 +02:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
#
|
|
|
|
# gPodder - A media aggregator and podcast client
|
2018-01-28 19:39:53 +01:00
|
|
|
# Copyright (c) 2005-2018 The gPodder Team
|
2007-08-29 20:30:26 +02:00
|
|
|
#
|
|
|
|
# gPodder is free software; you can redistribute it and/or modify
|
|
|
|
# it under the terms of the GNU General Public License as published by
|
|
|
|
# the Free Software Foundation; either version 3 of the License, or
|
|
|
|
# (at your option) any later version.
|
|
|
|
#
|
|
|
|
# gPodder is distributed in the hope that it will be useful,
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
# GNU General Public License for more details.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU General Public License
|
|
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
#
|
|
|
|
|
2012-02-23 20:38:55 +01:00
|
|
|
# This metadata block gets parsed by setup.py - use single quotes only
|
2018-03-18 00:47:54 +01:00
|
|
|
__tagline__ = 'Media aggregator and podcast client'
|
|
|
|
__author__ = 'Thomas Perl <thp@gpodder.org>'
|
2023-08-18 10:40:22 +02:00
|
|
|
__version__ = '3.11.2+1'
|
|
|
|
__date__ = '2023-08-18'
|
2023-02-18 03:18:40 +01:00
|
|
|
__copyright__ = '© 2005-2023 The gPodder Team'
|
2018-03-18 00:47:54 +01:00
|
|
|
__license__ = 'GNU General Public License, version 3 or later'
|
|
|
|
__url__ = 'http://gpodder.org/'
|
2009-05-07 16:26:07 +02:00
|
|
|
|
2021-08-06 13:39:17 +02:00
|
|
|
# Use public version part for __version_info__, see PEP 440
|
|
|
|
__public_version__, __local_version__ = next(
|
|
|
|
(v[0], v[1] if len(v) > 1 else '') for v in (__version__.split('+'),))
|
|
|
|
__version_info__ = tuple(int(x) for x in __public_version__.split('.'))
|
2011-06-25 11:10:56 +02:00
|
|
|
|
2009-05-07 16:26:07 +02:00
|
|
|
import gettext
|
2009-05-12 19:48:45 +02:00
|
|
|
import locale
|
2019-06-09 16:11:23 +02:00
|
|
|
import os
|
|
|
|
import platform
|
|
|
|
import socket
|
|
|
|
import sys
|
2009-05-07 16:26:07 +02:00
|
|
|
|
2018-05-02 14:39:47 +02:00
|
|
|
from gpodder.build_info import BUILD_TYPE
|
|
|
|
|
2009-05-07 16:26:07 +02:00
|
|
|
# Check if real hard dependencies are available
|
|
|
|
try:
|
2016-02-06 17:46:07 +01:00
|
|
|
import podcastparser
|
2009-05-07 16:26:07 +02:00
|
|
|
except ImportError:
|
2016-11-21 23:13:46 +01:00
|
|
|
print("""
|
2016-02-06 17:46:07 +01:00
|
|
|
Error: Module "podcastparser" (python-podcastparser) not found.
|
|
|
|
The podcastparser module can be downloaded from
|
|
|
|
http://gpodder.org/podcastparser/
|
2014-05-24 09:35:06 +02:00
|
|
|
|
2022-11-08 06:51:07 +01:00
|
|
|
From a source checkout, see https://gpodder.github.io/docs/run-from-git.html
|
2016-11-21 23:13:46 +01:00
|
|
|
""")
|
2009-05-07 16:26:07 +02:00
|
|
|
sys.exit(1)
|
2016-02-06 17:46:07 +01:00
|
|
|
del podcastparser
|
2009-05-07 16:26:07 +02:00
|
|
|
|
2010-01-19 23:43:59 +01:00
|
|
|
try:
|
|
|
|
import mygpoclient
|
|
|
|
except ImportError:
|
2016-11-21 23:13:46 +01:00
|
|
|
print("""
|
2011-11-06 23:51:39 +01:00
|
|
|
Error: Module "mygpoclient" (python-mygpoclient) not found.
|
|
|
|
The mygpoclient module can be downloaded from
|
2016-02-06 17:46:07 +01:00
|
|
|
http://gpodder.org/mygpoclient/
|
2014-05-24 09:35:06 +02:00
|
|
|
|
2022-11-08 06:51:07 +01:00
|
|
|
From a source checkout, see https://gpodder.github.io/docs/run-from-git.html
|
2016-11-21 23:13:46 +01:00
|
|
|
""")
|
2010-01-19 23:43:59 +01:00
|
|
|
sys.exit(1)
|
|
|
|
del mygpoclient
|
2009-05-07 16:26:07 +02:00
|
|
|
|
2012-02-22 20:27:10 +01:00
|
|
|
try:
|
|
|
|
import sqlite3
|
|
|
|
except ImportError:
|
2016-11-21 23:13:46 +01:00
|
|
|
print("""
|
2012-02-22 20:27:10 +01:00
|
|
|
Error: Module "sqlite3" not found.
|
|
|
|
Build Python with SQLite 3 support or get it from
|
|
|
|
http://code.google.com/p/pysqlite/
|
2016-11-21 23:13:46 +01:00
|
|
|
""")
|
2012-02-22 20:27:10 +01:00
|
|
|
sys.exit(1)
|
|
|
|
del sqlite3
|
|
|
|
|
|
|
|
|
2020-01-01 14:45:35 +01:00
|
|
|
# Is gpodder running in verbose mode?
|
|
|
|
verbose = False
|
2020-05-07 12:04:18 +02:00
|
|
|
# Is gpodder running in quiet mode?
|
|
|
|
quiet = False
|
2020-01-01 14:45:35 +01:00
|
|
|
|
|
|
|
|
2008-01-15 14:54:22 +01:00
|
|
|
# The User-Agent string for downloads
|
2020-12-20 16:05:01 +01:00
|
|
|
user_agent = 'gPodder/%s (+%s) %s' % (__version__, __url__, platform.system())
|
2007-09-18 20:25:25 +02:00
|
|
|
|
2018-02-11 00:22:00 +01:00
|
|
|
|
2016-02-03 19:54:33 +01:00
|
|
|
# Are we running in GUI or console mode?
|
2009-09-15 19:49:28 +02:00
|
|
|
class UI(object):
|
|
|
|
def __init__(self):
|
2011-10-12 14:22:33 +02:00
|
|
|
self.gtk = False
|
2012-02-21 10:14:23 +01:00
|
|
|
self.cli = False
|
2011-10-12 14:22:33 +02:00
|
|
|
|
2009-09-15 19:49:28 +02:00
|
|
|
|
|
|
|
ui = UI()
|
2008-01-15 14:54:22 +01:00
|
|
|
|
2009-02-25 14:57:45 +01:00
|
|
|
# D-Bus specific interface names
|
2010-01-11 20:39:55 +01:00
|
|
|
dbus_bus_name = 'org.gpodder'
|
2009-02-25 14:57:45 +01:00
|
|
|
dbus_gui_object_path = '/gui'
|
2010-01-08 01:58:15 +01:00
|
|
|
dbus_podcasts_object_path = '/podcasts'
|
2009-02-25 14:57:45 +01:00
|
|
|
dbus_interface = 'org.gpodder.interface'
|
2010-01-08 01:58:15 +01:00
|
|
|
dbus_podcasts = 'org.gpodder.podcasts'
|
2010-08-17 23:52:27 +02:00
|
|
|
dbus_session_bus = None
|
2009-02-25 14:57:45 +01:00
|
|
|
|
2009-05-12 19:48:45 +02:00
|
|
|
# Set "win32" to True if we are on Windows
|
2012-11-18 19:26:02 +01:00
|
|
|
ui.win32 = (platform.system() == 'Windows')
|
2011-11-10 15:16:34 +01:00
|
|
|
# Set "osx" to True if we are on Mac OS X
|
2012-11-18 19:26:02 +01:00
|
|
|
ui.osx = (platform.system() == 'Darwin')
|
2017-04-16 10:25:46 +02:00
|
|
|
# We assume it's a freedesktop.org system if it's not Windows or OS X
|
|
|
|
ui.freedesktop = not ui.win32 and not ui.osx
|
2009-05-12 19:48:45 +02:00
|
|
|
|
2009-05-07 16:26:07 +02:00
|
|
|
# i18n setup (will result in "gettext" to be available)
|
|
|
|
# Use _ = gpodder.gettext in modules to enable string translations
|
|
|
|
textdomain = 'gpodder'
|
|
|
|
locale_dir = gettext.bindtextdomain(textdomain)
|
2018-07-20 17:42:10 +02:00
|
|
|
|
|
|
|
if ui.win32:
|
|
|
|
# this must be done prior to gettext.translation to set the locale (see #484)
|
|
|
|
from gpodder.utilwin32locale import install
|
|
|
|
install(textdomain, locale_dir)
|
|
|
|
|
2009-05-07 16:26:07 +02:00
|
|
|
t = gettext.translation(textdomain, locale_dir, fallback=True)
|
2012-01-10 13:47:20 +01:00
|
|
|
|
2018-07-20 17:42:10 +02:00
|
|
|
gettext = t.gettext
|
|
|
|
ngettext = t.ngettext
|
2012-01-10 13:47:20 +01:00
|
|
|
|
2009-05-07 16:26:07 +02:00
|
|
|
del t
|
|
|
|
|
2016-09-25 14:31:58 +02:00
|
|
|
# Set up textdomain for Gtk.Builder (this accesses the C library functions)
|
2009-05-12 19:48:45 +02:00
|
|
|
if hasattr(locale, 'bindtextdomain'):
|
|
|
|
locale.bindtextdomain(textdomain, locale_dir)
|
|
|
|
|
|
|
|
del locale_dir
|
|
|
|
|
2009-05-26 12:43:26 +02:00
|
|
|
# Set up socket timeouts to fix bug 174
|
|
|
|
SOCKET_TIMEOUT = 60
|
|
|
|
socket.setdefaulttimeout(SOCKET_TIMEOUT)
|
|
|
|
del socket
|
2020-07-12 17:01:59 +02:00
|
|
|
SOCKET_TIMEOUT
|
2009-05-26 12:43:26 +02:00
|
|
|
|
2009-05-07 16:26:07 +02:00
|
|
|
# Variables reserved for GUI-specific use (will be set accordingly)
|
2009-09-01 23:59:20 +02:00
|
|
|
ui_folders = []
|
2009-05-07 16:26:07 +02:00
|
|
|
icon_file = None
|
2010-02-24 01:50:21 +01:00
|
|
|
images_folder = None
|
2012-02-04 21:43:37 +01:00
|
|
|
user_extensions = None
|
2009-05-07 16:26:07 +02:00
|
|
|
|
2009-08-10 23:14:35 +02:00
|
|
|
# Episode states used in the database
|
2016-11-21 23:13:46 +01:00
|
|
|
STATE_NORMAL, STATE_DOWNLOADED, STATE_DELETED = list(range(3))
|
2009-08-10 23:14:35 +02:00
|
|
|
|
2012-02-23 20:38:55 +01:00
|
|
|
# Paths (gPodder's home folder, config, db, download and data prefix)
|
2011-02-01 17:04:13 +01:00
|
|
|
home = None
|
|
|
|
config_file = None
|
|
|
|
database_file = None
|
|
|
|
downloads = None
|
2012-02-23 20:38:55 +01:00
|
|
|
prefix = None
|
2011-02-01 17:04:13 +01:00
|
|
|
|
2012-08-16 08:57:53 +02:00
|
|
|
ENV_HOME, ENV_DOWNLOADS = 'GPODDER_HOME', 'GPODDER_DOWNLOAD_DIR'
|
|
|
|
|
2021-08-17 02:37:33 +02:00
|
|
|
no_update_check_file = None
|
|
|
|
|
2018-02-11 00:22:00 +01:00
|
|
|
|
2011-02-01 17:04:13 +01:00
|
|
|
# Function to set a new gPodder home folder
|
|
|
|
def set_home(new_home):
|
|
|
|
global home, config_file, database_file, downloads
|
2011-04-28 15:28:23 +02:00
|
|
|
home = os.path.abspath(new_home)
|
2011-02-01 17:04:13 +01:00
|
|
|
|
2012-01-03 23:59:19 +01:00
|
|
|
config_file = os.path.join(home, 'Settings.json')
|
2011-02-01 17:04:13 +01:00
|
|
|
database_file = os.path.join(home, 'Database')
|
2012-08-16 08:57:53 +02:00
|
|
|
if ENV_DOWNLOADS not in os.environ:
|
|
|
|
downloads = os.path.join(home, 'Downloads')
|
2011-02-01 17:04:13 +01:00
|
|
|
|
2018-02-11 00:22:00 +01:00
|
|
|
|
2014-05-09 19:00:30 +02:00
|
|
|
def fixup_home(old_home):
|
2018-05-02 14:39:47 +02:00
|
|
|
if ui.osx or ui.win32:
|
|
|
|
if ui.osx:
|
|
|
|
new_home = os.path.expanduser(os.path.join('~', 'Library',
|
|
|
|
'Application Support', 'gPodder'))
|
|
|
|
elif BUILD_TYPE == 'windows-portable':
|
|
|
|
new_home = os.path.normpath(os.path.join(os.path.dirname(sys.executable), "..", "..", "config"))
|
2018-05-27 10:06:31 +02:00
|
|
|
old_home = new_home # force to config directory
|
2018-05-06 18:42:00 +02:00
|
|
|
print("D: windows-portable build; forcing home to config directory %s" % new_home, file=sys.stderr)
|
2018-05-27 10:06:31 +02:00
|
|
|
else: # ui.win32, not portable build
|
2020-09-07 11:40:54 +02:00
|
|
|
from gpodder.utilwin32ctypes import (
|
|
|
|
get_documents_folder, get_reg_current_user_string_value)
|
2018-05-02 14:39:47 +02:00
|
|
|
try:
|
2018-05-06 18:17:23 +02:00
|
|
|
# from old launcher, see
|
|
|
|
# https://github.com/gpodder/gpodder/blob/old/gtk2/tools/win32-launcher/folderselector.c
|
|
|
|
new_home = get_reg_current_user_string_value("Software\\gpodder.org\\gPodder", "GPODDER_HOME")
|
2018-05-06 18:42:00 +02:00
|
|
|
print("D: windows build; registry home = %s" % new_home, file=sys.stderr)
|
2018-05-02 14:39:47 +02:00
|
|
|
except Exception as e:
|
2018-05-06 18:42:00 +02:00
|
|
|
print("E: can't get GPODDER_HOME from registry: %s" % e, file=sys.stderr)
|
2018-05-06 18:17:23 +02:00
|
|
|
new_home = None
|
|
|
|
if new_home is None:
|
|
|
|
try:
|
|
|
|
new_home = os.path.join(get_documents_folder(), "gPodder")
|
2018-05-06 18:42:00 +02:00
|
|
|
print("D: windows build; documents home = %s" % new_home, file=sys.stderr)
|
2018-05-06 18:17:23 +02:00
|
|
|
except Exception as e:
|
2018-05-06 18:42:00 +02:00
|
|
|
print("E: can't get user's Documents folder: %s" % e, file=sys.stderr)
|
2018-05-06 18:17:23 +02:00
|
|
|
new_home = old_home
|
|
|
|
|
2014-05-09 19:00:30 +02:00
|
|
|
# Users who do not have the old home directory, or who have it but also
|
|
|
|
# have the new home directory (to cater to situations where the user
|
|
|
|
# might for some reason or the other have a ~/gPodder/ directory) get
|
|
|
|
# to use the new, more OS X-ish home.
|
|
|
|
if not os.path.exists(old_home) or os.path.exists(new_home):
|
|
|
|
return new_home
|
|
|
|
|
|
|
|
return old_home
|
|
|
|
|
2018-02-10 11:11:20 +01:00
|
|
|
|
2009-08-11 00:36:38 +02:00
|
|
|
# Default locations for configuration and data files
|
2010-12-20 03:09:35 +01:00
|
|
|
default_home = os.path.expanduser(os.path.join('~', 'gPodder'))
|
2014-05-09 19:00:30 +02:00
|
|
|
default_home = fixup_home(default_home)
|
2012-08-16 08:57:53 +02:00
|
|
|
set_home(os.environ.get(ENV_HOME, default_home))
|
2011-02-01 17:04:13 +01:00
|
|
|
|
|
|
|
if home != default_home:
|
2016-11-21 23:13:46 +01:00
|
|
|
print('Storing data in', home, '(GPODDER_HOME is set)', file=sys.stderr)
|
2009-08-11 00:36:38 +02:00
|
|
|
|
2012-08-16 08:57:53 +02:00
|
|
|
if ENV_DOWNLOADS in os.environ:
|
|
|
|
# Allow to relocate the downloads folder (pull request 4, bug 466)
|
|
|
|
downloads = os.environ[ENV_DOWNLOADS]
|
2016-11-21 23:13:46 +01:00
|
|
|
print('Storing downloads in %s (%s is set)' % (downloads,
|
|
|
|
ENV_DOWNLOADS), file=sys.stderr)
|
2012-08-16 08:57:53 +02:00
|
|
|
|
2009-12-04 00:13:56 +01:00
|
|
|
# Plugins to load by default
|
2012-02-20 23:55:36 +01:00
|
|
|
DEFAULT_PLUGINS = [
|
|
|
|
'gpodder.plugins.soundcloud',
|
|
|
|
]
|
2009-12-04 00:13:56 +01:00
|
|
|
|
2018-02-11 00:22:00 +01:00
|
|
|
|
2009-11-18 00:01:15 +01:00
|
|
|
def load_plugins():
|
2009-12-04 00:13:56 +01:00
|
|
|
"""Load (non-essential) plugin modules
|
|
|
|
|
|
|
|
This loads a default set of plugins, but you can use
|
|
|
|
the environment variable "GPODDER_PLUGINS" to modify
|
|
|
|
the list of plugins."""
|
|
|
|
PLUGINS = os.environ.get('GPODDER_PLUGINS', None)
|
|
|
|
if PLUGINS is None:
|
|
|
|
PLUGINS = DEFAULT_PLUGINS
|
|
|
|
else:
|
|
|
|
PLUGINS = PLUGINS.split()
|
|
|
|
for plugin in PLUGINS:
|
|
|
|
try:
|
|
|
|
__import__(plugin)
|
2016-11-21 23:13:46 +01:00
|
|
|
except Exception as e:
|
|
|
|
print('Cannot load plugin: %s (%s)' % (plugin, e), file=sys.stderr)
|