summaryrefslogtreecommitdiff
path: root/raphodo
diff options
context:
space:
mode:
Diffstat (limited to 'raphodo')
-rw-r--r--raphodo/__about__.py2
-rw-r--r--raphodo/constants.py48
-rw-r--r--raphodo/generatenameconfig.py40
-rwxr-xr-xraphodo/rapid.py8
-rw-r--r--raphodo/rpdfile.py25
-rw-r--r--raphodo/storage.py154
-rw-r--r--raphodo/thumbnaildisplay.py4
7 files changed, 203 insertions, 78 deletions
diff --git a/raphodo/__about__.py b/raphodo/__about__.py
index 20c1a7c..b276a8b 100644
--- a/raphodo/__about__.py
+++ b/raphodo/__about__.py
@@ -29,7 +29,7 @@ __summary__ = 'Downloads, renames and backs up photos and videos from cameras, p
'memory cards and other devices'
__uri__ = 'http://www.damonlynch.net/rapid'
-__version__ = '0.9.10'
+__version__ = '0.9.11'
__author__ = 'Damon Lynch'
__email__ = 'damonlynch@gmail.com'
diff --git a/raphodo/constants.py b/raphodo/constants.py
index 8406456..727e844 100644
--- a/raphodo/constants.py
+++ b/raphodo/constants.py
@@ -434,10 +434,6 @@ class StandardFileLocations(Enum):
downloads = 8
-class FileManagerType(Enum):
- regular = 1
- select = 2
-
max_remembered_destinations = 10
@@ -502,20 +498,54 @@ class Desktop(Enum):
unknown = 11
+class FileManagerType(Enum):
+ regular = 1
+ select = 2
+ dir_only_uri = 3
+
+
+FileManagerBehavior = dict(
+ nautilus=FileManagerType.regular,
+ dolphin=FileManagerType.select,
+ caja=FileManagerType.dir_only_uri,
+ thunar=FileManagerType.dir_only_uri,
+ nemo=FileManagerType.regular,
+ pcmanfm=FileManagerType.dir_only_uri,
+)
+FileManagerBehavior['pcmanfm-qt'] = FileManagerType.dir_only_uri
+
+
+DefaultFileBrowserFallback = dict(
+ gnome='nautilus',
+ ubuntugnome='nautilus',
+ popgnome='nautilus',
+ unity='nautilus',
+ kde='dolphin',
+ cinnamon='nemo',
+ mate='caja',
+ xfce='thunar',
+ lxde='pcmanfm',
+ lxqt='pcmanfm-qt',
+)
+
+
class Distro(Enum):
debian = 1
ubuntu = 2
fedora = 3
- unknown = 4
- manjaro = 5
- arch = 6
- neon = 7
+ neon = 4
+ linuxmint = 5
+ korora = 6
+ arch = 7
opensuse = 8
- gentoo = 9
+ manjaro = 9
galliumos = 10
peppermint = 11
antergos = 12
elementary = 13
+ centos = 14
+ gentoo = 15
+ unknown = 20
orientation_offset = dict(
diff --git a/raphodo/generatenameconfig.py b/raphodo/generatenameconfig.py
index 0908706..57ed788 100644
--- a/raphodo/generatenameconfig.py
+++ b/raphodo/generatenameconfig.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
-# Copyright (C) 2007-2017 Damon Lynch <damonlynch@gmail.com>
+# Copyright (C) 2007-2018 Damon Lynch <damonlynch@gmail.com>
# This file is part of Rapid Photo Downloader.
#
@@ -23,7 +23,7 @@
# these prefs to the user, and dictionaries are unsorted.
__author__ = 'Damon Lynch'
-__copyright__ = "Copyright 2007-2017, Damon Lynch"
+__copyright__ = "Copyright 2007-2018, Damon Lynch"
import os
from collections import OrderedDict
@@ -157,12 +157,14 @@ LIST_DATE_TIME_L2 = [
'DD', # 14
'Month (full)',
'Month (abbreviated)', # 16
+ 'Weekday (full)',
+ 'Weekday (abbreviated)', # 18
'HHMMSS',
- 'HHMM', # 18
+ 'HHMM', # 20
'HH-MM-SS',
- 'HH-MM', # 20
+ 'HH-MM', # 22
'HH',
- 'MM (minutes)', # 22
+ 'MM (minutes)', # 24
'SS'
]
@@ -361,6 +363,12 @@ class i18TranslateMeThanks:
_('Month (abbreviated)'),
# Translators: for an explanation of what this means,
# see http://damonlynch.net/rapid/documentation/index.html#renamedateandtime
+ _('Weekday (full)')
+ # Translators: for an explanation of what this means,
+ # see http://damonlynch.net/rapid/documentation/index.html#renamedateandtime
+ _('Weekday (abbreviated)')
+ # Translators: for an explanation of what this means,
+ # see http://damonlynch.net/rapid/documentation/index.html#renamedateandtime
_('HHMMSS')
# Translators: for an explanation of what this means,
# see http://damonlynch.net/rapid/documentation/index.html#renamedateandtime
@@ -450,7 +458,7 @@ PHOTO_RENAME_MENU_DEFAULTS_CONV = (
[
DATE_TIME, IMAGE_DATE, LIST_DATE_TIME_L2[0],
TEXT, '-', '',
- DATE_TIME, IMAGE_DATE, LIST_DATE_TIME_L2[18],
+ DATE_TIME, IMAGE_DATE, LIST_DATE_TIME_L2[20],
TEXT, '-', '',
SEQUENCES, DOWNLOAD_SEQ_NUMBER, SEQUENCE_NUMBER_1
],
@@ -464,7 +472,7 @@ PHOTO_RENAME_MENU_DEFAULTS_CONV = (
[
DATE_TIME, IMAGE_DATE, LIST_DATE_TIME_L2[0],
TEXT, '-', '',
- DATE_TIME, IMAGE_DATE, LIST_DATE_TIME_L2[18],
+ DATE_TIME, IMAGE_DATE, LIST_DATE_TIME_L2[20],
TEXT, '-', '',
FILENAME, IMAGE_NUMBER, IMAGE_NUMBER_ALL
],
@@ -472,7 +480,7 @@ PHOTO_RENAME_MENU_DEFAULTS_CONV = (
[
DATE_TIME, IMAGE_DATE, LIST_DATE_TIME_L2[0],
TEXT, '-', '',
- DATE_TIME, IMAGE_DATE, LIST_DATE_TIME_L2[18],
+ DATE_TIME, IMAGE_DATE, LIST_DATE_TIME_L2[20],
TEXT, '-', '',
JOB_CODE, '', '',
TEXT, '-', '',
@@ -546,7 +554,7 @@ VIDEO_RENAME_MENU_DEFAULTS_CONV = (
[
DATE_TIME, VIDEO_DATE, LIST_DATE_TIME_L2[0],
TEXT, '-', '',
- DATE_TIME, VIDEO_DATE, LIST_DATE_TIME_L2[18],
+ DATE_TIME, VIDEO_DATE, LIST_DATE_TIME_L2[20],
TEXT, '-', '',
SEQUENCES, DOWNLOAD_SEQ_NUMBER, SEQUENCE_NUMBER_1
],
@@ -560,7 +568,7 @@ VIDEO_RENAME_MENU_DEFAULTS_CONV = (
[
DATE_TIME, VIDEO_DATE, LIST_DATE_TIME_L2[0],
TEXT, '-', '',
- DATE_TIME, VIDEO_DATE, LIST_DATE_TIME_L2[18],
+ DATE_TIME, VIDEO_DATE, LIST_DATE_TIME_L2[20],
TEXT, '-', '',
FILENAME, VIDEO_NUMBER, IMAGE_NUMBER_ALL
],
@@ -568,7 +576,7 @@ VIDEO_RENAME_MENU_DEFAULTS_CONV = (
[
DATE_TIME, VIDEO_DATE, LIST_DATE_TIME_L2[0],
TEXT, '-', '',
- DATE_TIME, VIDEO_DATE, LIST_DATE_TIME_L2[18],
+ DATE_TIME, VIDEO_DATE, LIST_DATE_TIME_L2[20],
TEXT, '-', '',
JOB_CODE, '', '',
TEXT, '-', '',
@@ -586,7 +594,7 @@ VIDEO_RENAME_MENU_DEFAULTS_CONV = (
[
DATE_TIME, VIDEO_DATE, LIST_DATE_TIME_L2[0],
TEXT, '-', '',
- DATE_TIME, VIDEO_DATE, LIST_DATE_TIME_L2[18],
+ DATE_TIME, VIDEO_DATE, LIST_DATE_TIME_L2[20],
TEXT, '-', '',
SEQUENCES, DOWNLOAD_SEQ_NUMBER, SEQUENCE_NUMBER_1,
TEXT, '-', '',
@@ -615,12 +623,14 @@ DATE_TIME_CONVERT = [
'%d', # 14
'%B',
'%b', # 16
+ '%A',
+ '%a', # 18
'%H%M%S',
- '%H%M', # 18
+ '%H%M', # 20
'%H-%M-%S',
- '%H-%M', # 20
+ '%H-%M', # 22
'%H',
- '%M', # 22
+ '%M', # 24
'%S'
]
diff --git a/raphodo/rapid.py b/raphodo/rapid.py
index 54a3941..a23f893 100755
--- a/raphodo/rapid.py
+++ b/raphodo/rapid.py
@@ -485,6 +485,9 @@ class RapidWindow(QMainWindow):
for version in get_versions():
logging.info('%s', version)
+ if disable_version_check:
+ logging.debug("Version checking disabled via code")
+
if EXIFTOOL_VERSION is None:
logging.error("ExifTool is either missing or has a problem")
@@ -854,8 +857,9 @@ class RapidWindow(QMainWindow):
logging.debug("Probing for valid mounts")
self.validMounts = ValidMounts(onlyExternalMounts=self.prefs.only_external_mounts)
- logging.debug("Freedesktop.org thumbnails location: %s",
- get_fdo_cache_thumb_base_directory())
+ logging.debug(
+ "Freedesktop.org thumbnails location: %s", get_fdo_cache_thumb_base_directory()
+ )
logging.debug("Probing desktop environment")
desktop_env = get_desktop_environment()
diff --git a/raphodo/rpdfile.py b/raphodo/rpdfile.py
index 1703e51..eac310b 100644
--- a/raphodo/rpdfile.py
+++ b/raphodo/rpdfile.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2011-2017 Damon Lynch <damonlynch@gmail.com>
+# Copyright (C) 2011-2018 Damon Lynch <damonlynch@gmail.com>
# This file is part of Rapid Photo Downloader.
#
@@ -17,7 +17,7 @@
# see <http://www.gnu.org/licenses/>.
__author__ = 'Damon Lynch'
-__copyright__ = "Copyright 2011-2017, Damon Lynch"
+__copyright__ = "Copyright 2011-2018, Damon Lynch"
import os
import time
@@ -37,9 +37,11 @@ gi.require_version('GLib', '2.0')
from gi.repository import GLib
import raphodo.exiftool as exiftool
-from raphodo.constants import (DownloadStatus, FileType, FileExtension, FileSortPriority,
- ThumbnailCacheStatus, Downloaded, Desktop, thumbnail_offset,
- DeviceTimestampTZ, ThumbnailCacheDiskStatus, ExifSource)
+from raphodo.constants import (
+ DownloadStatus, FileType, FileExtension, FileSortPriority, ThumbnailCacheStatus, Downloaded,
+ Desktop, thumbnail_offset, DeviceTimestampTZ, ThumbnailCacheDiskStatus, ExifSource,
+ FileManagerType,
+)
from raphodo.storage import get_uri, CameraDetails
import raphodo.metadataphoto as metadataphoto
@@ -797,12 +799,15 @@ class RPDFile:
"""
if self.status in Downloaded:
- return 'file://{}'.format(pathname2url(self.download_full_file_name))
+ path = self.download_full_file_name
+ camera_details = None
else:
- return get_uri(
- full_file_name = self.full_file_name, camera_details=self.camera_details,
- desktop_environment=desktop_environment
- )
+ path = self.full_file_name
+ camera_details = self.camera_details
+ return get_uri(
+ full_file_name = path, camera_details=camera_details,
+ desktop_environment=desktop_environment
+ )
def get_souce_href(self) -> str:
return make_href(
diff --git a/raphodo/storage.py b/raphodo/storage.py
index 786b5d8..272ea53 100644
--- a/raphodo/storage.py
+++ b/raphodo/storage.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2015-2017 Damon Lynch <damonlynch@gmail.com>
+# Copyright (C) 2015-2018 Damon Lynch <damonlynch@gmail.com>
# Copyright (C) 2008-2015 Canonical Ltd.
# Copyright (C) 2013 Bernard Baeyens
@@ -43,7 +43,7 @@ regarding mount points and XDG related functionality.
"""
__author__ = 'Damon Lynch'
-__copyright__ = "Copyright 2011-2017, Damon Lynch. Copyright 2008-2015 Canonical Ltd. Copyright" \
+__copyright__ = "Copyright 2011-2018, Damon Lynch. Copyright 2008-2015 Canonical Ltd. Copyright" \
" 2013 Bernard Baeyens."
import logging
@@ -75,7 +75,9 @@ from gi.repository import GUdev, UDisks, GLib
from gettext import gettext as _
-from raphodo.constants import Desktop, Distro, FileManagerType
+from raphodo.constants import (
+ Desktop, Distro, FileManagerType, DefaultFileBrowserFallback, FileManagerBehavior
+)
from raphodo.utilities import (
process_running, log_os_release, remove_topmost_directory_from_path, find_mount_point
)
@@ -106,9 +108,23 @@ def get_distro_id(id_or_id_like: str) -> Distro:
def get_distro() -> Distro:
- if os.path.isfile('/etc/os-release'):
- with open('/etc/os-release', 'r') as f:
+ """
+ Determine the Linux distribution using /etc/os-release
+ """
+
+ os_release = '/etc/os-release'
+ if os.path.isfile(os_release):
+ with open(os_release, 'r') as f:
for line in f:
+ if line.startswith('NAME='):
+ if line.find('Korora') > 0:
+ return Distro.korora
+ if line.find('elementary') > 0:
+ return Distro.elementary
+ if line.find('CentOS Linux') > 0:
+ return Distro.centos
+ if line.find('openSUSE') > 0:
+ return Distro.opensuse
if line.startswith('ID='):
return get_distro_id(line[3:])
if line.startswith('ID_LIKE='):
@@ -160,9 +176,11 @@ def get_media_dir() -> str:
Distro.ubuntu, Distro.debian, Distro.neon, Distro.galliumos, Distro.peppermint,
Distro.elementary):
if distro not in (Distro.fedora, Distro.manjaro, Distro.arch, Distro.opensuse,
- Distro.gentoo, Distro.antergos):
- logging.debug("Detected /run/media directory, but distro does not appear to "
- "be Fedora, Arch, openSUSE, Gentoo, Manjaro or Antergos")
+ Distro.gentoo, Distro.antergos, Distro.korora, Distro.centos):
+ logging.debug(
+ "Detected /run/media directory, but distro does not appear to be CentOS, "
+ "Fedora, Arch, openSUSE, Gentoo, Korora, Manjaro, or Antergos"
+ )
log_os_release()
return run_media_dir
return media_dir
@@ -379,6 +397,11 @@ def get_desktop() -> Desktop:
env = 'ubuntugnome'
elif env == 'pop:gnome':
env = 'popgnome'
+ elif env == 'gnome-classic:gnome':
+ env = 'gnome'
+ elif env == 'budgie:gnome':
+ env = 'gnome'
+
try:
return Desktop[env]
except KeyError:
@@ -566,20 +589,67 @@ def get_fdo_cache_thumb_base_directory() -> str:
return os.path.join(BaseDirectory.xdg_cache_home, 'thumbnails')
-def get_default_file_manager(remove_args: bool = True) -> Tuple[
- Optional[str], Optional[FileManagerType]]:
+# Module level variables important for determining among other things the generation of URIs
+# Pretty ugly, but the alternative is passing values around between several processes
+_desktop = get_desktop()
+_quoted_comma = quote(',')
+_default_file_manager_probed = False
+_default_file_manager = None
+_default_file_manager_type = None
+
+
+def _default_file_manager_for_desktop() -> Tuple[Optional[str], Optional[FileManagerType]]:
+ """
+ If default file manager cannot be determined using system tools, guess
+ based on desktop environment.
+
+ Sets module level globals if found.
+
+ :return: file manager command (without path), and type; if not detected, (None, None)
+ """
+
+ global _default_file_manager
+ global _default_file_manager_type
+
+ try:
+ fm = DefaultFileBrowserFallback[_desktop.name]
+ assert shutil.which(fm)
+ t = FileManagerBehavior[fm]
+ _default_file_manager = fm
+ _default_file_manager_type = t
+ return fm, t
+ except KeyError:
+ logging.debug("Error determining default file manager")
+ return None, None
+ except AssertionError:
+ logging.debug("Default file manager %s cannot be found")
+ return None, None
+
+
+def get_default_file_manager() -> Tuple[Optional[str], Optional[FileManagerType]]:
"""
Attempt to determine the default file manager for the system
:param remove_args: if True, remove any arguments such as %U from
the returned command
- :return: command (without path) if found, else None
+ :return: file manager command (without path), and type; if not detected, (None, None)
"""
+
+ global _default_file_manager_probed
+ global _default_file_manager
+ global _default_file_manager_type
+
+ if _default_file_manager_probed:
+ return _default_file_manager, _default_file_manager_type
+
+ _default_file_manager_probed = True
+
assert sys.platform.startswith('linux')
cmd = shlex.split('xdg-mime query default inode/directory')
try:
desktop_file = subprocess.check_output(cmd, universal_newlines=True) # type: str
except:
- return None, None
+ return _default_file_manager_for_desktop()
+
# Remove new line character from output
desktop_file = desktop_file[:-1]
if desktop_file.endswith(';'):
@@ -591,46 +661,48 @@ def get_default_file_manager(remove_args: bool = True) -> Tuple[
try:
desktop_entry = DesktopEntry(path)
except xdg.Exceptions.ParsingError:
- return None, None
+ return _default_file_manager_for_desktop()
try:
desktop_entry.parse(path)
except:
- return None, None
+ return _default_file_manager_for_desktop()
+
fm = desktop_entry.getExec()
- if fm.startswith('dolphin'):
- file_manager_type = FileManagerType.select
- else:
+
+ # Unhelpful results
+ if fm.startswith('baobab') or fm.startswith('exo-open'):
+ logging.debug('%s returned as default file manager: will substitute', fm)
+ return _default_file_manager_for_desktop()
+
+ # Strip away any extraneous arguments
+ fm_cmd = fm.split()[0]
+ try:
+ file_manager_type = FileManagerBehavior[fm_cmd]
+ except KeyError:
file_manager_type = FileManagerType.regular
- if remove_args:
- return fm.split()[0], file_manager_type
- else:
- return fm, file_manager_type
- # Special case: LXQt
- if get_desktop() == Desktop.lxqt:
- if shutil.which('pcmanfm-qt'):
- return 'pcmanfm-qt', FileManagerType.regular
+ _default_file_manager = fm_cmd
+ _default_file_manager_type = file_manager_type
+ return _default_file_manager, file_manager_type
+
+ # Special case: no base dirs set, e.g. LXQt
+ return _default_file_manager_for_desktop()
- return None, None
def open_in_file_manager(file_manager: str,
file_manager_type: FileManagerType,
uri: str) -> None:
- if file_manager_type == FileManagerType.regular:
- arg = ''
- else:
+ if file_manager_type == FileManagerType.select:
arg = '--select '
+ else:
+ arg = ''
- cmd = '{} {}"{}"'.format(file_manager, arg, uri)
+ cmd = '{} {}{}'.format(file_manager, arg, uri)
logging.debug("Launching: %s", cmd)
args = shlex.split(cmd)
subprocess.Popen(args)
-_desktop = get_desktop()
-_quoted_comma = quote(',')
-
-
def get_uri(full_file_name: Optional[str]=None,
path: Optional[str]=None,
camera_details: Optional[CameraDetails]=None,
@@ -643,16 +715,19 @@ def get_uri(full_file_name: Optional[str]=None,
:param path: straight path when not passing a full_file_name
:param camera_details: see named tuple CameraDetails for parameters
:param desktop_environment: if True, will to generate a URI accepted
- by Gnome and KDE desktops, which means adjusting the URI if it appears to be an
- MTP mount. Includes the port too.
+ by Gnome, KDE and other desktops, which means adjusting the URI if it appears to be an
+ MTP mount. Includes the port too, for cameras. Takes into account
+ file manager characteristics.
:return: the URI
"""
+ if not _default_file_manager_probed:
+ get_default_file_manager()
+
if camera_details is None:
prefix = 'file://'
if desktop_environment:
- desktop = get_desktop()
- if full_file_name and desktop == Desktop.mate:
+ if full_file_name and _default_file_manager_type == FileManagerType.dir_only_uri:
full_file_name = os.path.dirname(full_file_name)
else:
if not desktop_environment:
@@ -682,13 +757,14 @@ def get_uri(full_file_name: Optional[str]=None,
else:
prefix = 'gphoto2://' + pathname2url('[{}]'.format(camera_details.port))
- if _desktop == Desktop.lxqt:
+ if _default_file_manager == 'pcmanfm-qt':
# pcmanfm-qt does not like the quoted form of the comma
prefix = prefix.replace(_quoted_comma, ',')
if full_file_name:
# pcmanfm-qt does not like the the filename as part of the path
full_file_name = os.path.dirname(full_file_name)
+
if full_file_name or path:
uri = '{}{}'.format(prefix, pathname2url(full_file_name or path))
else:
diff --git a/raphodo/thumbnaildisplay.py b/raphodo/thumbnaildisplay.py
index e7a3f9b..85c3747 100644
--- a/raphodo/thumbnaildisplay.py
+++ b/raphodo/thumbnaildisplay.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2015-2017 Damon Lynch <damonlynch@gmail.com>
+# Copyright (C) 2015-2018 Damon Lynch <damonlynch@gmail.com>
# This file is part of Rapid Photo Downloader.
#
@@ -17,7 +17,7 @@
# see <http://www.gnu.org/licenses/>.
__author__ = 'Damon Lynch'
-__copyright__ = "Copyright 2015-2017, Damon Lynch"
+__copyright__ = "Copyright 2015-2018, Damon Lynch"
import pickle
import os