Skip to content

Commit e10c3d1

Browse files
committed
add separate keybind to delete downloaded episodes
1 parent d2a314e commit e10c3d1

File tree

12 files changed

+91
-19
lines changed

12 files changed

+91
-19
lines changed

castero/__init__.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,11 @@
2323
{key_help} - show this help screen
2424
{key_exit} - exit the client
2525
{key_add_feed} - add a feed
26-
{key_delete} - delete the selected feed
27-
{key_reload} - reload/refresh all feeds
28-
{key_reload_selected} - reload/refresh selected feed
26+
{key_remove} - remove the selected feed
27+
{key_reload} - reload all feeds
28+
{key_reload_selected} - reload the selected feed
2929
{key_save} - save episode for offline playback
30+
{key_delete} - delete downloaded episodes
3031
{key_up/key_down} - navigate up/down in menus
3132
{key_right/key_left} - navigate right/left in menus
3233
{key_scroll_up/key_scroll_down} - scroll up/down in menus

castero/config.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,13 @@ def migrate(self, conf, default_conf) -> None:
130130
for key in default_conf[section]:
131131
default_conf_dict[key] = default_conf[section][key]
132132

133+
# In an update, we renamed key_delete to key_remove and added a
134+
# different key_delete value. If the user has key_delete but not
135+
# key_removed, we swap these values manually.
136+
if 'key_delete' in conf_dict and 'key_remove' not in conf_dict:
137+
conf_dict['key_remove'] = conf_dict['key_delete']
138+
conf_dict['key_delete'] = default_conf_dict['key_delete']
139+
133140
with open(self._default_path, "r") as default_conf_file:
134141
lines = default_conf_file.readlines()
135142
for line in lines:

castero/display.py

Lines changed: 51 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -562,33 +562,74 @@ def reload_selected_feed(self, feed: Feed) -> None:
562562
def save_episodes(self, feed=None, episode=None) -> None:
563563
"""Save a feed or episode.
564564
565-
If the user is saving an episode and the episode is already saved, this
566-
method will instead ask the user if they would like to delete the
567-
downloaded episode. However, if the user is saving a feed, there is no
568-
prompt to delete episodes, even if some are downloaded. In this case,
569-
downloaded episodes are simply skipped.
570-
571565
Exactly one of either feed or episode must be given.
572566
573567
Args:
574568
feed: (optional) a feed to download all episodes of
575-
episode: (optional) an episode to download or delete
569+
episode: (optional) an episode to download
576570
"""
577571
assert (feed is None or episode is None) and (feed is not episode)
578572

579573
if feed is not None:
574+
num_saved = 0
575+
num_to_save = 0
580576
for episode in self.database.episodes(feed):
581577
if not episode.downloaded:
582-
self._download_queue.add(episode)
578+
num_to_save += 1
579+
580+
if num_to_save == 0:
581+
return
582+
583+
should_delete = self._get_y_n(
584+
"Are you sure you want to download %d"
585+
" episodes from this feed? (y/n): " % num_to_save)
586+
if should_delete:
587+
for episode in self.database.episodes(feed):
588+
if not episode.downloaded:
589+
self._download_queue.add(episode)
590+
else:
591+
if not episode.downloaded:
592+
self._download_queue.add(episode)
593+
594+
def delete_episodes(self, feed=None, episode=None) -> None:
595+
"""Delete a downloaded episode, or all of those from a feed.
596+
597+
Exactly one of either feed or episode must be given.
598+
599+
Args:
600+
feed: (optional) a feed to delete all episodes of
601+
episode: (optional) an episode or delete
602+
"""
603+
assert (feed is None or episode is None) and (feed is not episode)
604+
605+
if feed is not None:
606+
num_deleted = 0
607+
num_to_delete = 0
608+
for episode in self.database.episodes(feed):
609+
if episode.downloaded:
610+
num_to_delete += 1
611+
612+
if num_to_delete == 0:
613+
return
614+
615+
should_delete = self._get_y_n(
616+
"Are you sure you want to delete %d downloaded"
617+
" episodes from this feed? (y/n): " % num_to_delete)
618+
if should_delete:
619+
for episode in self.database.episodes(feed):
620+
if episode.downloaded:
621+
episode.delete(self)
622+
num_deleted += 1
623+
self.menus_valid = False
624+
self.change_status(
625+
"Successfully deleted %d episodes" % num_deleted)
583626
else:
584627
if episode.downloaded:
585628
should_delete = self._get_y_n(
586629
"Are you sure you want to delete the downloaded"
587630
" episode? (y/n): ")
588631
if should_delete:
589632
episode.delete(self)
590-
else:
591-
self._download_queue.add(episode)
592633

593634
def filter_menu(self, menu: Menu) -> None:
594635
menu.filter_text = self._get_input_str("Filter: ")

castero/perspective.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ def _generic_handle_input(self, c) -> bool:
172172
queue.change_rate(-1, display=self._display)
173173
elif c == key_mapping[Config['key_add_feed']]:
174174
self._display.add_feed()
175-
elif c == key_mapping[Config['key_delete']]:
175+
elif c == key_mapping[Config['key_remove']]:
176176
if self._active_window == 0:
177177
self._display.delete_feed(self._feed_menu.item)
178178
self.update_menus()
@@ -190,6 +190,11 @@ def _generic_handle_input(self, c) -> bool:
190190
self._display.save_episodes(feed=self._feed_menu.item)
191191
elif self._active_window == 1 and self._episode_menu.item:
192192
self._display.save_episodes(episode=self._episode_menu.item)
193+
elif c == key_mapping[Config['key_delete']]:
194+
if self._active_window == 0 and self._feed_menu.item:
195+
self._display.delete_episodes(feed=self._feed_menu.item)
196+
elif self._active_window == 1 and self._episode_menu.item:
197+
self._display.delete_episodes(episode=self._episode_menu.item)
193198
elif c == key_mapping[Config['key_execute']]:
194199
if self._active_window == 1 and self._episode_menu.item:
195200
self._display.execute_command(self._episode_menu.item)

castero/perspectives/downloadedperspective.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,10 @@ def handle_input(self, c) -> bool:
138138
if self._downloaded_menu.item:
139139
self._display.save_episodes(episode=self._downloaded_menu.item)
140140
self._display.menus_valid = False
141+
elif c == key_mapping[Config['key_delete']]:
142+
if self._downloaded_menu.item:
143+
self._display.delete_episodes(episode=self._downloaded_menu.item)
144+
self._display.menus_valid = False
141145
elif c == key_mapping[Config['key_mark_played']]:
142146
if self._active_window == 0:
143147
episode = self._downloaded_menu.item
@@ -149,7 +153,9 @@ def handle_input(self, c) -> bool:
149153
episode = self._downloaded_menu.item
150154
if episode is not None:
151155
self._display.execute_command(episode)
152-
elif c == key_mapping[Config['key_delete']]:
156+
elif c == key_mapping[Config['key_reload_selected']]:
157+
pass
158+
elif c == key_mapping[Config['key_remove']]:
153159
pass
154160
else:
155161
keep_running = self._generic_handle_input(c)

castero/perspectives/queueperspective.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ def handle_input(self, c) -> bool:
132132
queue.stop()
133133
queue.clear()
134134
self._display.menus_valid = False
135-
elif c == key_mapping[Config['key_delete']]:
135+
elif c == key_mapping[Config['key_remove']]:
136136
self._remove_selected_from_queue()
137137
elif c == key_mapping[Config['key_show_url']]:
138138
item = self._queue_menu.item
@@ -146,6 +146,8 @@ def handle_input(self, c) -> bool:
146146
pass
147147
elif c == key_mapping[Config['key_save']]:
148148
pass
149+
elif c == key_mapping[Config['key_delete']]:
150+
pass
149151
elif c == key_mapping[Config['key_mark_played']]:
150152
pass
151153
elif c == key_mapping[Config['key_filter']]:

castero/templates/castero.conf

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,9 +164,9 @@ key_exit = q
164164
# default: a
165165
key_add_feed = a
166166

167-
# Delete the selected feed.
167+
# Remove the selected feed.
168168
# default: d
169-
key_delete = d
169+
key_remove = d
170170

171171
# Reload/refresh all feeds.
172172
# default: r
@@ -180,6 +180,10 @@ key_reload_selected = R
180180
# default: s
181181
key_save = s
182182

183+
# Delete downloaded episodes.
184+
# default: x
185+
key_delete = x
186+
183187
# Navigate up.
184188
# default: UP
185189
key_up = UP

tests/datafiles/working_no_comments.conf

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ key_exit = q
3939

4040
key_add_feed = a
4141

42-
key_delete = d
42+
key_remove = d
43+
44+
key_delete = x
4345

4446
key_reload = r
4547

tests/test_perspective_downloaded.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ def test_perspective_downloaded_input_keys(display):
8686

8787
operation_keys = [
8888
display.KEY_MAPPING[Config['key_delete']],
89+
display.KEY_MAPPING[Config['key_remove']],
8990
display.KEY_MAPPING[Config['key_reload']],
9091
display.KEY_MAPPING[Config['key_reload_selected']],
9192
display.KEY_MAPPING[Config['key_save']],

tests/test_perspective_primary.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ def test_perspective_primary_input_keys(display):
8989
operation_keys = [
9090
display.KEY_MAPPING[Config['key_add_feed']],
9191
display.KEY_MAPPING[Config['key_delete']],
92+
display.KEY_MAPPING[Config['key_remove']],
9293
display.KEY_MAPPING[Config['key_reload']],
9394
display.KEY_MAPPING[Config['key_reload_selected']],
9495
display.KEY_MAPPING[Config['key_save']],

0 commit comments

Comments
 (0)