Forked from thebitguru/facebook-photo-download.go
Last active
March 24, 2018 17:03
-
-
Save Takhion/bfe32ce208024835c3b60eacf9bb9d41 to your computer and use it in GitHub Desktop.
A simple go program to download all the high resolution pictures from your facebook albums.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
/* | |
* A simple go program to download all the high resolution pictures from your facebook albums. | |
* | |
* To run this: | |
* 1. Go to https://developers.facebook.com/tools/explorer/?method=GET&path=me&version=v2.8 | |
* 2. Get an Access Token: Get Token > Get User Access Token > Check "user_photos" | |
* 3. Paste in the app. | |
*/ | |
import ( | |
"encoding/json" | |
"fmt" | |
"io" | |
"log" | |
"net/http" | |
"net/url" | |
"os" | |
"path/filepath" | |
"unicode/utf8" | |
"strings" | |
"github.com/kennygrant/sanitize" | |
fb "github.com/huandu/facebook" | |
) | |
var logger *log.Logger | |
// On macOS: '/' is not allowed and ':' is displayed as '/' ¯\_(ツ)_/¯ | |
var safeReplacer = strings.NewReplacer(":", "", "/", ":") | |
func safeName(name string) string { return safeReplacer.Replace(name) } | |
func main() { | |
logger = log.New(os.Stdout, "LOG: ", log.Ldate) | |
// Get access token manually from https://developers.facebook.com/tools/explorer/?method=GET&path=me&version=v2.8 | |
var accessToken string | |
fmt.Println("Please go to the following URL and to get the access token") | |
fmt.Println("\thttps://developers.facebook.com/tools/explorer/?method=GET&path=me&version=v2.8") | |
fmt.Printf("\tGet Token (button) > Get User Access Token > Check 'user_photos'\n\n") | |
fmt.Print("Paste the access token: ") | |
fmt.Scanln(&accessToken) | |
var fbApp = fb.New("", "") | |
session := fbApp.Session(accessToken) | |
res, err := session.Get("/me", nil) | |
if err != nil { | |
logger.Fatal(err) | |
} | |
fmt.Println("Albums for", res["name"]) | |
res, _ = session.Get("/me/albums", nil) | |
paging, _ := res.Paging(session) | |
for { | |
items := paging.Data() | |
for _, album := range items { | |
// Create directory and process album | |
var albumDirName = safeName(album.Get("name").(string)) | |
os.Mkdir(albumDirName, os.ModePerm) | |
processAlbum(session, album, albumDirName) | |
} | |
noMore, _ := paging.Next() | |
if noMore { | |
break | |
} | |
} | |
} | |
func processAlbum(session *fb.Session, album fb.Result, albumDirName string) { | |
fmt.Printf("%s: %s [%s]\n", album.GetField("id"), album.GetField("name"), albumDirName) | |
// Get the photos in the album | |
res, _ := session.Get(fmt.Sprintf("/%s/photos", album.GetField("id")), fb.Params{ | |
"fields": "name,images", | |
}) | |
paging, _ := res.Paging(session) | |
for { | |
items := paging.Data() | |
for _, photo := range items { | |
// Find the largest image. | |
var largest fb.Result | |
var lastLargestHeight int64 | |
var lastLargestWidth int64 | |
var images []fb.Result | |
photo.DecodeField("images", &images) | |
for _, imageSpecs := range images { | |
height, _ := imageSpecs["height"].(json.Number).Int64() | |
width, _ := imageSpecs["width"].(json.Number).Int64() | |
// fmt.Printf("\t%d x %d\n", height, width) | |
if height > lastLargestHeight { | |
lastLargestHeight = height | |
largest = imageSpecs | |
} | |
if width > lastLargestWidth { | |
lastLargestWidth = width | |
largest = imageSpecs | |
} | |
} | |
// fmt.Printf("Final: %s\n\n", largest) | |
var filename string | |
if photo.Get("name") == nil { | |
filename = photo.GetField("id").(string) | |
} else { | |
filename = photo.GetField("name").(string) | |
} | |
if utf8.RuneCountInString(filename) > 100 { | |
filename = filename[:100] | |
} | |
filename = sanitize.BaseName(filename) | |
filename = safeName(filename) | |
// Download the image | |
photoSource := largest["source"].(string) | |
photoURL, _ := url.Parse(photoSource) | |
fmt.Printf("\t\t%s: %s [%s]\n", | |
photo.GetField("id"), photo.GetField("name"), filename) | |
extension := filepath.Ext(photoURL.Path) | |
response, err := http.Get(photoSource) | |
if err != nil { | |
logger.Panic(err) | |
} | |
defer response.Body.Close() | |
file, err := os.Create(filepath.Join(albumDirName, filename+extension)) | |
if err != nil { | |
logger.Panic(err) | |
} | |
_, err = io.Copy(file, response.Body) | |
if err != nil { | |
logger.Panic(err) | |
} | |
file.Close() | |
} | |
noMore, _ := paging.Next() | |
if noMore { | |
break | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment