A few minor bugfixes
This commit is contained in:
parent
a0408f9b2a
commit
4e7965f9e9
18
CHANGES
18
CHANGES
@ -1,3 +1,21 @@
|
||||
v1.2.008 (30 Sep 2019)
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
MINOR NEW FEATURES
|
||||
- Tartube now ignores the YouTube 'WARNING: video doesn't have subtitles'
|
||||
by default. You can change this setting, if you want to
|
||||
|
||||
MAJOR FIXES
|
||||
- When moving a channel/playlist/folder to a different place on your
|
||||
filesystem, or when renaming a channel/playlist/folder, in certain rare
|
||||
situations data in the Tartube database isn't updated correctly. This may
|
||||
lead to a freeze or a crash. I'm not sure yet what the cause is, but I have
|
||||
added temporary code to prevent the problem affecting any user
|
||||
- Fixed error messages generated when checking/downloading individual
|
||||
channels/playlists/folders
|
||||
- Fixed faulty code for importing videos/channels/playlists/folders into the
|
||||
database
|
||||
|
||||
v1.2.0 (31 Aug 2019)
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
|
@ -12,11 +12,11 @@ Problems can be reported at `our GitHub page <https://github.com/axcore/tartube/
|
||||
Downloads
|
||||
---------
|
||||
|
||||
Latest version: **v1.2.0 (31 Aug 2019)**
|
||||
Latest version: **v1.2.008 (30 Sep 2019)**
|
||||
|
||||
- `MS Windows (32-bit) installer <https://sourceforge.io/projects/tartube/files/v1.2.0/install-tartube-1.2.0-32bit.exe/download>`__ from Sourceforge
|
||||
- `MS Windows (64-bit) installer <https://sourceforge.io/projects/tartube/files/v1.2.0/install-tartube-1.2.0-64bit.exe/download>`__ from Sourceforge
|
||||
- `Source code <https://sourceforge.io/projects/tartube/files/v1.2.0/tartube_v1.2.0.tar.gz/download>`__ from Sourceforge
|
||||
- `MS Windows (32-bit) installer <https://sourceforge.io/projects/tartube/files/v1.2.008/install-tartube-1.2.008-32bit.exe/download>`__ from Sourceforge
|
||||
- `MS Windows (64-bit) installer <https://sourceforge.io/projects/tartube/files/v1.2.008/install-tartube-1.2.008-64bit.exe/download>`__ from Sourceforge
|
||||
- `Source code <https://sourceforge.io/projects/tartube/files/v1.2.008/tartube_v1.2.008.tar.gz/download>`__ from Sourceforge
|
||||
- `Source code <https://github.com/axcore/tartube>`__ and `support <https://github.com/axcore/tartube/issues>`__ from GitHub
|
||||
|
||||
Why should I use Tartube?
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Tartube v1.2.0 installer script for MS Windows
|
||||
# Tartube v1.2.008 installer script for MS Windows
|
||||
#
|
||||
# Copyright (C) 2019 A S Lewis
|
||||
#
|
||||
@ -139,7 +139,7 @@
|
||||
|
||||
;Name and file
|
||||
Name "Tartube"
|
||||
OutFile "install-tartube-1.2.0-32bit.exe"
|
||||
OutFile "install-tartube-1.2.008-32bit.exe"
|
||||
|
||||
;Default installation folder
|
||||
InstallDir "$LOCALAPPDATA\Tartube"
|
||||
@ -244,7 +244,7 @@ Section "Tartube" SecClient
|
||||
"Publisher" "A S Lewis"
|
||||
WriteRegStr HKLM \
|
||||
"Software\Microsoft\Windows\CurrentVersion\Uninstall\Tartube" \
|
||||
"DisplayVersion" "1.2.0"
|
||||
"DisplayVersion" "1.2.008"
|
||||
|
||||
# Create uninstaller
|
||||
WriteUninstaller "$INSTDIR\Uninstall.exe"
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Tartube v1.2.0 installer script for MS Windows
|
||||
# Tartube v1.2.008 installer script for MS Windows
|
||||
#
|
||||
# Copyright (C) 2019 A S Lewis
|
||||
#
|
||||
@ -140,7 +140,7 @@
|
||||
|
||||
;Name and file
|
||||
Name "Tartube"
|
||||
OutFile "install-tartube-1.2.0-64bit.exe"
|
||||
OutFile "install-tartube-1.2.008-64bit.exe"
|
||||
|
||||
;Default installation folder
|
||||
InstallDir "$LOCALAPPDATA\Tartube"
|
||||
@ -245,7 +245,7 @@ Section "Tartube" SecClient
|
||||
"Publisher" "A S Lewis"
|
||||
WriteRegStr HKLM \
|
||||
"Software\Microsoft\Windows\CurrentVersion\Uninstall\Tartube" \
|
||||
"DisplayVersion" "1.2.0"
|
||||
"DisplayVersion" "1.2.008"
|
||||
|
||||
# Create uninstaller
|
||||
WriteUninstaller "$INSTDIR\Uninstall.exe"
|
||||
|
2
setup.py
2
setup.py
@ -62,7 +62,7 @@ if env_var_value is not None:
|
||||
# Setup
|
||||
setuptools.setup(
|
||||
name='tartube',
|
||||
version='1.2.0',
|
||||
version='1.2.008',
|
||||
description='GUI front-end for youtube-dl',
|
||||
# long_description=long_description,
|
||||
long_description="""Tartube is a GUI front-end for youtube-dl, partly based
|
||||
|
@ -4749,6 +4749,7 @@ class SystemPrefWin(GenericPrefWin):
|
||||
self.setup_scheduling_tab()
|
||||
self.setup_operations_tab()
|
||||
self.setup_ytdl_tab()
|
||||
self.setup_ignore_tab()
|
||||
self.setup_debug_tab()
|
||||
|
||||
|
||||
@ -5624,37 +5625,61 @@ class SystemPrefWin(GenericPrefWin):
|
||||
)
|
||||
checkbutton.connect('toggled', self.on_json_button_toggled)
|
||||
|
||||
checkbutton2 = self.add_checkbutton(grid,
|
||||
|
||||
def setup_ignore_tab(self):
|
||||
|
||||
"""Called by self.setup_tabs().
|
||||
|
||||
Sets up the 'Ignore' tab.
|
||||
"""
|
||||
|
||||
tab, grid = self.add_notebook_tab('_Ignore')
|
||||
|
||||
# Ignore options
|
||||
self.add_label(grid,
|
||||
'<u>Ignore options</u>',
|
||||
0, 0, 1, 1,
|
||||
)
|
||||
|
||||
checkbutton = self.add_checkbutton(grid,
|
||||
'Ignore \'Requested formats are incompatible for merge\' warnings',
|
||||
self.app_obj.ignore_merge_warning_flag,
|
||||
True, # Can be toggled by user
|
||||
0, 9, grid_width, 1,
|
||||
0, 1, 1, 1,
|
||||
)
|
||||
checkbutton2.connect('toggled', self.on_merge_button_toggled)
|
||||
checkbutton.connect('toggled', self.on_merge_button_toggled)
|
||||
|
||||
checkbutton3 = self.add_checkbutton(grid,
|
||||
checkbutton2 = self.add_checkbutton(grid,
|
||||
'Ignore YouTube copyright errors',
|
||||
self.app_obj.ignore_yt_copyright_flag,
|
||||
True, # Can be toggled by user
|
||||
0, 10, grid_width, 1,
|
||||
0, 2, 1, 1,
|
||||
)
|
||||
checkbutton3.connect('toggled', self.on_copyright_button_toggled)
|
||||
checkbutton2.connect('toggled', self.on_copyright_button_toggled)
|
||||
|
||||
checkbutton4 = self.add_checkbutton(grid,
|
||||
checkbutton3 = self.add_checkbutton(grid,
|
||||
'Ignore \'Child process exited with non-zero code\' errors',
|
||||
self.app_obj.ignore_child_process_exit_flag,
|
||||
True, # Can be toggled by user
|
||||
0, 11, grid_width, 1,
|
||||
0, 3, 1, 1,
|
||||
)
|
||||
checkbutton4.connect('toggled', self.on_child_process_button_toggled)
|
||||
checkbutton3.connect('toggled', self.on_child_process_button_toggled)
|
||||
|
||||
checkbutton5 = self.add_checkbutton(grid,
|
||||
checkbutton4 = self.add_checkbutton(grid,
|
||||
'Ignore \'There are no annotations to write\' warnings',
|
||||
self.app_obj.ignore_no_annotations_flag,
|
||||
True, # Can be toggled by user
|
||||
0, 12, grid_width, 1,
|
||||
0, 4, 1, 1,
|
||||
)
|
||||
checkbutton5.connect('toggled', self.on_no_annotations_button_toggled)
|
||||
checkbutton4.connect('toggled', self.on_no_annotations_button_toggled)
|
||||
|
||||
checkbutton5 = self.add_checkbutton(grid,
|
||||
'Ignore \'Video doesn\'t have subtitles\' warnings',
|
||||
self.app_obj.ignore_no_subtitles_flag,
|
||||
True, # Can be toggled by user
|
||||
0, 5, 1, 1,
|
||||
)
|
||||
checkbutton5.connect('toggled', self.on_no_subtitles_button_toggled)
|
||||
|
||||
|
||||
def setup_debug_tab(self):
|
||||
@ -6415,7 +6440,7 @@ class SystemPrefWin(GenericPrefWin):
|
||||
|
||||
def on_no_annotations_button_toggled(self, checkbutton):
|
||||
|
||||
"""Called from callback in self.setup_ytdl_tab().
|
||||
"""Called from callback in self.setup_ignore_tab().
|
||||
|
||||
Enables/disables ignoring of the 'no annotations' warning messages.
|
||||
|
||||
@ -6433,6 +6458,26 @@ class SystemPrefWin(GenericPrefWin):
|
||||
self.app_obj.set_ignore_no_annotations_flag(False)
|
||||
|
||||
|
||||
def on_no_subtitles_button_toggled(self, checkbutton):
|
||||
|
||||
"""Called from callback in self.setup_ignore_tab().
|
||||
|
||||
Enables/disables ignoring of the 'no subtitles' warning messages.
|
||||
|
||||
Args:
|
||||
|
||||
checkbutton (Gtk.CheckButton): The widget clicked
|
||||
|
||||
"""
|
||||
|
||||
if checkbutton.get_active() \
|
||||
and not self.app_obj.ignore_no_subtitles_flag:
|
||||
self.app_obj.set_ignore_no_subtitles_flag(True)
|
||||
elif not checkbutton.get_active() \
|
||||
and self.app_obj.ignore_no_subtitles_flag:
|
||||
self.app_obj.set_ignore_no_subtitles_flag(False)
|
||||
|
||||
|
||||
def on_reset_ffmpeg_button_clicked(self, button, entry):
|
||||
|
||||
"""Called from callback in self.setup_ytdl_tab().
|
||||
|
@ -2048,8 +2048,16 @@ class VideoDownloader(object):
|
||||
|
||||
if not os.path.isfile(thumb_path):
|
||||
request_obj = requests.get(thumbnail)
|
||||
with open(thumb_path, 'wb') as outfile:
|
||||
outfile.write(request_obj.content)
|
||||
|
||||
# with open(thumb_path, 'wb') as outfile:
|
||||
# outfile.write(request_obj.content)
|
||||
# v1.2.006 This crashes if the directory specified by
|
||||
# thumb_path doesn't exist, so need to use 'try'
|
||||
try:
|
||||
with open(thumb_path, 'wb') as outfile:
|
||||
outfile.write(request_obj.content)
|
||||
except:
|
||||
pass
|
||||
|
||||
# If a new media.Video object was created, add a line to the Results
|
||||
# List, as well as updating the Video Catalogue
|
||||
@ -2616,6 +2624,13 @@ class VideoDownloader(object):
|
||||
):
|
||||
return True
|
||||
|
||||
elif app_obj.ignore_no_subtitles_flag \
|
||||
and re.search(
|
||||
r'video doesn\'t have subtitles',
|
||||
stderr,
|
||||
):
|
||||
return True
|
||||
|
||||
else:
|
||||
# Not ignorable
|
||||
return False
|
||||
|
@ -607,6 +607,9 @@ class TartubeApp(Gtk.Application):
|
||||
# Flag set to True if 'There are no annotations to write' messages
|
||||
# should be ignored (in the Errors/Warnings tab)
|
||||
self.ignore_no_annotations_flag = True
|
||||
# Flag set to True if 'video doesn't have subtitles' errors should be
|
||||
# ignored (in the Errors/Warnings tab)
|
||||
self.ignore_no_subtitles_flag = True
|
||||
|
||||
# During a download operation, the number of simultaneous downloads
|
||||
# allowed. (An instruction to youtube-dl to download video(s) from a
|
||||
@ -1234,14 +1237,13 @@ class TartubeApp(Gtk.Application):
|
||||
# want
|
||||
new_mswin_flag = True
|
||||
custom_flag = True
|
||||
name = utils.upper_case_first(__main__.__packagename__)
|
||||
|
||||
dialogue_win = self.dialogue_manager_obj.show_msg_dialogue(
|
||||
'Click OK to create a folder in which\n' \
|
||||
+ utils.upper_case_first(__main__.__packagename__) \
|
||||
+ ' can store its videos\n\nIf you have used ' \
|
||||
+ utils.upper_case_first(__main__.__packagename__) \
|
||||
+ ' before,\nyou can select an existing folder\ninstead of'
|
||||
+ ' creating a new one',
|
||||
'Welcome to ' + name + '!\n\nClick OK to create a folder' \
|
||||
+ ' in which\n' + name + ' can store its videos\n\n' \
|
||||
+ 'If you have used ' + name + ' before,\nyou can select' \
|
||||
+ ' an existing folder\ninstead of creating a new one',
|
||||
'info',
|
||||
'ok',
|
||||
self.main_win_obj,
|
||||
@ -1353,9 +1355,9 @@ class TartubeApp(Gtk.Application):
|
||||
'Gtk v' + str(self.gtk_version_major) + '.' \
|
||||
+ str(self.gtk_version_minor) + '.' \
|
||||
+ str(self.gtk_version_micro) \
|
||||
+ ' is broken, which will cause problems when running ' \
|
||||
+ ' is broken, which may cause problems when running ' \
|
||||
+ utils.upper_case_first(__main__.__packagename__) \
|
||||
+ '. Please update it to at least Gtk v3.24',
|
||||
+ '. If possible, please update it to at least Gtk v3.24',
|
||||
)
|
||||
|
||||
# If file load/save has been disabled, we can now show a dialogue
|
||||
@ -1748,6 +1750,9 @@ class TartubeApp(Gtk.Application):
|
||||
if version >= 1001077: # v1.1.077
|
||||
self.ignore_no_annotations_flag \
|
||||
= json_dict['ignore_no_annotations_flag']
|
||||
if version >= 1002004: # v1.2.004
|
||||
self.ignore_no_subtitles_flag \
|
||||
= json_dict['ignore_no_subtitles_flag']
|
||||
|
||||
# (Setting the value of the Gtk widgets automatically sets the IVs)
|
||||
self.main_win_obj.spinbutton.set_value(json_dict['num_worker_default'])
|
||||
@ -1891,6 +1896,7 @@ class TartubeApp(Gtk.Application):
|
||||
'ignore_child_process_exit_flag': \
|
||||
self.ignore_child_process_exit_flag,
|
||||
'ignore_no_annotations_flag': self.ignore_no_annotations_flag,
|
||||
'ignore_no_subtitles_flag': self.ignore_no_subtitles_flag,
|
||||
|
||||
'num_worker_default': self.num_worker_default,
|
||||
'num_worker_apply_flag': self.num_worker_apply_flag,
|
||||
@ -2355,6 +2361,17 @@ class TartubeApp(Gtk.Application):
|
||||
options_obj.options_dict.pop('to_audio')
|
||||
|
||||
|
||||
if version < 1002005: # v1.2.005
|
||||
|
||||
# After moving videos from one filesystem location to another,
|
||||
# some media.Video had the wrong value for their .file_dir IV
|
||||
# To be safe, reset them all
|
||||
for media_data_obj in self.media_reg_dict.values():
|
||||
if isinstance(media_data_obj, media.Video):
|
||||
|
||||
media_data_obj.reset_file_dir(self)
|
||||
|
||||
|
||||
def save_db(self):
|
||||
|
||||
"""Called by self.start(), .stop(), .switch_db(),
|
||||
@ -4167,8 +4184,13 @@ class TartubeApp(Gtk.Application):
|
||||
|
||||
# All videos which are descendents of media_data_obj must have their
|
||||
# .file_dir IV updated to the new location
|
||||
for video_obj in media_data_obj.compile_all_videos( [] ):
|
||||
video_obj.reset_file_dir(self)
|
||||
# for video_obj in media_data_obj.compile_all_videos( [] ):
|
||||
# video_obj.reset_file_dir(self)
|
||||
# v1.2.006 This has been observed to fail. Don't know why, yet, so
|
||||
# reset the .file_dir IV for all videos, just to be safe
|
||||
for other_obj in self.media_reg_dict.values():
|
||||
if isinstance(other_obj, media.Video):
|
||||
other_obj.reset_file_dir(self)
|
||||
|
||||
# Save the database (because, if the user terminates Tartube and then
|
||||
# restarts it, then tries to perform a download operation, a load of
|
||||
@ -4324,8 +4346,13 @@ class TartubeApp(Gtk.Application):
|
||||
|
||||
# All videos which are descendents of dest_obj must have their
|
||||
# .file_dir IV updated to the new location
|
||||
for video_obj in source_obj.compile_all_videos( [] ):
|
||||
video_obj.reset_file_dir(self)
|
||||
# for video_obj in source_obj.compile_all_videos( [] ):
|
||||
# video_obj.reset_file_dir(self)
|
||||
# v1.2.006 This has been observed to fail. Don't know why, yet, so
|
||||
# reset the .file_dir IV for all videos, just to be safe
|
||||
for other_obj in self.media_reg_dict.values():
|
||||
if isinstance(other_obj, media.Video):
|
||||
other_obj.reset_file_dir(self)
|
||||
|
||||
# Save the database (because, if the user terminates Tartube and then
|
||||
# restarts it, then tries to perform a download operation, a load of
|
||||
@ -7703,6 +7730,17 @@ class TartubeApp(Gtk.Application):
|
||||
self.ignore_no_annotations_flag = True
|
||||
|
||||
|
||||
def set_ignore_no_subtitles_flag(self, flag):
|
||||
|
||||
if DEBUG_FUNC_FLAG:
|
||||
print('ap 7681 set_ignore_no_subtitles_flag')
|
||||
|
||||
if not flag:
|
||||
self.ignore_no_subtitles_flag = False
|
||||
else:
|
||||
self.ignore_no_subtitles_flag = True
|
||||
|
||||
|
||||
def set_ignore_yt_copyright_flag(self, flag):
|
||||
|
||||
if DEBUG_FUNC_FLAG:
|
||||
|
@ -5663,7 +5663,7 @@ class MainWin(Gtk.ApplicationWindow):
|
||||
)
|
||||
|
||||
# Start a download operation
|
||||
self.app_obj.download_manager_start(True, False, media_data_obj)
|
||||
self.app_obj.download_manager_start(True, False, [media_data_obj] )
|
||||
|
||||
|
||||
def on_video_index_delete_container(self, menu_item, media_data_obj):
|
||||
@ -5712,7 +5712,7 @@ class MainWin(Gtk.ApplicationWindow):
|
||||
)
|
||||
|
||||
# Start a download operation
|
||||
self.app_obj.download_manager_start(False, False, media_data_obj)
|
||||
self.app_obj.download_manager_start(False, False, [media_data_obj] )
|
||||
|
||||
|
||||
def on_video_index_drag_data_received(self, treeview, drag_context, x, y, \
|
||||
@ -6627,7 +6627,7 @@ class MainWin(Gtk.ApplicationWindow):
|
||||
)
|
||||
|
||||
# Start a download operation
|
||||
self.app_obj.download_manager_start(True, False, media_data_obj)
|
||||
self.app_obj.download_manager_start(True, False, [media_data_obj] )
|
||||
|
||||
|
||||
def on_video_catalogue_check_multi(self, menu_item, media_data_list):
|
||||
@ -6802,7 +6802,7 @@ class MainWin(Gtk.ApplicationWindow):
|
||||
)
|
||||
|
||||
# Start a download operation
|
||||
self.app_obj.download_manager_start(False, False, media_data_obj)
|
||||
self.app_obj.download_manager_start(False, False, [media_data_obj] )
|
||||
|
||||
|
||||
def on_video_catalogue_download_multi(self, menu_item, media_data_list):
|
||||
@ -6982,7 +6982,7 @@ class MainWin(Gtk.ApplicationWindow):
|
||||
self.app_obj.mark_video_downloaded(media_data_obj, False)
|
||||
|
||||
# Now we're ready to start the download operation
|
||||
self.app_obj.download_manager_start(False, False, media_data_obj)
|
||||
self.app_obj.download_manager_start(False, False, [media_data_obj] )
|
||||
|
||||
|
||||
def on_video_catalogue_remove_options(self, menu_item, media_data_obj):
|
||||
@ -10287,7 +10287,7 @@ class ImportDialogue(Gtk.Dialog):
|
||||
|
||||
# Update the data to be returned (eventually) to the calling
|
||||
# mainapp.TartubeApp.import_into_db() function
|
||||
mini_dict = self.processed_dict[self.liststore[path][3]]
|
||||
mini_dict = self.flat_db_dict[self.liststore[path][3]]
|
||||
mini_dict['import_flag'] = self.liststore[path][0]
|
||||
|
||||
|
||||
@ -10309,7 +10309,7 @@ class ImportDialogue(Gtk.Dialog):
|
||||
for path in range(0, len(self.liststore)):
|
||||
self.liststore[path][0] = True
|
||||
|
||||
for mini_dict in self.processed_dict.values():
|
||||
for mini_dict in self.flat_db_dict.values():
|
||||
mini_dict['import_flag'] = True
|
||||
|
||||
|
||||
@ -10331,7 +10331,7 @@ class ImportDialogue(Gtk.Dialog):
|
||||
for path in range(0, len(self.liststore)):
|
||||
self.liststore[path][0] = False
|
||||
|
||||
for mini_dict in self.processed_dict.values():
|
||||
for mini_dict in self.flat_db_dict.values():
|
||||
mini_dict['import_flag'] = False
|
||||
|
||||
|
||||
|
@ -35,8 +35,8 @@ import mainapp
|
||||
|
||||
# 'Global' variables
|
||||
__packagename__ = 'tartube'
|
||||
__version__ = '1.2.0'
|
||||
__date__ = '31 Aug 2019'
|
||||
__version__ = '1.2.008'
|
||||
__date__ = '30 Sep 2019'
|
||||
__copyright__ = 'Copyright \xa9 2019 A S Lewis'
|
||||
__license__ = """
|
||||
Copyright \xc2\xa9 2019 A S Lewis.
|
||||
|
@ -35,8 +35,8 @@ import mainapp
|
||||
|
||||
# 'Global' variables
|
||||
__packagename__ = 'tartube'
|
||||
__version__ = '1.2.0'
|
||||
__date__ = '31 Aug 2019'
|
||||
__version__ = '1.2.008'
|
||||
__date__ = '30 Sep 2019'
|
||||
__copyright__ = 'Copyright \xa9 2019 A S Lewis'
|
||||
__license__ = """
|
||||
Copyright \xc2\xa9 2019 A S Lewis.
|
||||
|
Loading…
x
Reference in New Issue
Block a user