Update to v1.1.050

This commit is contained in:
A S Lewis 2019-08-26 13:24:39 +01:00
parent 454eb9933d
commit 9efcfdd128
19 changed files with 3403 additions and 1415 deletions

11
.gitignore vendored
View File

@ -1,11 +0,0 @@
# This file copied from
# https://python-packaging.readthedocs.io/en/latest/minimal.html?highlight=gitignore
# Compiled python modules.
*.pyc
# Setuptools distribution folder.
/dist/
# Python egg metadata, regenerated from source files by setuptools.
/*.egg-info

View File

@ -1,32 +1,38 @@
Tartube installation problems on MS Windows
===========================================
Some users on MS Windows report that they can't run Tartube at all.
Some users on MS Windows report that they can't run Tartube at all. There are three possible fixes.
This page describes what you can do, if you are one of them.
Fix #1
~~~~~~
The problem
~~~~~~~~~~~
Wait for v1.2 of Tartube, which should fix the problem.
A full installation of Tartube and all of its dependencies uses over 2GB of your hard drive. The download is over 600MB.
Fix #2
~~~~~~
This is obviously too much, so I've removed everything that is not necessary. As a result, the installer is a 90MB download.
Find the **tartube_mswin.sh** file, and modify it.
The installer works for most people, but some users are reporting that they can't run Tartube at all.
If you used the MS Windows installer, it should be installed in
Obviously, something is missing from the installer. I can't reproduce the problem on any computer, so I don't know what is missing.
**C:\\Users\\YOURNAME\\AppData\\Local\\Tartube\\msys64\\home\\user\\tartube**
The solution
~~~~~~~~~~~~
(You may have to `make hidden folders visible <https://support.microsoft.com/en-us/help/14201/windows-show-hidden-files>`__ to see the parent folder.)
A workaround is to perform a manual installation. This takes about 10-30 minutes, depending on your internet speed.
Open the file in a text editor, and replace this line
If the manual installation works, you can try to diagnose the original problem.
**cd tartube**
As soon as someone discovers what is missing from the installer, I can add it, and everyone will be happy again.
with this line
MS Windows manual installation
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**cd /home/user/tartube/tartube**
Save the file. You may now be able to run Tartube from the Windows Start Menu, or from the desktop shortcut.
Fix #3
~~~~~~
Perform a manual installation. This takes about 10-30 minutes, depending on your internet speed.
- This section assumes you have a 64-bit computer
- Download and install MSYS2 from `msys2.org <https://msys2.org>`__. You need the file that looks something like **msys2-x86_64-yyyymmdd.exe**
@ -61,26 +67,3 @@ MS Windows manual installation
**python3 tartube**
Diagnosing the problem
----------------------
If the manual installation works, and if you have the time and the patience, you can work out what the missing dependency is. When you find it, please `tell me <https://github.com/axcore/tartube/issues>`__.
- Download the normal installer from `Sourceforge <https://tartube.sourceforge.io/>`__
- Run the installer. Tell it to install Tartube in **C:\\tartube**
.. image:: screenshots/diagnose1.png
:alt: Set the installation folder
- You now have two installations - a working one in **C:\\msys64\\**, and a broken one in **C:\\tartube\\msys64\\**
.. image:: screenshots/diagnose2.png
:alt: Picture of both folders
- Now, you can start moving files and folders from the working folder into the broken folder, **one at a time**
- For example, you could move the file **C:\\msys64\\usr\\bin\\awk** to **C:\\tartube\\msys64\\usr\\bin\\awk**
- For example, you could move the folder **C:\\msys64\\usr\\etc** to **C:\\tartube\\msys64\\usr\\bin\\etc**
- Every time you copy something, try to run Tartube (from the Start menu, or from the desktop shortcut)
- When Tartube runs for the first time, `tell me which file/folder you moved <https://github.com/axcore/tartube/issues>`__. I don't need to know everything - just tell me the **last** thing you moved.

View File

@ -0,0 +1,86 @@
Tartube installation problems on MS Windows
===========================================
Some users on MS Windows report that they can't run Tartube at all.
This page describes what you can do, if you are one of them.
The problem
~~~~~~~~~~~
A full installation of Tartube and all of its dependencies uses over 2GB of your hard drive. The download is over 600MB.
This is obviously too much, so I've removed everything that is not necessary. As a result, the installer is a 90MB download.
The installer works for most people, but some users are reporting that they can't run Tartube at all.
Obviously, something is missing from the installer. I can't reproduce the problem on any computer, so I don't know what is missing.
The solution
~~~~~~~~~~~~
A workaround is to perform a manual installation. This takes about 10-30 minutes, depending on your internet speed.
If the manual installation works, you can try to diagnose the original problem.
As soon as someone discovers what is missing from the installer, I can add it, and everyone will be happy again.
MS Windows manual installation
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- This section assumes you have a 64-bit computer
- Download and install MSYS2 from `msys2.org <https://msys2.org>`__. You need the file that looks something like **msys2-x86_64-yyyymmdd.exe**
- MSYS2 wants to install in **C:\\msys64**, so do that
- Open the MINGW64 terminal, which is **C:\\msys64\\mingw64.exe**
- In the MINGW64 terminal, type:
**pacman -Syu**
- If the terminal wants to shut down, close it, and then restart it
- Now type the following commands, one by one:
**pacman -Su**
**pacman -S mingw-w64-x86_64-python3**
**pacman -S mingw-w64-x86_64-python3-pip**
**pacman -S mingw-w64-x86_64-python3-gobject**
**pacman -S mingw-w64-x86_64-python3-requests**
**pacman -S mingw-w64-x86_64-gtk3**
**pacman -S mingw-w64-x86_64-gsettings-desktop-schemas**
- Download the `Tartube source code <https://sourceforge.net/projects/tartube/files/v0.7.0/tartube_v0.7.0.tar.gz/download>`__ from Sourceforge
- Extract it into the folder **C:\\msys64\\home\\YOURNAME**, creating a folder called **C:\\msys64\\home\\YOURNAME\\tartube**
- Now, to run Tartube, type these commands in the MINGW64 terminal:
**cd tartube**
**python3 tartube**
Diagnosing the problem
----------------------
If the manual installation works, and if you have the time and the patience, you can work out what the missing dependency is. When you find it, please `tell me <https://github.com/axcore/tartube/issues>`__.
- Download the normal installer from `Sourceforge <https://tartube.sourceforge.io/>`__
- Run the installer. Tell it to install Tartube in **C:\\tartube**
.. image:: screenshots/diagnose1.png
:alt: Set the installation folder
- You now have two installations - a working one in **C:\\msys64\\**, and a broken one in **C:\\tartube\\msys64\\**
.. image:: screenshots/diagnose2.png
:alt: Picture of both folders
- Now, you can start moving files and folders from the working folder into the broken folder, **one at a time**
- For example, you could move the file **C:\\msys64\\usr\\bin\\awk** to **C:\\tartube\\msys64\\usr\\bin\\awk**
- For example, you could move the folder **C:\\msys64\\usr\\etc** to **C:\\tartube\\msys64\\usr\\bin\\etc**
- Every time you copy something, try to run Tartube (from the Start menu, or from the desktop shortcut)
- When Tartube runs for the first time, `tell me which file/folder you moved <https://github.com/axcore/tartube/issues>`__. I don't need to know everything - just tell me the **last** thing you moved.

BIN
icons/small/archived.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
icons/small/folder_blue.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
icons/small/folder_red.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 451 B

View File

@ -34,8 +34,10 @@ import sys
# For the Debian distribution, use an environment variable. When specified,
# the default executable 'tartube' is replaced by the 'tartube_debian'
# executiable, in which youtube-dl updates are disabled
# the 'tartube_debian' file is the executable, rather than the 'tartube'
# file
# When the 'tartube_debian' file is the executable, youtube-dl updates are
# disabled, and Tartube's config file is stored at $XDG_CONFIG_HOME
# The package maintainer should use
# TARTUBE_NO_UPDATES=1 python3 setup.py build
env_var_name = 'TARTUBE_NO_UPDATES'
@ -60,7 +62,7 @@ if env_var_value is not None:
# Setup
setuptools.setup(
name='tartube',
version='1.1.015',
version='1.1.050',
description='GUI front-end for youtube-dl',
# long_description=long_description,
long_description="""Tartube is a GUI front-end for youtube-dl, partly based

File diff suppressed because it is too large Load Diff

View File

@ -341,6 +341,53 @@ class DownloadManager(threading.Thread):
break
def check_master_slave(self, media_data_obj):
"""Called by VideoDownloader.do_download().
When two channels/playlists/folders share a download destination, we
don't want to download both of them at the same time.
This function is called when media_data_obj is about to be
downloaded.
Every worker is checked, to see if it's downloading to the same
destination. If so, this function returns True, and
VideoDownloader.do_download() waits a few seconds, before trying
again.
Otherwise, this function returns False, and
VideoDownloader.do_download() is free to start its download.
Args:
media_data_obj (media.Channel, media.Playlist, media.Folder):
The media data object that the calling function wants to
download
Returns:
True or False, as described above
"""
for worker_obj in self.worker_list:
if not worker_obj.available_flag \
and worker_obj.download_item_obj:
other_obj = worker_obj.download_item_obj.media_data_obj
if other_obj.dbid != media_data_obj.dbid \
and (
other_obj.dbid == media_data_obj.master_dbid \
or other_obj.dbid in media_data_obj.slave_dbid_list
):
return True
return False
def check_workers_all_finished(self):
"""Called by self.run().
@ -763,7 +810,7 @@ class DownloadList(object):
else:
# Use the specified media data object. The True value tells
# self.create_item to download media_data_obj, even if it is a
# self.create_item() to download media_data_obj, even if it is a
# video in a channel or a playlist (which otherwise would be
# handled by downloading the channel/playlist)
self.create_item(media_data_obj, True)
@ -810,6 +857,11 @@ class DownloadList(object):
- media.Video objects in any restricted folder
- media.Video objects in the fixed 'Unsorted Videos' folder which
are already marked as downloaded
- media.Video objects which have an ancestor (e.g. a parent
media.Channel) for which checking/downloading is disabled
- media.Channel and media.Playlist objects for which checking/
downloading are disabled, or which have an ancestor (e.g. a
parent media.folder) for which checking/downloading is disabled
- media.Folder objects
Adds the resulting downloads.DownloadItem object to this object's IVs.
@ -856,6 +908,22 @@ class DownloadList(object):
):
return
# Don't create a download.DownloadItem object if the media data object
# has an ancestor for which checking/downloading is disabled
if isinstance(media_data_obj, media.Video):
dl_disable_flag = False
else:
dl_disable_flag = media_data_obj.dl_disable_flag
parent_obj = media_data_obj.parent_obj
while not dl_disable_flag and parent_obj is not None:
dl_disable_flag = parent_obj.dl_disable_flag
parent_obj = parent_obj.parent_obj
if dl_disable_flag:
return
# Don't create a download.DownloadItem object for a media.Folder,
# obviously
if not isinstance(media_data_obj, media.Folder):
@ -1102,11 +1170,26 @@ class VideoDownloader(object):
# The time (in seconds) between iterations of the loop in
# self.do_download()
self.sleep_time = 0.1
# The time (in seconds) to wait for an existing download, which shares
# a common download destination with this media data object, to
# finish downloading
self.long_sleep_time = 10
# Flag set to True if we are simulating downloads for this media data
# object, or False if we actually downloading videos (set below)
self.dl_sim_flag = None
# Flag set to True by a call from any function to self.stop_soon()
# After being set to True, this VideoDownloader should give up after
# the next call to self.confirm_new_video(), .confirm_old_video()
# .confirm_sim_video()
self.stop_soon_flag = False
# When self.stop_soon_flag is True, the next call to
# self.confirm_new_video(), .confirm_old_video() or
# .confirm_sim_video() sets this flag to True, informing
# self.do_download() that it can stop the child process
self.stop_now_flag = False
# youtube-dl is passed a URL, which might represent an individual
# video, a channel or a playlist
# Assume it's an individual video unless youtube-dl reports a
@ -1177,17 +1260,20 @@ class VideoDownloader(object):
# download
media_data_obj = self.download_item_obj.media_data_obj
# If the media data object is a video, channel or playlist, it can be
# marked as a simulated download only
# If it's a video inside a folder and the folder itself is marked as
# simulated downloads only, apply that to all videos in the folder
if self.download_manager_obj.force_sim_flag \
or media_data_obj.dl_sim_flag \
or (
isinstance(media_data_obj, media.Video) \
and isinstance(media_data_obj.parent_obj, media.Folder) \
and media_data_obj.parent_obj.dl_sim_flag
):
# All media data objects can be marked as simulate downloads only. The
# setting applies not just to the media data object, but all of its
# descendants
if self.download_manager_obj.force_sim_flag:
dl_sim_flag = True
else:
dl_sim_flag = media_data_obj.dl_sim_flag
parent_obj = media_data_obj.parent_obj
while not dl_sim_flag and parent_obj is not None:
dl_sim_flag = parent_obj.dl_sim_flag
parent_obj = parent_obj.parent_obj
if dl_sim_flag:
self.dl_sim_flag = True
self.video_num = 0
self.video_total = 0
@ -1229,6 +1315,18 @@ class VideoDownloader(object):
# time it was checked/downloaded
self.download_item_obj.media_data_obj.reset_error_warning()
# If two channels/playlists/folders share a download destination, we
# don't want to download both of them at the same time
# If this media data obj shares a download destination with another
# downloads.DownloadWorker, wait until that download has finished
# before starting this one
if not isinstance(self.download_item_obj.media_data_obj, media.Video):
while self.download_manager_obj.check_master_slave(
self.download_item_obj.media_data_obj,
):
time.sleep(self.long_sleep_time)
# Prepare a system command...
cmd_list = self.get_system_cmd()
# ...and create a new child process using that command
@ -1307,6 +1405,12 @@ class VideoDownloader(object):
+ ' to fetch a video\'s JSON data',
)
# Stop this video downloader, if required to do so, having just
# finished checking/downloading a video
if self.stop_now_flag:
self.stop()
# The child process has finished
while not self.stderr_queue.empty():
@ -1456,6 +1560,11 @@ class VideoDownloader(object):
options_manager_obj.options_dict['keep_thumbnail'],
)
# This VideoDownloader can now stop, if required to do so after a video
# has been checked/downloaded
if self.stop_soon_flag:
self.stop_now_flag = True
def confirm_old_video(self, dir_path, filename, extension):
@ -1549,15 +1658,36 @@ class VideoDownloader(object):
= self.download_worker_obj.options_manager_obj
# Update the main window
GObject.timeout_add(
0,
app_obj.announce_video_download,
self.download_item_obj,
video_obj,
options_manager_obj.options_dict['keep_description'],
options_manager_obj.options_dict['keep_info'],
options_manager_obj.options_dict['keep_thumbnail'],
)
if media_data_obj.master_dbid != media_data_obj.dbid:
# The container is storing its videos in another
# container's sub-directory, which (probably) explains
# why we couldn't find a match. Don't add anything to the
# Results List
GObject.timeout_add(
0,
app_obj.announce_video_clone,
video_obj,
)
else:
# Do add an entry to the Results List (as well as updating
# the Video Catalogue, as normal)
GObject.timeout_add(
0,
app_obj.announce_video_download,
self.download_item_obj,
video_obj,
options_manager_obj.options_dict['keep_description'],
options_manager_obj.options_dict['keep_info'],
options_manager_obj.options_dict['keep_thumbnail'],
)
# This VideoDownloader can now stop, if required to do so after a video
# has been checked/downloaded
if self.stop_soon_flag:
self.stop_now_flag = True
def confirm_sim_video(self, json_dict):
@ -1851,6 +1981,11 @@ class VideoDownloader(object):
if stop_flag:
self.stop()
# This VideoDownloader can now stop, if required to do so after a video
# has been checked/downloaded
elif self.stop_soon_flag:
self.stop_now_flag = True
def create_child_process(self, cmd_list):
@ -2243,6 +2378,9 @@ class VideoDownloader(object):
if DEBUG_FUNC_FLAG:
print('dl 1997 get_system_cmd')
# Import things for convenience
app_obj = self.download_manager_obj.app_obj
media_data_obj = self.download_item_obj.media_data_obj
options_list = self.download_worker_obj.options_list
# Simulate the download, rather than actually downloading videos, if
@ -2250,13 +2388,30 @@ class VideoDownloader(object):
if self.dl_sim_flag:
options_list.append('--dump-json')
# If actually downloading videos, create an archive file so that, if
# the user deletes the videos, youtube-dl won't try to download them
# again
else:
# (Create the archive file in the media data object's own
# sub-directory, not the alternative download destination, as
# this helps youtube-dl to work the way we want it)
if isinstance(media_data_obj, media.Video):
dl_path = media_data_obj.parent_obj.get_dir(app_obj)
else:
dl_path = media_data_obj.get_dir(app_obj)
options_list.append('--download-archive')
options_list.append(
os.path.abspath(os.path.join(dl_path, 'ytdl-archive.txt')),
)
# Show verbose output (youtube-dl debugging mode), if required
if self.download_manager_obj.app_obj.ytdl_write_verbose_flag:
if app_obj.ytdl_write_verbose_flag:
options_list.append('--verbose')
# Set the list
cmd_list = [self.download_manager_obj.app_obj.ytdl_path] \
+ options_list + [self.download_item_obj.media_data_obj.source]
cmd_list = [app_obj.ytdl_path] + options_list + [media_data_obj.source]
return cmd_list
@ -2478,7 +2633,8 @@ class VideoDownloader(object):
def stop(self):
"""Called by downloads.DownloadWorker.close().
"""Called by downloads.DownloadWorker.close() and also by
mainwin.MainWin.on_progress_list_stop_now().
Terminates the child process and sets this object's return code to
self.STOPPED.
@ -2505,6 +2661,21 @@ class VideoDownloader(object):
self.set_return_code(self.STOPPED)
def stop_soon(self):
"""Can be called by anything. Currently called by
mainwin.MainWin.on_progress_list_stop_soon().
Sets the flag that causes this VideoDownloader to stop after the
current video.
"""
if DEBUG_FUNC_FLAG:
print('dl 2224 stop_soon')
self.stop_soon_flag = True
class PipeReader(threading.Thread):
"""Called by downloads.VideoDownloader.__init__().

View File

@ -457,15 +457,19 @@ SMALL_ICON_DICT = {
'playlist_small': 'playlist.png',
'folder_small': 'folder.png',
'download_small': 'download.png',
'archived_small': 'archived.png',
'check_small': 'check.png',
'download_small': 'download.png',
'error_small': 'error.png',
'folder_black_small': 'folder_black.png',
'folder_blue_small': 'folder_blue.png',
'folder_green_small': 'folder_green.png',
'folder_red_small': 'folder_red.png',
'have_file_small': 'have_file.png',
'no_file_small': 'no_file.png',
'ok_small': 'ok.png',
'error_small': 'error.png',
'warning_small': 'warning.png',
'system_error_small': 'system_error.png',
'system_warning_small': 'system_warning.png',
'warning_small': 'warning.png',
}
WIN_ICON_LIST = [

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -541,6 +541,14 @@ class GenericContainer(GenericMedia):
# Set accessors
def set_dl_disable_flag(self, flag):
if flag:
self.dl_disable_flag = True
else:
self.dl_disable_flag = False
def reset_counts(self, vid_count, new_count, fav_count, dl_count):
"""Called by mainapp.TartubeApp.update_db().
@ -588,6 +596,56 @@ class GenericContainer(GenericMedia):
self.new_count -= 1
def set_master_dbid(self, app_obj, dbid):
if dbid == self.master_dbid:
# No change to the current value
return
else:
# Update the old alternative download destination
if self.master_dbid != self.dbid:
old_dest_obj = app_obj.media_reg_dict[self.master_dbid]
old_dest_obj.del_slave_dbid(self.dbid)
# Update this object's IV
self.master_dbid = dbid
if self.master_dbid != self.dbid:
# Update the new alternative download destination
new_dest_obj = app_obj.media_reg_dict[self.master_dbid]
new_dest_obj.add_slave_dbid(self.dbid)
def add_slave_dbid(self, dbid):
"""Called by self.set_master_dbid() only."""
# (Failsafe: don't add the same value to self.slave_dbid_list)
match_flag = False
for slave_dbid in self.slave_dbid_list:
if slave_dbid == dbid:
match_flag = True
break
if not match_flag:
self.slave_dbid_list.append(dbid)
def del_slave_dbid(self, dbid):
"""Called by self.set_master_dbid() only."""
new_list = []
for slave_dbid in self.slave_dbid_list:
if slave_dbid != dbid:
new_list.append(slave_dbid)
self.slave_dbid_list = new_list.copy()
def set_name(self, name):
"""Must only be called by mainapp.TartubeApp.rename_container()."""
@ -905,6 +963,9 @@ class Video(GenericMedia):
# it's marked as a favourite if the same IV in the parent channel,
# playlist or folder (also in the parent's parent, and so on) is True
self.fav_flag = False
# Flag set to True if the video is archived, meaning that it can't be
# auto-deleted (but it can still be deleted manually by the user)
self.archive_flag = False
# The file's directory, name and extension
self.file_dir = None
@ -1019,6 +1080,13 @@ class Video(GenericMedia):
# Set accessors
def set_archive_flag(self, flag):
if flag:
self.archive_flag = True
else:
self.archive_flag = False
def set_dl_flag(self, flag=False):
@ -1303,10 +1371,27 @@ class Channel(GenericRemoteContainer):
# Download source (a URL)
self.source = None
# Alternative download destination - the dbid of a channel, playlist or
# folder in whose directory videos, thumbnails (etc) are downloaded.
# By default, set to the dbid of this channel; but can be set to the
# dbid of any other channel/playlist/folder
# Used for: (1) adding a channel and its playlists to the Tartube
# database, so that duplicate videos don't exist on the user's
# filesystem, (2) tying together, for example, a YouTube and a
# BitChute account, so that duplicate videos don't exist on the
# user's filesystem
self.master_dbid = dbid
# A list of dbids for any channel, playlist or folder that uses this
# channel as its alternative destination
self.slave_dbid_list = []
# Flag set to True if Tartube should always simulate the download of
# videos in this channel, or False if the downloads.DownloadManager
# object should decide whether to simulate, or not
self.dl_sim_flag = False
# Flag set to True if this channel should never be checked or
# downloaded
self.dl_disable_flag = False
# Flag set to True if this channel is marked as favourite, meaning
# that all child video objects are automatically marked as
# favourites
@ -1440,10 +1525,27 @@ class Playlist(GenericRemoteContainer):
# Download source (a URL)
self.source = None
# Alternative download destination - the dbid of a channel, playlist or
# folder in whose directory videos, thumbnails (etc) are downloaded.
# By default, set to the dbid of this playlist; but can be set to the
# dbid of any other channel/playlist/folder
# Used for: (1) adding a channel and its playlists to the Tartube
# database, so that duplicate videos don't exist on the user's
# filesystem, (2) tying together, for example, a YouTube and a
# BitChute account, so that duplicate videos don't exist on the
# user's filesystem
self.master_dbid = dbid
# A list of dbids for any channel, playlist or folder that uses this
# playlist as its alternative destination
self.slave_dbid_list = []
# Flag set to True if Tartube should always simulate the download of
# videos in this playlist, or False if the downloads.DownloadManager
# object should decide whether to simulate, or not
self.dl_sim_flag = False
# Flag set to True if this playlist should never be checked or
# downloaded
self.dl_disable_flag = False
# Flag set to True if this playlist is marked as favourite, meaning
# that all child video objects are automatically marked as
# favourites
@ -1592,6 +1694,21 @@ class Folder(GenericContainer):
# folder can't be changed
self.nickname = name
# Alternative download destination - the dbid of a channel, playlist or
# folder in whose directory videos, thumbnails (etc) are downloaded.
# By default, set to the dbid of this folder; but can be set to the
# dbid of any other channel/playlist/folder
# Used for: (1) adding a channel and its playlists to the Tartube
# database, so that duplicate videos don't exist on the user's
# filesystem, (2) tying together, for example, a YouTube and a
# BitChute account, so that duplicate videos don't exist on the
# user's filesystem
# NB Fixed folders cannot have an alternative download destination
self.master_dbid = dbid
# A list of dbids for any channel, playlist or folder that uses this
# folder as its alternative destination
self.slave_dbid_list = []
# Flag set to False if the folder can be deleted by the user, or True
# if it can't be deleted by the user
self.fixed_flag = fixed_flag
@ -1611,6 +1728,10 @@ class Folder(GenericContainer):
# videos in this folder, or False if the downloads.DownloadManager
# object should decide whether to simulate, or not
self.dl_sim_flag = False
# Flag set to True if this folder should never be checked or
# downloaded. If True, the setting applies to any descendant
# channels, playlists and folders
self.dl_disable_flag = False
# Flag set to True if this folder is hidden (not visible in the Video
# Index). Note that only folders can be hidden; channels and
# playlists cannot

View File

@ -268,6 +268,13 @@ class OptionsManager(object):
temporary directories.
The same applies to the JSON and thumbnail files.
use_fixed_folder (str or None): If not None, then all videos are
downloaded to one of Tartube's fixed folders (not including private
folders) - currently, that group consists of only 'Temporary
Videos' and 'Unsorted Videos'. The value should match the name of
the folder
"""
@ -371,6 +378,7 @@ class OptionsManager(object):
'sim_keep_description': False,
'sim_keep_info': False,
'sim_keep_thumbnail': True,
'use_fixed_folder': None,
}
@ -518,6 +526,7 @@ class OptionsParser(object):
# OptionHolder('sim_keep_description', '', False),
# OptionHolder('sim_keep_info', '', False),
# OptionHolder('sim_keep_thumbnail', '', False),
# OptionHolder('use_fixed_folder', '', None),
]
@ -721,16 +730,31 @@ class OptionsParser(object):
"""
# Set the directory in which any downloaded videos will be saved
app_obj = self.download_manager_obj.app_obj
media_data_obj = download_item_obj.media_data_obj
if isinstance(media_data_obj, media.Video):
save_path = media_data_obj.parent_obj.get_dir(
self.download_manager_obj.app_obj
)
override_name = copy_dict['use_fixed_folder']
if not isinstance(media_data_obj, media.Video) \
and override_name is not None \
and override_name in app_obj.media_name_dict:
# Because of the override, save all videos to a fixed folder
other_dbid = app_obj.media_name_dict[override_name]
other_obj = app_obj.media_reg_dict[other_dbid]
save_path = other_obj.get_dir(app_obj)
else:
save_path = media_data_obj.get_dir(
self.download_manager_obj.app_obj
)
if isinstance(media_data_obj, media.Video):
save_path = media_data_obj.parent_obj.get_dir(
self.download_manager_obj.app_obj
)
else:
save_path = media_data_obj.get_dir(
self.download_manager_obj.app_obj
)
# Set the youtube-dl output template for the video's file
template = formats.FILE_OUTPUT_CONVERT_DICT[copy_dict['output_format']]

View File

@ -35,8 +35,8 @@ import mainapp
# 'Global' variables
__packagename__ = 'tartube'
__version__ = '1.1.015'
__date__ = '22 Aug 2019'
__version__ = '1.1.050'
__date__ = '26 Aug 2019'
__copyright__ = 'Copyright \xa9 2019 A S Lewis'
__license__ = """
Copyright \xc2\xa9 2019 A S Lewis.
@ -64,7 +64,7 @@ __app_id__ = 'io.sourceforge.tartube'
# This is the default executable, in which youtube-dl updates are enabled. For
# Debian packaging, use the 'tartube_debian' executable (see the comments in
# setup.py)
__disable_ytdl_update_flag__ = False
__debian_install_flag__ = False
# Tartube's icons are stored in the ../icons directory. If packagers want to
# move them somewhere else, then adding the directory path to this list will
# tell mainwin.MainWin.setup_pixbufs() how to find them

View File

@ -35,8 +35,8 @@ import mainapp
# 'Global' variables
__packagename__ = 'tartube'
__version__ = '1.1.015'
__date__ = '22 Aug 2019'
__version__ = '1.1.050'
__date__ = '26 Aug 2019'
__copyright__ = 'Copyright \xa9 2019 A S Lewis'
__license__ = """
Copyright \xc2\xa9 2019 A S Lewis.
@ -64,7 +64,7 @@ __app_id__ = 'io.sourceforge.tartube'
# This is a modified executable, in which youtube-dl updates are disabled
# (to meet the demands of Debian packaging). All other users should run the
# 'tartube' executable (see the comments in setup.py)
__disable_ytdl_update_flag__ = True
__debian_install_flag__ = True
# Tartube's icons are stored in the ../icons directory. If packagers want to
# move them somewhere else, then adding the directory path to this list will
# tell mainwin.MainWin.setup_pixbufs() how to find them