Skip to content

Commit cdeaf5b

Browse files
Merge pull request #191 from AndreyNikiforov/feature/remove-mt
remove multi-threaded downloading
2 parents 727d635 + 70174da commit cdeaf5b

File tree

5 files changed

+15
-47
lines changed

5 files changed

+15
-47
lines changed

.dockerignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,5 @@ __pycache__
1313
.coverage
1414
.coverage.*
1515
.git
16+
tests/fixures
17+
tests/__pycache__

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
- feature: Folder structure can be set to 'none' instead of a date pattern,
66
so all photos will be placed directly into the download directory.
77
- fix: Empty directory structure being created #185
8+
- feature: removed multi-threaded downloading and added deprecation notice to --threads-num parameter #180, #188
89

910
## 1.6.2 (2020-10-23)
1011

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ pip install icloudpd
120120
prints log messages on separate lines
121121
(Progress bar is disabled by default if
122122
there is no tty attached)
123-
--threads-num INTEGER RANGE Number of cpu threads (default: 1)
123+
--threads-num INTEGER RANGE Number of cpu threads -- deprecated. To be removed in future version
124124
--version Show the version and exit.
125125
-h, --help Show this message and exit.
126126

icloudpd/base.py

Lines changed: 4 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
import itertools
1010
import subprocess
1111
import json
12-
import threading
1312
import click
1413

1514
from tqdm import tqdm
@@ -29,11 +28,6 @@
2928
from icloudpd import constants
3029
from icloudpd.counter import Counter
3130

32-
try:
33-
import Queue as queue
34-
except ImportError:
35-
import queue
36-
3731
CONTEXT_SETTINGS = dict(help_option_names=["-h", "--help"])
3832

3933

@@ -195,7 +189,7 @@
195189
)
196190
@click.option(
197191
"--threads-num",
198-
help="Number of cpu threads (default: 1)",
192+
help="Number of cpu threads -- deprecated. To be removed in future version",
199193
type=click.IntRange(1),
200194
default=1,
201195
)
@@ -229,7 +223,7 @@ def main(
229223
log_level,
230224
no_progress_bar,
231225
notification_script,
232-
threads_num,
226+
threads_num, # pylint: disable=W0613
233227
):
234228
"""Download all iCloud photos to a local directory"""
235229

@@ -550,38 +544,12 @@ def download_photo(counter, photo):
550544
icloud, photo, lp_download_path, lp_size
551545
)
552546

553-
def get_threads_count():
554-
"""Disable threads if we have until_found or recent arguments"""
555-
if until_found is None and recent is None:
556-
return threads_num # pragma: no cover
557-
return 1
558-
559-
download_queue = queue.Queue(get_threads_count())
560547
consecutive_files_found = Counter(0)
561548

562549
def should_break(counter):
563550
"""Exit if until_found condition is reached"""
564551
return until_found is not None and counter.value() >= until_found
565552

566-
def worker(counter):
567-
"""Threaded worker"""
568-
while True:
569-
item = download_queue.get()
570-
if item is None:
571-
break
572-
573-
download_photo(counter, item)
574-
download_queue.task_done()
575-
576-
threads = []
577-
for _ in range(get_threads_count()):
578-
thread = threading.Thread(
579-
target=worker, args=(
580-
consecutive_files_found, ))
581-
thread.daemon = True
582-
thread.start()
583-
threads.append(thread)
584-
585553
photos_iterator = iter(photos_enumerator)
586554
while True:
587555
try:
@@ -590,19 +558,11 @@ def worker(counter):
590558
"Found %d consecutive previously downloaded photos. Exiting" %
591559
until_found)
592560
break
593-
download_queue.put(next(photos_iterator))
561+
item = next(photos_iterator)
562+
download_photo(consecutive_files_found, item)
594563
except StopIteration:
595564
break
596565

597-
if not should_break(consecutive_files_found):
598-
download_queue.join()
599-
600-
for _ in threads:
601-
download_queue.put(None)
602-
603-
for thread in threads:
604-
thread.join()
605-
606566
if only_print_filenames:
607567
sys.exit(0)
608568

tests/test_download_photos.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ def test_skip_existing_downloads(self):
295295
assert result.exit_code == 0
296296

297297
@pytest.mark.skipif(sys.platform == 'win32',
298-
reason="does not run on windows")
298+
reason="requires large timeout on windows to create big files")
299299
def test_until_found(self):
300300
base_dir = os.path.normpath("tests/fixtures/Photos")
301301
if os.path.exists(base_dir):
@@ -322,7 +322,7 @@ def test_until_found(self):
322322
files_to_skip.append(("2018/07/30/IMG_7400.JPG", "photo", 2308885))
323323
files_to_skip.append(("2018/07/30/IMG_7400-medium.MOV", "photo", 1238639))
324324
files_to_skip.append(("2018/07/30/IMG_7399.JPG", "photo", 2251047))
325-
files_to_download.append(("2018/07/30/IMG_7399-medium.MOV", "photo")) # TODO this should not be downloaded, correct?
325+
files_to_download.append(("2018/07/30/IMG_7399-medium.MOV", "photo"))
326326

327327
for f in files_to_skip:
328328
with open(os.path.join(base_dir, f[0]), "a") as fi:
@@ -386,6 +386,11 @@ def test_until_found(self):
386386
"INFO Found 3 consecutive previously downloaded photos. Exiting",
387387
self._caplog.text,
388388
)
389+
self.assertNotIn(
390+
f"INFO {os.path.join(base_dir, os.path.normpath('2018/07/30/IMG_7399-medium.MOV'))} already exists.",
391+
self._caplog.text
392+
)
393+
389394
assert result.exit_code == 0
390395

391396
def test_handle_io_error(self):

0 commit comments

Comments
 (0)