import java.util.*;
import java.util.zip.*;
import java.util.List;
import java.util.regex.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
import javax.swing.table.*;
import java.io.*;
import java.net.*;
import java.lang.reflect.*;
import java.lang.ref.*;
import java.lang.management.*;
import java.security.*;
import java.security.spec.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.imageio.*;
import java.math.*;
import android.app.Activity;
import android.app.*;
import android.media.*;
import android.net.*;
public class main {
public static void main(String[] args) throws Exception {
File mp3 = loadLibrary("#1001093");
androidPlayMp3(androidContext(), mp3);
print("Playback done.");
}
static Activity androidContext() {
return getAndroidContext();
}
static File loadLibrary(String snippetID) {
return loadBinarySnippet(snippetID);
}
static volatile StringBuffer local_log = new StringBuffer(); // not redirected
static volatile StringBuffer print_log = local_log; // might be redirected, e.g. to main bot
// in bytes - will cut to half that
static volatile int print_log_max = 1024*1024;
static volatile int local_log_max = 100*1024;
static boolean print_silent; // total mute if set
static void print() {
print("");
}
// slightly overblown signature to return original object...
static A print(A o) {
if (print_silent) return o;
String s = String.valueOf(o) + "\n";
StringBuffer loc = local_log;
StringBuffer buf = print_log;
int loc_max = print_log_max;
if (buf != loc && buf != null) {
print_append(buf, s, print_log_max);
loc_max = local_log_max;
}
if (loc != null)
print_append(loc, s, loc_max);
System.out.print(s);
return o;
}
static void print(long l) {
print(String.valueOf(l));
}
static void print(char c) {
print(String.valueOf(c));
}
static void print_append(StringBuffer buf, String s, int max) {
synchronized(buf) {
buf.append(s);
max /= 2;
if (buf.length() > max) try {
int newLength = max/2;
int ofs = buf.length()-newLength;
String newString = buf.substring(ofs);
buf.setLength(0);
buf.append("[...] ").append(newString);
} catch (Exception e) {
buf.setLength(0);
}
}
}
// do not call in ui thread.
// waits until playback done.
static void androidPlayMp3(Activity androidContext, File mp3) {
final MediaPlayer mPlayer = MediaPlayer.create(androidContext, Uri.fromFile(mp3));
final Flag done = new Flag();
mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
mPlayer.release();
done.raise();
}
});
mPlayer.start();
done.waitUntilUp();
}
static File loadBinarySnippet(String snippetID) { try {
long id = parseSnippetID(snippetID);
File f = DiskSnippetCache_getLibrary(id);
if (f == null) {
byte[] data = loadDataSnippetImpl(snippetID);
DiskSnippetCache_putLibrary(id, data);
f = DiskSnippetCache_getLibrary(id);
}
return f;
} catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }}
static Activity androidContext;
static Activity getAndroidContext() {
return androidContext;
}
// Data files are immutable, use centralized cache
public static File DiskSnippetCache_getLibrary(long snippetID) throws IOException {
File file = new File(getGlobalCache(), "data_" + snippetID + ".jar");
return file.exists() ? file : null;
}
public static void DiskSnippetCache_putLibrary(long snippetID, byte[] data) throws IOException {
saveBinaryFile(new File(getGlobalCache(), "data_" + snippetID).getPath() + ".jar", data);
}
static byte[] loadDataSnippetImpl(String snippetID) throws IOException {
byte[] data;
try {
URL url = new URL("http://eyeocr.sourceforge.net/filestore/filestore.php?cmd=serve&file=blob_"
+ parseSnippetID(snippetID) + "&contentType=application/binary");
System.err.println("Loading library: " + url);
try {
data = loadBinaryPage(url.openConnection());
} catch (IOException e) {
data = null;
}
if (data == null || data.length == 0) {
url = new URL("http://data.tinybrain.de/blobs/"
+ parseSnippetID(snippetID));
System.err.println("Loading library: " + url);
data = loadBinaryPage(url.openConnection());
}
System.err.println("Bytes loaded: " + data.length);
} catch (FileNotFoundException e) {
throw new IOException("Binary snippet #" + snippetID + " not found or not public");
}
return data;
}
public static long parseSnippetID(String snippetID) {
long id = Long.parseLong(shortenSnippetID(snippetID));
if (id == 0) throw fail("0 is not a snippet ID");
return id;
}
static byte[] loadBinaryPage(String url) throws IOException {
return loadBinaryPage(new URL(url).openConnection());
}
public static byte[] loadBinaryPage(URLConnection con) throws IOException {
//setHeaders(con);
ByteArrayOutputStream buf = new ByteArrayOutputStream();
InputStream inputStream = con.getInputStream();
int n = 0;
while (true) {
int ch = inputStream.read();
if (ch < 0)
break;
buf.write(ch);
if (++n % 100000 == 0)
System.err.println(" " + n + " bytes loaded.");
}
inputStream.close();
return buf.toByteArray();
}
/** writes safely (to temp file, then rename) */
public static void saveBinaryFile(String fileName, byte[] contents) throws IOException {
File file = new File(fileName);
File parentFile = file.getParentFile();
if (parentFile != null)
parentFile.mkdirs();
String tempFileName = fileName + "_temp";
FileOutputStream fileOutputStream = new FileOutputStream(tempFileName);
fileOutputStream.write(contents);
fileOutputStream.close();
if (file.exists() && !file.delete())
throw new IOException("Can't delete " + fileName);
if (!new File(tempFileName).renameTo(file))
throw new IOException("Can't rename " + tempFileName + " to " + fileName);
}
static void saveBinaryFile(File fileName, byte[] contents) {
try {
saveBinaryFile(fileName.getPath(), contents);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
static RuntimeException fail() {
throw new RuntimeException("fail");
}
static RuntimeException fail(Object msg) {
throw new RuntimeException(String.valueOf(msg));
}
static RuntimeException fail(String msg) {
throw new RuntimeException(unnull(msg));
}
// disabled for now to shorten some programs
/*static RuntimeException fail(S msg, O... args) {
throw new RuntimeException(format(msg, args));
}*/
static File getGlobalCache() {
File file = new File(userHome(), ".tinybrain/snippet-cache");
file.mkdirs();
return file;
}
static String shortenSnippetID(String snippetID) {
if (snippetID.startsWith("#"))
snippetID = snippetID.substring(1);
String httpBlaBla = "http://tinybrain.de/";
if (snippetID.startsWith(httpBlaBla))
snippetID = snippetID.substring(httpBlaBla.length());
return "" + parseLong(snippetID);
}
static String unnull(String s) {
return s == null ? "" : s;
}
static List unnull(List l) {
return l == null ? emptyList() : l;
}
static Object[] unnull(Object[] a) {
return a == null ? new Object[0] : a;
}
static String _userHome;
static String userHome() {
if (_userHome == null) {
if (isAndroid())
_userHome = "/storage/sdcard0/";
else
_userHome = System.getProperty("user.home");
//System.out.println("userHome: " + _userHome);
}
return _userHome;
}
static File userHome(String path) {
return new File(userDir(), path);
}
static long parseLong(String s) {
if (s == null) return 0;
return Long.parseLong(dropSuffix("L", s));
}
static long parseLong(Object s) {
return Long.parseLong((String) s);
}
static String dropSuffix(String suffix, String s) {
return s.endsWith(suffix) ? s.substring(0, l(s)-l(suffix)) : s;
}
static List emptyList() {
return new ArrayList();
//ret Collections.emptyList();
}
static File userDir() {
return new File(userHome());
}
static File userDir(String path) {
return new File(userHome(), path);
}
static boolean isAndroid() { return System.getProperty("java.vendor").toLowerCase().indexOf("android") >= 0; }
static int l(Object[] array) {
return array == null ? 0 : array.length;
}
static int l(byte[] array) {
return array == null ? 0 : array.length;
}
static int l(int[] array) {
return array == null ? 0 : array.length;
}
static int l(char[] array) {
return array == null ? 0 : array.length;
}
static int l(Collection c) {
return c == null ? 0 : c.size();
}
static int l(Map m) {
return m == null ? 0 : m.size();
}
static int l(String s) {
return s == null ? 0 : s.length();
}
static int l(Object o) {
return l((List) o); // incomplete
}
/** this class is fully thread-safe */
static class Flag {
private boolean up;
/** returns true if flag was down before */
public synchronized boolean raise() {
return doRaise();
}
private synchronized boolean doRaise() {
if (!up) {
up = true;
notifyAll();
return true;
} else
return false;
}
public synchronized void waitUntilUp() {
if (!up) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public synchronized void waitUntilUp(long timeout) {
if (!up) {
try {
wait(timeout);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public synchronized boolean isUp() {
return up;
}
public String toString() {
return isUp() ? "up" : "down";
}
// currently does a semi-active wait with latency = 50 ms
public void waitForThisOr(Flag otherFlag) { try {
while (!isUp() && !otherFlag.isUp())
Thread.sleep(50);
} catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }}
}
}