Lua
Lua
Facebook Download all Photos to Local Files
See more Facebook Examples
Demonstrates how to download all of one's Facebook photos to a local filesystem directory. This sample code keeps a local cache to avoid re-downloading the same photos twice. The program can be run again after a time, and it will download only photos that haven't yet been downloaded.Chilkat Lua Downloads
local chilkat = require("chilkat")
-- This example requires the Chilkat API to have been previously unlocked.
-- See Global Unlock Sample for sample code.
-- This example will use a local disk cache to avoid re-fetching the same
-- photo id after it's been fetched once.
local fbCache = chilkat.Cache.new()
-- The cache will use 1 level of 256 sub-directories.
fbCache.level = 1
-- Use a directory path that makes sense on your operating system..
fbCache:add_root("C:/fbCache")
-- This example assumes a previously obtained an access token
local oauth2 = chilkat.OAuth2.new()
oauth2.access_token = "FACEBOOK-ACCESS-TOKEN"
local rest = chilkat.Rest.new()
-- Connect to Facebook.
local success = rest:connect("graph.facebook.com", 443, true, true)
if not success then
print(rest.last_error_text)
return
end
-- Provide the authentication credentials (i.e. the access key)
rest:set_auth_oauth2(oauth2)
-- There are two choices:
-- We can choose to download the photos the person is tagged in or has uploaded
-- by setting type to "tagged" or "uploaded".
rest:add_query_param("type", "uploaded")
-- To download all photos, we begin with an outer loop that iterates over
-- the list of photo nodes in pages. Each page returned contains a list of
-- photo node ids. Each photo node id must be retrieved to get the download URL(s)
-- of the actual image.
-- I don't know the max limit for the number of records that can be downloaded at once.
rest:add_query_param("limit", "100")
-- Get the 1st page of photos ids.
-- See https://developers.facebook.com/docs/graph-api/reference/user/photos/ for more information.
local responseJson = rest:full_request_no_body("GET", "/v2.7/me/photos")
if not rest.last_method_success then
print(rest.last_error_text)
return
end
local photoJson = chilkat.JsonObject.new()
local saPhotoUrls = chilkat.StringArray.new()
local sbPhotoIdPath = chilkat.StringBuilder.new()
local json = chilkat.JsonObject.new()
json.emit_compact = false
json:load(responseJson)
local i = 0
local photoId = ""
local imageUrl = ""
-- Get the "after" cursor.
local afterCursor = json:string_of("paging.cursors.after")
while json.last_method_success do
print("-------------------")
print("afterCursor = " .. afterCursor)
-- For each photo id in this page...
i = 0
local numItems = json:size_of_array("data")
while i < numItems do
json.i = i
photoId = json:string_of("data[i].id")
print("photoId = " .. photoId)
-- We need to fetch the JSON for this photo. Check to see if it's in the local disk cache,
-- and if not, then get it from Facebook.
local photoJsonStr = fbCache:fetch_text(photoId)
if not fbCache.last_method_success then
-- It's not locally available, so get it from Facebook..
sbPhotoIdPath:clear()
sbPhotoIdPath:append("/v2.7/")
sbPhotoIdPath:append(photoId)
rest:clear_all_query_params()
rest:add_query_param("fields", "id,album,images")
print("Fetching photo node from Facebook...")
-- This REST request will continue using the existing connection.
-- If the connection was closed, it will automatically reconnect to send the request.
photoJsonStr = rest:full_request_no_body("GET", sbPhotoIdPath:get_as_string())
if not rest.last_method_success then
print(rest.last_error_text)
return
end
-- Add the photo JSON to the local cache.
fbCache:save_text_no_expire(photoId, "", photoJsonStr)
end
-- Parse the photo JSON and add the main photo download URL to saPhotoUrls
-- There may be multiple URLs in the images array, but the 1st one is the largest and main photo URL.
-- The others are smaller sizes of the same photo.
photoJson:load(photoJsonStr)
imageUrl = photoJson:string_of("images[0].source")
if photoJson.last_method_success then
-- Actually, we'll add a small JSON document that contains both the image ID and the URL.
local imgUrlJson = chilkat.JsonObject.new()
imgUrlJson:append_string("id", photoId)
imgUrlJson:append_string("url", imageUrl)
saPhotoUrls:append(imgUrlJson:emit())
print("imageUrl = " .. imageUrl)
end
i = i + 1
end
-- Prepare for getting the next page of photos ids.
-- We can continue using the same REST object.
-- If already connected, we'll continue using the existing connection.
-- Otherwise, a new connection will automatically be made if needed.
rest:clear_all_query_params()
rest:add_query_param("type", "uploaded")
rest:add_query_param("limit", "20")
rest:add_query_param("after", afterCursor)
-- Get the next page of photo ids.
responseJson = rest:full_request_no_body("GET", "/v2.7/me/photos")
if not rest.last_method_success then
print(rest.last_error_text)
return
end
json:load(responseJson)
afterCursor = json:string_of("paging.cursors.after")
end
print("No more pages of photos.")
-- Now iterate over the photo URLs and download each to a file.
-- We can use Chilkat HTTP. No Facebook authorization (access token) is required to download
-- the photo once the URL is known.
local http = chilkat.Http.new()
-- We'll cache the image data so that if run again, we don't re-download the same image again.
local numUrls = saPhotoUrls.count
i = 0
local urlJson = chilkat.JsonObject.new()
local fac = chilkat.FileAccess.new()
while i < numUrls do
urlJson:load(saPhotoUrls:get_string(i))
photoId = urlJson:string_of("id")
imageUrl = urlJson:string_of("url")
-- Check the local cache for the image data.
-- Only download and save if not already cached.
imageBytes = ERROR: Method not in Chilkat for Lua: Cache.FetchFromCache
fbCache:ERROR()
if not fbCache.last_method_success then
-- This photo needs to be downloaded.
local sbImageUrl = chilkat.StringBuilder.new()
sbImageUrl:append(imageUrl)
-- Let's form a filename..
local extension = ".jpg"
if sbImageUrl:contains(".gif", false) then
extension = ".gif"
end
if sbImageUrl:contains(".png", false) then
extension = ".png"
end
if sbImageUrl:contains(".tiff", false) then
extension = ".tiff"
end
if sbImageUrl:contains(".bmp", false) then
extension = ".bmp"
end
local sbLocalFilePath = chilkat.StringBuilder.new()
sbLocalFilePath:append("C:/Photos/facebook/uploaded/")
sbLocalFilePath:append(photoId)
sbLocalFilePath:append(extension)
imageBytes = ERROR: Method not in Chilkat for Lua: Http.QuickGet
http:ERROR()
if not http.last_method_success then
print(http.last_error_text)
return
end
-- We've downloaded the photo image bytes into memory.
-- Save it to the cache AND save it to the output file.
ERROR: Method not in Chilkat for Lua: Cache.SaveToCacheNoExpire
fbCache:ERROR()
ERROR: Method not in Chilkat for Lua: FileAccess.WriteEntireFile
fac:ERROR()
print("Downloaded to " .. sbLocalFilePath:get_as_string())
end
i = i + 1
end
print("Finished downloading all Facebook photos!")