/* * Copyright (c) 2011 Enrico Franchi, Michele Tomaiuolo and University of Parma. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package net.blogracy.controller; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.security.InvalidParameterException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.TimeZone; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import javax.jms.Connection; import javax.jms.ConnectionFactory; import javax.jms.DeliveryMode; import javax.jms.Destination; import javax.jms.Message; import javax.jms.MessageConsumer; import javax.jms.MessageListener; import javax.jms.MessageProducer; import javax.jms.Session; import javax.jms.TextMessage; import javax.xml.bind.DatatypeConverter; import net.blogracy.config.Configurations; import net.blogracy.model.hashes.Hashes; import net.blogracy.util.FileUtils; import org.apache.activemq.ActiveMQConnection; import org.apache.activemq.ActiveMQConnectionFactory; import org.apache.commons.codec.binary.Base32; import org.apache.shindig.protocol.conversion.BeanConverter; import org.apache.shindig.protocol.conversion.BeanJsonConverter; import org.apache.shindig.social.core.model.ActivityEntryImpl; import org.apache.shindig.social.core.model.ActivityObjectImpl; import org.apache.shindig.social.core.model.AlbumImpl; import org.apache.shindig.social.core.model.MediaItemImpl; import org.apache.shindig.social.opensocial.model.ActivityEntry; import org.apache.shindig.social.opensocial.model.ActivityObject; import org.apache.shindig.social.opensocial.model.Album; import org.apache.shindig.social.opensocial.model.MediaItem; import org.apache.shindig.social.opensocial.model.MediaItem.Type; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import org.json.JSONTokener; import com.google.inject.Binder; import com.google.inject.Guice; import com.google.inject.Module; import com.google.inject.name.Names; /** * Generic functions to manipulate feeds are defined in this class. */ public class FileSharing { private ConnectionFactory connectionFactory; private Connection downloadConnection; private Connection seedConnection; private Session downloadSession; private Session seedSession; private Destination seedQueue; private Destination downloadQueue; private MessageProducer downloadProducer; private MessageProducer seedProducer; static final DateFormat ISO_DATE_FORMAT = new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ss'Z'"); static final String CACHE_FOLDER = Configurations.getPathConfig() .getCachedFilesDirectoryPath(); private static final FileSharing theInstance = new FileSharing(); private static BeanJsonConverter CONVERTER = new BeanJsonConverter( Guice.createInjector(new Module() { @Override public void configure(Binder b) { b.bind(BeanConverter.class) .annotatedWith( Names.named("shindig.bean.converter.json")) .to(BeanJsonConverter.class); } })); public static FileSharing getSingleton() { return theInstance; } public static String hash(String text) { String result = null; try { MessageDigest digester = MessageDigest.getInstance("SHA-1"); Base32 encoder = new Base32(); byte[] digest = digester.digest(text.getBytes()); result = encoder.encodeAsString(digest); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return result; } public static String hash(File file) { String result = null; try { MessageDigest digester = MessageDigest.getInstance("SHA-1"); Base32 encoder = new Base32(); byte[] digest = digester.digest(FileUtils.getBytesFromFile(file)); result = encoder.encodeAsString(digest); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return result; } public FileSharing() { ISO_DATE_FORMAT.setTimeZone(TimeZone.getTimeZone("UTC")); try { connectionFactory = new ActiveMQConnectionFactory( ActiveMQConnection.DEFAULT_BROKER_URL); downloadConnection = connectionFactory.createConnection(); downloadConnection.start(); seedConnection = connectionFactory.createConnection(); seedConnection.start(); downloadSession = downloadConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); downloadProducer = downloadSession.createProducer(null); downloadProducer.setDeliveryMode(DeliveryMode.NON_PERSISTENT); downloadQueue = downloadSession.createQueue("download"); seedSession = seedConnection.createSession(false, Session.AUTO_ACKNOWLEDGE); seedProducer = seedSession.createProducer(null); seedProducer.setDeliveryMode(DeliveryMode.NON_PERSISTENT); seedQueue = seedSession.createQueue("seed"); } catch (Exception e) { e.printStackTrace(); } } public String seed(File file) { String uri = null; try { Destination tempDest = seedSession.createTemporaryQueue(); MessageConsumer responseConsumer = seedSession .createConsumer(tempDest); JSONObject requestObj = new JSONObject(); requestObj.put("file", file.getAbsolutePath()); TextMessage request = seedSession.createTextMessage(); request.setText(requestObj.toString()); request.setJMSReplyTo(tempDest); seedProducer.send(seedQueue, request); TextMessage response = (TextMessage) responseConsumer.receive(); String msgText = ((TextMessage) response).getText(); JSONObject responseObj = new JSONObject(msgText); uri = responseObj.getString("uri"); } catch (Exception e) { e.printStackTrace(); } return uri; } public static String getHashFromMagnetURI(String uri) { String hash = null; int btih = uri.indexOf("xt=urn:btih:"); if (btih >= 0) { hash = uri.substring(btih + "xt=urn:btih:".length()); int amp = hash.indexOf('&'); if (amp >= 0) hash = hash.substring(0, amp); } return hash; } public void download(final String uri) { String hash = getHashFromMagnetURI(uri); downloadByHash(hash, null, null); } public void download(final String uri, final String ext) { String hash = getHashFromMagnetURI(uri); downloadByHash(hash, ext, null); } public void downloadByHash(final String hash) { downloadByHash(hash, null, null); } public void downloadByHash(final String hash, final String ext, final MessageListener listener) { try { Destination tempDest = downloadSession.createTemporaryQueue(); MessageConsumer responseConsumer = downloadSession .createConsumer(tempDest); if (listener != null) { responseConsumer.setMessageListener(listener); } else { responseConsumer.setMessageListener(new MessageListener() { @Override public void onMessage(Message response) { } }); } String file = CACHE_FOLDER + File.separator + hash; if (ext != null) file += ext; JSONObject sharedFile = new JSONObject(); sharedFile.put("uri", "magnet:?xt=urn:btih:" + hash); sharedFile.put("file", file); byte[] bytes = (Hashes.fromString(hash)).getValue(); String encoded = DatatypeConverter.printHexBinary(bytes); sharedFile.put("hash", encoded); TextMessage message = downloadSession.createTextMessage(); message.setText(sharedFile.toString()); message.setJMSReplyTo(tempDest); downloadProducer.send(downloadQueue, message); } catch (Exception e) { e.printStackTrace(); } } public static String byteArrayToURLString(byte in[]) { byte ch = 0x00; int i = 0; if (in == null || in.length <= 0) return null; String pseudo[] = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F" }; StringBuffer out = new StringBuffer(in.length * 2); while (i < in.length) { // First check to see if we need ASCII or HEX if ((in[i] >= '0' && in[i] <= '9') || (in[i] >= 'a' && in[i] <= 'z') || (in[i] >= 'A' && in[i] <= 'Z') || in[i] == '$' || in[i] == '-' || in[i] == '_' || in[i] == '.' || in[i] == '!') { out.append((char) in[i]); i++; } else { out.append('%'); ch = (byte) (in[i] & 0xF0); // Strip off high nibble ch = (byte) (ch >>> 4); // shift the bits down ch = (byte) (ch & 0x0F); // must do this is high order bit is // on! out.append(pseudo[(int) ch]); // convert the nibble to a // String Character ch = (byte) (in[i] & 0x0F); // Strip off low nibble out.append(pseudo[(int) ch]); // convert the nibble to a // String Character i++; } } String rslt = new String(out); return rslt; } }