Skip to content

Instantly share code, notes, and snippets.

@aviflax
Created May 9, 2011 03:13
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aviflax/961993 to your computer and use it in GitHub Desktop.
Save aviflax/961993 to your computer and use it in GitHub Desktop.
Simple little web app for clipboard exchange -- handles text and files
#!/usr/bin/env groovy
@GrabResolver(name='restlet', root='http://maven.restlet.org/')
@Grab(group='org.restlet.jse', module='org.restlet', version='[2.0,2.1[')
@Grab('commons-lang:commons-lang:2.4')
import java.awt.*
import java.awt.datatransfer.*
import java.io.*
import java.util.logging.*
import static org.apache.commons.lang.StringEscapeUtils.escapeHtml
import org.restlet.*
import org.restlet.data.*
import org.restlet.representation.*
import org.restlet.resource.*
import org.restlet.routing.*
class ClipboardHelper {
static clipboard = Toolkit.defaultToolkit.systemClipboard
static String getClipboardString() {
def contents = clipboard.getContents(null)
if (contents.isDataFlavorSupported(DataFlavor.stringFlavor))
return contents.getTransferData(DataFlavor.stringFlavor) as String
else
return '[clipboard contents cannot be provided as text]'
}
static Boolean doesClipboardContainFile() {
def contents = clipboard.getContents(null)
return contents.isDataFlavorSupported(DataFlavor.javaFileListFlavor)
}
static java.util.List<File> getClipboardFiles() {
def contents = clipboard.getContents(null)
if (contents.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
return contents.getTransferData(DataFlavor.javaFileListFlavor) as java.util.List<File>
else
throw new Exception('The clipboard does not contain a file.')
}
static void setClipboardString(String string) {
clipboard.setContents new StringSelection(string), null
}
}
class ClipboardResource extends ServerResource {
@Get('html')
String view() {
def html = """
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Clipboard</title>
<meta name="author" content="Avi Flax">
<style>
form, input, textarea {
display: block;
}
textarea {
width: 100%;
}
html, body, form, textarea {
height: 95%
}
</style>
</head>
<body>
<h1>Clipboard Exchange</h1
<form action="/" method="POST">
"""
if (ClipboardHelper.doesClipboardContainFile()) {
html += """
<h2>Clipboard contains file: <a href="file">${ClipboardHelper.getClipboardFiles()[0].name}</a></h2>
<hr>
<h2>Set Text</h2>
<textarea name="value"></textarea>
<input type="submit" value="Set Text"/>
"""
} else {
html += """
<h2>Get/Set Text</h2>
<textarea name="value">${escapeHtml(ClipboardHelper.getClipboardString())}</textarea>
<input type="submit" value="Set Text"/>
"""
}
html += """
</form>
</body>
</html>
"""
return html
}
@Post('form:html')
String post(Form form) {
String newValue = form.getFirstValue('value')
if (newValue == null)
throw new ResourceException(400, "The form must include the field 'value'")
ClipboardHelper.setClipboardString newValue
return view()
}
}
class FileResource extends ServerResource {
@Get
Representation retrieveFile() {
if (! ClipboardHelper.doesClipboardContainFile())
throw new ResourceException(404, 'The clipboard does not contain a file.')
def file = ClipboardHelper.getClipboardFiles()[0]
def representation = new FileRepresentation(file, MediaType.APPLICATION_OCTET_STREAM)
representation.disposition.filename = file.name
representation.disposition.type = Disposition.TYPE_ATTACHMENT
return representation
}
}
router = new Router()
router.attach '', ClipboardResource.class
router.attach '/', ClipboardResource.class
router.attach '/file', FileResource.class
component = new org.restlet.Component()
component.servers.add(Protocol.HTTP, 80)
component.defaultHost.attach router
component.start()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment