Last active
February 3, 2018 14:37
-
-
Save tomger/32c32abde6d9ca5111e1 to your computer and use it in GitHub Desktop.
Downloads all images from your Instagram timeline to your disk and reinsert geo and time EXIF metadata.
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
/* | |
* Downloads all images from your Instagram timeline | |
* to your disk and reinserts geo and time EXIF metadata. | |
*/ | |
// conductance deps | |
var http = require('sjs:http'); | |
var fs = require('sjs:nodejs/fs'); | |
var string = require('sjs:string'); | |
// node deps | |
var nodeFs = require('fs'); | |
var nodeHttp = require('https'); | |
var ex = require('exiv2'); | |
var util = require('util'); | |
// read instagram access token from a file called token | |
// go get a token at https://apigee.com/console/instagram | |
var accessToken = fs.readFile('token').toString(); | |
var base = 'https://api.instagram.com/v1/users/self/media/recent/?access_token=' + accessToken; | |
var data = []; | |
var urlCursor = base; | |
function downloadItem(item) { | |
var file = downloadFile( | |
item.images.standard_resolution.url, | |
'timeline/' + item.id + '.jpg'); | |
var timestamp = customFormat( | |
new Date(parseInt(item.created_time)*1000), | |
'#YYYY#:#MM#:#DD# #hh#:#mm#:#ss#'); | |
var tags = { | |
'Exif.Image.DateTime': timestamp, | |
'Exif.Image.DateTimeOriginal': timestamp, | |
'Exif.Image.ImageDescription': item.caption ? item.caption.text : '' | |
}; | |
if (item.location) { | |
var lat = ConvertDDToDMS(item.location.latitude, false); | |
var lng = ConvertDDToDMS(item.location.longitude, true); | |
tags['Exif.GPSInfo.GPSLatitude'] = GPSString(lat); | |
tags['Exif.GPSInfo.GPSLatitudeRef'] = lat.dir; | |
tags['Exif.GPSInfo.GPSLongitude'] = GPSString(lng); | |
tags['Exif.GPSInfo.GPSLongitudeRef'] = lng.dir; | |
} | |
setImageTags(file, tags); | |
} | |
while (urlCursor) { | |
var response = http.json(urlCursor); | |
timeline = timeline.concat(response.data); | |
response.data.forEach(downloadItem); | |
urlCursor = response.pagination.next_url; | |
} | |
fs.writeFile('timeline.json', JSON.stringify(timeline)); | |
/*********** Code found on the internet ***********/ | |
function GPSString(obj) { | |
return dec2frac(obj.deg) + ' ' + dec2frac(obj.min) + ' ' + dec2frac(obj.sec); | |
} | |
function ConvertDDToDMS(D, lng){ | |
return { | |
dir : D<0?lng?'W':'S':lng?'E':'N', | |
deg : 0|(D<0?D=-D:D), | |
min : 0|D%1*60, | |
sec :(0|D*60%1*6000)/100 | |
}; | |
} | |
function downloadFile(path, file) { | |
waitfor() { | |
var f = nodeFs.createWriteStream(file); | |
nodeHttp.get(path,function(res){ | |
res.on('data', function (chunk) { | |
f.write(chunk); | |
}); | |
res.on('end',function(){ | |
f.end(); | |
hold(10); | |
resume(); | |
}); | |
}); | |
} | |
return file; | |
} | |
function getImageTags(path) { | |
var rv; | |
waitfor() { | |
ex.getImageTags(path, function(err, tags) { | |
rv = tags; | |
resume(); | |
}); | |
} | |
return rv; | |
} | |
function setImageTags(path, tags) { | |
waitfor() { | |
ex.setImageTags(path, tags, function(err){ | |
resume(); | |
}); | |
} | |
} | |
function customFormat(date, formatString){ | |
var YYYY,YY,MMMM,MMM,MM,M,DDDD,DDD,DD,D,hhhh,hhh,hh,h,mm,m,ss,s,ampm,AMPM,dMod,th; | |
YY = ((YYYY=date.getFullYear())+"").slice(-2); | |
MM = (M=date.getMonth()+1)<10?('0'+M):M; | |
MMM = (MMMM=["January","February","March","April","May","June","July","August","September","October","November","December"][M-1]).substring(0,3); | |
DD = (D=date.getDate())<10?('0'+D):D; | |
DDD = (DDDD=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"][date.getDay()]).substring(0,3); | |
th=(D>=10&&D<=20)?'th':((dMod=D%10)==1)?'st':(dMod==2)?'nd':(dMod==3)?'rd':'th'; | |
formatString = formatString.replace("#YYYY#",YYYY).replace("#YY#",YY).replace("#MMMM#",MMMM).replace("#MMM#",MMM).replace("#MM#",MM).replace("#M#",M).replace("#DDDD#",DDDD).replace("#DDD#",DDD).replace("#DD#",DD).replace("#D#",D).replace("#th#",th); | |
h=(hhh=date.getHours()); | |
if (h===0) h=24; | |
if (h>12) h-=12; | |
hh = h<10?('0'+h):h; | |
hhhh = h<10?('0'+hhh):hhh; | |
AMPM=(ampm=hhh<12?'am':'pm').toUpperCase(); | |
mm=(m=date.getMinutes())<10?('0'+m):m; | |
ss=(s=date.getSeconds())<10?('0'+s):s; | |
return formatString.replace("#hhhh#",hhhh).replace("#hhh#",hhh).replace("#hh#",hh).replace("#h#",h).replace("#mm#",mm).replace("#m#",m).replace("#ss#",ss).replace("#s#",s).replace("#ampm#",ampm).replace("#AMPM#",AMPM); | |
} | |
function dec2frac(d) { | |
var df = 1; | |
var top = 1; | |
var bot = 1; | |
while (df != d) { | |
if (df < d) { | |
top += 1; | |
} else { | |
bot += 1; | |
top = parseInt(d * bot); | |
} | |
df = top / bot; | |
} | |
return top + '/' + bot; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment