-
Notifications
You must be signed in to change notification settings - Fork 6
/
fetch.py
executable file
·171 lines (134 loc) · 5.27 KB
/
fetch.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
#!/usr/bin/env python
import datetime
# import os for file system functions
import os
# import json
import json
# import regex
import re
# for date parsing
import time
# import flickrapi
# `easy_install flickrapi` or `pip install flickrapi`
import flickrapi
# main program
def fetch(api_key, api_secret):
# create an unauthenticated flickrapi object
flickr=flickrapi.FlickrAPI(api_key, api_secret)
print "Open the following URL in your browser "
print "This Url >>>> %s" % flickr.web_login_url(perms='read')
print "When you're ready press ENTER",
raw_input()
print "Copy and paste the URL (from theopenphotoproject.org) here: ",
frob_url = raw_input()
print "\nThanks!"
print "Parsing URL for the token...",
match = re.search('frob=([^&]+)', frob_url)
frob = match.group(1)
token = flickr.get_token(frob)
print "OK"
# create an authenticated flickrapi object
flickr = flickrapi.FlickrAPI(api_key, api_secret, token=token)
# now we get the authenticated user's id
print "Fetching user id...",
user_resp = flickr.urls_getUserProfile()
user_fields = user_resp.findall('user')[0]
user_id = user_fields.get('nsid')
print "OK"
# print "Enter your token: ",
# token = raw_input()
per_page = 100
(token, frob) = flickr.get_token_part_one('read')
flickr.get_token_part_two((token, frob))
# we'll paginate through the results
# start at `page` and get `per_page` results at a time
page=1
# store everything in a list or array or whatever python calls this
photos_out=[]
# while True loop till we get no photos back
while True:
# call the photos.search API
# http://www.flickr.com/services/api/flickr.photos.search.html
print "Fetching page %d..." % page,
photos_resp = flickr.people_getPhotos(user_id=user_id, per_page=per_page, page=page, extras='original_format,tags,geo,url_o,url_b,url_c,url_z,date_upload,date_taken,license,description')
print "OK"
# increment the page number before we forget so we don't endlessly loop
page = page+1;
# grab the first and only 'photos' node
photo_list = photos_resp.findall('photos')[0]
# if the list of photos is empty we must have reached the end of this user's library and break out of the while True
if len(photo_list) == 0:
break;
# else we loop through the photos
for photo in photo_list:
# get all the data we can
p = {}
p['id'] = photo.get('id')
p['permission'] = bool(int(photo.get('ispublic')))
p['title'] = photo.get('title')
p['license'] = getLicense(photo.get('license'))
description = photo.findall('description')[0].text
if description is not None:
p['description'] = description
if photo.get('latitude') != '0':
p['latitude'] = float(photo.get('latitude'))
if photo.get('longitude') != '0':
p['longitude'] = float(photo.get('longitude'))
if len(photo.get('tags')) > 0:
p['tags'] = photo.get('tags').split(' ')
else:
p['tags'] = []
if photo.get('place_id') is not None:
p['tags'].append("flickr:place_id=%s" % photo.get('place_id'))
if photo.get('woe_id') is not None:
p['tags'].append("geo:woe_id=%s" % photo.get('woe_id'))
p['tags'] = ",".join(p['tags'])
p['dateUploaded'] = int(photo.get('dateupload'))
p['dateTaken'] = int(time.mktime(time.strptime(photo.get('datetaken'), '%Y-%m-%d %H:%M:%S')))
# Attention : this is returned only for Pro accounts, it seems
if photo.get('url_o') is not None:
p['photo'] = photo.get('url_o')
elif photo.get('url_b') is not None:
p['photo'] = photo.get('url_b')
elif photo.get('url_c') is not None:
p['photo'] = photo.get('url_c')
elif photo.get('url_z') is not None:
p['photo'] = photo.get('url_z')
t = datetime.datetime.fromtimestamp(float(p['dateUploaded']))
filename = '%s-%s' % (t.strftime('%Y%m%dT%H%M%S'), p['id'])
print " * Storing photo %s to fetched/%s.json" % (p['id'], filename),
f = open("fetched/%s.json" % filename, 'w')
f.write(json.dumps(p))
f.close()
print "OK"
# create a directory only if it doesn't already exist
def createDirectorySafe( name ):
if not os.path.exists(name):
os.makedirs(name)
# construct the url for the original photo
# currently this requires a pro account
def constructUrl( photo ):
return "http://farm%s.staticflickr.com/%s/%s_%s_o.%s" % (photo.get('farm'), photo.get('server'), photo.get('id'), photo.get('originalsecret'), photo.get('originalformat'))
# map Flickr licenses to short names
def getLicense( num ):
licenses = {}
licenses['0'] = ''
licenses['4'] = 'CC BY'
licenses['5'] = 'CC BY-SA'
licenses['6'] = 'CC BY-ND'
licenses['2'] = 'CC BY-NC'
licenses['1'] = 'CC BY-NC-SA'
licenses['3'] = 'CC BY-NC-ND'
if licenses[num] is None:
return licenses[0]
else:
return licenses[num]
if __name__ == '__main__':
import argparse
parser = argparse.ArgumentParser(description='Backup your Flickr photos')
parser.add_argument('--api-key', required=True, help='Flickr API key')
parser.add_argument('--api-secret', required=True, help='Flickr API secret')
config = parser.parse_args()
# check if a fetched directory exist else create it
createDirectorySafe('fetched')
fetch(config.api_key, config.api_secret)