Skip to content

Commit ce82027

Browse files
committed
adds timer code and shaves off two API calls
1 parent 9f9a17f commit ce82027

2 files changed

Lines changed: 73 additions & 22 deletions

File tree

flickr_download/flick_download.py

Lines changed: 39 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
from flickr_download.filename_handlers import get_filename_handler
2525
from flickr_download.filename_handlers import get_filename_handler_help
2626
from flickr_download.utils import get_full_path
27+
from flickr_download.utils import get_photo_page
28+
from flickr_download.utils import Timer
2729

2830
CONFIG_FILE = "~/.flickr_download"
2931
OAUTH_TOKEN_FILE = "~/.flickr_token"
@@ -108,13 +110,15 @@ def download_list(pset, photos_title, get_filename, size_label, skip_download=Fa
108110
@param size_label: str|None, size to download (or None for largest available)
109111
@param skip_download: bool, do not actually download the photo
110112
"""
111-
photos = pset.getPhotos()
113+
with Timer('getPhotos()'):
114+
photos = pset.getPhotos()
112115
pagenum = 2
113116
while True:
114117
try:
115118
if pagenum > photos.info.pages:
116119
break
117-
page = pset.getPhotos(page=pagenum)
120+
with Timer('getPhotos()'):
121+
page = pset.getPhotos(page=pagenum)
118122
photos.extend(page)
119123
pagenum += 1
120124
except FlickrAPIError as ex:
@@ -147,8 +151,13 @@ def do_download_photo(dirname, pset, photo, size_label, suffix, get_filename, sk
147151
"""
148152
fname = get_full_path(dirname, get_filename(pset, photo, suffix))
149153

150-
if 'video' in photo.getInfo():
151-
if 'HD MP4' in photo.getSizes():
154+
with Timer('getInfo()'):
155+
pInfo = photo.getInfo()
156+
157+
if 'video' in pInfo:
158+
with Timer('getSizes()'):
159+
pSizes = photo.getSizes()
160+
if 'HD MP4' in pSizes:
152161
photo_size_label = 'HD MP4'
153162
else:
154163
# Fall back for old 'short videos'
@@ -160,7 +169,9 @@ def do_download_photo(dirname, pset, photo, size_label, suffix, get_filename, sk
160169
# Flickr returns JPEG, except for when downloading originals. The only way to find the
161170
# original type it seems is through the source filename. This is not pretty...
162171
if (photo_size_label == 'Original' or not photo_size_label):
163-
meta = photo.getSizes().get('Original')
172+
with Timer('getSizes()'):
173+
pSizes = photo.getSizes()
174+
meta = pSizes.get('Original')
164175
if (meta and meta['source']):
165176
ext = os.path.splitext(meta['source'])[1]
166177
if (ext):
@@ -174,19 +185,19 @@ def do_download_photo(dirname, pset, photo, size_label, suffix, get_filename, sk
174185
print('Skipping {0}, as it exists already'.format(fname))
175186
return
176187

177-
print('Saving: {} ({})'.format(fname, photo.getPageUrl()))
188+
print('Saving: {} ({})'.format(fname, get_photo_page(pInfo)))
178189
if skip_download:
179190
return
180191

181192
try:
182-
photo.save(fname, photo_size_label)
193+
with Timer('save()'):
194+
photo.save(fname, photo_size_label)
183195
except IOError, ex:
184196
logging.warning('IO error saving photo: {}'.format(ex.strerror))
185197
return
186198

187199
# Set file times to when the photo was taken
188-
info = photo.getInfo()
189-
taken = parser.parse(info['taken'])
200+
taken = parser.parse(pInfo['taken'])
190201
taken_unix = time.mktime(taken.timetuple())
191202
os.utime(fname, (taken_unix, taken_unix))
192203

@@ -215,7 +226,8 @@ def download_user(username, get_filename, size_label, skip_download=False):
215226
@param skip_download: bool, do not actually download the photo
216227
"""
217228
user = Flickr.Person.findByUserName(username)
218-
photosets = user.getPhotosets()
229+
with Timer('getPhotosets()'):
230+
photosets = user.getPhotosets()
219231
for photoset in photosets:
220232
download_set(photoset.id, get_filename, size_label, skip_download)
221233

@@ -239,8 +251,10 @@ def print_sets(username):
239251
240252
@param username: str,
241253
"""
242-
user = Flickr.Person.findByUserName(username)
243-
photosets = user.getPhotosets()
254+
with Timer('findByUserName()'):
255+
user = Flickr.Person.findByUserName(username)
256+
with Timer('getPhotosets()'):
257+
photosets = user.getPhotosets()
244258
for photo in photosets:
245259
print('{0} - {1}'.format(photo.id, photo.title))
246260

@@ -329,16 +343,19 @@ def main():
329343

330344
if args.download or args.download_user or args.download_user_photos or args.download_photo:
331345
try:
332-
get_filename = get_filename_handler(args.naming)
333-
if args.download:
334-
download_set(args.download, get_filename, args.quality, args.skip_download)
335-
elif args.download_user:
336-
download_user(args.download_user, get_filename, args.quality, args.skip_download)
337-
elif args.download_photo:
338-
download_photo(args.download_photo, get_filename, args.quality, args.skip_download)
339-
else:
340-
download_user_photos(args.download_user_photos, get_filename, args.quality,
341-
args.skip_download)
346+
with Timer('total run'):
347+
get_filename = get_filename_handler(args.naming)
348+
if args.download:
349+
download_set(args.download, get_filename, args.quality, args.skip_download)
350+
elif args.download_user:
351+
download_user(args.download_user, get_filename, args.quality,
352+
args.skip_download)
353+
elif args.download_photo:
354+
download_photo(args.download_photo, get_filename, args.quality,
355+
args.skip_download)
356+
else:
357+
download_user_photos(args.download_user_photos, get_filename, args.quality,
358+
args.skip_download)
342359
except KeyboardInterrupt:
343360
print('Forcefully aborting. Last photo download might be partial :(', file=sys.stderr)
344361
return 0

flickr_download/utils.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import os
2+
from timeit import default_timer
23

34

45
def sanitize_filepath(fname):
@@ -23,3 +24,36 @@ def get_full_path(pset, photo):
2324
@return: str, full sanitized path
2425
"""
2526
return os.path.join(sanitize_filepath(pset), sanitize_filepath(photo))
27+
28+
29+
class Timer(object):
30+
"""
31+
Helper context manager to time pieces of code.
32+
"""
33+
def __init__(self, msg, verbose=False):
34+
self.msg = msg
35+
self.verbose = verbose
36+
self.timer = default_timer
37+
38+
def __enter__(self):
39+
self.start = self.timer()
40+
return self
41+
42+
def __exit__(self, *args):
43+
end = self.timer()
44+
self.elapsed_secs = end - self.start
45+
self.elapsed = self.elapsed_secs * 1000
46+
if self.verbose:
47+
print('--> time: {} = {:0.02f}ms'.format(self.msg, self.elapsed))
48+
49+
50+
def get_photo_page(photo_info):
51+
"""
52+
Get the photo page URL from a photo info object
53+
"""
54+
ret = ''
55+
if photo_info.get('urls') and photo_info['urls'].get('url'):
56+
for url in photo_info['urls']['url']:
57+
if url.get('type') == 'photopage':
58+
ret = url.get('text')
59+
return ret

0 commit comments

Comments
 (0)