forked from rictic/code_swarm
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Selectable AvatarFetcher and smarter loading of avatars to eliminate lag
Now supports the option "AvatarFetcher" which can be either GravatarFetcher or FreebaseAvatarFetcher. Leave blank for no avatar images. FreebaseAvatarFetcher is mostly useful for some visualizations I've been working on for visualizing freebase.com. The avatar cache is primed as the xml is read in. This, combined with a larger read ahead queue keeps lag pretty much nonexistent.
- Loading branch information
Showing
5 changed files
with
211 additions
and
64 deletions.
There are no files selected for viewing
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
import java.io.File; | ||
import java.io.FileOutputStream; | ||
import java.io.IOException; | ||
import java.io.InputStream; | ||
import java.io.UnsupportedEncodingException; | ||
import java.net.URL; | ||
import java.net.URLConnection; | ||
import java.security.MessageDigest; | ||
import java.security.NoSuchAlgorithmException; | ||
|
||
|
||
public class AvatarFetcher { | ||
protected CodeSwarmConfig cfg; | ||
public AvatarFetcher(CodeSwarmConfig cfg) { | ||
this.cfg = cfg; | ||
} | ||
|
||
public String fetchUserImage(String username) { | ||
//Override fetchUserImage in your Avatar Fetcher | ||
return null; | ||
} | ||
|
||
protected static String getFilename(String key){ | ||
return "image_cache/" + key; | ||
} | ||
|
||
protected static boolean imageCached(String key) { | ||
return new File(getFilename(key)).exists(); | ||
} | ||
|
||
protected static String getImage(String key, URL url) { | ||
String filename = getFilename(key); | ||
if (!imageCached(key)){ | ||
boolean successful = fetchImage(filename, url); | ||
if (!successful) | ||
return null; | ||
} | ||
|
||
return filename; | ||
} | ||
|
||
protected static boolean fetchImage(String filename, URL url) { | ||
try { | ||
new File("image_cache").mkdirs(); | ||
URLConnection con = url.openConnection(); | ||
InputStream input = con.getInputStream(); | ||
FileOutputStream output = new FileOutputStream(filename); | ||
|
||
int length = con.getContentLength(); | ||
if (length == -1){ | ||
//read until exhausted | ||
while(true){ | ||
int val = input.read(); | ||
if (val == -1) | ||
break; | ||
output.write(input.read()); | ||
} | ||
} | ||
else{ | ||
//read length bytes | ||
for(int i = 0; i < length; i++) | ||
output.write(input.read()); | ||
} | ||
|
||
output.close(); | ||
input.close(); | ||
return true; | ||
} catch (IOException e) { | ||
// TODO Auto-generated catch block | ||
e.printStackTrace(); | ||
return false; | ||
} | ||
} | ||
|
||
//these two methods taken from http://en.gravatar.com/site/implement/java | ||
private static String hex(byte[] array) { | ||
StringBuffer sb = new StringBuffer(); | ||
for (int i = 0; i < array.length; ++i) | ||
sb.append(Integer.toHexString((array[i] & 0xFF) | 0x100).substring(1,3)); | ||
return sb.toString(); | ||
} | ||
protected static String md5Hex (String message) { | ||
try { | ||
MessageDigest md = MessageDigest.getInstance("MD5"); | ||
return hex (md.digest(message.getBytes("CP1252"))); | ||
} catch (NoSuchAlgorithmException e) { | ||
} catch (UnsupportedEncodingException e) { | ||
} | ||
return null; | ||
} | ||
|
||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
import java.io.BufferedReader; | ||
import java.io.File; | ||
import java.io.IOException; | ||
import java.io.InputStreamReader; | ||
import java.net.MalformedURLException; | ||
import java.net.URL; | ||
import java.net.URLConnection; | ||
import java.util.regex.Matcher; | ||
import java.util.regex.Pattern; | ||
|
||
|
||
public class FreebaseAvatarFetcher extends AvatarFetcher{ | ||
public FreebaseAvatarFetcher(CodeSwarmConfig cfg) { | ||
super(cfg); | ||
} | ||
|
||
static private Pattern imageIDPattern = Pattern.compile("\"image:id\"\\s*:\\s*\"(.*?)\""); | ||
|
||
private static String readURLToString(URL url) { | ||
try { | ||
URLConnection con = url.openConnection(); | ||
BufferedReader reader = new BufferedReader(new InputStreamReader(con.getInputStream())); | ||
StringBuilder sb = new StringBuilder(); | ||
int length = con.getContentLength(); | ||
if (length == -1){ | ||
//read until exhausted | ||
while(true){ | ||
String line = reader.readLine(); | ||
if (line == null) break; | ||
sb.append(line); | ||
} | ||
} | ||
else{ | ||
//read length bytes | ||
for(int i = 0; i < length; i++) | ||
sb.append((char)reader.read()); | ||
} | ||
return sb.toString(); | ||
} catch (IOException e) { | ||
e.printStackTrace(); | ||
return null; | ||
} | ||
} | ||
|
||
private static String getUserImageID(String username) { | ||
try { | ||
new File("image_cache").mkdirs(); | ||
String json = readURLToString(new URL("http://www.freebase.com/api/service/mqlread?query=" + | ||
"{%22query%22:{%22!/common/image/appears_in_topic_gallery%22:"+ | ||
"[{%22image:id%22:null}],%22id%22:%22/user/" + username + "%22}}")); | ||
if (json == null) return null; | ||
Matcher m = imageIDPattern.matcher(json); | ||
if (m.find()) | ||
return m.group(1); | ||
} catch (IOException e) { | ||
// TODO Auto-generated catch block | ||
e.printStackTrace(); | ||
} | ||
return null; | ||
} | ||
|
||
public String fetchUserImage(String username) { | ||
String key = md5Hex("metaweb:" + username); | ||
if (imageCached(key)) | ||
return getFilename(key); | ||
try { | ||
String imageID = getUserImageID(username); | ||
if (imageID == null) return null; | ||
return getImage(key, new URL("http://www.freebase.com/api/trans/image_thumb/" +imageID+ "?maxheight=40&mode=fillcrop&maxwidth=40")); | ||
} catch (MalformedURLException e) { | ||
e.printStackTrace(); //should be impossible... | ||
return null; | ||
} | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,63 +1,18 @@ | ||
import java.io.*; | ||
import java.net.MalformedURLException; | ||
import java.net.URL; | ||
import java.net.URLConnection; | ||
import java.security.*; | ||
|
||
public class GravatarFetcher { | ||
|
||
//these two methods taken from http://en.gravatar.com/site/implement/java | ||
private static String hex(byte[] array) { | ||
StringBuffer sb = new StringBuffer(); | ||
for (int i = 0; i < array.length; ++i) | ||
sb.append(Integer.toHexString((array[i] & 0xFF) | 0x100).substring(1,3)); | ||
return sb.toString(); | ||
public class GravatarFetcher extends AvatarFetcher { | ||
public GravatarFetcher(CodeSwarmConfig cfg) { | ||
super(cfg); | ||
} | ||
private static String md5Hex (String message) { | ||
try { | ||
MessageDigest md = MessageDigest.getInstance("MD5"); | ||
return hex (md.digest(message.getBytes("CP1252"))); | ||
} catch (NoSuchAlgorithmException e) { | ||
} catch (UnsupportedEncodingException e) { | ||
} | ||
return null; | ||
} | ||
|
||
public static String fetchUserImage(String username) { | ||
|
||
public String fetchUserImage(String username) { | ||
String hash = md5Hex(username); | ||
String filename = "image_cache/" + hash; | ||
if (!new File(filename).exists()){ | ||
try { | ||
new File("image_cache").mkdirs(); | ||
URL url = new URL("http://www.gravatar.com/avatar/" + hash + "?d=identicon&s=40"); | ||
URLConnection con = url.openConnection(); | ||
InputStream input = con.getInputStream(); | ||
FileOutputStream output = new FileOutputStream(filename); | ||
|
||
int length = con.getContentLength(); | ||
if (length == -1){ | ||
//read until exhausted | ||
while(true){ | ||
int val = input.read(); | ||
if (val == -1) | ||
break; | ||
output.write(input.read()); | ||
} | ||
} | ||
else{ | ||
//read length bytes | ||
for(int i = 0; i < length; i++) | ||
output.write(input.read()); | ||
} | ||
|
||
output.close(); | ||
input.close(); | ||
} catch (IOException e) { | ||
// TODO Auto-generated catch block | ||
e.printStackTrace(); | ||
return null; | ||
} | ||
try { | ||
return getImage(hash, new URL("http://www.gravatar.com/avatar/" + hash + "?d=identicon&s=40")); | ||
} catch (MalformedURLException e) { | ||
e.printStackTrace(); //should be impossible... | ||
return null; | ||
} | ||
|
||
return filename; | ||
} | ||
} |
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