FileDocCategorySizeDatePackage
PublishTransaction.javaAPI DocAzureus 3.0.3.421171Thu Aug 02 12:19:32 BST 2007com.aelitis.azureus.ui.swt.browser.listener.publish

PublishTransaction

public class PublishTransaction extends com.aelitis.azureus.ui.swt.browser.txn.Transaction
Tracks the progress of creating a torrent during the publish process.
author
dharkness
created
Jul 20, 2006

Fields Summary
private static final String
ELEMENTS
public static final String
PUBLISH_ATTRIBUTE_KEY
private static final int
DEFAULT_IMAGE_BOX_SIZE
private static final float
DEFAULT_JPEG_QUALITY
private Shell
shell
private LocalHoster
hoster
private TorrentCreator
creator
private TorrentCreatorListener
creatorListener
private File
dataFile
Constructors Summary
public PublishTransaction(int id, String type, com.aelitis.azureus.core.messenger.ClientMessageContext context)
Creates the transaction. Called by the manager.

param
id unique ID assigned by the manager
param
type passed by manager
param
context used to access the browser

        super(id, type, context);
    
Methods Summary
protected booleancanceling()

    	if(creator != null) {
    		creator.cancel();
    		creator.removeListener(creatorListener);
    		creator = null;
    		//Gudy	sendBrowserMessage("torrent","canceled");
    	}
        return true;
    
public voidchooseFile(com.aelitis.azureus.ui.swt.browser.msg.BrowserMessage message)
Opens a file dialog so the user can choose the file to torrent.

    	
    	FileDialog dialog = new FileDialog(shell);    	
    	String file = dialog.open();    	
    	createTorrentFile(file);
    
public voidchooseFolder(com.aelitis.azureus.ui.swt.browser.msg.BrowserMessage message)
Opens a file dialog so the user can choose the folder to torrent.

    	DirectoryDialog dialog = new DirectoryDialog(shell);    	
    	String file = dialog.open();
    	createTorrentFile(file);
    
public voidchooseThumbnail(com.aelitis.azureus.ui.swt.browser.msg.BrowserMessage message)
Opens a file dialog so the user can choose the image to use as a thumbnail

    	final int resize_size[] = {DEFAULT_IMAGE_BOX_SIZE,DEFAULT_IMAGE_BOX_SIZE};
    	final float image_quality[] = {DEFAULT_JPEG_QUALITY};
    	Map elements = null; //will be used if several thumbnails are required on a single page
        if ( message.isParamObject() ) {
            Map parameters = message.getDecodedMap();
    		try {
    			resize_size[0] = MapUtils.getMapInt(parameters, "width", 
    					DEFAULT_IMAGE_BOX_SIZE);
    			resize_size[1] = MapUtils.getMapInt(parameters, "height", 
    					DEFAULT_IMAGE_BOX_SIZE);
    			image_quality[0] = ((Number) MapUtils.getMapObject(parameters,
						"quality", new Double(DEFAULT_JPEG_QUALITY), Number.class)).floatValue();
    			if (parameters.containsKey(ELEMENTS)){
    				elements = (Map) parameters.get(ELEMENTS);
    			}
    		} catch(Exception e) {
    			//Possible bad parameters given, use default values
    			e.printStackTrace();
    		}
        }
    	FileDialog dialog = new FileDialog(shell,SWT.OPEN);
    	dialog.setFilterNames(new String[] {"Image Files"});
    	dialog.setFilterExtensions(new String[] {"*.jpg;*.jpeg;*.bmp;*.gif;*.png"});
    	final String fileName = dialog.open();
    	if(fileName != null) {
    		//Run async not to block the UI
			/*Thread runner = 
                new Thread("Thumbnail Creator") {
    				public void run() {*/
    		
    					try {
                            sendBrowserMessage("thumb", "start", elements);
                            
        					File file = new File(fileName);    				
    	    				ResizedImageInfo info = loadAndResizeImage(file,resize_size[0],resize_size[1],1);
    	    				if(info == null) {
    	    					debug("User canceled image resizing");
    	    					sendBrowserMessage("thumb", "clear", elements);
    	    				} else {
	    	    				final String thumbURL = info.url.toString();
	    	    				debug("Size : " + info.data.length);
	    	    				
	    	    				final String encoded = new String(Base64.encode(info.data));
	                            Map params = new HashMap();
	                            params.put("url", thumbURL);
	                            params.put("width", new Long(info.width));
	                            params.put("height", new Long(info.height));
	                            params.put("data", encoded);
	                            if ( elements != null ){
	                            	params.put(ELEMENTS, elements);
	                            }
	                            sendBrowserMessage("thumb", "done", params);
    	    				}
        	    		}
    					catch(ImageResizeException e) {
    						debug("Error resizing image",e);
    						sendBrowserMessage("thumb", "clear", elements);
                            
                            Map params = new HashMap();
                            params.put("message", e.getMessage());
                            sendBrowserMessage("page", "error",params);
    					}
                        catch (Exception e) {
        					debug("Error reading file",e);
                            sendBrowserMessage("thumb", "clear", elements);
                            
                            Map params = new HashMap();
                            params.put("message", "Azureus cannot process this image. Please select another one.");
                            sendBrowserMessage("page", "error",params);
        				}
                        catch (OutOfMemoryError e) {
                        	debug("Error processing the image",e);
                        	
                        	sendBrowserMessage("thumb", "clear", elements);
                            
                            Map params = new HashMap();
                            params.put("message", "Azureus cannot process this image (likely reason is that it is too big). Please select another one.");
                            sendBrowserMessage("page", "error",params);
                        	
                        }
    				/*}
			    };
			runner.setDaemon(true);
			runner.start();    	*/		
    	}
    
private voidcreateTorrentFile(java.lang.String file)

    	if(file != null) {   		
    		dataFile = new File(file);
    		try {
    			PluginInterface pi = PluginInitializer.getDefaultInterface();
    			creator = pi.getTorrentManager().createFromDataFileEx(dataFile,
						new URL("http://xxxxxxxxxxxxxxxxx:6969/announce"), false);

    			creatorListener = new TorrentCreatorListener() {

    				public void complete(Torrent torrent) {    					
    					try {
    						
    						torrent.setDefaultEncoding();
    						
    						debug("local torrent creation complete: " +torrent.getName()+ " : " +torrent.getMagnetURI() );        						    						
    						
    						final String tData = new String( Base64.encode( torrent.writeToBEncodedData() ) );
    						Map params = new HashMap();
                            params.put("data", tData);
    						sendBrowserMessage("torrent", "done", params);
    					}
    					catch (Throwable t) {
    						// TODO: handle exception
    						debug("error encoding torrent", t);
    					}

    				}

    				public void failed(TorrentException cause) {
    					torrentCreationFailed(cause);
    				}

    				public void reportActivity(String activity) {
    					//debug("creation status : " + activity);
    				}

    				public void reportPercentageDone(int percent) {
    					//debug("creation progress : " + percent);
    					Map params = new HashMap();
    					params.put("percent", new Long(percent));
    					sendBrowserMessage("torrent", "progress", params);
    				}

    			};

    			creator.addListener(creatorListener);

    			creator.start();

    		} catch (MalformedURLException e) {
    			
    			torrentCreationFailed(e);
				
    		} catch (TorrentException e) {
    			
    			torrentCreationFailed(e);
				
    		}
            
            Map params = new HashMap();
            params.put("folder", new Boolean(dataFile.isDirectory()));
            params.put("name", dataFile.getName());
            long size = getSize(dataFile);
            params.put("size", new Long(size));
            params.put("size-text", DisplayFormatters.formatByteCountToKiBEtc(size));
            sendBrowserMessage("torrent", "chosen", params);
    	} else {
    		//No file was chosen, cancel the transaction
    		cancel();
            stop();
    	}
    
private longgetSize(java.io.File folderFile)

    	if (folderFile.isFile()) {
    		return folderFile.length();
    	}
    	if (folderFile.isDirectory()) {
    		long size = 0;
    		File[] files = folderFile.listFiles();
    		if (files != null) {
    			for (int i = 0; i < files.length; i++) {
						File file = files[i];
						size += getSize(file);
					}
    		}
    		return size;
    	}
    	return 0;
    
private com.aelitis.azureus.ui.swt.browser.listener.publish.PublishTransaction$ResizedImageInfoloadAndResizeImage(java.io.File f, int width, int height, float quality)

		ImageLoader loader = new ImageLoader();
		final Display display = shell.getDisplay();
		Image source = null;
		try {
			source = new Image(shell.getDisplay(), f.getAbsolutePath());
		} catch (Error e) {
		}
		
		if (source == null) {
			throw new ImageResizeException("Unable to read image.  Please choose another.");
		}

		// If size is already an exact match, and the file isn't too big, use
		// original file
		Rectangle bounds = source.getBounds();
		try {
			if (bounds.width == width && bounds.height == height
					&& f.length() < 60000 && false) {
				URL url = hoster.hostFile(f);
				final FileInputStream fos = new FileInputStream(f);
				byte[] buf = new byte[(int) f.length()];
				fos.read(buf);
				fos.close();

				ResizedImageInfo result = new ResizedImageInfo(url, width, height, buf);
				return result;
			}
		} catch (Exception e) {
			Debug.out(e);
		}

		ImageResizer resizer = new ImageResizer(display, width, height, shell);

		Image output = resizer.resize(source);
		if (output == null)
			return null;
		ImageData data = output.getImageData();
		//Dispose the image
		if (output != null && !output.isDisposed()) {
			output.dispose();
		}

		//debug("final ByteArrayOutputStream baos = new ByteArrayOutputStream();");
		final ByteArrayOutputStream baos = new ByteArrayOutputStream();

		loader.data = new ImageData[] { data
		};
		
		String ext;
		if (SWT.getVersion() >= 3500) {
			// XXX Bug in SWT which borks some PNGs.. thus we can't use PNG saving
			//     at all until they fix it.. See 
			//     https://bugs.eclipse.org/bugs/show_bug.cgi?id=172290
			loader.save(baos, SWT.IMAGE_PNG);
			ext = ".png";
		} else {
			try {
				Class cJPGFF = Class.forName("org.eclipse.swt.internal.image.JPEGFileFormat");

				Constructor jpgConst = cJPGFF.getDeclaredConstructor(new Class[0]);

				jpgConst.setAccessible(true);

				FileFormat format = (FileFormat) jpgConst.newInstance(new Object[0]);

				Field field = cJPGFF.getDeclaredField("encoderQFactor");

				field.setAccessible(true);

				field.setInt(format, (int) (quality * 100));

				Class claLEDataOS = Class.forName("org.eclipse.swt.internal.image.LEDataOutputStream");

				Constructor le_constructor = claLEDataOS.getDeclaredConstructor(new Class[] { OutputStream.class
				});

				le_constructor.setAccessible(true);

				Object le_stream = le_constructor.newInstance(new Object[] { baos
				});

				Method unloadIntoStream = cJPGFF.getMethod("unloadIntoStream",
						new Class[] {
							ImageLoader.class,
							claLEDataOS
						});

				try {
					unloadIntoStream.invoke(format, new Object[] {
						loader,
						le_stream
					});
				} catch (Exception ex) {
					//Too bad for us here
					//However we don't want to try the other way, as it may be an io 
					//exception, ie the stream is corrupted...
					ex.printStackTrace();
				}
			} catch (Exception e) {
				e.printStackTrace();
				// The reflection way failed, do it the normal way with default 
				// (0.75) quality...
				loader.save(baos, SWT.IMAGE_JPEG);
			}
			ext = ".jpg";
		}


		byte[] bs = baos.toByteArray();

		File fDest = File.createTempFile("thumbnail", ext);
		FileOutputStream fos = new FileOutputStream(fDest);
		fos.write(bs);
		fos.close();

		URL url = hoster.hostFile(fDest);
		ResizedImageInfo result = new ResizedImageInfo(url, width, height, bs);

		return result;
	
public voidsetLocalHoster(LocalHoster hoster)

		this.hoster = hoster;
	
public voidsetShell(Shell shell)

	
	    
		this.shell = shell;
	
private voidtorrentCreationFailed(java.lang.Exception cause)

    	debug("Torrent Creation Failed", cause);
    	
    	sendBrowserMessage("torrent","failed");
    	
    	Map params = new HashMap();
		params.put("message", "Azureus cannot process this file. Please select another file.");
		sendBrowserMessage("page", "error",params);
		
    
public voidtorrentIsReady(com.aelitis.azureus.ui.swt.browser.msg.BrowserMessage message)
Pulls the modified torrent from the result web page and saves it locally.

		String torrent = MapUtils.getMapString(message.getDecodedMap(),
				"torrent", null);
		if (torrent != null) {
			torrentIsReady(torrent);
		}
	
protected voidtorrentIsReady(java.lang.String strTorrent)


		try {
			strTorrent = strTorrent.replaceAll("\\n", "");
			debug("data file path = [" + dataFile.getPath() + "]");
			debug("Torrent is ready, size = " + strTorrent.length()
					+ ", content (base64) : " + strTorrent);

			byte[] torrent_data = Base64.decode(strTorrent);

			debug("Torrent Byte Length: " + torrent_data.length /* + ", content : " + new String(torrent_data) */);

			// use PluginInterface since it has nice functions for
			// setting complete and adding a download via Torrent
			PluginInterface pi = PluginInitializer.getDefaultInterface();
			Torrent torrent = pi.getTorrentManager().createFromBEncodedData(
					torrent_data);

			torrent.setDefaultEncoding();
			torrent.setComplete(dataFile);

			final Download download = pi.getDownloadManager().addDownload(torrent,
					null, dataFile);

			PublishUtils.setPublished(download);

			download.setForceStart(true);

			//Transaction is finished
			stop();
		} catch (Throwable t) {
			Debug.out("torrentIsReady", t);
		}