Update to v2.0.016

master
A S Lewis 2020-04-10 15:59:43 +01:00
parent 577d1f03d0
commit b9e3f56093
17 changed files with 290 additions and 78 deletions

11
.gitignore vendored Normal file
View File

@ -0,0 +1,11 @@
# 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

35
CHANGES
View File

@ -1,3 +1,38 @@
v2.0.016 (10 Apr 2020)
-------------------------------------------------------------------------------
MINOR NEW FEATURES
- Tartube's config file is stored in a standard location for your system, by
default. For testing purposes, you can copy a config file into Tartube's
installation directory (the one containing this file). If you do so,
Tartube will load and later save that config file, rather than the one in
the standard location
- Tartube no longer creates a youtube-dl archive file in its 'Unsorted Videos'
and 'Temporary Videos' folders. Any existing archive files in those folders
are automatically deleted. Other folders are not affected (Git #64)
- In the Videos tab, you can expand the tree on the left-hand side of the
window by clicking on a folder (if this behaviour has been enabled). This
behaviour has now been modified slightly. Clicking on a folder will also
collapse the tree, if already expanded. You can tell Tartube to expand the
whole tree, not just the folder itself. The settings can be specified by
selecting the checkbuttons in Edit > System preferences > Windows >
Main window
MINOR FIXES
- The system preferences window didn't show the correct location for the
loaded config file. Fixed
- The DEB package has been improved to generate fewer Lintian error messages
- Tartube was unable to switch between databases, if the main 'Download all'
button had been disabled. Fixed
- After deleting a folder, clicking the 'Add a new folder' button generated an
error. Fixed
- If the internet connection goes down during a check operation, Tartube is
now less likely to freeze
- The 'Apply changes without closing the window' button at the bottom of many
edit windows did not work as intended. Fixed
- Video descriptions are no longer editable in a video's 'Video Properties'
window
v2.0.0 (29 Feb 2020) v2.0.0 (29 Feb 2020)
------------------------------------------------------------------------------- -------------------------------------------------------------------------------

View File

@ -3,5 +3,4 @@ recursive-include docs *
recursive-include icons * recursive-include icons *
recursive-include pack * recursive-include pack *
recursive-include screenshots * recursive-include screenshots *
recursive-include share *

View File

@ -16,10 +16,10 @@ Attention `Linux Format <https://www.linuxformat.com/>`__ readers! There are eas
* `4 Quick start guide`_ * `4 Quick start guide`_
* `5 Installation`_ * `5 Installation`_
* `6 Using Tartube`_ * `6 Using Tartube`_
* `7. Frequently-Asked Questions`_ * `7 Frequently-Asked Questions`_
* `8. Contributing`_ * `8 Contributing`_
* `9. Authors`_ * `9 Authors`_
* `10. License`_ * `10 License`_
1 Introduction 1 Introduction
============== ==============
@ -44,14 +44,14 @@ Problems can be reported at `our GitHub page <https://github.com/axcore/tartube/
3 Downloads 3 Downloads
=========== ===========
Latest version: **v2.0.0 (29 Feb 2019)** Latest version: **v2.0.016 (10 Apr 2020)**
- `MS Windows (32-bit) installer <https://sourceforge.net/projects/tartube/files/v2.0.0/install-tartube-2.0.0-32bit.exe/download>`__ from Sourceforge - `MS Windows (32-bit) installer <https://sourceforge.net/projects/tartube/files/v2.0.016/install-tartube-2.0.016-32bit.exe/download>`__ from Sourceforge
- `MS Windows (64-bit) installer <https://sourceforge.net/projects/tartube/files/v2.0.0/install-tartube-2.0.0-64bit.exe/download>`__ from Sourceforge - `MS Windows (64-bit) installer <https://sourceforge.net/projects/tartube/files/v2.0.016/install-tartube-2.0.016-64bit.exe/download>`__ from Sourceforge
- `DEB package (for Debian-based distros, e.g. Ubuntu, Linux Mint) <https://sourceforge.net/projects/tartube/files/v2.0.0/python3-tartube_2.0.0.deb/download>`__ from Sourceforge - `DEB package (for Debian-based distros, e.g. Ubuntu, Linux Mint) <https://sourceforge.net/projects/tartube/files/v2.0.016/python3-tartube_2.0.016.deb/download>`__ from Sourceforge
- `RPM package (for RHEL-based distros, e.g. Fedora) <https://sourceforge.net/projects/tartube/files/v2.0.0/tartube-2.0.0.rpm/download>`__ from Sourceforge - `RPM package (for RHEL-based distros, e.g. Fedora) <https://sourceforge.net/projects/tartube/files/v2.0.016/tartube-2.0.016.rpm/download>`__ from Sourceforge
- `Gentoo ebuild (available in src_prepare-overlay) <https://gitlab.com/src_prepare/src_prepare-overlay/>`__ from Gitlab - `Gentoo ebuild (available in src_prepare-overlay) <https://gitlab.com/src_prepare/src_prepare-overlay/>`__ from Gitlab
- `Source code <https://sourceforge.net/projects/tartube/files/v2.0.0/tartube_v2.0.0.tar.gz/download>`__ from Sourceforge - `Source code <https://sourceforge.net/projects/tartube/files/v2.0.016/tartube_v2.0.016.tar.gz/download>`__ from Sourceforge
- `Source code <https://github.com/axcore/tartube>`__ and `support <https://github.com/axcore/tartube/issues>`__ from GitHub - `Source code <https://github.com/axcore/tartube>`__ and `support <https://github.com/axcore/tartube/issues>`__ from GitHub
There are also DEB/RPM packages marked STRICT. In these packages, updates to **youtube-dl** from within **Tartube** have been disabled. If **Tartube** is uploaded to a repository with lots of rules, such as the official Debian repository, then you should probably use the STRICT packages. There are also DEB/RPM packages marked STRICT. In these packages, updates to **youtube-dl** from within **Tartube** have been disabled. If **Tartube** is uploaded to a repository with lots of rules, such as the official Debian repository, then you should probably use the STRICT packages.
@ -75,7 +75,7 @@ There are also DEB/RPM packages marked STRICT. In these packages, updates to **y
- If you want to download the videos, click the **Download all** button - If you want to download the videos, click the **Download all** button
4.2 Linux/BSD 4.2 Linux/BSD
~~~~~~~~~~~~~ -------------
- Install **Tartube** by downloading the DEB or RPM package from the links above. Alternatively, install it from PyPI, using the instructions below - Install **Tartube** by downloading the DEB or RPM package from the links above. Alternatively, install it from PyPI, using the instructions below
- It's strongly recommended that you install `Ffmpeg <https://ffmpeg.org/>`__ or `AVConv <https://sourceforge.io/projects/avconv/>`__, too - It's strongly recommended that you install `Ffmpeg <https://ffmpeg.org/>`__ or `AVConv <https://sourceforge.io/projects/avconv/>`__, too
@ -794,8 +794,8 @@ N.B. Many video websites, such as **YouTube**, allow you to download the audio (
- Click the **Add format >>>** button to add it to the list - Click the **Add format >>>** button to add it to the list
- Click the **OK** button at the bottom of the window to apply your changes - Click the **OK** button at the bottom of the window to apply your changes
7. Frequently-Asked Questions 7 Frequently-Asked Questions
============================= ============================
**Q: I can't install Tartube / I can't run Tartube / Tartube doesn't work properly / Tartube keeps crashing!** **Q: I can't install Tartube / I can't run Tartube / Tartube doesn't work properly / Tartube keeps crashing!**
@ -882,6 +882,18 @@ If you installed an earlier version of **Tartube**, and if you want to move your
- Delete the empty **downloads** directory - Delete the empty **downloads** directory
- You can now restart **Tartube** - You can now restart **Tartube**
**Q: Tartube stores its database file in the same place as its videos. Why can't I store them in different places?**
A: This question has been asked by several people who were storing their videos on some remote filesystem (perhaps in the so-called 'cloud'). They found that the videos could be downloaded to that remote location, but that Tartube couldn't save its database file there.
At the moment, the answer is "**Tartube** is working fine, fix your own computer". Perhaps in the future, someone will think of an urgent need for the database file and the data folder to be split up. Until then, there are a number of good reasons for keeping them together:
- If the database file exists in the folder, **Tartube** can be confident that it's downloading videos to the place you actually intended
- If **Tartube** can't read/write its own database file, that probably means that it won't be possible to store any videos, thumbnails, descriptions, and so on
- **Tartube** actually creates a number of temporary files at this location, most of which are invisible but need to be in the same place as the videos
- If you want to move your videos from one location to another, it's easy - just move a single directory (folder) and everything it contains. There is no need to reconfigure anything; just tell **Tartube** where to find the new directory (folder)
- Splitting up the data folder and the database file would require a lot of code to be rewritten, and this would probably introduce lots of new bugs
**Q: I want to convert the video files to audio files!** **Q: I want to convert the video files to audio files!**
A: See `6.20 Converting to audio`_ A: See `6.20 Converting to audio`_
@ -904,9 +916,23 @@ A: Click **Edit > System preferences... > Windows > Main window > Don't show lab
MS Windows users can already see a toolbar without labels. MS Windows users can already see a toolbar without labels.
**Q: I added my YouTube username and password, but I am still seeing authentification errors!**
A: The questioner is talking about the settings in **Edit > General download options... > Advanced**.
This is a `youtube-dl <https://youtube-dl.org/>`__ issue. A general solution is described in `this post <https://github.com/ytdl-org/youtube-dl/issues/21313#issuecomment-499496235>`__.
The solution describes how to create a cookies.txt file, which can be specified as a download option.
Having created the file, in the same edit window, click the **General** tab. In the box labelled **Extra youtube-dl command options**, you can add:
**--cookies=YT-cookies.txt**
See also the **Tartube** thread `here <https://github.com/axcore/tartube/issues/68>`__.
**Q: Why is the Windows installer so big?** **Q: Why is the Windows installer so big?**
**Tartube** is a Linux application. The installer for MS Windows contains not just **Tartube** itself, but a copy of Python and a whole bunch of essential graphics libraries, all of them ported to MS Windows. A: **Tartube** is a Linux application. The installer for MS Windows contains not just **Tartube** itself, but a copy of Python and a whole bunch of essential graphics libraries, all of them ported to MS Windows.
If you're at all suspicious that such a small application uses such a large installer, you are invited to examine the installed files for yourself: If you're at all suspicious that such a small application uses such a large installer, you are invited to examine the installed files for yourself:
@ -922,19 +948,19 @@ The NSIS scripts used to create the installers can be found here:
The scripts contain full instructions, so you should be able to create your own installer, and compare it with the official one. The scripts contain full instructions, so you should be able to create your own installer, and compare it with the official one.
8. Contributing 8 Contributing
=============== ==============
- Report a bug: Use the Github - Report a bug: Use the Github
`issues <https://github.com/axcore/tartube/issues>`__ page `issues <https://github.com/axcore/tartube/issues>`__ page
9. Authors 9 Authors
========== =========
See the `AUTHORS <AUTHORS>`__ file. See the `AUTHORS <AUTHORS>`__ file.
10. License 10 License
=========== ==========
**Tartube** is licensed under the `GNU General Public License v3.0 <https://www.gnu.org/licenses/gpl-3.0.en.html>`__. **Tartube** is licensed under the `GNU General Public License v3.0 <https://www.gnu.org/licenses/gpl-3.0.en.html>`__.

View File

@ -1,4 +1,4 @@
# Tartube v2.0.006 installer script for MS Windows # Tartube v2.0.016 installer script for MS Windows
# #
# Copyright (C) 2019-2020 A S Lewis # Copyright (C) 2019-2020 A S Lewis
# #
@ -225,7 +225,7 @@
;Name and file ;Name and file
Name "Tartube" Name "Tartube"
OutFile "install-tartube-2.0.006-32bit.exe" OutFile "install-tartube-2.0.016-32bit.exe"
;Default installation folder ;Default installation folder
InstallDir "$LOCALAPPDATA\Tartube" InstallDir "$LOCALAPPDATA\Tartube"
@ -328,7 +328,7 @@ Section "Tartube" SecClient
# "Publisher" "A S Lewis" # "Publisher" "A S Lewis"
# WriteRegStr HKLM \ # WriteRegStr HKLM \
# "Software\Microsoft\Windows\CurrentVersion\Uninstall\Tartube" \ # "Software\Microsoft\Windows\CurrentVersion\Uninstall\Tartube" \
# "DisplayVersion" "2.0.006" # "DisplayVersion" "2.0.016"
# Create uninstaller # Create uninstaller
WriteUninstaller "$INSTDIR\Uninstall.exe" WriteUninstaller "$INSTDIR\Uninstall.exe"

View File

@ -1,4 +1,4 @@
# Tartube v2.0.006 installer script for MS Windows # Tartube v2.0.016 installer script for MS Windows
# #
# Copyright (C) 2019-2020 A S Lewis # Copyright (C) 2019-2020 A S Lewis
# #
@ -226,7 +226,7 @@
;Name and file ;Name and file
Name "Tartube" Name "Tartube"
OutFile "install-tartube-2.0.006-64bit.exe" OutFile "install-tartube-2.0.016-64bit.exe"
;Default installation folder ;Default installation folder
InstallDir "$LOCALAPPDATA\Tartube" InstallDir "$LOCALAPPDATA\Tartube"
@ -329,7 +329,7 @@ Section "Tartube" SecClient
# "Publisher" "A S Lewis" # "Publisher" "A S Lewis"
# WriteRegStr HKLM \ # WriteRegStr HKLM \
# "Software\Microsoft\Windows\CurrentVersion\Uninstall\Tartube" \ # "Software\Microsoft\Windows\CurrentVersion\Uninstall\Tartube" \
# "DisplayVersion" "2.0.006" # "DisplayVersion" "2.0.016"
# Create uninstaller # Create uninstaller
WriteUninstaller "$INSTDIR\Uninstall.exe" WriteUninstaller "$INSTDIR\Uninstall.exe"

View File

@ -43,8 +43,8 @@ import mainapp
# 'Global' variables # 'Global' variables
__packagename__ = 'tartube' __packagename__ = 'tartube'
__prettyname__ = 'Tartube' __prettyname__ = 'Tartube'
__version__ = '2.0.006' __version__ = '2.0.016'
__date__ = '3 Mar 2020' __date__ = '10 Apr 2020'
__copyright__ = 'Copyright \xa9 2019-2020 A S Lewis' __copyright__ = 'Copyright \xa9 2019-2020 A S Lewis'
__license__ = """ __license__ = """
Copyright \xa9 2019-2020 A S Lewis. Copyright \xa9 2019-2020 A S Lewis.

View File

@ -43,8 +43,8 @@ import mainapp
# 'Global' variables # 'Global' variables
__packagename__ = 'tartube' __packagename__ = 'tartube'
__prettyname__ = 'Tartube' __prettyname__ = 'Tartube'
__version__ = '2.0.006' __version__ = '2.0.016'
__date__ = '3 Mar 2020' __date__ = '10 Apr 2020'
__copyright__ = 'Copyright \xa9 2019-2020 A S Lewis' __copyright__ = 'Copyright \xa9 2019-2020 A S Lewis'
__license__ = """ __license__ = """
Copyright \xa9 2019-2020 A S Lewis. Copyright \xa9 2019-2020 A S Lewis.

View File

@ -1,4 +1,4 @@
.TH man 1 "3 Mar 2020" "2.0.006" "tartube man page" .TH man 1 "10 Apr 2020" "2.0.016" "tartube man page"
.SH NAME .SH NAME
tartube \- GUI front-end for youtube-dl tartube \- GUI front-end for youtube-dl
.SH SYNOPSIS .SH SYNOPSIS

View File

@ -1,6 +1,6 @@
[Desktop Entry] [Desktop Entry]
Name=Tartube Name=Tartube
Version=2.0.006 Version=2.0.016
Exec=tartube Exec=tartube
Icon=tartube Icon=tartube
Type=Application Type=Application

View File

@ -140,7 +140,7 @@ for subdir in subdir_list:
# Setup # Setup
setuptools.setup( setuptools.setup(
name='tartube', name='tartube',
version='2.0.006', version='2.0.016',
description='GUI front-end for youtube-dl', description='GUI front-end for youtube-dl',
long_description=long_description, long_description=long_description,
long_description_content_type='text/plain', long_description_content_type='text/plain',

View File

@ -424,7 +424,7 @@ class GenericEditWin(GenericConfigWin):
# Apply any changes the user has made # Apply any changes the user has made
for key in self.edit_dict.keys(): for key in self.edit_dict.keys():
setattr(self.edit_obj, self.edit_dict[key]) setattr(self.edit_obj, key, self.edit_dict[key])
# The changes can now be cleared # The changes can now be cleared
self.edit_dict = {} self.edit_dict = {}
@ -497,7 +497,11 @@ class GenericEditWin(GenericConfigWin):
if name in self.edit_dict: if name in self.edit_dict:
return self.edit_dict[name] return self.edit_dict[name]
else: else:
return getattr(self.edit_obj, name) attrib = getattr(self.edit_obj, name)
if type(attrib) is list or type(attrib) is dict:
return attrib.copy()
else:
return attrib
# (Add widgets) # (Add widgets)
@ -4863,11 +4867,11 @@ class VideoEditWin(GenericEditWin):
# window, the changes are applied to self.edit_obj # window, the changes are applied to self.edit_obj
# If the user clicks the 'Reset' or 'Cancel' buttons, the dictionary # If the user clicks the 'Reset' or 'Cancel' buttons, the dictionary
# is emptied and the changes are lost # is emptied and the changes are lost
# The key-value pairs in the dictionary correspond directly to # The key-value pairs in the dictionary correspond directly to the
# the names of attributes, and their balues in self.edit_obj # names of attributes, and their values in self.edit_obj
# Key-value pairs are added to this dictionary whenever the user # Key-value pairs are added to this dictionary whenever the user makes
# makes a change (so if no changes are made when the window is # a change (so if no changes are made when the window is closed, the
# closed, the dictionary will still be empty) # dictionary will still be empty)
self.edit_dict = {} self.edit_dict = {}
# String identifying the media type # String identifying the media type
@ -5094,10 +5098,11 @@ class VideoEditWin(GenericEditWin):
0, 0, 1, 1, 0, 0, 1, 1,
) )
self.add_textview(grid, textview, textbuffer = self.add_textview(grid,
'descrip', 'descrip',
0, 1, 1, 1, 0, 1, 1, 1,
) )
textview.set_editable(False)
def setup_errors_warnings_tab(self): def setup_errors_warnings_tab(self):
@ -6173,10 +6178,14 @@ class SystemPrefWin(GenericPrefWin):
0, 8, grid_width, 1, 0, 8, grid_width, 1,
) )
if self.app_obj.config_file_xdg_path is not None: if self.app_obj.config_file_xdg_path is None \
config_path = self.app_obj.config_file_xdg_path or (
else: os.path.isfile(self.app_obj.config_file_path) \
and not __main__.__pkg_strict_install_flag__
):
config_path = self.app_obj.config_file_path config_path = self.app_obj.config_file_path
else:
config_path = self.app_obj.config_file_xdg_path
entry3 = self.add_entry(grid, entry3 = self.add_entry(grid,
config_path, config_path,
@ -6355,7 +6364,7 @@ class SystemPrefWin(GenericPrefWin):
treeview.connect( treeview.connect(
'cursor-changed', 'cursor-changed',
self.on_data_dir_cursor_changed, self.on_data_dir_cursor_changed,
button2, # Use button2, # Switch
button3, # Forget button3, # Forget
button4, # Forget all button4, # Forget all
button5, # Move up button5, # Move up
@ -6664,57 +6673,92 @@ class SystemPrefWin(GenericPrefWin):
checkbutton5.connect('toggled', self.on_complex_button_toggled) checkbutton5.connect('toggled', self.on_complex_button_toggled)
checkbutton6 = self.add_checkbutton(grid, checkbutton6 = self.add_checkbutton(grid,
'After clicking on a folder, automatically expand the Video' \ 'After clicking on a folder, automatically expand/collapse the' \
+ ' Index beneath it', + ' tree around it',
self.app_obj.auto_expand_video_index_flag, self.app_obj.auto_expand_video_index_flag,
True, # Can be toggled by user True, # Can be toggled by user
0, 6, 1, 1, 0, 6, 1, 1,
) )
checkbutton6.connect('toggled', self.on_expand_tree_toggled) # signal_connect appears below
checkbutton7 = self.add_checkbutton(grid, checkbutton7 = self.add_checkbutton(grid,
'Expand the whole tree, not just the level beneath the clicked' \
+ ' folder',
self.app_obj.full_expand_video_index_flag,
True, # Can be toggled by user
0, 7, 1, 1,
)
if not self.app_obj.auto_expand_video_index_flag:
checkbutton7.set_sensitive(False)
# signal_connect appears below
# signal_connects from above
checkbutton6.connect(
'toggled',
self.on_expand_tree_toggled,
checkbutton7,
)
checkbutton7.connect('toggled', self.on_expand_full_tree_toggled)
checkbutton8 = self.add_checkbutton(grid,
'Disable the \'Download all\' buttons in the toolbar and the' \ 'Disable the \'Download all\' buttons in the toolbar and the' \
+ ' Videos Tab', + ' Videos Tab',
self.app_obj.disable_dl_all_flag, self.app_obj.disable_dl_all_flag,
True, # Can be toggled by user True, # Can be toggled by user
0, 7, 1, 1, 0, 8, 1, 1,
) )
checkbutton7.connect('toggled', self.on_disable_dl_all_toggled) checkbutton8.connect('toggled', self.on_disable_dl_all_toggled)
checkbutton8 = self.add_checkbutton(grid,
def setup_windows_tabs_tab(self, inner_notebook):
"""Called by self.setup_windows_tab().
Sets up the 'Tabs' inner notebook tab.
"""
tab, grid = self.add_inner_notebook_tab('_Tabs', inner_notebook)
# Tab preferences
self.add_label(grid,
'<u>Tab preferences</u>',
0, 0, 1, 1,
)
checkbutton = self.add_checkbutton(grid,
'In the Videos Tab, show \'today\' and \'yesterday\' as the' \ 'In the Videos Tab, show \'today\' and \'yesterday\' as the' \
+ ' date, when possible', + ' date, when possible',
self.app_obj.show_pretty_dates_flag, self.app_obj.show_pretty_dates_flag,
True, # Can be toggled by user True, # Can be toggled by user
0, 8, 1, 1, 0, 1, 1, 1,
) )
checkbutton8.connect('toggled', self.on_pretty_date_button_toggled) checkbutton.connect('toggled', self.on_pretty_date_button_toggled)
checkbutton9 = self.add_checkbutton(grid, checkbutton2 = self.add_checkbutton(grid,
'In the Progress Tab, hide finished videos / channels' \ 'In the Progress Tab, hide finished videos / channels' \
+ ' / playlists', + ' / playlists',
self.app_obj.progress_list_hide_flag, self.app_obj.progress_list_hide_flag,
True, # Can be toggled by user True, # Can be toggled by user
0, 9, 1, 1, 0, 2, 1, 1,
) )
checkbutton9.connect('toggled', self.on_hide_button_toggled) checkbutton2.connect('toggled', self.on_hide_button_toggled)
checkbutton10 = self.add_checkbutton(grid, checkbutton3 = self.add_checkbutton(grid,
'In the Progress Tab, show results in reverse order', 'In the Progress Tab, show results in reverse order',
self.app_obj.results_list_reverse_flag, self.app_obj.results_list_reverse_flag,
True, # Can be toggled by user True, # Can be toggled by user
0, 10, 1, 1, 0, 3, 1, 1,
) )
checkbutton10.connect('toggled', self.on_reverse_button_toggled) checkbutton3.connect('toggled', self.on_reverse_button_toggled)
checkbutton11 = self.add_checkbutton(grid, checkbutton4 = self.add_checkbutton(grid,
'In the Errors/Warnings Tab, preserve message counts in the' \ 'In the Errors/Warnings Tab, preserve message counts in the' \
+ ' tab label for longer', + ' tab label for longer',
self.app_obj.system_msg_keep_totals_flag, self.app_obj.system_msg_keep_totals_flag,
True, # Can be toggled by user True, # Can be toggled by user
0, 11, 1, 1, 0, 4, 1, 1,
) )
checkbutton11.connect('toggled', self.on_system_keep_button_toggled) checkbutton4.connect('toggled', self.on_system_keep_button_toggled)
def setup_windows_system_tray_tab(self, inner_notebook): def setup_windows_system_tray_tab(self, inner_notebook):
@ -7943,8 +7987,8 @@ class SystemPrefWin(GenericPrefWin):
) )
checkbutton = self.add_checkbutton(grid, checkbutton = self.add_checkbutton(grid,
'Allow youtube-dl to create its own archive (so deleted videos' \ 'Allow youtube-dl to create its own archive file (so deleted' \
+ ' are not re-downloaded)', + ' videos are not re-downloaded)',
self.app_obj.allow_ytdl_archive_flag, self.app_obj.allow_ytdl_archive_flag,
True, # Can be toggled by user True, # Can be toggled by user
0, 8, grid_width, 1, 0, 8, grid_width, 1,
@ -9516,7 +9560,7 @@ class SystemPrefWin(GenericPrefWin):
self.app_obj.set_scheduled_dl_wait_hours(spinbutton.get_value()) self.app_obj.set_scheduled_dl_wait_hours(spinbutton.get_value())
def on_expand_tree_toggled(self, checkbutton): def on_expand_tree_toggled(self, checkbutton, checkbutton2):
"""Called from callback in self.setup_windows_main_window_tab(). """Called from callback in self.setup_windows_main_window_tab().
@ -9527,14 +9571,40 @@ class SystemPrefWin(GenericPrefWin):
checkbutton (Gtk.CheckButton): The widget clicked checkbutton (Gtk.CheckButton): The widget clicked
checkbutton2 (Gtk.CheckButton): Another widget that must be
modified
""" """
if checkbutton.get_active() \ if checkbutton.get_active() \
and not self.app_obj.auto_expand_video_index_flag: and not self.app_obj.auto_expand_video_index_flag:
self.app_obj.set_auto_expand_video_index_flag(True) self.app_obj.set_auto_expand_video_index_flag(True)
checkbutton2.set_sensitive(True)
elif not checkbutton.get_active() \ elif not checkbutton.get_active() \
and self.app_obj.auto_expand_video_index_flag: and self.app_obj.auto_expand_video_index_flag:
self.app_obj.set_auto_expand_video_index_flag(False) self.app_obj.set_auto_expand_video_index_flag(False)
checkbutton2.set_sensitive(False)
def on_expand_full_tree_toggled(self, checkbutton):
"""Called from callback in self.setup_windows_main_window_tab().
Enables/disables full auto-expansion of the Video Index after a folder
is selected (clicked).
Args:
checkbutton (Gtk.CheckButton): The widget clicked
"""
if checkbutton.get_active() \
and not self.app_obj.full_expand_video_index_flag:
self.app_obj.set_full_expand_video_index_flag(True)
elif not checkbutton.get_active() \
and self.app_obj.full_expand_video_index_flag:
self.app_obj.set_full_expand_video_index_flag(False)
def on_gtk_emulate_button_toggled(self, checkbutton): def on_gtk_emulate_button_toggled(self, checkbutton):

View File

@ -2604,13 +2604,16 @@ class VideoDownloader(object):
thumb_path = utils.convert_path_to_temp(app_obj, thumb_path) thumb_path = utils.convert_path_to_temp(app_obj, thumb_path)
if not os.path.isfile(thumb_path): if not os.path.isfile(thumb_path):
request_obj = requests.get(thumbnail)
# v1.2.006 This crashes if the directory specified by # v2.0.013 The requets module fails if the connection drops
# thumb_path doesn't exist, so need to use 'try' # v1.2.006 Wiriting the file fails if the directory specified
# by thumb_path doesn't exist
# Use 'try' so that neither problem is fatal
try: try:
request_obj = requests.get(thumbnail)
with open(thumb_path, 'wb') as outfile: with open(thumb_path, 'wb') as outfile:
outfile.write(request_obj.content) outfile.write(request_obj.content)
except: except:
pass pass

View File

@ -291,10 +291,14 @@ class TartubeApp(Gtk.Application):
# Flag set to True if small icons should be used in the Video Index, # Flag set to True if small icons should be used in the Video Index,
# False if large icons should be used # False if large icons should be used
self.show_small_icons_in_index = False self.show_small_icons_in_index = False
# Flag set to True if the Video Index treeview should auto-expand # Flag set to True if the Video Index treeview should auto-expand/
# when an item is clicked, to show its children (only folders # auto-collapse when an item is clicked, to show/hide its children
# have children visible in the Video Index, though) # (only folders have children visible in the Video Index, though)
self.auto_expand_video_index_flag = False self.auto_expand_video_index_flag = False
# Flag set to True if the treeview should be fully expanded when an
# item is clicked; False if only the next level should be expanded
# (ignored if self.auto_expand_video_index_flag is False)
self.full_expand_video_index_flag = False
# Flag set to True if the 'Download all' buttons in the main window # Flag set to True if the 'Download all' buttons in the main window
# toolbar and in the Videos tab should be disabled (in case the u # toolbar and in the Videos tab should be disabled (in case the u
# user is sure they only want to do simulated downloads) # user is sure they only want to do simulated downloads)
@ -1034,6 +1038,7 @@ class TartubeApp(Gtk.Application):
# passed, --download-archive, creating the file ytdl-archive.txt # passed, --download-archive, creating the file ytdl-archive.txt
# If the file exists, youtube-dl won't re-download a video a user has # If the file exists, youtube-dl won't re-download a video a user has
# deleted # deleted
# Ignored for system folders like 'Unsorted Videos'
self.allow_ytdl_archive_flag = True self.allow_ytdl_archive_flag = True
# If self.allow_ytdl_archive_flag is set, youtube-dl will have created # If self.allow_ytdl_archive_flag is set, youtube-dl will have created
# a ytdl_archive.txt, recording every video ever downloaded in the # a ytdl_archive.txt, recording every video ever downloaded in the
@ -2470,6 +2475,9 @@ class TartubeApp(Gtk.Application):
if version >= 1001077: # v1.1.077 if version >= 1001077: # v1.1.077
self.auto_expand_video_index_flag \ self.auto_expand_video_index_flag \
= json_dict['auto_expand_video_index_flag'] = json_dict['auto_expand_video_index_flag']
if version >= 2000014: # v2.0.014
self.full_expand_video_index_flag \
= json_dict['full_expand_video_index_flag']
if version >= 1001064: # v1.1.064 if version >= 1001064: # v1.1.064
self.disable_dl_all_flag = json_dict['disable_dl_all_flag'] self.disable_dl_all_flag = json_dict['disable_dl_all_flag']
if version >= 1004011: # v1.4.011 if version >= 1004011: # v1.4.011
@ -2930,6 +2938,7 @@ class TartubeApp(Gtk.Application):
'show_tooltips_flag': self.show_tooltips_flag, 'show_tooltips_flag': self.show_tooltips_flag,
'show_small_icons_in_index': self.show_small_icons_in_index, 'show_small_icons_in_index': self.show_small_icons_in_index,
'auto_expand_video_index_flag': self.auto_expand_video_index_flag, 'auto_expand_video_index_flag': self.auto_expand_video_index_flag,
'full_expand_video_index_flag': self.full_expand_video_index_flag,
'disable_dl_all_flag': self.disable_dl_all_flag, 'disable_dl_all_flag': self.disable_dl_all_flag,
'show_pretty_dates_flag': self.show_pretty_dates_flag, 'show_pretty_dates_flag': self.show_pretty_dates_flag,
@ -3836,6 +3845,36 @@ class TartubeApp(Gtk.Application):
if isinstance(media_data_obj, media.Video): if isinstance(media_data_obj, media.Video):
del media_data_obj.file_dir del media_data_obj.file_dir
if version < 2000012: # v2.0.012
# This version does not add the ytdl-archive.txt file to system
# folders ('Unsorted Videos' and 'Temporary Videos'), but
# continues to add it to channels, playlists and non-system
# folders
# Remove the archive file from system folders, if present
# 'Temporary Videos'
temp_path = os.path.abspath(
os.path.join(
self.fixed_temp_folder.get_default_dir(self),
'ytdl-archive.txt',
),
)
if os.path.isfile(temp_path):
os.remove(temp_path)
# 'Unsorted Videos'
unsorted_path = os.path.abspath(
os.path.join(
self.fixed_misc_folder.get_default_dir(self),
'ytdl-archive.txt',
),
)
if os.path.isfile(unsorted_path):
os.remove(unsorted_path)
def save_db(self): def save_db(self):
@ -13095,6 +13134,17 @@ class TartubeApp(Gtk.Application):
self.ffmpeg_path = path self.ffmpeg_path = path
def set_full_expand_video_index_flag(self, flag):
if DEBUG_FUNC_FLAG:
utils.debug_time('app 13074 set_full_expand_video_index_flag')
if not flag:
self.full_expand_video_index_flag = False
else:
self.full_expand_video_index_flag = True
def set_gtk_emulate_broken_flag(self, flag): def set_gtk_emulate_broken_flag(self, flag):
if DEBUG_FUNC_FLAG: if DEBUG_FUNC_FLAG:

View File

@ -8871,9 +8871,18 @@ class MainWin(Gtk.ApplicationWindow):
# Expand the tree beneath the selected line, if allowed # Expand the tree beneath the selected line, if allowed
if self.app_obj.auto_expand_video_index_flag: if self.app_obj.auto_expand_video_index_flag:
self.video_index_treeview.expand_to_path( if not self.video_index_treeview.row_expanded(
model.get_path(iter), model.get_path(iter),
) ):
self.video_index_treeview.expand_row(
model.get_path(iter),
self.app_obj.full_expand_video_index_flag,
)
else:
self.video_index_treeview.collapse_row(
model.get_path(iter),
)
# Redraw the Video Catalogue, on the first page, and reset its # Redraw the Video Catalogue, on the first page, and reset its
# scrollbars back to the top # scrollbars back to the top

View File

@ -43,8 +43,8 @@ import mainapp
# 'Global' variables # 'Global' variables
__packagename__ = 'tartube' __packagename__ = 'tartube'
__prettyname__ = 'Tartube' __prettyname__ = 'Tartube'
__version__ = '2.0.006' __version__ = '2.0.016'
__date__ = '3 Mar 2020' __date__ = '10 Apr 2020'
__copyright__ = 'Copyright \xa9 2019-2020 A S Lewis' __copyright__ = 'Copyright \xa9 2019-2020 A S Lewis'
__license__ = """ __license__ = """
Copyright \xa9 2019-2020 A S Lewis. Copyright \xa9 2019-2020 A S Lewis.

View File

@ -746,8 +746,17 @@ dl_sim_flag=False, divert_mode=None):
# If actually downloading videos, create an archive file so that, if the # 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 # user deletes the videos, youtube-dl won't try to download them again
elif app_obj.allow_ytdl_archive_flag: # (Videos downloaded into a system folder should never create an archive
# file)
if app_obj.allow_ytdl_archive_flag \
and (
not isinstance(media_data_obj, media.Folder)
or not media_data_obj.fixed_flag
) and (
not isinstance(media_data_obj, media.Video)
or not isinstance(media_data_obj.parent_obj, media.Folder)
or not media_data_obj.parent_obj.fixed_flag
):
# (Create the archive file in the media data object's default # (Create the archive file in the media data object's default
# sub-directory, not the alternative download destination, as this # sub-directory, not the alternative download destination, as this
# helps youtube-dl to work the way we want it to work) # helps youtube-dl to work the way we want it to work)