Skip to content

Instantly share code, notes, and snippets.

@kbsriram
Created May 8, 2014 19:14
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save kbsriram/05544b3f12a7b316c113 to your computer and use it in GitHub Desktop.
Save kbsriram/05544b3f12a7b316c113 to your computer and use it in GitHub Desktop.
Simple facebook archiver
package archiver.facebook;
import java.io.*;
import java.net.*;
import java.util.*;
import java.text.SimpleDateFormat;
import org.json.*;
public class Main
{
public static void main(String args[])
throws IOException
{
Properties props = new Properties();
BufferedReader br = new BufferedReader(new FileReader("fbtokens.txt"));
props.load(br);
br.close();
s_access = props.getProperty("access_token");
String names[] = props.getProperty("download", "").split(",");
for (int i=0; i<names.length; i++) {
s_dump.add(names[i].trim());
}
URL target = new URL("https://graph.facebook.com/me/friends?access_token="+s_access);
do {
try { target = handleFriends(U.getJSON(target)); }
catch (IOException ignore) {
System.out.println("IGNORE: ");
ignore.printStackTrace();
target = null;
}
} while (target != null);
}
private final static URL handleFriends(JSONObject friends)
throws IOException
{
JSONArray data = friends.getJSONArray("data");
for (int i=0; i<data.length(); i++) {
handleFriend(data.getJSONObject(i));
}
return paging(friends);
}
private final static void handleFriend(JSONObject friend)
throws IOException
{
String n = friend.getString("name");
if (!s_dump.contains(n)) { return; }
String owner = friend.getString("id");
URL target = new URL("https://graph.facebook.com/"+owner+"/albums?access_token="+s_access);
do {
try { target = handleAlbums(owner, U.getJSON(target)); }
catch (IOException ignore) {
System.out.println("IGNORE: "+ignore);
target = null;
}
} while (target != null);
target = new URL("https://graph.facebook.com/"+owner+"/photos?access_token="+s_access);
do {
try { target = handlePictures(owner+"/tag", U.getJSON(target)); }
catch (IOException ignore) {
System.out.println("IGNORE: "+ignore);
target = null;
}
} while (target != null);
}
private final static URL handleAlbums(String owner, JSONObject albums)
throws IOException
{
JSONArray data = albums.getJSONArray("data");
for (int i=0; i<data.length(); i++) {
JSONObject album = data.getJSONObject(i);
int count = album.optInt("count", 0);
if (count == 0) { continue; }
handleAlbum(owner, album);
}
return paging(albums);
}
private final static void handleAlbum(String owner, JSONObject album)
throws IOException
{
URL target = new URL("https://graph.facebook.com/"+album.getString("id")+"/photos?access_token="+s_access);
do {
try { target = handlePictures(owner, U.getJSON(target)); }
catch (IOException ignore) {
System.out.println("IGNORE: "+ignore);
target = null;
}
} while (target != null);
}
private final static URL paging(JSONObject j)
throws IOException
{
JSONObject paging = j.optJSONObject("paging");
if (paging == null) { return null; }
String n = paging.optString("next");
if (n == null) { return null; }
try { return new URL(n); }
catch (IOException ign) {
System.out.println("Paging ends : '"+n+"'");
return null;
}
}
private final static URL handlePictures(String owner, JSONObject pictures)
throws IOException
{
JSONArray data = pictures.optJSONArray("data");
if (data != null) {
for (int i=0; i<data.length(); i++) {
handlePicture(owner, data.getJSONObject(i));
}
}
return paging(pictures);
}
private final static void handlePicture(String owner, JSONObject data)
throws IOException
{
String oid = data.getString("id");
File mpath = getPath(owner, oid, "json");
File ppath = getPath(owner, oid, "jpg");
long ts = getTimestamp(data);
if (mpath.exists() && ppath.exists()) {
ppath.setLastModified(ts);
return;
}
U.writeJSON(mpath, data);
U.dumpURL(new URL(getBiggestImage(data)), ppath, ts);
}
private final static long getTimestamp(JSONObject data)
{
String ctime = data.optString("created_time");
if (ctime == null) {
return System.currentTimeMillis();
}
try {
return (s_format.parse(ctime)).getTime();
} catch(Throwable th) {
th.printStackTrace();
return System.currentTimeMillis();
}
}
private final static String getBiggestImage(JSONObject data)
{
String ret = data.getString("source");
// But, over-ride from images array if found.
JSONArray images = data.optJSONArray("images");
if (images == null) { return ret; }
int max = 0;
for (int i=0; i<images.length(); i++) {
JSONObject io = images.getJSONObject(i);
int cur = io.getInt("width");
if (cur > max) {
ret = io.getString("source");
max = cur;
}
}
return ret;
}
private final static File getPath(String owner, String id, String sfx)
{
File root = new File("archive/facebook/"+sfx+"/"+owner);
if (!root.isDirectory()) { root.mkdirs(); }
return new File(root, id+"."+sfx);
}
private static String s_access;
private final static HashSet<String> s_dump = new HashSet<String>();
private static final SimpleDateFormat s_format =
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss+SSSS");
}
package archiver.facebook;
import java.io.*;
import java.net.*;
import java.util.*;
import org.json.*;
public class U
{
public static JSONObject getJSON(URL url)
throws IOException
{
sleep(1000);
System.out.println("fetch: "+url);
URLConnection con = url.openConnection();
BufferedReader br = new BufferedReader
(new InputStreamReader(con.getInputStream()));
JSONTokener tok = new JSONTokener(br);
JSONObject ret = new JSONObject(tok);
br.close();
return ret;
}
public static void writeJSON(File out, JSONObject j)
throws IOException
{
PrintWriter pr = new PrintWriter(new FileWriter(out));
pr.println(j.toString(2));
pr.close();
}
public static void sleep(long msec)
{
try { Thread.sleep(msec); }
catch (InterruptedException ie) {}
}
public static void dumpURL(URL src, File target, long ts)
throws IOException
{
sleep(1000);
System.out.println(src+" -> "+target);
URLConnection con = src.openConnection();
InputStream in = con.getInputStream();
FileOutputStream out = new FileOutputStream(target);
byte buf[] = new byte[8192];
int nread;
while ((nread = in.read(buf)) > 0) {
out.write(buf, 0, nread);
}
out.close();
in.close();
target.setLastModified(ts);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment