Skip to content

Instantly share code, notes, and snippets.

@tomger
Last active February 3, 2018 14:37
Show Gist options
  • Select an option

  • Save tomger/32c32abde6d9ca5111e1 to your computer and use it in GitHub Desktop.

Select an option

Save tomger/32c32abde6d9ca5111e1 to your computer and use it in GitHub Desktop.

Revisions

  1. tomger renamed this gist Feb 3, 2018. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  2. tomger created this gist Sep 14, 2015.
    146 changes: 146 additions & 0 deletions export_timeline.sjs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,146 @@
    /*
    * 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;
    }