-
-
Save kbsriram/05544b3f12a7b316c113 to your computer and use it in GitHub Desktop.
Simple facebook archiver
This file contains 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 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"); | |
} |
This file contains 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 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