/**************************************************************** Traction Software, Inc. Confidential and Proprietary Information Copyright (c) 1996-2012 Traction Software, Inc. All rights reserved. ****************************************************************/ // PLEASE DO NOT DELETE THIS LINE -- make copyright depends on it. package com.traction.soap.test; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import java.util.Properties; import org.apache.soap.SOAPException; import com.traction.soap.client.CustomData; import com.traction.soap.client.FaultException; import com.traction.soap.client.NewAttachment; import com.traction.soap.client.PublishEntry3; import com.traction.soap.client.PublishResult; import com.traction.soap.client.Traction; /** * Works somewhat like the tractionpublish perl script. */ public class TractionPublish extends TractionSOAPRequest { private static final String[] BOOLEAN_ARGS = new String[] { "text", "nocapture", "images" }; private static final String[] REQUIRED_ARGS = new String[] { "url", "auth", "project" }; public static final void main(String[] args) throws Exception { try { (new TractionPublish()).call(args); } catch (Exception e) { e.printStackTrace(System.err); throw e; } } @Override protected String[] getRequiredArgs() { return REQUIRED_ARGS; } @Override protected String[] getBooleanArgs() { return BOOLEAN_ARGS; } @Override protected void call(Args args, Traction soapClient) throws Exception { String project = args.get("project"); String title = args.get("title", ""); String body = args.get("body"); String entryProps = args.get("props"); String entryPropFile = args.get("propfile"); if (body == null) { // get the body from standard input body = new String(readContentBytes(System.in)); } boolean textOnly = args.get("text") != null; boolean autoCapture = args.get("nocapture") == null; boolean images = args.get("images") != null; boolean simplifyHtml = false; String initialStatusArg = args.get("status"); int initialStatus = -1; try { initialStatus = Integer.parseInt(initialStatusArg, 10); } catch (NumberFormatException nfe) { } String[] attachmentFileNames = args.getRemainingArgs(); NewAttachment[] attachments = uploadAttachments(attachmentFileNames, soapClient); if (images && attachments != null) { // reference all attachments as inline images if -images // specified on command line [cjn 26.Jun.2008] body = body + getInlineImageReferences(attachmentFileNames); } ArrayList valueList = new ArrayList(); ArrayList nameList = new ArrayList(); if (entryPropFile != null) { readEntryPropsFromXmlPropertiesFile(nameList, valueList, entryPropFile); } else if (entryProps != null) { readEntryPropertiesFromArg(nameList, valueList, entryProps); } String requestedCustomEntryType = args.get("customEntryType"); if (requestedCustomEntryType != null) { nameList.add("__custom_entry_type"); valueList.add(requestedCustomEntryType); } String[] customDataNames = null; String[] customDataValues = null; if (!nameList.isEmpty()) { customDataNames = nameList.toArray(new String[nameList.size()]); customDataValues = valueList.toArray(new String[valueList.size()]); } CustomData data = new CustomData(customDataNames, customDataValues); PublishEntry3 entry = new PublishEntry3(project, title, body, textOnly, simplifyHtml, attachments, initialStatus, data); entry.setAutoCapture(autoCapture); PublishResult result = soapClient.Publish3(entry); System.err.println(result.getDisplayUrl()); } // borrowed from com.traction.sdk.util.FormUtil private static byte[] readContentBytes(InputStream in) throws IOException { if (in==null) return null; ByteArrayOutputStream ba = new ByteArrayOutputStream(); int bytesRead = 0; byte b[] = new byte[10240]; // 10K blocks do { bytesRead = in.read( b ); if (bytesRead > 0) { ba.write(b, 0, bytesRead); } } while(bytesRead >= 0); b = null; return ba.toByteArray(); } private static final void readEntryPropsFromXmlPropertiesFile(List nameList, List valueList, String entryPropFilePath) throws IOException { Properties prop = new Properties(); FileInputStream fis = new FileInputStream(entryPropFilePath); prop.loadFromXML(fis); Enumeration e = prop.propertyNames(); while (e.hasMoreElements()) { String key = (String) e.nextElement(); nameList.add(key); valueList.add(prop.getProperty(key)); } } private static final void readEntryPropertiesFromArg(List nameList, List valueList, String entryPropsSpec) { while (entryPropsSpec.indexOf("=") != -1) { int index = entryPropsSpec.indexOf("="); nameList.add(entryPropsSpec.substring(0,index).trim()); entryPropsSpec = entryPropsSpec.substring(index+1); if (entryPropsSpec.charAt(0) != ' ') { int ValueEnd = entryPropsSpec.indexOf("\' "); if (ValueEnd != -1) { valueList.add(entryPropsSpec.substring(1,ValueEnd).trim()); } else { valueList.add(entryPropsSpec.substring(1,entryPropsSpec.length()-1).trim()); } entryPropsSpec = entryPropsSpec.substring(ValueEnd+2); } else { valueList.add(""); } } } private static final NewAttachment[] uploadAttachments(String[] filePaths, Traction soapClient) throws SOAPException, FaultException { int sz = filePaths.length; ArrayList newattach = new ArrayList(sz); for (String filePath : filePaths) { try { System.err.println("Trying to add " + filePath + " as an attachment."); FileInputStream fis = new FileInputStream(filePath); byte[] data = readContentBytes(fis); NewAttachment attachment = new NewAttachment(); attachment.setFilename(filePath); // do the upload attachment = soapClient.UploadAttachment(data, attachment); // add it to the list newattach.add(attachment); System.err.println("Added " + filePath + " as an attachment."); } catch (IOException e) { System.err.println(e); } } if (newattach.isEmpty()) { return null; } return newattach.toArray(new NewAttachment[newattach.size()]); } private static final String getInlineImageReferences(String[] attachments) { StringBuilder sb = new StringBuilder(""); for (int i = 0; i < attachments.length; i++) { sb.append("\n\n[[/image @" + (i + 1) + "]]"); } return sb.toString(); } @Override protected void printUsage() { System.err.println("usage: java com.traction.soap.client.TractionPublish [options] [attachments]"); System.err.println(""); System.err.println("This application can be used to publish content to Traction. Normally the"); System.err.println("content to publish is taken from STDIN, but it can also be passed on"); System.err.println("the command line."); System.err.println(""); System.err.println(" -url [rpcurl] URL of RPC service. This URL consists of your"); System.err.println(" Traction server's base URL plus a component that"); System.err.println(" identifies the SOAP router."); System.err.println(""); System.err.println(" Note that if your server is not running on port"); System.err.println(" 80, you must specify the port in the base URL."); System.err.println(""); System.err.println(" Examples:"); System.err.println(""); System.err.println(" http://yourtractionserver/soap/servlet/rpcrouter"); System.err.println(" http://yourtractionserver/soap/rpcrouter"); System.err.println(" http://yourtractionserver:8080/rpc"); System.err.println(""); System.err.println(" -auth [auth] User authentication information in the form:"); System.err.println(" username:password"); System.err.println(""); System.err.println(" -project [project] Traction project to which to publish."); System.err.println(""); System.err.println(" -title [title] Title of the new entry. If more than one word,"); System.err.println(" should be enclosed in quotes."); System.err.println(""); System.err.println(" -text Treat the body as plain text (preserve linebreaks)"); System.err.println(""); System.err.println(" -nocapture Don't automatically attach images referenced inline."); System.err.println(""); System.err.println(" -images Create one inlined image reference per attachment after body."); System.err.println(""); System.err.println(" -body [body] Body of the new entry. If not specified, STDIN is "); System.err.println(" taken as the body."); System.err.println(""); System.err.println(" -customEntryType [typeName]"); System.err.println(" The custom entry type to use for the posted entry. If the "); System.err.println(" entry represents an update to an existing entry, the server "); System.err.println(" will ignore this unless the entry doesn't have a custom"); System.err.println(" entry type already."); System.err.println(""); System.err.println(" -props [properties] Entry properties written as foo='bar' foo2='bar' "); System.err.println("Any of the command line parameters listed above can also be stored in"); System.err.println("a .tractionpublish file in your home directory."); System.err.println(""); System.err.println("The format is as follows:"); System.err.println(""); System.err.println("url=http://xanadu:8083/rpc"); System.err.println("auth=admin:"); System.err.println("text=true"); System.err.println(""); System.err.println("If those values are set in the config file, they do not need to appear"); System.err.println("in the command line."); System.err.println(""); System.err.println("Example:"); System.err.println(""); System.err.println("To post the current directory listing to Traction, with the current"); System.err.println("working directory as the title of the Traction entry (note, in the"); System.err.println("example, the admin account has no password):"); System.err.println(""); System.err.println(" ls -1 | tractionpublish -url http://xanadu:8083/rpc \\"); System.err.println(" -title `pwd` -project Private -auth admin: -text"); System.err.println(""); System.err.println("Labels can be included in the contents of the data sent in by"); System.err.println("including the appropriate rapid selector syntax label in the text, e.g."); System.err.println(""); System.err.println(" echo \"the title :headline\\n\\nthe lead\\n\\nsecond paragraph +:newlabel\" \\"); System.err.println(" | tractionpublish -project Private "); System.err.println(""); System.err.println("The second example above requires that the .tractionpublish file be"); System.err.println("present."); System.err.println(""); System.err.println("Note: this script requires a Traction server version 2.8b or later."); System.err.println(" uploading of attachments requires version 2.9 or later."); } }