deviceProps = new ArrayList<>();
private int deviceVersion = -1;
private String sDeviceVersion = "???";
private static ADBDevice adbDevice = null;
public static int KEY_HOME = 3;
public static int KEY_BACK = 4;
public static int KEY_MENU = 82;
public static int KEY_POWER = 26;
private ADBDevice() {
}
public static ADBDevice init() {
if (adbDevice == null) {
adbDevice = new ADBDevice();
adbDevice.device = ADBClient.getDevice();
if (adbDevice.device == null) {
adbDevice = null;
} else {
adbDevice.deviceProps = Arrays.asList(adbDevice.exec("getprop").split("\n"));
//[ro.build.version.release]: [6.0.1]
//[ro.product.brand]: [google]
//[ro.product.manufacturer]: [asus]
//[ro.product.model]: [Nexus 7]
//[ro.product.name]: [razor]
//[ro.serialno]: [094da986]
Pattern pProp = Pattern.compile("\\[(.*?)\\]:.*?\\[(.*)\\]");
Matcher mProp = null;
String val = "";
String key = "";
for (String prop : adbDevice.deviceProps) {
if (!prop.startsWith("[ro.")) continue;
mProp = pProp.matcher(prop);
if (mProp.find()) {
key = mProp.group(1);
if (key.contains("build.version.release")) {
val = mProp.group(2);
try {
adbDevice.deviceVersion = Integer.parseInt(val.split("\\.")[0]);
adbDevice.sDeviceVersion = val;
} catch (Exception e) {
}
}
}
}
log(lvl, "init: %s", adbDevice.toString());
}
}
return adbDevice;
}
public static void reset() {
adbDevice = null;
ADBClient.reset();
}
public String toString() {
return String.format("attached device: serial(%s) display(%dx%d) version(%s)",
getDeviceSerial(), getBounds().width, getBounds().height, sDeviceVersion);
}
public ADBRobot getRobot(ADBScreen screen) {
if (robot == null) {
this.screen = screen;
robot = new ADBRobot(screen, this);
}
return robot;
}
public String getDeviceSerial() {
return device.getSerial();
}
public Rectangle getBounds() {
if (devW < 0) {
Dimension dim = getDisplayDimension();
devW = (int) dim.getWidth();
devH = (int) dim.getHeight();
}
return new Rectangle(0, 0, devW, devH);
}
public ScreenImage captureScreen() {
BufferedImage bimg = captureDeviceScreen();
return new ScreenImage(getBounds(), bimg);
}
public ScreenImage captureScreen(Rectangle rect) {
BufferedImage bimg = captureDeviceScreen(rect.x, rect.y, rect.width, rect.height);
return new ScreenImage(rect, bimg);
}
public BufferedImage captureDeviceScreen() {
return captureDeviceScreen(0, 0, devW, devH);
}
public BufferedImage captureDeviceScreen(int y, int _h) {
return captureDeviceScreen(0, y, devW, _h);
}
public BufferedImage captureDeviceScreen(int x, int y, int w, int h) {
Mat matImage = captureDeviceScreenMat(x, y, w, h);
BufferedImage bImage = null;
if (matImage != null) {
bImage = new BufferedImage(matImage.width(), matImage.height(), BufferedImage.TYPE_3BYTE_BGR);
byte[] bImageData = ((DataBufferByte) bImage.getRaster().getDataBuffer()).getData();
matImage.get(0, 0, bImageData);
}
return bImage;
}
public Mat captureDeviceScreenMat(int x, int y, int w, int h) {
byte[] imagePrefix = new byte[12];
byte[] image = new byte[0];
int actW = w;
if (x + w > devW) {
actW = devW - x;
}
int actH = h;
if (y + h > devH) {
actH = devH - y;
}
Debug timer = Debug.startTimer();
try {
InputStream stdout = device.executeShell("screencap");
stdout.read(imagePrefix);
if (imagePrefix[8] != 0x01) {
log(-1, "captureDeviceScreenMat: image type not RGBA");
return null;
}
if (byte2int(imagePrefix, 0, 4) != devW || byte2int(imagePrefix, 4, 4) != devH) {
log(-1, "captureDeviceScreenMat: width or height differ from device values");
return null;
}
image = new byte[actW * actH * 4];
int lenRow = devW * 4;
byte[] row = new byte[lenRow];
for (int count = 0; count < y; count++) {
stdout.read(row);
}
boolean shortRow = x + actW < devW;
for (int count = 0; count < actH; count++) {
if (shortRow) {
stdout.read(row);
System.arraycopy(row, x * 4, image, count * actW * 4, actW * 4);
} else {
stdout.read(image, count * actW * 4, actW * 4);
}
}
long duration = timer.end();
log(lvl, "captureDeviceScreenMat:[%d,%d %dx%d] %d", x, y, actW, actH, duration);
} catch (IOException | JadbException e) {
log(-1, "captureDeviceScreenMat: [%d,%d %dx%d] %s", x, y, actW, actH, e);
}
Mat matOrg = new Mat(actH, actW, CvType.CV_8UC4);
matOrg.put(0, 0, image);
Mat matImage = new Mat();
Imgproc.cvtColor(matOrg, matImage, Imgproc.COLOR_RGBA2BGR, 3);
return matImage;
}
private int byte2int(byte[] bytes, int start, int len) {
int val = 0;
int fact = 1;
for (int i = start; i < start + len; i++) {
int b = bytes[i] & 0xff;
val += b * fact;
fact *= 256;
}
return val;
}
private Dimension getDisplayDimension() {
String dump = dumpsys("display");
String token = "mDefaultViewport= ... deviceWidth=1200, deviceHeight=1920}";
Dimension dim = null;
Pattern displayDimension = Pattern.compile(
"mDefaultViewport.*?=.*?deviceWidth=(\\d*).*?deviceHeight=(\\d*)");
Matcher match = displayDimension.matcher(dump);
if (match.find()) {
int w = Integer.parseInt(match.group(1));
int h = Integer.parseInt(match.group(2));
dim = new Dimension(w, h);
} else {
log(-1, "getDisplayDimension: dumpsys display: token not found: %s", token);
}
return dim;
}
public String exec(String command, String... args) {
InputStream stdout = null;
String out = "";
try {
stdout = device.executeShell(command, args);
out = inputStreamToString(stdout, "UTF-8");
} catch (IOException | JadbException e) {
log(-1, "exec: %s: %s", command, e);
}
return out;
}
public String dumpsys(String component) {
InputStream stdout = null;
String out = "";
try {
if (component == null || component.isEmpty()) {
component = "power";
}
if (component.toLowerCase().contains("all")) {
stdout = device.executeShell("dumpsys");
} else {
stdout = device.executeShell("dumpsys", component);
}
out = inputStreamToString(stdout, "UTF-8");
} catch (IOException | JadbException e) {
log(-1, "dumpsys: %s: %s", component, e);
}
return out;
}
public String printDump(String component) {
String dump = dumpsys(component);
if (!dump.isEmpty()) {
System.out.println("***** Android device dump: " + component);
System.out.println(dump);
}
return dump;
}
public String printDump() {
String dump = dumpsys("all");
if (!dump.isEmpty()) {
File out = new File(RunTime.get().fSikulixStore, "android_dump_" + getDeviceSerial() + ".txt");
System.out.println("***** Android device dump all services");
System.out.println("written to file: " + out.getAbsolutePath());
FileManager.writeStringToFile(dump, out);
}
return dump;
}
private static final int BUFFER_SIZE = 4 * 1024;
private static String inputStreamToString(InputStream inputStream, String charsetName) {
StringBuilder builder = new StringBuilder();
InputStreamReader reader = null;
try {
reader = new InputStreamReader(inputStream, charsetName);
char[] buffer = new char[BUFFER_SIZE];
int length;
while ((length = reader.read(buffer)) != -1) {
builder.append(buffer, 0, length);
}
return builder.toString();
} catch (Exception e) {
return "";
}
}
public void wakeUp(int seconds) {
int times = seconds * 4;
try {
if (null == isDisplayOn()) {
log(-1, "wakeUp: not possible - see log");
return;
}
device.executeShell("input", "keyevent", "26");
while (0 < times--) {
if (isDisplayOn()) {
return;
} else {
RunTime.pause(0.25f);
}
}
} catch (Exception e) {
log(-1, "wakeUp: did not work: %s", e);
}
log(-1, "wakeUp: timeout: %d seconds", seconds);
}
public Boolean isDisplayOn() {
// deviceidle | grep mScreenOn=true|false
// v < 5: power | grep mScreenOn=true|false
// v > 4: power | grep Display Power: state=ON|OFF
String dump = dumpsys("power");
Pattern displayOn = Pattern.compile("mScreenOn=(..)");
String isOn = "tr";
if (deviceVersion > 4) {
displayOn = Pattern.compile("Display Power: state=(..)");
isOn = "ON";
}
Matcher match = displayOn.matcher(dump);
if (match.find()) {
if (match.group(1).contains(isOn)) {
return true;
}
return false;
} else {
log(-1, "isDisplayOn: (Android version %d) dumpsys power: pattern not found: %s", deviceVersion, displayOn);
}
return null;
}
public void inputKeyEvent(int key) {
try {
device.executeShell("input", "keyevent", Integer.toString(key));
} catch (Exception e) {
log(-1, "inputKeyEvent: %d did not work: %s", e.getMessage());
}
}
public void tap(int x, int y) {
try {
device.executeShell("input tap", Integer.toString(x), Integer.toString(y));
} catch (IOException | JadbException e) {
log(-1, "tap: %s", e);
}
}
public void swipe(int x1, int y1, int x2, int y2) {
try {
device.executeShell("input swipe", Integer.toString(x1), Integer.toString(y1),
Integer.toString(x2), Integer.toString(y2));
} catch (IOException | JadbException e) {
log(-1, "swipe: %s", e);
}
}
private String textBuffer = "";
private boolean typing = false;
public synchronized boolean typeStarts() {
if (!typing) {
textBuffer = "";
typing = true;
return true;
}
return false;
}
public synchronized void typeEnds() {
if (typing) {
input(textBuffer);
typing = false;
}
}
public void typeChar(char character) {
if (typing) {
textBuffer += character;
}
}
public static float inputDelay = 0.05f;
public void input(String text) {
try {
device.executeShell("input text ", text);
RunTime.pause(text.length() * inputDelay);
} catch (Exception e) {
log(-1, "input: %s", e);
}
}
}
sikulix-1.1.1/API/src/main/java/org/sikuli/android/ADBRobot.java 0000775 0000000 0000000 00000010426 13157261304 0024225 0 ustar 00root root 0000000 0000000 package org.sikuli.android;
import org.sikuli.basics.Debug;
import org.sikuli.script.*;
import java.awt.*;
import java.awt.image.BufferedImage;
/**
* Created by Törcsi on 2016. 06. 26.
* Revised by RaiMan
*/
public class ADBRobot implements IRobot {
private int mouse_X1 = -1;
private int mouse_Y1 = -1;
private int mouse_X2 = -1;
private int mouse_Y2 = -1;
private boolean mouseDown = false;
private int autodelay = 0;
private boolean waitForIdle = false;
final static int MAX_DELAY = 60000;
private ADBScreen screen;
private ADBDevice device;
public ADBRobot(ADBScreen screen, ADBDevice device) {
this.screen = screen;
this.device = device;
}
private void notSupported(String feature) {
Debug.error("ADBRobot: %s: not supported yet", feature);
}
@Override
public boolean isRemote() {
return true;
}
@Override
public IScreen getScreen() {
return screen;
}
@Override
public void cleanup() {
notSupported("feature");
}
//
@Override
public void keyDown(String keys) {
notSupported("keyDown");
}
@Override
public void keyUp(String keys) {
notSupported("keyUp");
}
@Override
public void keyDown(int code) {
notSupported("keyDown");
}
@Override
public void keyUp(int code) {
notSupported("keyUp");
}
@Override
public void keyUp() {
notSupported("keyUp");
}
@Override
public void pressModifiers(int modifiers) {
if (modifiers != 0) {
notSupported("pressModifiers");
}
}
@Override
public void releaseModifiers(int modifiers) {
if (modifiers != 0) {
notSupported("releaseModifiers");
}
}
@Override
public void typeChar(char character, KeyMode mode) {
if (device == null) {
return;
}
device.typeChar(character);
}
@Override
public void typeKey(int key) {
notSupported("typeKey");
}
@Override
public void typeStarts() {
if (device == null) {
return;
}
while (!device.typeStarts()) {
RunTime.pause(1);
}
}
@Override
public void typeEnds() {
if (device == null) {
return;
}
device.typeEnds();
}
//
@Override
public void mouseMove(int x, int y) {
if (!mouseDown) {
mouse_X1 = x;
mouse_Y1 = y;
} else {
mouse_X2 = x;
mouse_Y2 = y;
}
}
@Override
public void mouseDown(int buttons) {
clickStarts();
}
@Override
public int mouseUp(int buttons) {
clickEnds();
return 0;
}
@Override
public void mouseReset() {
mouseDown = false;
}
@Override
public void clickStarts() {
mouseDown = true;
mouse_X2 = mouse_X1;
mouse_Y2 = mouse_Y1;
}
@Override
public void clickEnds() {
if (device == null) {
return;
}
if (mouseDown) {
mouseDown = false;
if (mouse_X1 == mouse_X2 && mouse_Y1 == mouse_Y2) {
device.tap(mouse_X1, mouse_Y1);
} else {
device.swipe(mouse_X1, mouse_Y1, mouse_X2, mouse_Y2);
}
}
}
//
@Override
public void smoothMove(Location dest) {
mouseMove(dest.x, dest.y);
}
@Override
public void smoothMove(Location src, Location dest, long ms) {
notSupported("smoothMove");
}
@Override
public void mouseWheel(int wheelAmt) {
notSupported("mouseWheel");
}
//
@Override
public ScreenImage captureScreen(Rectangle screenRect) {
if (device == null) {
return null;
}
return device.captureScreen(screenRect);
}
@Override
public Color getColorAt(int x, int y) {
notSupported("getColorAt");
return null;
}
@Override
public void waitForIdle() {
try {
new java.awt.Robot().waitForIdle();
} catch (AWTException e) {
Debug.log(-1, "Error-could non instantiate robot: " + e);
}
}
@Override
public void delay(int ms) {
if (ms < 0) {
ms = 0;
}
if (ms > MAX_DELAY) {
ms = MAX_DELAY;
}
try {
Thread.sleep(ms);
} catch (InterruptedException e) {
Debug.log(-1, "Thread Interrupted: " + e);
}
}
@Override
public void setAutoDelay(int ms) {
if (ms < 0) {
ms = 0;
}
if (ms > MAX_DELAY) {
ms = MAX_DELAY;
}
autodelay = ms;
}
}
sikulix-1.1.1/API/src/main/java/org/sikuli/android/ADBScreen.java 0000775 0000000 0000000 00000012604 13157261304 0024357 0 ustar 00root root 0000000 0000000 package org.sikuli.android;
import org.sikuli.basics.Debug;
import org.sikuli.basics.Settings;
import org.sikuli.script.*;
import org.sikuli.util.*;
import java.awt.*;
/**
* Created by Törcsi on 2016. 06. 26.
* Revised by RaiMan
*/
public class ADBScreen extends Region implements EventObserver, IScreen {
static {
RunTime.loadLibrary("VisionProxy");
}
private static String me = "ADBScreen: ";
private static void log(int level, String message, Object... args) {
Debug.logx(level, me + message, args);
}
private static boolean isFake = false;
protected IRobot robot = null;
private static int logLvl = 3;
private ScreenImage lastScreenImage = null;
private Rectangle bounds;
private boolean waitPrompt = false;
protected OverlayCapturePrompt prompt;
private String promptMsg = "Select a region on the screen";
private static int waitForScreenshot = 300;
public boolean needsUnLock = false;
public int waitAfterAction = 1;
//---------------------------Inits
private ADBDevice device = null;
private static ADBScreen screen = null;
public static ADBScreen start() {
if (screen == null) {
try {
screen = new ADBScreen();
} catch (Exception e) {
log(-1, "start: No devices attached");
screen = null;
}
}
return screen;
}
public static void stop() {
ADBDevice.reset();
screen = null;
}
public ADBScreen() {
super();
setOtherScreen(this);
device = ADBDevice.init();
if (device != null) {
robot = device.getRobot(this);
robot.setAutoDelay(10);
bounds = device.getBounds();
w = bounds.width;
h = bounds.height;
}
}
public boolean isValid() {
return null != device;
}
public ADBDevice getDevice() {
return device;
}
public String toString() {
if (null == device) {
return "ADBScreen: No Android device attached";
} else {
return String.format("ADBScreen: Android device: %s", getDeviceDescription());
}
}
public String getDeviceDescription() {
return String.format("%s (%d x %d)", device.getDeviceSerial(), bounds.width, bounds.height);
}
public void wakeUp(int seconds) {
if (null == device) {
return;
}
if (null == device.isDisplayOn()) {
log(-1, "wakeUp: not possible - see log");
return;
}
if (!device.isDisplayOn()) {
device.wakeUp(seconds);
if (needsUnLock) {
aSwipeUp();
}
}
}
public String exec(String command, String... args) {
if (device == null) {
return null;
}
return device.exec(command, args);
}
//-----------------------------Overrides
@Override
public IScreen getScreen() {
return this;
}
@Override
public void update(EventSubject s) {
waitPrompt = false;
}
@Override
public IRobot getRobot() {
return robot;
}
@Override
public Rectangle getBounds() {
return bounds;
}
@Override
public ScreenImage capture() {
return capture(x, y, w, h);
}
@Override
public ScreenImage capture(int x, int y, int w, int h) {
ScreenImage simg = null;
if (device != null) {
log(logLvl, "ADBScreen.capture: (%d,%d) %dx%d", x, y, w, h);
simg = device.captureScreen(new Rectangle(x, y, w, h));
} else {
log(-1, "capture: no ADBRobot available");
}
lastScreenImage = simg;
return simg;
}
@Override
public ScreenImage capture(Region reg) {
return capture(reg.x, reg.y, reg.w, reg.h);
}
@Override
public ScreenImage capture(Rectangle rect) {
return capture(rect.x, rect.y, rect.width, rect.height);
}
public void showTarget(Location loc) {
showTarget(loc, Settings.SlowMotionDelay);
}
protected void showTarget(Location loc, double secs) {
if (Settings.isShowActions()) {
ScreenHighlighter overlay = new ScreenHighlighter(this, null);
overlay.showTarget(loc, (float) secs);
}
}
@Override
public int getID() {
return 0;
}
public String getIDString() {
return "Android";
}
@Override
public ScreenImage getLastScreenImageFromScreen() {
return lastScreenImage;
}
private EventObserver captureObserver = null;
@Override
public ScreenImage userCapture(final String msg) {
if (robot == null) {
return null;
}
waitPrompt = true;
Thread th = new Thread() {
@Override
public void run() {
prompt = new OverlayCapturePrompt(ADBScreen.this);
prompt.prompt(msg);
}
};
th.start();
boolean hasShot = false;
ScreenImage simg = null;
int count = 0;
while (!hasShot) {
this.wait(0.1f);
if (count++ > waitForScreenshot) {
break;
}
if (prompt == null) {
continue;
}
if (prompt.isComplete()) {
simg = prompt.getSelection();
if (simg != null) {
lastScreenImage = simg;
hasShot = true;
}
prompt.close();
}
}
prompt.close();
prompt = null;
return simg;
}
@Override
public int getIdFromPoint(int srcx, int srcy) {
return 0;
}
public Region newRegion(Location loc, int width, int height) {
return new Region(loc.x, loc.y, width, height, this);
}
public Region newRegion(int _x, int _y, int width, int height) {
return new Region(_x, _y, width, height, this);
}
public Location newLocation(int _x, int _y) {
return new Location(_x, _y).setOtherScreen(this);
}
}
sikulix-1.1.1/API/src/main/java/org/sikuli/android/ADBTest.java 0000664 0000000 0000000 00000006244 13157261304 0024057 0 ustar 00root root 0000000 0000000 /*
* Copyright (c) 2010-2016, Sikuli.org, sikulix.com
* Released under the MIT License.
*
*/
package org.sikuli.android;
import org.sikuli.basics.Debug;
import org.sikuli.script.*;
import org.sikuli.script.Image;
/**
* Created by RaiMan on 12.07.16.
*
* Test for the basic ADB based features
*/
public class ADBTest {
private static int lvl = 3;
private static void log(int level, String message, Object... args) {
Debug.logx(level, "ADBDevice: " + message, args);
}
private static void logp(String message, Object... args) {
System.out.println(String.format(message, args));
}
private static RunTime rt = null;
private static boolean runTests = true;
public static void main(String[] args) throws FindFailed {
ADBScreen aScr = startTest();
if (aScr.isValid()) {
if (runTests) {
basicTest(aScr);
ADBScreen.stop();
System.exit(0);
}
} else {
System.exit(1);
}
// ********* playground
}
private static ADBScreen startTest() {
Debug.on(3);
rt = RunTime.get();
ADBScreen adbs = new ADBScreen();
if (adbs.isValid()) {
adbs.wakeUp(2);
adbs.wait(1f);
if (runTests) {
adbs.aKey(ADBDevice.KEY_HOME);
adbs.wait(1f);
}
}
return adbs;
}
private static void basicTest(ADBScreen adbs) throws FindFailed {
log(lvl, "**************** running basic test");
adbs.aSwipeLeft();
adbs.aSwipeRight();
adbs.wait(1f);
ScreenImage sIMg = adbs.userCapture("Android");
sIMg.save(RunTime.get().fSikulixStore.getAbsolutePath(), "android");
adbs.aTap(new Image(sIMg));
}
/**
* used in SikuliIDE menu tool to run a test against an attached device
*
* @param aScr
*/
public static void ideTest(ADBScreen aScr) {
String title = "Android Support - Testing device";
Sikulix.popup("Take care\n\nthat device is on and unlocked\n\nbefore clicking ok", title);
aScr.wakeUp(2);
aScr.aKey(ADBDevice.KEY_HOME);
if (Sikulix.popAsk("Now the device should show the HOME screen.\n" +
"\nclick YES to proceed watching the test on the device" +
"\nclick NO to end the test now", title)) {
aScr.aSwipeLeft();
aScr.aSwipeRight();
aScr.wait(1f);
if (Sikulix.popAsk("You should have seen a swipe left and a swipe right.\n" +
"\nclick YES to capture an icon from homescreen and then aTap it" +
"\nclick NO to end the test now", title)) {
ScreenImage sIMg = aScr.userCapture("AndroidTest");
sIMg.save(RunTime.get().fSikulixStore.getAbsolutePath(), "android");
try {
aScr.aTap(new Image(sIMg));
Sikulix.popup("The image was found on the device's current screen" +
"\nand should have been tapped.\n" +
"\nIf you think it worked, you can now try\n" +
"to capture needed images from the device.\n" +
"\nYou have to come back here and click Default!", title);
} catch (FindFailed findFailed) {
Sikulix.popError("Sorry, the image you captured was\nnot found on the device's current screen", title);
}
}
}
}
}
sikulix-1.1.1/API/src/main/java/org/sikuli/basics/ 0000775 0000000 0000000 00000000000 13157261304 0021604 5 ustar 00root root 0000000 0000000 sikulix-1.1.1/API/src/main/java/org/sikuli/basics/Animator.java 0000664 0000000 0000000 00000000442 13157261304 0024221 0 ustar 00root root 0000000 0000000 /*
* Copyright (c) 2010-2016, Sikuli.org, sikulix.com
* Released under the MIT License.
*
*/
package org.sikuli.basics;
/**
* INTERNAL USE
* allows to implement timed animations (e.g. mouse move)
*/
public interface Animator {
public float step();
public boolean running();
}
sikulix-1.1.1/API/src/main/java/org/sikuli/basics/AnimatorLinear.java 0000664 0000000 0000000 00000000512 13157261304 0025352 0 ustar 00root root 0000000 0000000 /*
* Copyright (c) 2010-2016, Sikuli.org, sikulix.com
* Released under the MIT License.
*
*/
package org.sikuli.basics;
public class AnimatorLinear extends AnimatorTimeBased {
public AnimatorLinear(float beginVal, float endVal, long totalMS) {
super(new AnimatorLinearInterpolation(beginVal, endVal, totalMS));
}
}
sikulix-1.1.1/API/src/main/java/org/sikuli/basics/AnimatorLinearInterpolation.java 0000664 0000000 0000000 00000001053 13157261304 0030123 0 ustar 00root root 0000000 0000000 /*
* Copyright (c) 2010-2016, Sikuli.org, sikulix.com
* Released under the MIT License.
*
*/
package org.sikuli.basics;
public class AnimatorLinearInterpolation extends AnimatorTimeValueFunction {
float _stepUnit;
public AnimatorLinearInterpolation(float beginVal, float endVal, long totalTime) {
super(beginVal, endVal, totalTime);
_stepUnit = (endVal - beginVal) / (float) totalTime;
}
@Override
public float getValue(long t) {
if (t > _totalTime) {
return _endVal;
}
return _beginVal + _stepUnit * t;
}
}
sikulix-1.1.1/API/src/main/java/org/sikuli/basics/AnimatorOutQuarticEase.java 0000664 0000000 0000000 00000001145 13157261304 0027041 0 ustar 00root root 0000000 0000000 /*
* Copyright (c) 2010-2016, Sikuli.org, sikulix.com
* Released under the MIT License.
*
*/
package org.sikuli.basics;
public class AnimatorOutQuarticEase extends AnimatorTimeValueFunction {
public AnimatorOutQuarticEase(float beginVal, float endVal, long totalTime) {
super(beginVal, endVal, totalTime);
}
@Override
public float getValue(long t) {
if (t > _totalTime) {
return _endVal;
}
double t1 = (double) t / _totalTime;
double t2 = t1 * t1;
return (float) (_beginVal
+ (_endVal - _beginVal) * (-1 * t2 * t2 + 4 * t1 * t2 - 6 * t2 + 4 * t1));
}
}
sikulix-1.1.1/API/src/main/java/org/sikuli/basics/AnimatorPulse.java 0000664 0000000 0000000 00000001663 13157261304 0025240 0 ustar 00root root 0000000 0000000 /*
* Copyright (c) 2010-2016, Sikuli.org, sikulix.com
* Released under the MIT License.
*
*/
package org.sikuli.basics;
import java.util.Date;
public class AnimatorPulse implements Animator {
protected float _v1, _v2;
protected long _interval, _totalMS;
protected boolean _running;
protected long _begin_time = -1;
public AnimatorPulse(float v1, float v2, long interval, long totalMS) {
_v1 = v1;
_v2 = v2;
_interval = interval;
_totalMS = totalMS;
_running = true;
}
@Override
public float step() {
if (_begin_time == -1) {
_begin_time = (new Date()).getTime();
return _v1;
}
long now = (new Date()).getTime();
long delta = now - _begin_time;
if (delta >= _totalMS) {
_running = false;
}
if ((delta / _interval) % 2 == 0) {
return _v1;
} else {
return _v2;
}
}
@Override
public boolean running() {
return _running;
}
}
sikulix-1.1.1/API/src/main/java/org/sikuli/basics/AnimatorQuarticEase.java 0000664 0000000 0000000 00000001035 13157261304 0026347 0 ustar 00root root 0000000 0000000 /*
* Copyright (c) 2010-2016, Sikuli.org, sikulix.com
* Released under the MIT License.
*
*/
package org.sikuli.basics;
public class AnimatorQuarticEase extends AnimatorTimeValueFunction {
public AnimatorQuarticEase(float beginVal, float endVal, long totalTime) {
super(beginVal, endVal, totalTime);
}
@Override
public float getValue(long t) {
if (t > _totalTime) {
return _endVal;
}
double t1 = (double) t / _totalTime;
return (float) (_beginVal + (_endVal - _beginVal) * t1 * t1 * t1 * t1);
}
}
sikulix-1.1.1/API/src/main/java/org/sikuli/basics/AnimatorStopExtention.java 0000664 0000000 0000000 00000001102 13157261304 0026757 0 ustar 00root root 0000000 0000000 /*
* Copyright (c) 2010-2016, Sikuli.org, sikulix.com
* Released under the MIT License.
*
*/
package org.sikuli.basics;
public class AnimatorStopExtention extends AnimatorTimeValueFunction {
AnimatorTimeValueFunction _func;
public AnimatorStopExtention(AnimatorTimeValueFunction func, long totalTime) {
super(func._beginVal, func._endVal, totalTime);
_func = func;
_totalTime = totalTime;
}
@Override
public float getValue(long t) {
return _func.getValue(t);
}
@Override
public boolean isEnd(long t) {
return t >= _totalTime;
}
}
sikulix-1.1.1/API/src/main/java/org/sikuli/basics/AnimatorTimeBased.java 0000664 0000000 0000000 00000001442 13157261304 0026000 0 ustar 00root root 0000000 0000000 /*
* Copyright (c) 2010-2016, Sikuli.org, sikulix.com
* Released under the MIT License.
*
*/
package org.sikuli.basics;
public class AnimatorTimeBased implements Animator {
private long _begin_time;
private boolean _running;
private AnimatorTimeValueFunction _func;
public AnimatorTimeBased(AnimatorTimeValueFunction func) {
_begin_time = -1;
_running = true;
_func = func;
}
@Override
public float step() {
if (_begin_time == -1) {
_begin_time = System.currentTimeMillis();
return _func.getValue(0);
}
long now = System.currentTimeMillis();
long delta = now - _begin_time;
float ret = _func.getValue(delta);
_running = !_func.isEnd(delta);
return ret;
}
@Override
public boolean running() {
return _running;
}
}
sikulix-1.1.1/API/src/main/java/org/sikuli/basics/AnimatorTimeValueFunction.java 0000664 0000000 0000000 00000001007 13157261304 0027541 0 ustar 00root root 0000000 0000000 /*
* Copyright (c) 2010-2016, Sikuli.org, sikulix.com
* Released under the MIT License.
*
*/
package org.sikuli.basics;
public abstract class AnimatorTimeValueFunction {
protected float _beginVal, _endVal;
protected long _totalTime;
public AnimatorTimeValueFunction(float beginVal, float endVal, long totalTime) {
_beginVal = beginVal;
_endVal = endVal;
_totalTime = totalTime;
}
public boolean isEnd(long t) {
return t >= _totalTime;
}
abstract public float getValue(long t);
}
sikulix-1.1.1/API/src/main/java/org/sikuli/basics/Debug.java 0000664 0000000 0000000 00000064736 13157261304 0023515 0 ustar 00root root 0000000 0000000 /*
* Copyright (c) 2010-2016, Sikuli.org, sikulix.com
* Released under the MIT License.
*
*/
package org.sikuli.basics;
import java.io.FileNotFoundException;
import java.io.PrintStream;
import java.lang.reflect.Method;
import java.text.DateFormat;
import java.util.Arrays;
import java.util.Date;
import org.sikuli.util.JythonHelper;
/**
* Debug is a utility class that wraps println statements and allows more or less command line
* output to be turned on.
For debug messages only ( Debug.log() ):
Use system
* property: sikuli.Debug to set the debug level (default = 1)
On the command line, use
* -Dsikuli.Debug=n to set it to level n
-Dsikuli.Debug will disable any debug messages
* (which is equivalent to using Settings.Debuglogs = false)
It prints if the level
* number is less than or equal to the currently set DEBUG_LEVEL.
For messages
* ActionLogs, InfoLogs see Settings
You might send all messages generated by this
* class to a file:
-Dsikuli.Logfile=pathname (no path given: SikuliLog.txt in working
* folder)
This can be restricted to Debug.user only (others go to System.out):
* -Dsikuli.LogfileUser=pathname (no path given: UserLog.txt in working folder)
*
* You might redirect info, action, error and debug messages to your own logger object
* Start with setLogger() and then define with setLoggerXyz() the redirection targets
*
* This solution is NOT threadsafe !!!
*/
public class Debug {
private static int DEBUG_LEVEL = 0;
private static boolean loggerRedirectSupported = true;
public static boolean shouldLogJython = false;
private long _beginTime = 0;
private String _message;
private String _title = null;
private static PrintStream printout = null;
private static PrintStream printoutuser = null;
private static final DateFormat df =
DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM);
public static String logfile;
private static Object privateLogger = null;
private static boolean privateLoggerPrefixAll = true;
private static Method privateLoggerUser = null;
private static String privateLoggerUserName = "";
private static String privateLoggerUserPrefix = "";
private static Method privateLoggerInfo = null;
private static String privateLoggerInfoName = "";
private static final String infoPrefix = "info";
private static String privateLoggerInfoPrefix = "[" + infoPrefix + "] ";
private static Method privateLoggerAction = null;
private static String privateLoggerActionName = "";
private static final String actionPrefix = "log";
private static String privateLoggerActionPrefix = "[" + actionPrefix + "] ";
private static Method privateLoggerError = null;
private static String privateLoggerErrorName = "";
private static final String errorPrefix = "error";
private static String privateLoggerErrorPrefix = "[" + errorPrefix + "] ";
private static Method privateLoggerDebug = null;
private static String privateLoggerDebugName = "";
private static final String debugPrefix = "debug";
private static String privateLoggerDebugPrefix = "";
private static boolean isJython;
private static boolean isJRuby;
private static Object scriptRunner = null;
private static boolean searchHighlight = false;
private static PrintStream redirectedOut = null, redirectedErr = null;
static {
String debug = System.getProperty("sikuli.Debug");
if (debug != null && "".equals(debug)) {
DEBUG_LEVEL = 0;
Settings.DebugLogs = false;
} else {
try {
DEBUG_LEVEL = Integer.parseInt(debug);
if (DEBUG_LEVEL > 0) {
Settings.DebugLogs = true;
} else {
Settings.DebugLogs = false;
}
} catch (NumberFormatException numberFormatException) {
}
}
setLogFile(null);
setUserLogFile(null);
}
public static void init() {
if (DEBUG_LEVEL > 0) {
logx(DEBUG_LEVEL, "Debug.init: from sikuli.Debug: on: %d", DEBUG_LEVEL);
}
}
public static void highlightOn() {
searchHighlight = true;
Settings.Highlight = true;
}
public static void highlightOff() {
searchHighlight = false;
Settings.Highlight = false;
}
public static boolean shouldHighlight() {
return searchHighlight;
}
/**
* A logger object that is intended, to get Sikuli's log messages per redirection
* @param logger the logger object
*/
public static void setLogger(Object logger) {
if (!doSetLogger(logger)) return;
privateLoggerPrefixAll = true;
logx(3, "Debug: setLogger %s", logger);
}
/**
* same as setLogger(), but the Sikuli prefixes are omitted in all redirected messages
* @param logger the logger object
*/
public static void setLoggerNoPrefix(Object logger) {
if (!doSetLogger(logger)) return;
privateLoggerPrefixAll = false;
}
private static boolean doSetLogger(Object logger) {
String className = logger.getClass().getName();
isJython = className.contains("org.python");
isJRuby = className.contains("org.jruby");
if ( isJRuby ) {
logx(3, "Debug: setLogger: given instance's class: %s", className);
error("setLogger: not yet supported in JRuby script");
loggerRedirectSupported=false;
return false;
}
privateLogger = logger;
return true;
}
/**
* sets the redirection for all message types user, info, action, error and debug
* must be the name of an instance method of the previously defined logger and
* must accept exactly one string parameter, that contains the message text
* @param mAll name of the method where the message should be sent
* @return true if the method is available false otherwise */
public static boolean setLoggerAll(String mAll) {
if (!loggerRedirectSupported) {
logx(3, "Debug: setLoggerAll: logger redirect not supported");
return false;
}
if (privateLogger != null) {
logx(3, "Debug.setLoggerAll: %s", mAll);
boolean success = true;
success &= setLoggerUser(mAll);
success &= setLoggerInfo(mAll);
success &= setLoggerAction(mAll);
success &= setLoggerError(mAll);
success &= setLoggerDebug(mAll);
return success;
}
return false;
}
private static boolean doSetLoggerCallback(String mName, CallbackType type) {
if (privateLogger == null) {
error("Debug: setLogger: no logger specified yet");
return false;
}
if (!loggerRedirectSupported) {
logx(3, "Debug: setLogger: %s (%s) logger redirect not supported", mName, type);
}
if (isJython) {
Object[] args = new Object[]{privateLogger, mName, type.toString()};
if (!JythonHelper.get().checkCallback(args)) {
logx(3, "Debug: setLogger: Jython: checkCallback returned: %s", args[0]);
return false;
}
}
try {
if (type == CallbackType.INFO) {
if ( !isJython && !isJRuby ) {
privateLoggerInfo = privateLogger.getClass().getMethod(mName, new Class[]{String.class});
}
privateLoggerInfoName = mName;
return true;
} else if (type == CallbackType.ACTION) {
if ( !isJython && !isJRuby ) {
privateLoggerAction = privateLogger.getClass().getMethod(mName, new Class[]{String.class});
}
privateLoggerActionName = mName;
return true;
} else if (type == CallbackType.ERROR) {
if ( !isJython && !isJRuby ) {
privateLoggerError = privateLogger.getClass().getMethod(mName, new Class[]{String.class});
}
privateLoggerErrorName = mName;
return true;
} else if (type == CallbackType.DEBUG) {
if ( !isJython && !isJRuby ) {
privateLoggerDebug = privateLogger.getClass().getMethod(mName, new Class[]{String.class});
}
privateLoggerDebugName = mName;
return true;
} else if (type == CallbackType.USER) {
if ( !isJython && !isJRuby ) {
privateLoggerUser = privateLogger.getClass().getMethod(mName, new Class[]{String.class});
}
privateLoggerUserName = mName;
return true;
} else {
return false;
}
} catch (Exception e) {
error("Debug: setLoggerInfo: redirecting to %s failed: \n%s", mName, e.getMessage());
}
return false;
}
/**
* specify the target method for redirection of Sikuli's user log messages [user]
* must be the name of an instance method of the previously defined logger and
* must accept exactly one string parameter, that contains the info message
* @param mUser name of the method where the message should be sent
*
reset to default logging by either null or empty string
* @return true if the method is available false otherwise
*/
public static boolean setLoggerUser(String mUser) {
if (mUser == null || mUser.isEmpty()) {
privateLoggerUserName = "";
return true;
}
return doSetLoggerCallback(mUser, CallbackType.USER);
}
/**
* specify the target method for redirection of Sikuli's info messages [info]
* must be the name of an instance method of the previously defined logger and
* must accept exactly one string parameter, that contains the info message
* @param mInfo name of the method where the message should be sent
*
reset to default logging by either null or empty string
* @return true if the method is available false otherwise
*/
public static boolean setLoggerInfo(String mInfo) {
if (mInfo == null || mInfo.isEmpty()) {
privateLoggerInfoName = "";
return true;
}
return doSetLoggerCallback(mInfo, CallbackType.INFO);
}
/**
* specify the target method for redirection of Sikuli's action messages [log]
* must be the name of an instance method of the previously defined logger and
* must accept exactly one string parameter, that contains the info message
* @param mAction name of the method where the message should be sent
*
reset to default logging by either null or empty string
* @return true if the method is available false otherwise
*/
public static boolean setLoggerAction(String mAction) {
if (mAction == null || mAction.isEmpty()) {
privateLoggerActionName = "";
return true;
}
return doSetLoggerCallback(mAction, CallbackType.ACTION);
}
/**
* specify the target method for redirection of Sikuli's error messages [error]
* must be the name of an instance method of the previously defined logger and
* must accept exactly one string parameter, that contains the info message
* @param mError name of the method where the message should be sent
*
reset to default logging by either null or empty string
* @return true if the method is available false otherwise
*/
public static boolean setLoggerError(String mError) {
if (mError == null || mError.isEmpty()) {
privateLoggerErrorName = "";
return true;
}
return doSetLoggerCallback(mError, CallbackType.ERROR);
}
/**
* specify the target method for redirection of Sikuli's debug messages [debug]
* must be the name of an instance method of the previously defined logger and
* must accept exactly one string parameter, that contains the info message
* @param mDebug name of the method where the message should be sent
*
reset to default logging by either null or empty string
* @return true if the method is available false otherwise
*/
public static boolean setLoggerDebug(String mDebug) {
if (mDebug == null || mDebug.isEmpty()) {
privateLoggerDebugName = "";
return true;
}
return doSetLoggerCallback(mDebug, CallbackType.DEBUG);
}
public static void saveRedirected(PrintStream rdo, PrintStream rde) {
redirectedOut = rdo;
redirectedErr = rde;
}
public static void out(String msg) {
if (redirectedOut != null && DEBUG_LEVEL > 2) {
redirectedOut.println(msg);
}
}
/**
* specify, where the logs should be written:
* null - use from property sikuli.Logfile
* empty - use SikuliLog.txt in working folder
* not empty - use given filename
* @param fileName null, empty or absolute filename
* @return success
*/
public static boolean setLogFile(String fileName) {
if (fileName == null) {
fileName = System.getProperty("sikuli.Logfile");
}
if (fileName != null) {
if ("".equals(fileName)) {
if (Settings.isMacApp) {
fileName = "SikulixLog.txt";
} else {
fileName = FileManager.slashify(System.getProperty("user.dir"), true) + "SikulixLog.txt";
}
}
try {
logfile = fileName;
if (printout != null) {
printout.close();
}
printout = new PrintStream(fileName);
log(3, "Debug: setLogFile: " + fileName);
return true;
} catch (Exception ex) {
System.out.printf("[Error] Logfile %s not accessible - check given path", fileName);
System.out.println();
return false;
}
}
return false;
}
/**
* does Sikuli log go to a file?
* @return true if yes, false otherwise
*/
public static boolean isLogToFile() {
return (printout != null);
}
/**
* specify, where the user logs (Debug.user) should be written:
* null - use from property sikuli.LogfileUser
* empty - use UserLog.txt in working folder
* not empty - use given filename
* @param fileName null, empty or absolute filename
* @return success
*/
public static boolean setUserLogFile(String fileName) {
if (fileName == null) {
fileName = System.getProperty("sikuli.LogfileUser");
}
if (fileName != null) {
if ("".equals(fileName)) {
if (Settings.isMacApp) {
fileName = "UserLog.txt";
} else {
fileName = FileManager.slashify(System.getProperty("user.dir"), true) + "UserLog.txt";
}
}
try {
if (printoutuser != null) {
printoutuser.close();
}
printoutuser = new PrintStream(fileName);
log(3, "Debug: setLogFile: " + fileName);
return true;
} catch (FileNotFoundException ex) {
System.out.printf("[Error] User logfile %s not accessible - check given path", fileName);
System.out.println();
return false;
}
}
return false;
}
/**
* does user log go to a file?
* @return true if yes, false otherwise
*/
public static boolean isUserLogToFile() {
return (printoutuser != null);
}
/**
*
* @return current debug level
*/
public static int getDebugLevel() {
return DEBUG_LEVEL;
}
/**
* set debug level to default level
*
* @return default level
*/
public static int setDebugLevel() {
setDebugLevel(0);
return DEBUG_LEVEL;
}
/**
* set debug level to given value
*
* @param level value
*/
public static void setDebugLevel(int level) {
DEBUG_LEVEL = level;
if (DEBUG_LEVEL > 0) {
Settings.DebugLogs = true;
} else {
Settings.DebugLogs = false;
}
}
public static void on(int level) {
setDebugLevel(level);
}
public static void on(String level) {
setDebugLevel(level);
}
public static boolean is(int level) {
return DEBUG_LEVEL >= level;
}
public static int is() {
return DEBUG_LEVEL;
}
public static void off() {
setDebugLevel(0);
}
/**
* set debug level to given number value as string (ignored if invalid)
*
* @param level valid number string
*/
public static void setDebugLevel(String level) {
try {
DEBUG_LEVEL = Integer.parseInt(level);
if (DEBUG_LEVEL > 0) {
Settings.DebugLogs = true;
} else {
Settings.DebugLogs = false;
}
} catch (NumberFormatException e) {
}
}
private static boolean doRedirect(CallbackType type, String pre, String message, Object... args) {
boolean success = false;
String error = "";
if (privateLogger != null) {
String prefix = "", pln = "";
Method plf = null;
if (type == CallbackType.INFO && !privateLoggerInfoName.isEmpty()) {
prefix = privateLoggerPrefixAll ? privateLoggerInfoPrefix : "";
plf = privateLoggerInfo;
pln = privateLoggerInfoName;
} else if (type == CallbackType.ACTION && !privateLoggerActionName.isEmpty()) {
prefix = privateLoggerPrefixAll ? privateLoggerActionPrefix : "";
plf = privateLoggerAction;
pln = privateLoggerActionName;
} else if (type == CallbackType.ERROR && !privateLoggerErrorName.isEmpty()) {
prefix = privateLoggerPrefixAll ? privateLoggerErrorPrefix : "";
plf = privateLoggerError;
pln = privateLoggerErrorName;
} else if (type == CallbackType.DEBUG && !privateLoggerDebugName.isEmpty()) {
prefix = privateLoggerPrefixAll ?
(privateLoggerDebugPrefix.isEmpty() ? pre : privateLoggerDebugPrefix) : "";
plf = privateLoggerDebug;
pln = privateLoggerDebugName;
} else if (type == CallbackType.USER && !privateLoggerUserName.isEmpty()) {
prefix = privateLoggerPrefixAll ?
(privateLoggerUserPrefix.isEmpty() ? pre : privateLoggerUserPrefix) : "";
plf = privateLoggerUser;
pln = privateLoggerUserName;
}
if (!pln.isEmpty()) {
String msg = null;
if (args == null) {
msg = prefix + message;
} else {
msg = String.format(prefix + message, args);
}
if (isJython) {
success = JythonHelper.get().runLoggerCallback(new Object[]{privateLogger, pln, msg});
} else if (isJRuby) {
success = false;
} else {
try {
plf.invoke(privateLogger,
new Object[]{msg});
return true;
} catch (Exception e) {
error = ": " + e.getMessage();
success = false;
}
}
if (!success) {
Debug.error("calling (%s) logger.%s failed - resetting to default%s", type, pln, error);
if (type == CallbackType.INFO) {
privateLoggerInfoName = "";
} else if (type == CallbackType.ACTION) {
privateLoggerActionName = "";
} else if (type == CallbackType.ERROR) {
privateLoggerErrorName = "";
} else if (type == CallbackType.DEBUG) {
privateLoggerDebugName = "";
} else if (type == CallbackType.USER) {
privateLoggerUserName = "";
}
}
}
}
return success;
}
/**
* Sikuli messages from actions like click, ...
switch on/off: Settings.ActionLogs
*
* @param message String or format string (String.format)
* @param args to use with format string
*/
public static void action(String message, Object... args) {
if (Settings.ActionLogs) {
if (doRedirect(CallbackType.ACTION, "", message, args)) {
return;
}
if (is(3)) {
logx(3, message, args);
} else {
log(-1, actionPrefix, message, args);
}
}
}
/**
* use Debug.action() instead
* @param message String or format string (String.format)
* @param args to use with format string
* @deprecated
*/
@Deprecated
public static void history(String message, Object... args) {
action(message, args);
}
/**
* informative Sikuli messages
switch on/off: Settings.InfoLogs
*
* @param message String or format string (String.format)
* @param args to use with format string
*/
public static void info(String message, Object... args) {
if (Settings.InfoLogs) {
if (doRedirect(CallbackType.INFO, "", message, args)) {
return;
}
log(-1, infoPrefix, message, args);
}
if (is(3)) {
logx(3, message, args);
}
}
/**
* Sikuli error messages
switch on/off: always on
*
* @param message String or format string (String.format)
* @param args to use with format string
*/
public static void error(String message, Object... args) {
if (doRedirect(CallbackType.ERROR, "", message, args)) {
return;
}
log(-1, errorPrefix, message, args);
}
/**
* Sikuli messages to use in tests
switch on/off: always on
*
* @param message String or format string (String.format)
* @param args to use with format string
*/
public static void test(String message, Object... args) {
if (message.contains("#returned#")) {
message = message.replace("#returned#", "returned: " +
((Boolean) args[0] ? "true" : "false"));
args = Arrays.copyOfRange(args, 1, args.length);
}
log(-1, "test", message, args);
}
/**
* Sikuli debug messages with default level
switch on/off: Settings.DebugLogs (off) and/or
* -Dsikuli.Debug
*
* @param message String or format string (String.format)
* @param args to use with format string
*/
public static void log(String message, Object... args) {
log(0, message, args);
}
public static boolean logJython() {
return logJython(null);
}
public static boolean logJython(Boolean state) {
if (null != state) {
shouldLogJython = state;
}
return shouldLogJython;
}
public static void logj(String message, Object... args) {
if (shouldLogJython) {
log(0, "Jython: " + message, args);
}
}
/**
* messages given by the user
switch on/off: Settings.UserLogs
depending on
* Settings.UserLogTime, the prefix contains a timestamp
the user prefix (default "user")
* can be set: Settings,UserLogPrefix
*
* @param message String or format string (String.format)
* @param args to use with format string
*/
public static void user(String message, Object... args) {
if (Settings.UserLogs) {
if (Settings.UserLogTime) {
//TODO replace the hack -99 to filter user logs
log(-99, String.format("%s (%s)",
Settings.UserLogPrefix, df.format(new Date())), message, args);
} else {
log(-99, String.format("%s", Settings.UserLogPrefix), message, args);
}
}
}
/**
* Sikuli debug messages with level
switch on/off: Settings.DebugLogs (off) and/or
* -Dsikuli.Debug
*
* @param level value
* @param message String or format string (String.format)
* @param args to use with format string
*/
public static void log(int level, String message, Object... args) {
if (Settings.DebugLogs) {
log(level, debugPrefix, message, args);
}
}
/**
* INTERNAL USE: special debug messages
* @param level value
* @param message text or format string
* @param args for use with format string
* @return generated message
*/
public static String logx(int level, String message, Object... args) {
String sout = "";
if (level == -1 || level == -100) {
sout = log(level, errorPrefix, message, args);
} else if (level == -2) {
sout = log(level, actionPrefix, message, args);
} else if (level == -3) {
sout = log(level, "", message, args);
} else {
sout = log(level, debugPrefix, message, args);
}
return sout;
}
public static String logp(String msg, Object... args) {
String out = String.format(msg, args);
System.out.println(out);
return out;
}
private static synchronized String log(int level, String prefix, String message, Object... args) {
//TODO replace the hack -99 to filter user logs
String sout = "";
String stime = "";
if (level <= DEBUG_LEVEL) {
if (level == 3) {
if (message.startsWith("TRACE: ")) {
if (!Settings.TraceLogs) {
return "";
}
}
}
if (Settings.LogTime && level != -99) {
stime = String.format(" (%s)", df.format(new Date()));
}
if (!prefix.isEmpty()) {
prefix = "[" + prefix + stime + "] ";
}
sout = String.format(message, args);
boolean isRedirected = false;
if (level > -99) {
isRedirected = doRedirect(CallbackType.DEBUG, prefix, sout, null);
} else if (level == -99) {
isRedirected = doRedirect(CallbackType.USER, prefix, sout, null);
}
if (!isRedirected) {
if (level == -99 && printoutuser != null) {
printoutuser.print(prefix + sout);
printoutuser.println();
} else if (printout != null) {
printout.print(prefix + sout);
printout.println();
} else {
System.out.print(prefix + sout);
System.out.println();
}
if (level == -1 || level == -100 || level > 2) {
out(prefix + sout);
}
}
}
return prefix + sout;
}
/**
* Sikuli profiling messages
switch on/off: Settings.ProfileLogs, default off
*
* @param message String or format string
* @param args to use with format string
*/
public static void profile(String message, Object... args) {
if (Settings.ProfileLogs) {
log(-1, "profile", message, args);
}
}
/**
* profile convenience: entering a method
* @param message String or format string
* @param args to use with format string
*/
public static void enter(String message, Object... args) {
profile("entering: " + message, args);
}
/**
* profile convenience: exiting a method
* @param message String or format string
* @param args to use with format string
*/
public static void exit(String message, Object... args) {
profile("exiting: " + message, args);
}
/**
* start timer
*
log output depends on Settings.ProfileLogs
* @return timer
*/
public static Debug startTimer() {
return startTimer("");
}
/**
* start timer with a message
*
log output depends on Settings.ProfileLogs
* @param message String or format string
* @param args to use with format string
* @return timer
*/
public static Debug startTimer(String message, Object... args) {
Debug timer = new Debug();
timer.startTiming(message, args);
return timer;
}
/**
* stop timer and print timer message
*
log output depends on Settings.ProfileLogs
*
* @return the time in msec
*/
public long end() {
if (_title == null) {
return endTiming(_message, false, new Object[0]);
} else {
return endTiming(_title, false, new Object[0]);
}
}
/**
* lap timer and print message with timer message
*
log output depends on Settings.ProfileLogs
*
* @param message String or format string
* @return the time in msec
*/
public long lap(String message) {
if (_title == null) {
return endTiming("(" + message + ") " + _message, true, new Object[0]);
} else {
return endTiming("(" + message + ") " + _title, true, new Object[0]);
}
}
private void startTiming(String message, Object... args) {
int pos;
if ((pos = message.indexOf("\t")) < 0) {
_title = null;
_message = message;
} else {
_title = message.substring(0, pos);
_message = message.replace("\t", " ");
}
if (!"".equals(_message)) {
profile("TStart: " + _message, args);
}
_beginTime = (new Date()).getTime();
}
private long endTiming(String message, boolean isLap, Object... args) {
if (_beginTime == 0) {
profile("TError: timer not started (%s)", message);
return -1;
}
long t = (new Date()).getTime();
long dt = t - _beginTime;
if (!isLap) {
_beginTime = 0;
}
if (!"".equals(message)) {
profile(String.format((isLap ? "TLap:" : "TEnd") +
" (%.3f sec): ", (float) dt / 1000) + message, args);
}
return dt;
}
private static enum CallbackType {
INFO, ACTION, ERROR, DEBUG, USER;
}
}
sikulix-1.1.1/API/src/main/java/org/sikuli/basics/ExtensionManager.java 0000664 0000000 0000000 00000011134 13157261304 0025716 0 ustar 00root root 0000000 0000000 /*
* Copyright (c) 2010-2016, Sikuli.org, sikulix.com
* Released under the MIT License.
*
*/
package org.sikuli.basics;
import org.sikuli.script.RunTime;
import java.io.*;
import java.net.URL;
import java.util.ArrayList;
import java.util.regex.Pattern;
public class ExtensionManager {
private static ExtensionManager _instance = null;
private ArrayList extensions;
private ExtensionManager() {
extensions = new ArrayList();
Extension e;
String p, n, v;
File dir = new File(Settings.getUserExtPath());
for (File d : dir.listFiles()) {
if (d.getAbsolutePath().endsWith(".jar")) {
p = d.getAbsolutePath();
n = d.getName();
n = n.substring(0, n.length()-4);
if (n.contains("-")) {
v = n.substring(n.lastIndexOf("-")+1);
n = n.substring(0, n.lastIndexOf("-"));
} else {
v = "0.0";
}
e = new Extension(n, p, v);
extensions.add(e);
}
}
}
public static ExtensionManager getInstance() {
if (_instance == null) {
_instance = new ExtensionManager();
}
return _instance;
}
public boolean install(String name, String url, String version) {
if (url.startsWith("---extensions---")) {
url = RunTime.get().SikuliRepo + name + "-" + version + ".jar";
}
String extPath = Settings.getUserExtPath();
String tmpdir = RunTime.get().fpBaseTempPath;
try {
File localFile = new File(FileManager.downloadURL(new URL(url), tmpdir));
String extName = localFile.getName();
File targetFile = new File(extPath, extName);
if (targetFile.exists()) {
targetFile.delete();
}
if (!localFile.renameTo(targetFile)) {
Debug.error("ExtensionManager: Failed to install " + localFile.getName() + " to " + targetFile.getAbsolutePath());
return false;
}
addExtension(name, localFile.getAbsolutePath(), version);
} catch (IOException e) {
Debug.error("ExtensionManager: Failed to download " + url);
return false;
}
return true;
}
private void addExtension(String name, String path, String version) {
Extension e = find(name, version);
if (e == null) {
extensions.add(new Extension(name, path, version));
} else {
e.path = path;
}
}
public boolean isInstalled(String name) {
if (find(name) != null) {
return true;
}
else {
return false;
}
}
public String getLoadPath(String name) {
Extension e = find(name);
if (e != null) {
Debug.log(2, "ExtensionManager: found: "+ name + " ( " + e.version + " )");
return e.path;
}
else {
if (!name.endsWith(".jar")) {
Debug.error("ExtensionManager: not found: "+ name );
}
return null;
}
}
public boolean isOutOfDate(String name, String version) {
Extension e = find(name);
if (e == null) {
return false;
} else {
String s1 = normalisedVersion(e.version); // installed version
String s2 = normalisedVersion(version); // version number to check
int cmp = s1.compareTo(s2);
return cmp < 0;
}
}
public String getVersion(String name) {
Extension e = find(name);
if (e != null) {
return e.version;
} else {
return null;
}
}
private Extension find(String name) {
if (name.endsWith(".jar")) {
name = name.substring(0, name.length()-4);
}
String v;
if (name.contains("-")) {
v = name.substring(name.lastIndexOf("-")+1);
return find(name.substring(0, name.lastIndexOf("-")), v);
} else {
v = normalisedVersion("0.0");
}
Extension ext = null;
for (Extension e : extensions) {
if (e.name.equals(name)) {
if (v.compareTo(normalisedVersion(e.version)) <= 0) {
ext = e;
v = normalisedVersion(e.version);
}
}
}
return ext;
}
private Extension find(String name, String version) {
String v = normalisedVersion(version);
for (Extension e : extensions) {
if (e.name.equals(name) && normalisedVersion(e.version).equals(v)) {
return e;
}
}
return null;
}
private static String normalisedVersion(String version) {
return normalisedVersion(version, ".", 4);
}
private static String normalisedVersion(String version, String sep, int maxWidth) {
String[] split = Pattern.compile(sep, Pattern.LITERAL).split(version);
StringBuilder sb = new StringBuilder();
for (String s : split) {
sb.append(String.format("%" + maxWidth + 's', s));
}
return sb.toString();
}
}
class Extension implements Serializable {
public String name, path, version;
public Extension(String name_, String path_, String version_) {
name = name_;
path = path_;
version = version_;
}
}
sikulix-1.1.1/API/src/main/java/org/sikuli/basics/FileManager.java 0000664 0000000 0000000 00000132650 13157261304 0024630 0 ustar 00root root 0000000 0000000 /*
* Copyright (c) 2010-2016, Sikuli.org, sikulix.com
* Released under the MIT License.
*
*/
package org.sikuli.basics;
import org.sikuli.script.RunTime;
import java.awt.Desktop;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.MalformedURLException;
import java.net.Proxy;
import java.net.URL;
import java.net.URLDecoder;
import java.net.UnknownHostException;
import java.nio.charset.Charset;
import java.security.CodeSource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Random;
import java.util.Set;
import java.util.jar.JarOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import org.sikuli.script.Image;
import org.sikuli.script.ImagePath;
import org.sikuli.script.Sikulix;
/**
* INTERNAL USE: Support for accessing files and other ressources
*/
public class FileManager {
private static String me = "FileManager";
private static int lvl = 3;
private static void log(int level, String message, Object... args) {
Debug.logx(level, me + ": " + message, args);
}
static final int DOWNLOAD_BUFFER_SIZE = 153600;
private static SplashFrame _progress = null;
private static final String EXECUTABLE = "#executable";
public static int tryGetFileSize(URL aUrl) {
HttpURLConnection conn = null;
try {
if (getProxy() != null) {
conn = (HttpURLConnection) aUrl.openConnection(getProxy());
} else {
conn = (HttpURLConnection) aUrl.openConnection();
}
conn.setConnectTimeout(30000);
conn.setReadTimeout(30000);
conn.setRequestMethod("HEAD");
conn.getInputStream();
return conn.getContentLength();
} catch (Exception ex) {
return 0;
} finally {
if (conn != null) {
conn.disconnect();
}
}
}
public static int isUrlUseabel(String sURL) {
try {
return isUrlUseabel(new URL(sURL));
} catch (Exception ex) {
return -1;
}
}
public static int isUrlUseabel(URL aURL) {
HttpURLConnection conn = null;
try {
// HttpURLConnection.setFollowRedirects(false);
if (getProxy() != null) {
conn = (HttpURLConnection) aURL.openConnection(getProxy());
} else {
conn = (HttpURLConnection) aURL.openConnection();
}
// con.setInstanceFollowRedirects(false);
conn.setRequestMethod("HEAD");
int retval = conn.getResponseCode();
// HttpURLConnection.HTTP_BAD_METHOD 405
// HttpURLConnection.HTTP_NOT_FOUND 404
if (retval == HttpURLConnection.HTTP_OK) {
return 1;
} else if (retval == HttpURLConnection.HTTP_NOT_FOUND) {
return 0;
} else if (retval == HttpURLConnection.HTTP_FORBIDDEN) {
return 0;
} else {
return -1;
}
} catch (Exception ex) {
return -1;
} finally {
if (conn != null) {
conn.disconnect();
}
}
}
public static Proxy getProxy() {
Proxy proxy = Settings.proxy;
if (!Settings.proxyChecked) {
String phost = Settings.proxyName;
String padr = Settings.proxyIP;
String pport = Settings.proxyPort;
InetAddress a = null;
int p = -1;
if (phost != null) {
a = getProxyAddress(phost);
}
if (a == null && padr != null) {
a = getProxyAddress(padr);
}
if (a != null && pport != null) {
p = getProxyPort(pport);
}
if (a != null && p > 1024) {
proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(a, p));
log(lvl, "Proxy defined: %s : %d", a.getHostAddress(), p);
}
Settings.proxyChecked = true;
Settings.proxy = proxy;
}
return proxy;
}
public static boolean setProxy(String pName, String pPort) {
InetAddress a = null;
String host = null;
String adr = null;
int p = -1;
if (pName != null) {
a = getProxyAddress(pName);
if (a == null) {
a = getProxyAddress(pName);
if (a != null) {
adr = pName;
}
} else {
host = pName;
}
}
if (a != null && pPort != null) {
p = getProxyPort(pPort);
}
if (a != null && p > 1024) {
log(lvl, "Proxy stored: %s : %d", a.getHostAddress(), p);
Settings.proxyChecked = true;
Settings.proxyName = host;
Settings.proxyIP = adr;
Settings.proxyPort = pPort;
Settings.proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(a, p));
PreferencesUser prefs = PreferencesUser.getInstance();
prefs.put("ProxyName", (host == null ? "" : host));
prefs.put("ProxyIP", (adr == null ? "" : adr));
prefs.put("ProxyPort", ""+p);
return true;
}
return false;
}
/**
* download a file at the given url to a local folder
*
* @param url a valid url
* @param localPath the folder where the file should go (will be created if necessary)
* @return the absolute path to the downloaded file or null on any error
*/
public static String downloadURL(URL url, String localPath) {
String[] path = url.getPath().split("/");
String filename = path[path.length - 1];
String targetPath = null;
int srcLength = 1;
int srcLengthKB = 0;
int done;
int totalBytesRead = 0;
File fullpath = new File(localPath);
if (fullpath.exists()) {
if (fullpath.isFile()) {
log(-1, "download: target path must be a folder:\n%s", localPath);
fullpath = null;
}
} else {
if (!fullpath.mkdirs()) {
log(-1, "download: could not create target folder:\n%s", localPath);
fullpath = null;
}
}
if (fullpath != null) {
srcLength = tryGetFileSize(url);
srcLengthKB = (int) (srcLength / 1024);
if (srcLength > 0) {
log(lvl, "Downloading %s having %d KB", filename, srcLengthKB);
} else {
log(lvl, "Downloading %s with unknown size", filename);
}
fullpath = new File(localPath, filename);
targetPath = fullpath.getAbsolutePath();
done = 0;
if (_progress != null) {
_progress.setProFile(filename);
_progress.setProSize(srcLengthKB);
_progress.setProDone(0);
_progress.setVisible(true);
}
InputStream reader = null;
FileOutputStream writer = null;
try {
writer = new FileOutputStream(fullpath);
if (getProxy() != null) {
reader = url.openConnection(getProxy()).getInputStream();
} else {
reader = url.openConnection().getInputStream();
}
byte[] buffer = new byte[DOWNLOAD_BUFFER_SIZE];
int bytesRead = 0;
long begin_t = (new Date()).getTime();
long chunk = (new Date()).getTime();
while ((bytesRead = reader.read(buffer)) > 0) {
writer.write(buffer, 0, bytesRead);
totalBytesRead += bytesRead;
if (srcLength > 0) {
done = (int) ((totalBytesRead / (double) srcLength) * 100);
} else {
done = (int) (totalBytesRead / 1024);
}
if (((new Date()).getTime() - chunk) > 1000) {
if (_progress != null) {
_progress.setProDone(done);
}
chunk = (new Date()).getTime();
}
}
writer.close();
log(lvl, "downloaded %d KB to:\n%s", (int) (totalBytesRead / 1024), targetPath);
log(lvl, "download time: %d", (int) (((new Date()).getTime() - begin_t) / 1000));
} catch (Exception ex) {
log(-1, "problems while downloading\n%s", ex);
targetPath = null;
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException ex) {
}
}
if (writer != null) {
try {
writer.close();
} catch (IOException ex) {
}
}
}
if (_progress != null) {
if (targetPath == null) {
_progress.setProDone(-1);
} else {
if (srcLength <= 0) {
_progress.setProSize((int) (totalBytesRead / 1024));
}
_progress.setProDone(100);
}
_progress.closeAfter(3);
_progress = null;
}
}
if (targetPath == null) {
fullpath.delete();
}
return targetPath;
}
/**
* download a file at the given url to a local folder
*
* @param url a string representing a valid url
* @param localPath the folder where the file should go (will be created if necessary)
* @return the absolute path to the downloaded file or null on any error
*/
public static String downloadURL(String url, String localPath) {
URL urlSrc = null;
try {
urlSrc = new URL(url);
} catch (MalformedURLException ex) {
log(-1, "download: bad URL: " + url);
return null;
}
return downloadURL(urlSrc, localPath);
}
public static String downloadURL(String url, String localPath, JFrame progress) {
_progress = (SplashFrame) progress;
return downloadURL(url, localPath);
}
public static String downloadURLtoString(String src) {
URL url = null;
try {
url = new URL(src);
} catch (MalformedURLException ex) {
log(-1, "download to string: bad URL:\n%s", src);
return null;
}
return downloadURLtoString(url);
}
public static String downloadURLtoString(URL uSrc) {
String content = "";
InputStream reader = null;
log(lvl, "download to string from:\n%s,", uSrc);
try {
if (getProxy() != null) {
reader = uSrc.openConnection(getProxy()).getInputStream();
} else {
reader = uSrc.openConnection().getInputStream();
}
byte[] buffer = new byte[DOWNLOAD_BUFFER_SIZE];
int bytesRead = 0;
while ((bytesRead = reader.read(buffer)) > 0) {
content += (new String(Arrays.copyOfRange(buffer, 0, bytesRead), Charset.forName("utf-8")));
}
} catch (Exception ex) {
log(-1, "problems while downloading\n" + ex.getMessage());
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException ex) {
}
}
}
return content;
}
/**
* open the given url in the standard browser
*
* @param url string representing a valid url
* @return false on error, true otherwise
*/
public static boolean openURL(String url) {
try {
URL u = new URL(url);
Desktop.getDesktop().browse(u.toURI());
} catch (Exception ex) {
log(-1, "show in browser: bad URL: " + url);
return false;
}
return true;
}
public static File createTempDir(String path) {
File fTempDir = new File(RunTime.get().fpBaseTempPath, path);
log(lvl, "createTempDir:\n%s", fTempDir);
if (!fTempDir.exists()) {
fTempDir.mkdirs();
} else {
FileManager.resetFolder(fTempDir);
}
if (!fTempDir.exists()) {
log(-1, "createTempDir: not possible: %s", fTempDir);
return null;
}
return fTempDir;
}
public static File createTempDir() {
File fTempDir = createTempDir("tmp-" + getRandomInt() + ".sikuli");
if (null != fTempDir) {
fTempDir.deleteOnExit();
}
return fTempDir;
}
public static int getRandomInt() {
int rand = 1 + new Random().nextInt();
return (rand < 0 ? rand * -1 : rand);
}
public static void deleteTempDir(String path) {
if (!deleteFileOrFolder(path)) {
log(-1, "deleteTempDir: not possible");
}
}
public static boolean deleteFileOrFolder(File fPath, FileFilter filter) {
return doDeleteFileOrFolder(fPath, filter);
}
public static boolean deleteFileOrFolder(File fPath) {
return doDeleteFileOrFolder(fPath, null);
}
public static boolean deleteFileOrFolder(String fpPath, FileFilter filter) {
if (fpPath.startsWith("#")) {
fpPath = fpPath.substring(1);
} else {
log(lvl, "deleteFileOrFolder: %s\n%s", (filter == null ? "" : "filtered: "), fpPath);
}
return doDeleteFileOrFolder(new File(fpPath), filter);
}
public static boolean deleteFileOrFolder(String fpPath) {
if (fpPath.startsWith("#")) {
fpPath = fpPath.substring(1);
} else {
log(lvl, "deleteFileOrFolder:\n%s", fpPath);
}
return doDeleteFileOrFolder(new File(fpPath), null);
}
public static void resetFolder(File fPath) {
log(lvl, "resetFolder:\n%s", fPath);
doDeleteFileOrFolder(fPath, null);
fPath.mkdirs();
}
private static boolean doDeleteFileOrFolder(File fPath, FileFilter filter) {
if (fPath == null) {
return false;
}
File aFile;
String[] entries;
boolean somethingLeft = false;
if (fPath.exists() && fPath.isDirectory()) {
entries = fPath.list();
for (int i = 0; i < entries.length; i++) {
aFile = new File(fPath, entries[i]);
if (filter != null && !filter.accept(aFile)) {
somethingLeft = true;
continue;
}
if (aFile.isDirectory()) {
if (!doDeleteFileOrFolder(aFile, filter)) {
return false;
}
} else {
try {
aFile.delete();
} catch (Exception ex) {
log(-1, "deleteFile: not deleted:\n%s\n%s", aFile, ex);
return false;
}
}
}
}
// deletes intermediate empty directories and finally the top now empty dir
if (!somethingLeft && fPath.exists()) {
try {
fPath.delete();
} catch (Exception ex) {
log(-1, "deleteFolder: not deleted:\n" + fPath.getAbsolutePath() + "\n" + ex.getMessage());
return false;
}
}
return true;
}
public static void traverseFolder(File fPath, FileFilter filter) {
if (fPath == null) {
return;
}
File aFile;
String[] entries;
if (fPath.isDirectory()) {
entries = fPath.list();
for (int i = 0; i < entries.length; i++) {
aFile = new File(fPath, entries[i]);
if (filter != null) {
filter.accept(aFile);
}
if (aFile.isDirectory()) {
traverseFolder(aFile, filter);
}
}
}
}
public static File createTempFile(String suffix) {
return createTempFile(suffix, null);
}
public static File createTempFile(String suffix, String path) {
String temp1 = "sikuli-";
String temp2 = "." + suffix;
File fpath = new File(RunTime.get().fpBaseTempPath);
if (path != null) {
fpath = new File(path);
}
try {
fpath.mkdirs();
File temp = File.createTempFile(temp1, temp2, fpath);
temp.deleteOnExit();
String fpTemp = temp.getAbsolutePath();
if (!fpTemp.endsWith(".script")) {
log(lvl, "tempfile create:\n%s", temp.getAbsolutePath());
}
return temp;
} catch (IOException ex) {
log(-1, "createTempFile: IOException: %s\n%s", ex.getMessage(),
fpath + File.separator + temp1 + "12....56" + temp2);
return null;
}
}
public static String saveTmpImage(BufferedImage img) {
return saveTmpImage(img, null);
}
public static String saveTmpImage(BufferedImage img, String path) {
File tempFile;
try {
tempFile = createTempFile("png", path);
if (tempFile != null) {
ImageIO.write(img, "png", tempFile);
return tempFile.getAbsolutePath();
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public static String saveTimedImage(BufferedImage img) {
return saveTimedImage(img, ImagePath.getBundlePath(), null);
}
public static String saveTimedImage(BufferedImage img, String path) {
return saveTimedImage(img, path, null);
}
public static String saveTimedImage(BufferedImage img, String path, String name) {
RunTime.pause(0.01f);
File fImage = new File(path, String.format("%s-%d.png", name, new Date().getTime()));
try {
ImageIO.write(img, "png", fImage);
} catch (Exception ex) {
return "";
}
return fImage.getAbsolutePath();
}
public static boolean unzip(String inpZip, String target) {
return unzip(new File(inpZip), new File(target));
}
public static boolean unzip(File fZip, File fTarget) {
String fpZip = null;
String fpTarget = null;
log(lvl, "unzip: from: %s\nto: %s", fZip, fTarget);
try {
fpZip = fZip.getCanonicalPath();
if (!new File(fpZip).exists()) {
throw new IOException();
}
} catch (IOException ex) {
log(-1, "unzip: source not found:\n%s\n%s", fpZip, ex);
return false;
}
try {
fpTarget = fTarget.getCanonicalPath();
deleteFileOrFolder(fpTarget);
new File(fpTarget).mkdirs();
if (!new File(fpTarget).exists()) {
throw new IOException();
}
} catch (IOException ex) {
log(-1, "unzip: target cannot be created:\n%s\n%s", fpTarget, ex);
return false;
}
ZipInputStream inpZip = null;
ZipEntry entry = null;
try {
final int BUF_SIZE = 2048;
inpZip = new ZipInputStream(new BufferedInputStream(new FileInputStream(fZip)));
while ((entry = inpZip.getNextEntry()) != null) {
if (entry.getName().endsWith("/") || entry.getName().endsWith("\\")) {
new File(fpTarget, entry.getName()).mkdir();
continue;
}
int count;
byte data[] = new byte[BUF_SIZE];
File outFile = new File(fpTarget, entry.getName());
File outFileParent = outFile.getParentFile();
if (! outFileParent.exists()) {
outFileParent.mkdirs();
}
FileOutputStream fos = new FileOutputStream(outFile);
BufferedOutputStream dest = new BufferedOutputStream(fos, BUF_SIZE);
while ((count = inpZip.read(data, 0, BUF_SIZE)) != -1) {
dest.write(data, 0, count);
}
dest.close();
}
} catch (Exception ex) {
log(-1, "unzip: not possible: source:\n%s\ntarget:\n%s\n(%s)%s",
fpZip, fpTarget, entry.getName(), ex);
return false;
} finally {
try {
inpZip.close();
} catch (IOException ex) {
log(-1, "unzip: closing source:\n%s\n%s", fpZip, ex);
}
}
return true;
}
public static boolean xcopy(File fSrc, File fDest) {
if (fSrc == null || fDest == null) {
return false;
}
try {
doXcopy(fSrc, fDest, null);
} catch (Exception ex) {
log(lvl, "xcopy from: %s\nto: %s\n%s", fSrc, fDest, ex);
return false;
}
return true;
}
public static boolean xcopy(File fSrc, File fDest, FileFilter filter) {
if (fSrc == null || fDest == null) {
return false;
}
try {
doXcopy(fSrc, fDest, filter);
} catch (Exception ex) {
log(lvl, "xcopy from: %s\nto: %s\n%s", fSrc, fDest, ex);
return false;
}
return true;
}
public static void xcopy(String src, String dest) throws IOException {
doXcopy(new File(src), new File(dest), null);
}
public static void xcopy(String src, String dest, FileFilter filter) throws IOException {
doXcopy(new File(src), new File(dest), filter);
}
private static void doXcopy(File fSrc, File fDest, FileFilter filter) throws IOException {
if (fSrc.getAbsolutePath().equals(fDest.getAbsolutePath())) {
return;
}
if (fSrc.isDirectory()) {
if (filter == null || filter.accept(fSrc)) {
if (!fDest.exists()) {
fDest.mkdirs();
}
String[] children = fSrc.list();
for (String child : children) {
if (child.equals(fDest.getName())) {
continue;
}
doXcopy(new File(fSrc, child), new File(fDest, child), filter);
}
}
} else {
if (filter == null || filter.accept(fSrc)) {
if (fDest.isDirectory()) {
fDest = new File(fDest, fSrc.getName());
}
InputStream in = new FileInputStream(fSrc);
OutputStream out = new FileOutputStream(fDest);
// Copy the bits from instream to outstream
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
}
}
}
private static String makeFileListString;
private static String makeFileListPrefix;
public static String makeFileList(File path, String prefix) {
makeFileListPrefix = prefix;
return makeFileListDo(path, true);
}
private static String makeFileListDo(File path, boolean starting) {
String x;
if (starting) {
makeFileListString = "";
}
if (!path.exists()) {
return makeFileListString;
}
if (path.isDirectory()) {
String[] fcl = path.list();
for (String fc : fcl) {
makeFileListDo(new File(path, fc), false);
}
} else {
x = path.getAbsolutePath();
if (!makeFileListPrefix.isEmpty()) {
x = x.replace(makeFileListPrefix, "").replace("\\", "/");
if (x.startsWith("/")) {
x = x.substring(1);
}
}
makeFileListString += x + "\n";
}
return makeFileListString;
}
/**
* Copy a file *src* to the path *dest* and check if the file name conflicts. If a file with the
* same name exists in that path, rename *src* to an alternative name.
* @param src source file
* @param dest destination path
* @return the destination file if ok, null otherwise
* @throws java.io.IOException on failure
*/
public static File smartCopy(String src, String dest) throws IOException {
File fSrc = new File(src);
String newName = fSrc.getName();
File fDest = new File(dest, newName);
if (fSrc.equals(fDest)) {
return fDest;
}
while (fDest.exists()) {
newName = getAltFilename(newName);
fDest = new File(dest, newName);
}
xcopy(src, fDest.getAbsolutePath());
if (fDest.exists()) {
return fDest;
}
return null;
}
public static String convertStreamToString(InputStream is) {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line;
try {
while ((line = reader.readLine()) != null) {
sb.append(line).append("\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return sb.toString();
}
public static String getAltFilename(String filename) {
int pDot = filename.lastIndexOf('.');
int pDash = filename.lastIndexOf('-');
int ver = 1;
String postfix = filename.substring(pDot);
String name;
if (pDash >= 0) {
name = filename.substring(0, pDash);
ver = Integer.parseInt(filename.substring(pDash + 1, pDot));
ver++;
} else {
name = filename.substring(0, pDot);
}
return name + "-" + ver + postfix;
}
public static boolean exists(String path) {
File f = new File(path);
return f.exists();
}
public static void mkdir(String path) {
File f = new File(path);
if (!f.exists()) {
f.mkdirs();
}
}
public static String getName(String filename) {
File f = new File(filename);
return f.getName();
}
public static String slashify(String path, Boolean isDirectory) {
if (path != null) {
if (path.contains("%")) {
try {
path = URLDecoder.decode(path, "UTF-8");
} catch (Exception ex) {
log(lvl, "slashify: decoding problem with %s\nwarning: filename might not be useable.", path);
}
}
if (File.separatorChar != '/') {
path = path.replace(File.separatorChar, '/');
}
if (isDirectory != null) {
if (isDirectory) {
if (!path.endsWith("/")) {
path = path + "/";
}
} else if (path.endsWith("/")) {
path = path.substring(0, path.length() - 1);
}
}
if (path.startsWith("./")) {
path = path.substring(2);
}
return path;
} else {
return "";
}
}
public static String normalize(String filename) {
return slashify(filename, false);
}
public static String normalizeAbsolute(String filename, boolean withTrailingSlash) {
filename = slashify(filename, false);
String jarSuffix = "";
int nJarSuffix;
if (-1 < (nJarSuffix = filename.indexOf(".jar!/"))) {
jarSuffix = filename.substring(nJarSuffix + 4);
filename = filename.substring(0, nJarSuffix + 4);
}
File aFile = new File(filename);
try {
filename = aFile.getCanonicalPath();
aFile = new File(filename);
} catch (Exception ex) {
}
String fpFile = aFile.getAbsolutePath();
if (!fpFile.startsWith("/")) {
fpFile = "/" + fpFile;
}
return slashify(fpFile + jarSuffix, withTrailingSlash);
}
public static boolean isFilenameDotted(String name) {
String nameParent = new File(name).getParent();
if (nameParent != null && nameParent.contains(".")) {
return true;
}
return false;
}
/**
* Returns the directory that contains the images used by the ScriptRunner.
*
* @param scriptFile The file containing the script.
* @return The directory containing the images.
*/
public static File resolveImagePath(File scriptFile) {
if (!scriptFile.isDirectory()) {
return scriptFile.getParentFile();
}
return scriptFile;
}
public static URL makeURL(String fName) {
return makeURL(fName, "file");
}
public static URL makeURL(String fName, String type) {
try {
if ("file".equals(type)) {
fName = normalizeAbsolute(fName, false);
if (!fName.startsWith("/")) {
fName = "/" + fName;
}
}
if ("jar".equals(type)) {
if (!fName.contains("!/")) {
fName += "!/";
}
return new URL("jar:" + fName);
} else if ("file".equals(type)) {
File aFile = new File(fName);
if (aFile.exists() && aFile.isDirectory()) {
if (!fName.endsWith("/")) {
fName += "/";
}
}
}
return new URL(type, null, fName);
} catch (MalformedURLException ex) {
return null;
}
}
public static URL makeURL(URL path, String fName) {
try {
if ("file".equals(path.getProtocol())) {
return makeURL(new File(path.getFile(), fName).getAbsolutePath());
} else if ("jar".equals(path.getProtocol())) {
String jp = path.getPath();
if (!jp.contains("!/")) {
jp += "!/";
}
String jpu = "jar:" + jp;
if (jp.endsWith("!/")) {
jpu += fName;
} else {
jpu += "/" + fName;
}
return new URL(jpu);
}
return new URL(path, slashify(fName, false));
} catch (MalformedURLException ex) {
return null;
}
}
public static URL getURLForContentFromURL(URL uRes, String fName) {
URL aURL = null;
if ("jar".equals(uRes.getProtocol())) {
return makeURL(uRes, fName);
} else if ("file".equals(uRes.getProtocol())) {
aURL = makeURL(new File(slashify(uRes.getPath(), false), slashify(fName, false)).getPath(), uRes.getProtocol());
} else if (uRes.getProtocol().startsWith("http")) {
String sRes = uRes.toString();
if (!sRes.endsWith("/")) {
sRes += "/";
}
try {
aURL = new URL(sRes + fName);
if (1 == isUrlUseabel(aURL)) {
return aURL;
} else {
return null;
}
} catch (MalformedURLException ex) {
return null;
}
}
try {
if (aURL != null) {
aURL.getContent();
return aURL;
}
} catch (IOException ex) {
return null;
}
return aURL;
}
public static boolean checkJarContent(String jarPath, String jarContent) {
URL jpu = makeURL(jarPath, "jar");
if (jpu != null && jarContent != null) {
jpu = makeURL(jpu, jarContent);
}
if (jpu != null) {
try {
jpu.getContent();
return true;
} catch (IOException ex) {
ex.getMessage();
}
}
return false;
}
public static int getPort(String p) {
int port;
int pDefault = 50000;
if (p != null) {
try {
port = Integer.parseInt(p);
} catch (NumberFormatException ex) {
return -1;
}
} else {
return pDefault;
}
if (port < 1024) {
port += pDefault;
}
return port;
}
public static int getProxyPort(String p) {
int port;
int pDefault = 8080;
if (p != null) {
try {
port = Integer.parseInt(p);
} catch (NumberFormatException ex) {
return -1;
}
} else {
return pDefault;
}
return port;
}
public static String getAddress(String arg) {
try {
if (arg == null) {
return InetAddress.getLocalHost().getHostAddress();
}
return InetAddress.getByName(arg).getHostAddress();
} catch (UnknownHostException ex) {
return null;
}
}
public static InetAddress getProxyAddress(String arg) {
try {
return InetAddress.getByName(arg);
} catch (UnknownHostException ex) {
return null;
}
}
public static String saveImage(BufferedImage img, String sImage, String bundlePath) {
final int MAX_ALT_NUM = 3;
String fullpath = bundlePath;
File fBundle = new File(fullpath);
if (!fBundle.exists()) {
fBundle.mkdir();
}
if (!sImage.endsWith(".png")) {
sImage += ".png";
}
File fImage = new File(fBundle, sImage);
boolean shouldReload = false;
int count = 0;
String msg = fImage.getName() + " exists - using ";
while (count < MAX_ALT_NUM) {
if (fImage.exists()) {
if (Settings.OverwriteImages) {
shouldReload = true;
break;
} else {
fImage = new File(fBundle, FileManager.getAltFilename(fImage.getName()));
}
} else {
if (count > 0) {
Debug.log(msg + fImage.getName() + " (Utils.saveImage)");
}
break;
}
count++;
}
if (count >= MAX_ALT_NUM) {
fImage = new File(fBundle, Settings.getTimestamp() + ".png");
Debug.log(msg + fImage.getName() + " (Utils.saveImage)");
}
String fpImage = fImage.getAbsolutePath();
fpImage = fpImage.replaceAll("\\\\", "/");
try {
ImageIO.write(img, "png", new File(fpImage));
} catch (IOException e) {
Debug.error("Util.saveImage: Problem trying to save image file: %s\n%s", fpImage, e.getMessage());
return null;
}
if (shouldReload) {
Image.reload(sImage);
}
return fpImage;
}
//TODO consolidate with FileManager and Settings
public static void deleteNotUsedImages(String bundle, Set usedImages) {
File scriptFolder = new File(bundle);
if (!scriptFolder.isDirectory()) {
return;
}
String path;
for (File image : scriptFolder.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
if ((name.endsWith(".png") || name.endsWith(".jpg") || name.endsWith(".jpeg"))) {
if (!name.startsWith("_")) {
return true;
}
}
return false;
}
})) {
if (!usedImages.contains(image.getName())) {
Debug.log(3, "FileManager: delete not used: %s", image.getName());
image.delete();
}
}
}
public static boolean isBundle(String dir) {
return dir.endsWith(".sikuli");
}
// public static IResourceLoader getNativeLoader(String name, String[] args) {
// if (nativeLoader != null) {
// return nativeLoader;
// }
// IResourceLoader nl = null;
// ServiceLoader loader = ServiceLoader.load(IResourceLoader.class);
// Iterator resourceLoaderIterator = loader.iterator();
// while (resourceLoaderIterator.hasNext()) {
// IResourceLoader currentLoader = resourceLoaderIterator.next();
// if ((name != null && currentLoader.getName().toLowerCase().equals(name.toLowerCase()))) {
// nl = currentLoader;
// nl.init(args);
// break;
// }
// }
// if (nl == null) {
// log0(-1, "Fatal error 121: Could not load any NativeLoader!");
// (121);
// } else {
// nativeLoader = nl;
// }
// return nativeLoader;
// }
//
public static String getJarParentFolder() {
CodeSource src = FileManager.class.getProtectionDomain().getCodeSource();
String jarParentPath = "--- not known ---";
String RunningFromJar = "Y";
if (src.getLocation() != null) {
String jarPath = src.getLocation().getPath();
if (!jarPath.endsWith(".jar")) RunningFromJar = "N";
jarParentPath = FileManager.slashify((new File(jarPath)).getParent(), true);
} else {
log(-1, "Fatal Error 101: Not possible to access the jar files!");
Sikulix.terminate(101);
}
return RunningFromJar + jarParentPath;
}
public static String getJarPath(Class cname) {
CodeSource src = cname.getProtectionDomain().getCodeSource();
if (src.getLocation() != null) {
return new File(src.getLocation().getPath()).getAbsolutePath();
}
return "";
}
public static String getJarName(Class cname) {
String jp = getJarPath(cname);
if (jp.isEmpty()) {
return "";
}
return new File(jp).getName();
}
public static boolean writeStringToFile(String text, String path) {
return writeStringToFile(text, new File(path));
}
public static boolean writeStringToFile(String text, File fPath) {
PrintStream out = null;
try {
out = new PrintStream(new FileOutputStream(fPath));
out.print(text);
} catch (Exception e) {
log(-1,"writeStringToFile: did not work: " + fPath + "\n" + e.getMessage());
}
if (out != null) {
out.close();
return true;
}
return false;
}
public static String readFileToString(File fPath) {
try {
return doRreadFileToString(fPath);
} catch (Exception ex) {
return "";
}
}
private static String doRreadFileToString(File fPath) throws IOException {
StringBuilder result = new StringBuilder();
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(fPath));
char[] buf = new char[1024];
int r = 0;
while ((r = reader.read(buf)) != -1) {
result.append(buf, 0, r);
}
} finally {
if (reader != null) {
reader.close();
}
}
return result.toString();
}
public static boolean packJar(String folderName, String jarName, String prefix) {
jarName = FileManager.slashify(jarName, false);
if (!jarName.endsWith(".jar")) {
jarName += ".jar";
}
folderName = FileManager.slashify(folderName, true);
if (!(new File(folderName)).isDirectory()) {
log(-1, "packJar: not a directory or does not exist: " + folderName);
return false;
}
try {
File dir = new File((new File(jarName)).getAbsolutePath()).getParentFile();
if (dir != null) {
if (!dir.exists()) {
dir.mkdirs();
}
} else {
throw new Exception("workdir is null");
}
log(lvl, "packJar: %s from %s in workDir %s", jarName, folderName, dir.getAbsolutePath());
if (!folderName.startsWith("http://") && !folderName.startsWith("https://")) {
folderName = "file://" + (new File(folderName)).getAbsolutePath();
}
URL src = new URL(folderName);
JarOutputStream jout = new JarOutputStream(new FileOutputStream(jarName));
addToJar(jout, new File(src.getFile()), prefix);
jout.close();
} catch (Exception ex) {
log(-1, "packJar: " + ex.getMessage());
return false;
}
log(lvl, "packJar: completed");
return true;
}
public static boolean buildJar(String targetJar, String[] jars,
String[] files, String[] prefixs, FileManager.JarFileFilter filter) {
boolean logShort = false;
if (targetJar.startsWith("#")) {
logShort = true;
targetJar = targetJar.substring(1);
log(lvl, "buildJar: %s", new File(targetJar).getName());
} else {
log(lvl, "buildJar:\n%s", targetJar);
}
try {
JarOutputStream jout = new JarOutputStream(new FileOutputStream(targetJar));
ArrayList done = new ArrayList();
for (int i = 0; i < jars.length; i++) {
if (jars[i] == null) {
continue;
}
if (logShort) {
log(lvl, "buildJar: adding: %s", new File(jars[i]).getName());
} else {
log(lvl, "buildJar: adding:\n%s", jars[i]);
}
BufferedInputStream bin = new BufferedInputStream(new FileInputStream(jars[i]));
ZipInputStream zin = new ZipInputStream(bin);
for (ZipEntry zipentry = zin.getNextEntry(); zipentry != null; zipentry = zin.getNextEntry()) {
if (filter == null || filter.accept(zipentry, jars[i])) {
if (!done.contains(zipentry.getName())) {
jout.putNextEntry(zipentry);
if (!zipentry.isDirectory()) {
bufferedWrite(zin, jout);
}
done.add(zipentry.getName());
log(lvl+1, "adding: %s", zipentry.getName());
}
}
}
zin.close();
bin.close();
}
if (files != null) {
for (int i = 0; i < files.length; i++) {
if (files[i] == null) {
continue;
}
if (logShort) {
log(lvl, "buildJar: adding %s at %s", new File(files[i]).getName(), prefixs[i]);
} else {
log(lvl, "buildJar: adding %s at %s", files[i], prefixs[i]);
}
addToJar(jout, new File(files[i]), prefixs[i]);
}
}
jout.close();
} catch (Exception ex) {
log(-1, "buildJar: %s", ex);
return false;
}
log(lvl, "buildJar: completed");
return true;
}
/**
* unpack a jar file to a folder
* @param jarName absolute path to jar file
* @param folderName absolute path to the target folder
* @param del true if the folder should be deleted before unpack
* @param strip true if the path should be stripped
* @param filter to select specific content
* @return true if success, false otherwise
*/
public static boolean unpackJar(String jarName, String folderName, boolean del, boolean strip,
FileManager.JarFileFilter filter) {
jarName = FileManager.slashify(jarName, false);
if (!jarName.endsWith(".jar")) {
jarName += ".jar";
}
if (!new File(jarName).isAbsolute()) {
log(-1, "unpackJar: jar path not absolute");
return false;
}
if (folderName == null) {
folderName = jarName.substring(0, jarName.length() - 4);
} else if (!new File(folderName).isAbsolute()) {
log(-1, "unpackJar: folder path not absolute");
return false;
}
folderName = FileManager.slashify(folderName, true);
ZipInputStream in;
BufferedOutputStream out;
try {
if (del) {
FileManager.deleteFileOrFolder(folderName);
}
in = new ZipInputStream(new BufferedInputStream(new FileInputStream(jarName)));
log(lvl, "unpackJar: %s to %s", jarName, folderName);
boolean isExecutable;
int n;
File f;
for (ZipEntry z = in.getNextEntry(); z != null; z = in.getNextEntry()) {
if (filter == null || filter.accept(z, null)) {
if (z.isDirectory()) {
(new File(folderName, z.getName())).mkdirs();
} else {
n = z.getName().lastIndexOf(EXECUTABLE);
if (n >= 0) {
f = new File(folderName, z.getName().substring(0, n));
isExecutable = true;
} else {
f = new File(folderName, z.getName());
isExecutable = false;
}
if (strip) {
f = new File(folderName, f.getName());
} else {
f.getParentFile().mkdirs();
}
out = new BufferedOutputStream(new FileOutputStream(f));
bufferedWrite(in, out);
out.close();
if (isExecutable) {
f.setExecutable(true, false);
}
}
}
}
in.close();
} catch (Exception ex) {
log(-1, "unpackJar: " + ex.getMessage());
return false;
}
log(lvl, "unpackJar: completed");
return true;
}
private static void addToJar(JarOutputStream jar, File dir, String prefix) throws IOException {
File[] content;
prefix = prefix == null ? "" : prefix;
if (dir.isDirectory()) {
content = dir.listFiles();
for (int i = 0, l = content.length; i < l; ++i) {
if (content[i].isDirectory()) {
jar.putNextEntry(new ZipEntry(prefix + (prefix.equals("") ? "" : "/") + content[i].getName() + "/"));
addToJar(jar, content[i], prefix + (prefix.equals("") ? "" : "/") + content[i].getName());
} else {
addToJarWriteFile(jar, content[i], prefix);
}
}
} else {
addToJarWriteFile(jar, dir, prefix);
}
}
private static void addToJarWriteFile(JarOutputStream jar, File file, String prefix) throws IOException {
if (file.getName().startsWith(".")) {
return;
}
String suffix = "";
//TODO buildjar: suffix EXECUTABL
// if (file.canExecute()) {
// suffix = EXECUTABLE;
// }
jar.putNextEntry(new ZipEntry(prefix + (prefix.equals("") ? "" : "/") + file.getName() + suffix));
FileInputStream in = new FileInputStream(file);
bufferedWrite(in, jar);
in.close();
}
public static File[] getScriptFile(File fScriptFolder) {
if (fScriptFolder == null) {
return null;
}
String scriptName;
String scriptType = "";
String fpUnzippedSkl = null;
File[] content = null;
if (fScriptFolder.getName().endsWith(".skl") || fScriptFolder.getName().endsWith(".zip")) {
fpUnzippedSkl = FileManager.unzipSKL(fScriptFolder.getAbsolutePath());
if (fpUnzippedSkl == null) {
return null;
}
scriptType = "sikuli-zipped";
fScriptFolder = new File(fpUnzippedSkl);
}
int pos = fScriptFolder.getName().lastIndexOf(".");
if (pos == -1) {
scriptName = fScriptFolder.getName();
scriptType = "sikuli-plain";
} else {
scriptName = fScriptFolder.getName().substring(0, pos);
scriptType = fScriptFolder.getName().substring(pos + 1);
}
boolean success = true;
if (!fScriptFolder.exists()) {
if ("sikuli-plain".equals(scriptType)) {
fScriptFolder = new File(fScriptFolder.getAbsolutePath() + ".sikuli");
if (!fScriptFolder.exists()) {
success = false;
}
} else {
success = false;
}
}
if (!success) {
log(-1, "Not a valid Sikuli script project:\n%s", fScriptFolder.getAbsolutePath());
return null;
}
if (scriptType.startsWith("sikuli")) {
content = fScriptFolder.listFiles(new FileFilterScript(scriptName + "."));
if (content == null || content.length == 0) {
log(-1, "Script project %s \n has no script file %s.xxx", fScriptFolder, scriptName);
return null;
}
} else if ("jar".equals(scriptType)) {
log(-1, "Sorry, script projects as jar-files are not yet supported;");
//TODO try to load and run as extension
return null; // until ready
}
return content;
}
private static class FileFilterScript implements FilenameFilter {
private String _check;
public FileFilterScript(String check) {
_check = check;
}
@Override
public boolean accept(File dir, String fileName) {
return fileName.startsWith(_check);
}
}
public static String unzipSKL(String fpSkl) {
File fSkl = new File(fpSkl);
if (!fSkl.exists()) {
log(-1, "unzipSKL: file not found: %s", fpSkl);
}
String name = fSkl.getName();
name = name.substring(0, name.lastIndexOf('.'));
File fSikuliDir = FileManager.createTempDir(name + ".sikuli");
if (null != fSikuliDir) {
fSikuliDir.deleteOnExit();
FileManager.unzip(fSkl, fSikuliDir);
}
if (null == fSikuliDir) {
log(-1, "unzipSKL: not possible for:\n%s", fpSkl);
return null;
}
return fSikuliDir.getAbsolutePath();
}
public interface JarFileFilter {
public boolean accept(ZipEntry entry, String jarname);
}
public interface FileFilter {
public boolean accept(File entry);
}
public static String extractResourceAsLines(String src) {
String res = null;
ClassLoader cl = FileManager.class.getClassLoader();
InputStream isContent = cl.getResourceAsStream(src);
if (isContent != null) {
res = "";
String line;
try {
BufferedReader cnt = new BufferedReader(new InputStreamReader(isContent));
line = cnt.readLine();
while (line != null) {
res += line + "\n";
line = cnt.readLine();
}
cnt.close();
} catch (Exception ex) {
log(-1, "extractResourceAsLines: %s\n%s", src, ex);
}
}
return res;
}
public static boolean extractResource(String src, File tgt) {
ClassLoader cl = FileManager.class.getClassLoader();
InputStream isContent = cl.getResourceAsStream(src);
if (isContent != null) {
try {
log(lvl + 1, "extractResource: %s to %s", src, tgt);
tgt.getParentFile().mkdirs();
OutputStream osTgt = new FileOutputStream(tgt);
bufferedWrite(isContent, osTgt);
osTgt.close();
} catch (Exception ex) {
log(-1, "extractResource:\n%s", src, ex);
return false;
}
} else {
return false;
}
return true;
}
private static synchronized void bufferedWrite(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[1024 * 512];
int read;
while (true) {
read = in.read(buffer);
if (read == -1) {
break;
}
out.write(buffer, 0, read);
}
out.flush();
}
/**
* compares to path strings using java.io.File.equals()
* @param path1 string
* @param path2 string
* @return true if same file or folder
*/
public static boolean pathEquals(String path1, String path2) {
File f1 = new File(path1);
File f2 = new File(path2);
boolean isEqual = f1.equals(f2);
return isEqual;
}
}
sikulix-1.1.1/API/src/main/java/org/sikuli/basics/HotkeyEvent.java 0000664 0000000 0000000 00000000555 13157261304 0024721 0 ustar 00root root 0000000 0000000 /*
* Copyright (c) 2010-2016, Sikuli.org, sikulix.com
* Released under the MIT License.
*
*/
package org.sikuli.basics;
public class HotkeyEvent {
public int keyCode;
public int modifiers;
public HotkeyEvent(int code_, int mod_){
init(code_, mod_);
}
void init(int code_, int mod_){
keyCode = code_;
modifiers = mod_;
}
}
sikulix-1.1.1/API/src/main/java/org/sikuli/basics/HotkeyListener.java 0000664 0000000 0000000 00000001171 13157261304 0025420 0 ustar 00root root 0000000 0000000 /*
* Copyright (c) 2010-2016, Sikuli.org, sikulix.com
* Released under the MIT License.
*
*/
package org.sikuli.basics;
public abstract class HotkeyListener {
/**
* Override this to implement your own hotkey handler.
*
* @param e HotkeyEvent
*/
abstract public void hotkeyPressed(HotkeyEvent e);
/**
* INTERNAL USE: system specific handler implementation
*
* @param e HotkeyEvent
*/
public void invokeHotkeyPressed(final HotkeyEvent e) {
Thread hotkeyThread = new Thread() {
@Override
public void run() {
hotkeyPressed(e);
}
};
hotkeyThread.start();
}
}
sikulix-1.1.1/API/src/main/java/org/sikuli/basics/HotkeyManager.java 0000664 0000000 0000000 00000021722 13157261304 0025211 0 ustar 00root root 0000000 0000000 /*
* Copyright (c) 2010-2016, Sikuli.org, sikulix.com
* Released under the MIT License.
*
*/
package org.sikuli.basics;
import java.awt.event.KeyEvent;
import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.Map;
import org.sikuli.basics.Debug;
import org.sikuli.basics.PreferencesUser;
import org.sikuli.basics.Settings;
import org.sikuli.script.Key;
import org.sikuli.script.Key;
/**
* Singleton class to bind hotkeys to hotkey listeners
*/
public abstract class HotkeyManager {
private static HotkeyManager _instance = null;
private static Map hotkeys;
private static Map hotkeysGlobal = new HashMap();
private static final String HotkeyTypeCapture = "Capture";
private static int HotkeyTypeCaptureKey;
private static int HotkeyTypeCaptureMod;
private static final String HotkeyTypeAbort = "Abort";
private static int HotkeyTypeAbortKey;
private static int HotkeyTypeAbortMod;
public static HotkeyManager getInstance() {
if (_instance == null) {
/* uncomment for debugging puposes
if (Settings.isWindows()) {
_instance = new WindowsHotkeyManager();
} else if (Settings.isMac()) {
_instance = new MacHotkeyManager();
} else if (Settings.isLinux()) {
_instance = new LinuxHotkeyManager();
}
return _instance;
*/
String cls = getOSHotkeyManagerClass();
if (cls != null) {
try {
Class c = Class.forName(cls);
Constructor constr = c.getConstructor();
_instance = (HotkeyManager) constr.newInstance();
} catch (Exception e) {
Debug.error("HotkeyManager: Can't create " + cls + ": " + e.getMessage());
}
}
hotkeys = new HashMap();
}
return _instance;
}
/**
* remove all hotkeys
*/
public static void reset() {
if (_instance == null || hotkeys.isEmpty()) {
return;
}
Debug.log(3, "HotkeyManager: reset - removing all defined hotkeys.");
boolean res;
int[] hk = new int[hotkeys.size()];
int i = 0;
for (Integer k : hotkeys.keySet()) {
res = _instance._removeHotkey(k, hotkeys.get(k));
if (!res) {
Debug.error("HotkeyManager: reset: failed to remove hotkey: %s %s",
getKeyModifierText(hotkeys.get(k)), getKeyCodeText(k));
hk[i++] = -1;
} else {
hk[i++] = k;
Debug.log(3, "removed (%d, %d)" , k, hotkeys.get(k));
}
}
for (int k : hk) {
if (k == -1) {
continue;
}
hotkeys.remove(k);
}
}
private static String getOSHotkeyManagerClass() {
String pkg = "org.sikuli.basics.";
int theOS = Settings.getOS();
switch (theOS) {
case Settings.ISMAC:
return pkg + "MacHotkeyManager";
case Settings.ISWINDOWS:
return pkg + "WindowsHotkeyManager";
case Settings.ISLINUX:
return pkg + "LinuxHotkeyManager";
default:
Debug.error("HotkeyManager: Hotkey registration is not supported on your OS.");
}
return null;
}
private static String getKeyCodeText(int key) {
return KeyEvent.getKeyText(key).toUpperCase();
}
private static String getKeyModifierText(int modifiers) {
String txtMod = KeyEvent.getKeyModifiersText(modifiers).toUpperCase();
if (Settings.isMac()) {
txtMod = txtMod.replace("META", "CMD");
txtMod = txtMod.replace("WINDOWS", "CMD");
} else {
txtMod = txtMod.replace("META", "WIN");
txtMod = txtMod.replace("WINDOWS", "WIN");
}
return txtMod;
}
/**
* install a hotkey listener for a global hotkey (capture, abort, ...)
* @param hotkeyType a type string
* @param callback HotkeyListener
* @return success
*/
public boolean addHotkey(String hotkeyType, HotkeyListener callback) {
PreferencesUser pref = PreferencesUser.getInstance();
if (hotkeyType == HotkeyTypeCapture) {
HotkeyTypeCaptureKey = pref.getCaptureHotkey();
HotkeyTypeCaptureMod = pref.getCaptureHotkeyModifiers();
return installHotkey(HotkeyTypeCaptureKey, HotkeyTypeCaptureMod, callback, hotkeyType);
} else if (hotkeyType == HotkeyTypeAbort) {
HotkeyTypeAbortKey = pref.getStopHotkey();
HotkeyTypeAbortMod = pref.getStopHotkeyModifiers();
return installHotkey(HotkeyTypeAbortKey, HotkeyTypeAbortMod, callback, hotkeyType);
} else {
Debug.error("HotkeyManager: addHotkey: HotkeyType %s not supported", hotkeyType);
return false;
}
}
public String getHotKeyText(String hotkeyType) {
PreferencesUser pref = PreferencesUser.getInstance();
String key = "";
String mod = "";
if (hotkeyType == HotkeyTypeCapture) {
key = getKeyCodeText(pref.getCaptureHotkey());
mod = getKeyModifierText(pref.getCaptureHotkeyModifiers());
} else if (hotkeyType == HotkeyTypeAbort) {
key = getKeyCodeText(pref.getStopHotkey());
mod = getKeyModifierText(pref.getStopHotkeyModifiers());
} else {
Debug.error("HotkeyManager: getHotKeyText: HotkeyType %s not supported", hotkeyType);
}
return mod + " " + key;
}
/**
* install a hotkey listener.
*
* @param key key character (class Key)
* @param modifiers modifiers flag
* @param callback HotkeyListener
* @return true if success. false otherwise.
*/
public boolean addHotkey(char key, int modifiers, HotkeyListener callback) {
return addHotkey("" + key, modifiers, callback);
}
/**
* install a hotkey listener.
*
* @param key key character (class Key)
* @param modifiers modifiers flag
* @param callback HotkeyListener
* @return true if success. false otherwise.
*/
public boolean addHotkey(String key, int modifiers, HotkeyListener callback) {
int[] keyCodes = Key.toJavaKeyCode(key.toLowerCase());
int keyCode = keyCodes[0];
return installHotkey(keyCode, modifiers, callback, "");
}
private boolean installHotkey(int key, int mod, HotkeyListener callback, String hotkeyType) {
boolean res;
String txtMod = getKeyModifierText(mod);
String txtCode = getKeyCodeText(key);
Debug.info("HotkeyManager: add %s Hotkey: %s %s (%d, %d)" , hotkeyType, txtMod, txtCode, key, mod);
boolean checkGlobal = true;
for (Integer k : hotkeys.keySet()) {
if (k == key && mod == hotkeys.get(key)) {
res = _instance._removeHotkey(key, hotkeys.get(key));
if (!res) {
Debug.error("HotkeyManager: addHotkey: failed to remove already defined hotkey");
return false;
} else {
checkGlobal = false;
}
}
}
if (checkGlobal) {
for (Integer kg : hotkeysGlobal.keySet()) {
if (kg == key && mod == hotkeysGlobal.get(key)) {
Debug.error("HotkeyManager: addHotkey: ignored: trying to redefine a global hotkey");
return false;
}
}
}
res = _instance._addHotkey(key, mod, callback);
if (res) {
if (hotkeyType.isEmpty()) {
hotkeys.put(key, mod);
} else {
hotkeysGlobal.put(key, mod);
}
} else {
Debug.error("HotkeyManager: addHotkey: failed");
}
return res;
}
/**
* remove a hotkey by type (not supported yet)
* @param hotkeyType capture, abort, ...
* @return success
*/
public boolean removeHotkey(String hotkeyType) {
if (hotkeyType == HotkeyTypeCapture) {
return uninstallHotkey(HotkeyTypeCaptureKey, HotkeyTypeCaptureMod, hotkeyType);
} else if (hotkeyType == HotkeyTypeAbort) {
return uninstallHotkey(HotkeyTypeAbortKey, HotkeyTypeAbortMod, hotkeyType);
} else {
Debug.error("HotkeyManager: removeHotkey: using HotkeyType as %s not supported yet", hotkeyType);
return false;
}
}
/**
* remove a hotkey and uninstall a hotkey listener.
*
* @param key key character (class Key)
* @param modifiers modifiers flag
* @return true if success. false otherwise.
*/
public boolean removeHotkey(char key, int modifiers) {
return removeHotkey("" + key, modifiers);
}
/**
* uninstall a hotkey listener.
*
* @param key key string (class Key)
* @param modifiers modifiers flag
* @return true if success. false otherwise.
*/
public boolean removeHotkey(String key, int modifiers) {
int[] keyCodes = Key.toJavaKeyCode(key.toLowerCase());
int keyCode = keyCodes[0];
return uninstallHotkey(keyCode, modifiers, "");
}
private boolean uninstallHotkey(int key, int mod, String hotkeyType) {
boolean res;
String txtMod = getKeyModifierText(mod);
String txtCode = getKeyCodeText(key);
Debug.info("HotkeyManager: remove %s Hotkey: %s %s (%d, %d)" , hotkeyType, txtMod, txtCode, key, mod);
res = _instance._removeHotkey(key, mod);
if (res) {
hotkeys.remove(key);
} else {
Debug.error("HotkeyManager: removeHotkey: failed");
}
return res;
}
abstract public boolean _addHotkey(int keyCode, int modifiers, HotkeyListener callback);
abstract public boolean _removeHotkey(int keyCode, int modifiers);
abstract public void cleanUp();
}
sikulix-1.1.1/API/src/main/java/org/sikuli/basics/LinuxHotkeyManager.java 0000664 0000000 0000000 00000005044 13157261304 0026230 0 ustar 00root root 0000000 0000000 /*
* Copyright (c) 2010-2016, Sikuli.org, sikulix.com
* Released under the MIT License.
*
*/
package org.sikuli.basics;
import org.sikuli.script.RunTime;
import java.util.*;
import jxgrabkey.HotkeyConflictException;
import jxgrabkey.JXGrabKey;
import org.sikuli.basics.Debug;
import org.sikuli.script.RunTime;
public class LinuxHotkeyManager extends HotkeyManager {
static{
RunTime.loadLibrary("JXGrabKey");
}
class HotkeyData {
int key, modifiers;
HotkeyListener listener;
public HotkeyData(int key_, int mod_, HotkeyListener l_){
key = key_;
modifiers = mod_;
listener = l_;
}
};
class MyHotkeyHandler implements jxgrabkey.HotkeyListener{
public void onHotkey(int id){
Debug.log(4, "Hotkey pressed");
HotkeyData data = _idCallbackMap.get(id);
HotkeyEvent e = new HotkeyEvent(data.key, data.modifiers);
data.listener.invokeHotkeyPressed(e);
}
};
private Map _idCallbackMap = new HashMap();
private int _gHotkeyId = 1;
public boolean _addHotkey(int keyCode, int modifiers, HotkeyListener listener){
JXGrabKey grabKey = JXGrabKey.getInstance();
if(_gHotkeyId == 1){
grabKey.addHotkeyListener(new MyHotkeyHandler());
}
_removeHotkey(keyCode, modifiers);
int id = _gHotkeyId++;
HotkeyData data = new HotkeyData(keyCode, modifiers, listener);
_idCallbackMap.put(id, data);
try{
//JXGrabKey.setDebugOutput(true);
grabKey.registerAwtHotkey(id, modifiers, keyCode);
}catch(HotkeyConflictException e){
Debug.error("Hot key conflicts");
return false;
}
return true;
}
public boolean _removeHotkey(int keyCode, int modifiers){
for( Map.Entry entry : _idCallbackMap.entrySet() ){
HotkeyData data = entry.getValue();
if(data.key == keyCode && data.modifiers == modifiers){
JXGrabKey grabKey = JXGrabKey.getInstance();
int id = entry.getKey();
grabKey.unregisterHotKey(id);
_idCallbackMap.remove(id);
return true;
}
}
return false;
}
public void cleanUp(){
JXGrabKey grabKey = JXGrabKey.getInstance();
for( Map.Entry entry : _idCallbackMap.entrySet() ){
int id = entry.getKey();
grabKey.unregisterHotKey(id);
}
_gHotkeyId = 1;
_idCallbackMap.clear();
grabKey.getInstance().cleanUp();
}
}
sikulix-1.1.1/API/src/main/java/org/sikuli/basics/MacHotkeyManager.java 0000664 0000000 0000000 00000015431 13157261304 0025632 0 ustar 00root root 0000000 0000000 /*
* Copyright (c) 2010-2016, Sikuli.org, sikulix.com
* Released under the MIT License.
*
*/
package org.sikuli.basics;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import org.sikuli.script.RunTime;
// http://lists.apple.com/archives/mac-games-dev/2001/Sep/msg00113.html
// full key table: http://www.mactech.com/articles/mactech/Vol.04/04.12/Macinkeys/
// modifiers code: http://www.mactech.com/macintosh-c/chap02-1.html
public class MacHotkeyManager extends HotkeyManager {
static final int CARBON_MASK_CMD = 0x0100;
static final int CARBON_MASK_SHIFT = 0x0200;
static final int CARBON_MASK_OPT = 0x0800;
static final int CARBON_MASK_CTRL = 0x1000;
static {
RunTime.loadLibrary("MacHotkeyManager");
}
@Override
public boolean _addHotkey(int keyCode, int modifiers, HotkeyListener listener) {
int ckey = convertToCarbonKey(keyCode);
int cmod = convertToCarbonModifiers(modifiers);
boolean ret = installGlobalHotkey(keyCode, modifiers, ckey, cmod, listener);
return ret;
}
@Override
public boolean _removeHotkey(int keyCode, int modifiers) {
int ckey = convertToCarbonKey(keyCode);
int cmod = convertToCarbonModifiers(modifiers);
return uninstallGlobalHotkey(ckey, cmod);
}
private native boolean installGlobalHotkey(int jKey, int jMod, int keyCode, int modifiers, HotkeyListener listener);
private native boolean uninstallGlobalHotkey(int keyCode, int modifiers);
@Override
public native void cleanUp();
private int convertToCarbonModifiers(int mod) {
int cmod = 0;
if ((mod & InputEvent.SHIFT_MASK) != 0) {
cmod |= CARBON_MASK_SHIFT;
}
if ((mod & InputEvent.META_MASK) != 0) {
cmod |= CARBON_MASK_CMD;
}
if ((mod & InputEvent.ALT_MASK) != 0) {
cmod |= CARBON_MASK_OPT;
}
if ((mod & InputEvent.CTRL_MASK) != 0) {
cmod |= CARBON_MASK_CTRL;
}
return cmod;
}
private int convertToCarbonKey(int keycode) {
switch (keycode) {
case KeyEvent.VK_BACK_SPACE:
return 0x33;
case KeyEvent.VK_TAB:
return 0x30;
case KeyEvent.VK_CLEAR:
return 0x47;
case KeyEvent.VK_ENTER:
return 0x24;
case KeyEvent.VK_SHIFT:
return 0xF0;
case KeyEvent.VK_CONTROL:
return 0xF1;
case KeyEvent.VK_META:
return 0xF2;
case KeyEvent.VK_PAUSE:
return 0x71; // = F15
case KeyEvent.VK_ESCAPE:
return 0x35;
case KeyEvent.VK_SPACE:
return 0x31;
case KeyEvent.VK_OPEN_BRACKET:
return 0x21;
case KeyEvent.VK_BACK_SLASH:
return 0x2A;
case KeyEvent.VK_CLOSE_BRACKET:
return 0x1E;
case KeyEvent.VK_SLASH:
return 0x2C;
case KeyEvent.VK_PERIOD:
return 0x2F;
case KeyEvent.VK_COMMA:
return 0x2B;
case KeyEvent.VK_SEMICOLON:
return 0x29;
case KeyEvent.VK_END:
return 0x77;
case KeyEvent.VK_HOME:
return 0x73;
case KeyEvent.VK_LEFT:
return 0x7B;
case KeyEvent.VK_UP:
return 0x7E;
case KeyEvent.VK_RIGHT:
return 0x7C;
case KeyEvent.VK_DOWN:
return 0x7D;
case KeyEvent.VK_PRINTSCREEN:
return 0x69; // F13
case KeyEvent.VK_INSERT:
return 0x72; // help
case KeyEvent.VK_DELETE:
return 0x75;
case KeyEvent.VK_HELP:
return 0x72;
case KeyEvent.VK_0:
return 0x1D;
case KeyEvent.VK_1:
return 0x12;
case KeyEvent.VK_2:
return 0x13;
case KeyEvent.VK_3:
return 0x14;
case KeyEvent.VK_4:
return 0x15;
case KeyEvent.VK_5:
return 0x17;
case KeyEvent.VK_6:
return 0x16;
case KeyEvent.VK_7:
return 0x1A;
case KeyEvent.VK_8:
return 0x1C;
case KeyEvent.VK_9:
return 0x19;
case KeyEvent.VK_MINUS:
return 0x1B;
case KeyEvent.VK_EQUALS:
return 0x18;
case KeyEvent.VK_A:
return 0x00;
case KeyEvent.VK_B:
return 0x0B;
case KeyEvent.VK_C:
return 0x08;
case KeyEvent.VK_D:
return 0x02;
case KeyEvent.VK_E:
return 0x0E;
case KeyEvent.VK_F:
return 0x03;
case KeyEvent.VK_G:
return 0x05;
case KeyEvent.VK_H:
return 0x04;
case KeyEvent.VK_I:
return 0x22;
case KeyEvent.VK_J:
return 0x26;
case KeyEvent.VK_K:
return 0x28;
case KeyEvent.VK_L:
return 0x25;
case KeyEvent.VK_M:
return 0x2E;
case KeyEvent.VK_N:
return 0x2D;
case KeyEvent.VK_O:
return 0x1F;
case KeyEvent.VK_P:
return 0x23;
case KeyEvent.VK_Q:
return 0x0C;
case KeyEvent.VK_R:
return 0x0F;
case KeyEvent.VK_S:
return 0x01;
case KeyEvent.VK_T:
return 0x11;
case KeyEvent.VK_U:
return 0x20;
case KeyEvent.VK_V:
return 0x09;
case KeyEvent.VK_W:
return 0x0D;
case KeyEvent.VK_X:
return 0x07;
case KeyEvent.VK_Y:
return 0x10;
case KeyEvent.VK_Z:
return 0x06;
case KeyEvent.VK_NUMPAD0:
return 0x52;
case KeyEvent.VK_NUMPAD1:
return 0x53;
case KeyEvent.VK_NUMPAD2:
return 0x54;
case KeyEvent.VK_NUMPAD3:
return 0x55;
case KeyEvent.VK_NUMPAD4:
return 0x56;
case KeyEvent.VK_NUMPAD5:
return 0x57;
case KeyEvent.VK_NUMPAD6:
return 0x58;
case KeyEvent.VK_NUMPAD7:
return 0x59;
case KeyEvent.VK_NUMPAD8:
return 0x5B;
case KeyEvent.VK_NUMPAD9:
return 0x5C;
case KeyEvent.VK_MULTIPLY:
return 0x43;
case KeyEvent.VK_ADD:
return 0x45;
case KeyEvent.VK_SEPARATOR:
return 0xFF; // not supported with Button or GetKeys
case KeyEvent.VK_SUBTRACT:
return 0x4E;
case KeyEvent.VK_DECIMAL:
return 0x41;
case KeyEvent.VK_DIVIDE:
return 0x4B;
case KeyEvent.VK_F1:
return 0x7A;
case KeyEvent.VK_F2:
return 0x7B;
case KeyEvent.VK_F3:
return 0x63;
case KeyEvent.VK_F4:
return 0x76;
case KeyEvent.VK_F5:
return 0x60;
case KeyEvent.VK_F6:
return 0x61;
case KeyEvent.VK_F7:
return 0x62;
case KeyEvent.VK_F8:
return 0x64;
case KeyEvent.VK_F9:
return 0x65;
case KeyEvent.VK_F10:
return 0x6D;
case KeyEvent.VK_F11:
return 0x67;
case KeyEvent.VK_F12:
return 0x6F;
case KeyEvent.VK_F13:
return 0x69;
case KeyEvent.VK_F14:
return 0x6B;
case KeyEvent.VK_F15:
return 0x71;
case KeyEvent.VK_NUM_LOCK:
return 0x47;
default:
return 0xFF;
}
}
}
sikulix-1.1.1/API/src/main/java/org/sikuli/basics/OS.java 0000664 0000000 0000000 00000000431 13157261304 0022766 0 ustar 00root root 0000000 0000000 /*
* Copyright (c) 2010-2016, Sikuli.org, sikulix.com
* Released under the MIT License.
*
*/
package org.sikuli.basics;
/**
* @deprecated use Settings.isWindows(), ...isMac() or ...isLinux() instead
*/
@Deprecated
public enum OS {
MAC, WINDOWS, LINUX,
NOT_SUPPORTED
}
sikulix-1.1.1/API/src/main/java/org/sikuli/basics/PreferencesUser.java 0000664 0000000 0000000 00000032041 13157261304 0025547 0 ustar 00root root 0000000 0000000 /*
* Copyright (c) 2010-2016, Sikuli.org, sikulix.com
* Released under the MIT License.
*
*/
package org.sikuli.basics;
import java.awt.Dimension;
import java.awt.Event;
import java.awt.Point;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Arrays;
import java.util.Date;
import java.util.Locale;
import java.util.prefs.PreferenceChangeListener;
import java.util.prefs.Preferences;
import org.sikuli.script.Sikulix;
public class PreferencesUser {
public final static int yes = 1;
public final static int no = 0;
public final static int AUTO_NAMING_TIMESTAMP = 0;
public final static int AUTO_NAMING_OCR = 1;
public final static int AUTO_NAMING_OFF = 2;
public final static int HORIZONTAL = 0;
public final static int VERTICAL = 1;
public final static int UNKNOWN = -1;
public final static int NEWBEE = 0;
public final static int SCRIPTER = 1;
public final static int SIKULI_USER = 2;
public final static int THUMB_HEIGHT = 50;
public final static String DEFAULT_CONSOLE_CSS =
"body { font-family:serif; font-size: 12px; }"
+ ".normal{ color: black; }"
+ ".debug { color:#505000; }"
+ ".info { color: blue; }"
+ ".log { color: #09806A; }"
+ ".error { color: red; }";
static PreferencesUser _instance = null;
Preferences pref = Preferences.userNodeForPackage(Sikulix.class);
public static PreferencesUser getInstance() {
if (_instance == null) {
_instance = new PreferencesUser();
}
return _instance;
}
private PreferencesUser() {
Debug.log(2, "init user preferences");
}
public boolean exportPrefs(String path) {
try {
FileOutputStream pout = new FileOutputStream(new File(path)); ;
pref.exportSubtree(pout);
pout.close();
} catch (Exception ex) {
Debug.error("UserPrefs: export: did not work\n" + ex.getMessage());
return false;
}
return true;
}
public boolean importPrefs(String path) {
try {
Preferences.importPreferences(new FileInputStream(new File(path)));
} catch (Exception ex) {
Debug.error("UserPrefs: import: did not work\n" + ex.getMessage());
return false;
}
return true;
}
public void remove(String key) {
pref.remove(key);
}
public void removeAll(String prefix) {
try {
for (String item : pref.keys()) {
if (!item.startsWith(prefix)) {
continue;
}
pref.remove(item);
}
} catch (Exception ex) {
Debug.error("Prefs.removeAll: prefix (%s) did not work", prefix);
}
}
public void addPreferenceChangeListener(PreferenceChangeListener pcl) {
pref.addPreferenceChangeListener(pcl);
}
// ***** user type
public void setUserType(int typ) {
pref.putInt("USER_TYPE", typ);
}
public int getUserType() {
return pref.getInt("USER_TYPE", UNKNOWN);
}
// ***** capture hot key
public void setCaptureHotkey(int hkey) {
pref.putInt("CAPTURE_HOTKEY", hkey);
}
public int getCaptureHotkey() {
return pref.getInt("CAPTURE_HOTKEY", 50); // default: '2'
}
public void setCaptureHotkeyModifiers(int mod) {
if (mod < 0) {
}
pref.putInt("CAPTURE_HOTKEY_MODIFIERS", mod);
}
public int getCaptureHotkeyModifiers() {
return pref.getInt("CAPTURE_HOTKEY_MODIFIERS", defaultCaptureHotkeyModifiers());
}
private int defaultCaptureHotkeyModifiers() {
int mod = Event.SHIFT_MASK + Event.META_MASK;
if (!Settings.isMac()) {
mod = Event.SHIFT_MASK + Event.CTRL_MASK;
}
return mod;
}
public void setCaptureDelay(double v) {
pref.putDouble("CAPTURE_DELAY", v);
}
public double getCaptureDelay() {
return pref.getDouble("CAPTURE_DELAY", 1.0);
}
// ***** abort key
public void setStopHotkey(int hkey) {
pref.putInt("STOP_HOTKEY", hkey);
}
public int getStopHotkey() {
return pref.getInt("STOP_HOTKEY", 67); // default: 'c'
}
public void setStopHotkeyModifiers(int mod) {
pref.putInt("STOP_HOTKEY_MODIFIERS", mod);
}
public int getStopHotkeyModifiers() {
return pref.getInt("GET_HOTKEY_MODIFIERS", defaultStopHotkeyModifiers());
}
private int defaultStopHotkeyModifiers() {
int mod = Event.SHIFT_MASK + Event.META_MASK;
if (!Settings.isMac()) {
mod = Event.SHIFT_MASK + Event.ALT_MASK;
}
return mod;
}
// ***** indentation support
public void setExpandTab(boolean flag) {
pref.putBoolean("EXPAND_TAB", flag);
}
public boolean getExpandTab() {
return pref.getBoolean("EXPAND_TAB", true);
}
public void setTabWidth(int width) {
pref.putInt("TAB_WIDTH", width);
}
public int getTabWidth() {
return pref.getInt("TAB_WIDTH", 4);
}
public String getTabWhitespace() {
if (getExpandTab()) {
char[] blanks = new char[getTabWidth()];
Arrays.fill(blanks, ' ');
return new String(blanks);
} else {
return "\t";
}
}
// ***** font settings
public void setFontSize(int size) {
pref.putInt("FONT_SIZE", size);
}
public int getFontSize() {
return pref.getInt("FONT_SIZE", 18);
}
public void setFontName(String font) {
pref.put("FONT_NAME", font);
}
public String getFontName() {
return pref.get("FONT_NAME", "Monospaced");
}
// ***** locale support
public void setLocale(Locale l) {
pref.put("LOCALE", l.toString());
}
public Locale getLocale() {
String locale = pref.get("LOCALE", Locale.getDefault().toString());
String[] code = locale.split("_");
if (code.length == 1) {
return new Locale(code[0]);
} else if (code.length == 2) {
return new Locale(code[0], code[1]);
} else {
return new Locale(code[0], code[1], code[2]);
}
}
// ***** image capture and naming
public void setAutoNamingMethod(int m) {
pref.putInt("AUTO_NAMING", m);
}
public int getAutoNamingMethod() {
return pref.getInt("AUTO_NAMING", AUTO_NAMING_OCR);
}
public void setDefaultThumbHeight(int h) {
pref.putInt("DEFAULT_THUMB_HEIGHT", h);
}
public void resetDefaultThumbHeight() {
pref.putInt("DEFAULT_THUMB_HEIGHT", THUMB_HEIGHT);
}
public int getDefaultThumbHeight() {
return pref.getInt("DEFAULT_THUMB_HEIGHT", THUMB_HEIGHT);
}
// ***** command bar
public void setPrefMoreCommandBar(boolean flag) {
pref.putInt("PREF_MORE_COMMAND_BAR", flag ? 1 : 0);
}
public boolean getPrefMoreCommandBar() {
return pref.getInt("PREF_MORE_COMMAND_BAR", 1) != 0;
}
public void setAutoCaptureForCmdButtons(boolean flag) {
pref.putInt("AUTO_CAPTURE_FOR_CMD_BUTTONS", flag ? 1 : 0);
}
public boolean getAutoCaptureForCmdButtons() {
return pref.getInt("AUTO_CAPTURE_FOR_CMD_BUTTONS", 1) != 0;
}
// ***** save options
public void setAtSaveMakeHTML(boolean flag) {
pref.putBoolean("AT_SAVE_MAKE_HTML", flag);
}
public boolean getAtSaveMakeHTML() {
return pref.getBoolean("AT_SAVE_MAKE_HTML", false);
}
public void setAtSaveCleanBundle(boolean flag) {
pref.putBoolean("AT_SAVE_CLEAN_BUNDLE", flag);
}
public boolean getAtSaveCleanBundle() {
return pref.getBoolean("AT_SAVE_CLEAN_BUNDLE", true);
}
// ***** script run options
public void setPrefMoreRunSave(boolean flag) {
pref.putBoolean("PREF_MORE_RUN_SAVE", flag);
}
public boolean getPrefMoreRunSave() {
return pref.getBoolean("PREF_MORE_RUN_SAVE", false);
}
public void setPrefMoreHighlight(boolean flag) {
pref.putBoolean("PREF_MORE_HIGHLIGHT", flag);
}
public boolean getPrefMoreHighlight() {
return pref.getBoolean("PREF_MORE_HIGHLIGHT", false);
}
// ***** auto update support
public void setCheckUpdate(boolean flag) {
pref.putBoolean("CHECK_UPDATE", flag);
}
public boolean getCheckUpdate() {
return pref.getBoolean("CHECK_UPDATE", true);
}
public void setWantBeta(boolean flag) {
pref.putBoolean("WANT_BETA", flag);
}
public boolean getWantBeta() {
return pref.getBoolean("WANT_BETA", false);
}
public void setLastSeenUpdate(String ver) {
pref.put("LAST_SEEN_UPDATE", ver);
}
public String getLastSeenUpdate() {
return pref.get("LAST_SEEN_UPDATE", "0.0");
}
public void setCheckUpdateTime() {
pref.putLong("LAST_CHECK_UPDATE", (new Date()).getTime());
}
public long getCheckUpdateTime() {
return pref.getLong("LAST_CHECK_UPDATE", (new Date()).getTime());
}
// ***** IDE general support
public void setIdeSize(Dimension size) {
String str = (int) size.getWidth() + "x" + (int) size.getHeight();
pref.put("IDE_SIZE", str);
}
public Dimension getIdeSize() {
String str = pref.get("IDE_SIZE", "1024x700");
String[] w_h = str.split("x");
return new Dimension(Integer.parseInt(w_h[0]), Integer.parseInt(w_h[1]));
}
public void setIdeLocation(Point p) {
String str = p.x + "," + p.y;
pref.put("IDE_LOCATION", str);
}
public Point getIdeLocation() {
String str = pref.get("IDE_LOCATION", "0,0");
String[] x_y = str.split(",");
return new Point(Integer.parseInt(x_y[0]), Integer.parseInt(x_y[1]));
}
// ***** IDE Editor options
public void setPrefMoreImageThumbs(boolean flag) {
pref.putBoolean("PREF_MORE_IMAGE_THUMBS", flag);
}
public boolean getPrefMoreImageThumbs() {
return pref.getBoolean("PREF_MORE_IMAGE_THUMBS", true);
}
public void setPrefMorePlainText(boolean flag) {
pref.putBoolean("PREF_MORE_PLAIN_TEXT", flag);
}
public boolean getPrefMorePlainText() {
return pref.getBoolean("PREF_MORE_PLAIN_TEXT", false);
}
// currently: last open filenames
public void setIdeSession(String session_str) {
pref.put("IDE_SESSION", session_str);
}
public String getIdeSession() {
return pref.get("IDE_SESSION", null);
}
// support for IDE image path
public void setPrefMoreImages(boolean flag) {
pref.putBoolean("PREF_MORE_IMAGES", flag);
}
public boolean getPrefMoreImages() {
return pref.getBoolean("PREF_MORE_IMAGES", false);
}
public void setPrefMoreImagesPath(String path) {
pref.put("PREF_MORE_IMAGES_PATH", path);
}
public String getPrefMoreImagesPath() {
return pref.get("PREF_MORE_IMAGES_PATH", null);
}
// ***** message area settings
public void setPrefMoreMessage(int typ) {
pref.putInt("PREF_MORE_MESSAGE", typ);
}
public int getPrefMoreMessage() {
return pref.getInt("PREF_MORE_MESSAGE", HORIZONTAL);
}
public void setPrefMoreLogActions(boolean flag) {
pref.putBoolean("PREF_MORE_LOG_ACTIONS", flag);
}
public boolean getPrefMoreLogActions() {
return pref.getBoolean("PREF_MORE_LOG_ACTIONS", true);
}
public void setPrefMoreLogInfo(boolean flag) {
pref.putBoolean("PREF_MORE_LOG_INFO", flag);
}
public boolean getPrefMoreLogInfo() {
return pref.getBoolean("PREF_MORE_LOG_INFO", true);
}
public void setPrefMoreLogDebug(boolean flag) {
pref.putBoolean("PREF_MORE_LOG_INFO", flag);
}
public boolean getPrefMoreLogDebug() {
return pref.getBoolean("PREF_MORE_LOG_DEBUG", true);
}
public void setConsoleCSS(String css) {
pref.put("CONSOLE_CSS", css);
}
public String getConsoleCSS() {
return pref.get("CONSOLE_CSS", DEFAULT_CONSOLE_CSS);
}
// ***** text search and OCR
public void setPrefMoreTextSearch(boolean flag) {
pref.putBoolean("PREF_MORE_TEXT_SEARCH", flag);
}
public boolean getPrefMoreTextSearch() {
return pref.getBoolean("PREF_MORE_TEXT_SEARCH", false);
}
public void setPrefMoreTextOCR(boolean flag) {
pref.putBoolean("PREF_MORE_TEXT_OCR", flag);
}
public boolean getPrefMoreTextOCR() {
return pref.getBoolean("PREF_MORE_TEXT_OCR", false);
}
// ***** general setter getter
public void put(String key, String val) {
pref.put(key, val);
}
public String get(String key, String default_) {
return pref.get(key, default_);
}
public void setDefaults(int typ) {
// ***** capture hot key
if (NEWBEE == typ) {
setCaptureHotkey(50);
setCaptureHotkeyModifiers(defaultCaptureHotkeyModifiers());
setCaptureDelay(1.0);
}
// ***** abort key
setStopHotkey(67);
setStopHotkeyModifiers(defaultStopHotkeyModifiers());
// ***** indentation support
if (NEWBEE == typ) {
setExpandTab(true);
setTabWidth(4);
}
// ***** font settings
if (NEWBEE == typ) {
setFontSize(14);
setFontName("Monospaced");
}
// ***** locale support
if (NEWBEE == typ) {
setLocale(Locale.getDefault());
}
// ***** image capture and naming
if (NEWBEE == typ) {
setAutoNamingMethod(AUTO_NAMING_TIMESTAMP);
}
if (getPrefMoreImageThumbs()) {
setDefaultThumbHeight(THUMB_HEIGHT);
} else {
setDefaultThumbHeight(0);
}
// ***** command bar
if (NEWBEE == typ) {
setPrefMoreCommandBar(true);
setAutoCaptureForCmdButtons(true);
} else {
setPrefMoreCommandBar(false);
}
// ***** save options
if (NEWBEE == typ) {
setAtSaveMakeHTML(true);
} else {
setAtSaveMakeHTML(false);
}
setAtSaveCleanBundle(true);
// ***** script run options
setPrefMoreRunSave(false);
setPrefMoreHighlight(false);
// ***** auto update support
setCheckUpdate(false);
setLastSeenUpdate("0.0.0");
setCheckUpdateTime();
// ***** IDE general support
if (NEWBEE == typ) {
setIdeSize(new Dimension(0, 0));
setIdeLocation(new Point(0, 0));
}
setPrefMoreImages(false);
setPrefMoreImagesPath("");
// ***** message area settings
if (NEWBEE == typ) {
setPrefMoreMessage(HORIZONTAL);
} else {
setPrefMoreMessage(VERTICAL);
}
setPrefMoreLogActions(true);
setPrefMoreLogInfo(true);
setPrefMoreLogDebug(true);
setConsoleCSS(DEFAULT_CONSOLE_CSS);
// ***** text search and OCR
setPrefMoreTextSearch(false);
setPrefMoreTextOCR(false);
}
}
sikulix-1.1.1/API/src/main/java/org/sikuli/basics/Settings.java 0000664 0000000 0000000 00000043767 13157261304 0024270 0 ustar 00root root 0000000 0000000 /*
* Copyright (c) 2010-2016, Sikuli.org, sikulix.com
* Released under the MIT License.
*
*/
package org.sikuli.basics;
import org.sikuli.script.RunTime;
import java.io.File;
import java.net.InetAddress;
import java.net.Proxy;
import java.util.Date;
import org.sikuli.script.Image;
/**
* This is the container for all
*/
public class Settings {
public static boolean experimental = false;
private static String me = "Settings: ";
private static int lvl = 3;
public static boolean noPupUps = false;
public static boolean FindProfiling = false;
public static boolean InputFontMono = false;
public static int InputFontSize = 14;
private static void log(int level, String message, Object... args) {
Debug.logx(level, me + message, args);
}
public static boolean runningSetupInValidContext = false;
public static String runningSetupInContext = null;
public static String runningSetupWithJar = null;
public static boolean isRunningIDE = false;
public static int breakPoint = 0;
public static boolean handlesMacBundles = true;
public static boolean runningSetup = false;
private static PreferencesUser prefs;
/**
* location of folder Tessdata
*/
public static String OcrDataPath = null;
/**
* standard place in the net to get information about extensions
* needs a file extensions.json with content
* {"extension-list":
* {"extensions":
* [
* {
* "name":"SikuliGuide",
* "version":"0.3",
* "description":"visual annotations",
* "imgurl":"somewhere in the net",
* "infourl":"http://doc.sikuli.org",
* "jarurl":"---extensions---"
* },
* ]
* }
* }
* imgurl: to get an icon from
* infourl: where to get more information
* jarurl: where to download the jar from (no url: this standard place)
*/
//
// public static int SikuliVersionMajor;
// public static int SikuliVersionMinor;
// public static int SikuliVersionSub;
// public static int SikuliVersionBetaN;
// public static String SikuliProjectVersionUsed = "";
// public static String SikuliProjectVersion = "";
// public static String SikuliVersionBuild;
// public static String SikuliVersionType;
// public static String SikuliVersionTypeText;
// public static String downloadBaseDirBase;
// public static String downloadBaseDirWeb;
// public static String downloadBaseDir;
// // used for download of production versions
// private static final String dlProdLink = "https://launchpad.net/raiman/sikulix2013+/";
// private static final String dlProdLink1 = ".0";
// private static final String dlProdLink2 = "/+download/";
// // used for download of development versions (nightly builds)
// private static final String dlDevLink = "http://nightly.sikuli.de/";
// public static String SikuliRepo;
// public static String SikuliLocalRepo = "";
// public static String[] ServerList = {"http://dl.dropboxusercontent.com/u/42895525/SikuliX"};
// private static String sversion;
// private static String bversion;
// public static String SikuliVersionDefault;
// public static String SikuliVersionBeta;
// public static String SikuliVersionDefaultIDE;
// public static String SikuliVersionBetaIDE;
// public static String SikuliVersionDefaultScript;
// public static String SikuliVersionBetaScript;
// public static String SikuliVersion;
// public static String SikuliVersionIDE;
// public static String SikuliVersionScript;
// public static String SikuliJythonVersion;
// public static String SikuliJythonVersion25 = "2.5.4-rc1";
// public static String SikuliJythonMaven;
// public static String SikuliJythonMaven25;
// public static String SikuliJython;
// public static String SikuliJRubyVersion;
// public static String SikuliJRuby;
// public static String SikuliJRubyMaven;
// public static String dlMavenRelease = "https://repo1.maven.org/maven2/";
// public static String dlMavenSnapshot = "https://oss.sonatype.org/content/groups/public/";
//
// public static Map tessData = new HashMap();
//
// //TODO needed ???
// public static final String libOpenCV = "libopencv_java248";
//
// public static String osName;
// public static String SikuliVersionLong;
// public static String SikuliSystemVersion;
// public static String SikuliJavaVersion;
//
public static final float FOREVER = Float.POSITIVE_INFINITY;
public static final int JavaVersion = makeJavaVersion();
private static int makeJavaVersion() {
try {
return Integer.parseInt(java.lang.System.getProperty("java.version").substring(2, 3));
} catch (Exception ex) {
//TODO Java9
return 9;
}
}
public static final String JREVersion = java.lang.System.getProperty("java.runtime.version");
public static final String JavaArch = System.getProperty("os.arch");
/**
* Resource types to be used with IResourceLoader implementations
*/
public static final String SIKULI_LIB = "*sikuli_lib";
public static String proxyName = "";
public static String proxyIP = "";
public static InetAddress proxyAddress = null;
public static String proxyPort = "";
public static boolean proxyChecked = false;
public static Proxy proxy = null;
/**
* INTERNAL USE: to trigger the initialization
*/
public static synchronized void init() {
// TODO check existence of an extension repository
//TODO Windows:
//Mrz 23, 2015 12:25:43 PM java.util.prefs.WindowsPreferences
//WARNING: Could not open/create prefs root node Software\JavaSoft\Prefs
//at root 0x80000002. Windows RegCreateKeyEx(...) returned error code 5.
// prefs = PreferencesUser.getInstance();
// proxyName = prefs.get("ProxyName", null);
// String proxyIP = prefs.get("ProxyIP", null);
// InetAddress proxyAddress = null;
// String proxyPort = prefs.get("ProxyPort", null);
//
// SikuliRepo = null;
// Properties prop = new Properties();
// String svf = "sikulixversion.txt";
// try {
// InputStream is;
// is = Settings.class.getClassLoader().getResourceAsStream("Settings/" + svf);
// prop.load(is);
// is.close();
// String svt = prop.getProperty("sikulixdev");
// SikuliVersionMajor = Integer.decode(prop.getProperty("sikulixvmaj"));
// SikuliVersionMinor = Integer.decode(prop.getProperty("sikulixvmin"));
// SikuliVersionSub = Integer.decode(prop.getProperty("sikulixvsub"));
// SikuliVersionBetaN = Integer.decode(prop.getProperty("sikulixbeta"));
// String ssxbeta = "";
// if (SikuliVersionBetaN > 0) {
// ssxbeta = String.format("-Beta%d", SikuliVersionBetaN);
// }
// SikuliVersionBuild = prop.getProperty("sikulixbuild");
// log(lvl + 1, "%s version from %s: %d.%d.%d%s build: %s", svf,
// SikuliVersionMajor, SikuliVersionMinor, SikuliVersionSub, ssxbeta,
// SikuliVersionBuild, svt);
// sversion = String.format("%d.%d.%d",
// SikuliVersionMajor, SikuliVersionMinor, SikuliVersionSub);
// bversion = String.format("%d.%d.%d-Beta%d",
// SikuliVersionMajor, SikuliVersionMinor, SikuliVersionSub, SikuliVersionBetaN);
// SikuliVersionDefault = "SikuliX " + sversion;
// SikuliVersionBeta = "Sikuli " + bversion;
// SikuliVersionDefaultIDE = "SikulixIDE " + sversion;
// SikuliVersionBetaIDE = "SikulixIDE " + bversion;
// SikuliVersionDefaultScript = "SikulixScript " + sversion;
// SikuliVersionBetaScript = "SikulixScript " + bversion;
//
// if ("release".equals(svt)) {
// downloadBaseDirBase = dlProdLink;
// downloadBaseDirWeb = downloadBaseDirBase + getVersionShortBasic() + dlProdLink1;
// downloadBaseDir = downloadBaseDirWeb + dlProdLink2;
// SikuliVersionType = "";
// SikuliVersionTypeText = "";
// } else {
// downloadBaseDirBase = dlDevLink;
// downloadBaseDirWeb = dlDevLink;
// downloadBaseDir = dlDevLink;
// SikuliVersionTypeText = "nightly";
// SikuliVersionBuild += SikuliVersionTypeText;
// SikuliVersionType = svt;
// }
// if (SikuliVersionBetaN > 0) {
// SikuliVersion = SikuliVersionBeta;
// SikuliVersionIDE = SikuliVersionBetaIDE;
// SikuliVersionScript = SikuliVersionBetaScript;
// SikuliVersionLong = bversion + "(" + SikuliVersionBuild + ")";
// } else {
// SikuliVersion = SikuliVersionDefault;
// SikuliVersionIDE = SikuliVersionDefaultIDE;
// SikuliVersionScript = SikuliVersionDefaultScript;
// SikuliVersionLong = sversion + "(" + SikuliVersionBuild + ")";
// }
// SikuliProjectVersionUsed = prop.getProperty("sikulixvused");
// SikuliProjectVersion = prop.getProperty("sikulixvproject");
// String osn = "UnKnown";
// String os = System.getProperty("os.name").toLowerCase();
// if (os.startsWith("mac")) {
// osn = "Mac";
// } else if (os.startsWith("windows")) {
// osn = "Windows";
// } else if (os.startsWith("linux")) {
// osn = "Linux";
// }
//
// SikuliLocalRepo = FileManager.slashify(prop.getProperty("sikulixlocalrepo"), true);
// SikuliJythonVersion = prop.getProperty("sikulixvjython");
// SikuliJythonMaven = "org/python/jython-standalone/" +
// SikuliJythonVersion + "/jython-standalone-" + SikuliJythonVersion + ".jar";
// SikuliJythonMaven25 = "org/python/jython-standalone/" +
// SikuliJythonVersion25 + "/jython-standalone-" + SikuliJythonVersion25 + ".jar";
// SikuliJython = SikuliLocalRepo + SikuliJythonMaven;
// SikuliJRubyVersion = prop.getProperty("sikulixvjruby");
// SikuliJRubyMaven = "org/jruby/jruby-complete/" +
// SikuliJRubyVersion + "/jruby-complete-" + SikuliJRubyVersion + ".jar";
// SikuliJRuby = SikuliLocalRepo + SikuliJRubyMaven;
//
// SikuliSystemVersion = osn + System.getProperty("os.version");
// SikuliJavaVersion = "Java" + JavaVersion + "(" + JavaArch + ")" + JREVersion;
////TODO this should be in RunSetup only
////TODO debug version: where to do in sikulixapi.jar
////TODO need a function: reveal all environment and system information
//// log(lvl, "%s version: downloading from %s", svt, downloadBaseDir);
// } catch (Exception e) {
// Debug.error("Settings: load version file %s did not work", svf);
// Sikulix.terminate(999);
// }
// tessData.put("eng", "http://tesseract-ocr.googlecode.com/files/tesseract-ocr-3.02.eng.tar.gz");
//
getOS();
}
@Deprecated
public static String getInstallBase() {
return RunTime.get().fSxBase.getAbsolutePath();
}
public static boolean isValidImageFilename(String fname) {
String validEndings = ".png.jpg.jpeg";
String defaultEnding = ".png";
int dot = fname.lastIndexOf(".");
String ending = defaultEnding;
if (dot > 0) {
ending = fname.substring(dot);
if (validEndings.contains(ending.toLowerCase())) {
return true;
}
}
return false;
}
public static String getValidImageFilename(String fname) {
if (isValidImageFilename(fname)) {
return fname;
}
return fname + ".png";
}
public static final int ISWINDOWS = 0;
public static final int ISMAC = 1;
public static final int ISLINUX = 2;
public static final int ISNOTSUPPORTED = 3;
public static boolean isMacApp = false;
public static boolean isWinApp = false;
public static final String appPathMac = "/Applications/SikuliX-IDE.app/Contents";
public static boolean ThrowException = true; // throw FindFailed exception
public static float AutoWaitTimeout = 3f; // in seconds
public static float WaitScanRate = 3f; // frames per second
public static float ObserveScanRate = 3f; // frames per second
public static int ObserveMinChangedPixels = 50; // in pixels
public static int RepeatWaitTime = 1; // wait 1 second for visual to vanish after action
public static double MinSimilarity = 0.7;
public static boolean CheckLastSeen = true;
public static float CheckLastSeenSimilar = 0.95f;
public static boolean UseImageFinder = false;
private static int ImageCache = 64;
/**
* set the maximum to be used for the {@link Image} cache
*
the start up value is 64 (meaning MB)
*
using 0 switches off caching and clears the cache in that moment
*
* @param max cache size in MB
*/
public static void setImageCache(int max) {
if (ImageCache > max) {
Image.clearCache(max);
}
ImageCache = max;
}
public static int getImageCache() {
return ImageCache;
}
public static double DelayValue = 0.3;
public static double DelayBeforeMouseDown = DelayValue;
@Deprecated
// use DelayBeforeDrag instead
public static double DelayAfterDrag = DelayValue;
public static double DelayBeforeDrag = -DelayValue;
public static double DelayBeforeDrop = DelayValue;
/**
* Specify a delay between the key presses in seconds as 0.nnn. This only
* applies to the next type and is then reset to 0 again. A value > 1 is cut
* to 1.0 (max delay of 1 second)
*/
public static double TypeDelay = 0.0;
/**
* Specify a delay between the mouse down and up in seconds as 0.nnn. This
* only applies to the next click action and is then reset to 0 again. A value
* > 1 is cut to 1.0 (max delay of 1 second)
*/
public static double ClickDelay = 0.0;
public static boolean ClickFast = false;
public static boolean RobotFake = true;
public static String BundlePath = null;
public static boolean OcrTextSearch = false;
public static boolean OcrTextRead = false;
public static String OcrLanguage = "eng";
/**
* true = start slow motion mode, false: stop it (default: false) show a
* visual for SlowMotionDelay seconds (default: 2)
*/
public static boolean TRUE = true;
public static boolean FALSE = false;
private static boolean ShowActions = false;
public static boolean OverwriteImages = false;
public static boolean isShowActions() {
return ShowActions;
}
public static void setShowActions(boolean ShowActions) {
if (ShowActions) {
MoveMouseDelaySaved = MoveMouseDelay;
} else {
MoveMouseDelay = MoveMouseDelaySaved;
}
Settings.ShowActions = ShowActions;
}
public static float SlowMotionDelay = 2.0f; // in seconds
public static float MoveMouseDelay = 0.5f; // in seconds
private static float MoveMouseDelaySaved = MoveMouseDelay;
/**
* true = highlight every match (default: false) (show red rectangle around)
* for DefaultHighlightTime seconds (default: 2)
*/
public static boolean Highlight = false;
public static float DefaultHighlightTime = 2f;
public static float WaitAfterHighlight = 0.3f;
public static boolean ActionLogs = true;
public static boolean InfoLogs = true;
public static boolean DebugLogs = false;
public static boolean ProfileLogs = false;
public static boolean LogTime = false;
public static boolean UserLogs = true;
public static String UserLogPrefix = "user";
public static boolean UserLogTime = true;
public static boolean TraceLogs = false;
/**
* default pixels to add around with nearby() and grow()
*/
public static final int DefaultPadding = 50;
public static boolean isJava7() {
return JavaVersion > 6;
}
public static boolean isJava6() {
return JavaVersion < 7;
}
// public static void showJavaInfo() {
// Debug.log(1, "Running on Java " + JavaVersion + " (" + JREVersion + ")");
// }
public static String getFilePathSeperator() {
return File.separator;
}
public static String getPathSeparator() {
if (isWindows()) {
return ";";
}
return ":";
}
public static String getSikuliDataPath() {
String home, sikuliPath;
if (isWindows()) {
home = System.getenv("APPDATA");
sikuliPath = "Sikulix";
} else if (isMac()) {
home = System.getProperty("user.home")
+ "/Library/Application Support";
sikuliPath = "Sikulix";
} else {
home = System.getProperty("user.home");
sikuliPath = ".Sikulix";
}
File fHome = new File(home, sikuliPath);
return fHome.getAbsolutePath();
}
/**
* @return absolute path to the user's extension path
*/
public static String getUserExtPath() {
String ret = getSikuliDataPath() + File.separator + "Extensions";
File f = new File(ret);
if (!f.exists()) {
f.mkdirs();
}
return ret;
}
public static int getOS() {
int osRet;
String os = System.getProperty("os.name").toLowerCase();
if (os.startsWith("mac")) {
osRet = ISMAC;
} else if (os.startsWith("windows")) {
osRet = ISWINDOWS;
} else {
osRet = ISLINUX;
}
return osRet;
}
public static boolean isWindows() {
return getOS() == ISWINDOWS;
}
public static boolean isLinux() {
return getOS() == ISLINUX;
}
public static boolean isMac() {
return getOS() == ISMAC;
}
public static boolean isMac10() {
if (isMac() && Settings.getOSVersion().startsWith("10.1")) {
return true;
}
return false;
}
public static String getShortOS() {
if (isWindows()) {
return "win";
}
if (isMac()) {
return "mac";
}
return "lux";
}
public static String getOSVersion() {
return System.getProperty("os.version");
}
public static String getTimestamp() {
return (new Date()).getTime() + "";
}
}
sikulix-1.1.1/API/src/main/java/org/sikuli/basics/SikulixForJython.java 0000664 0000000 0000000 00000000476 13157261304 0025751 0 ustar 00root root 0000000 0000000 /*
* Copyright (c) 2010-2016, Sikuli.org, sikulix.com
* Released under the MIT License.
*
*/
package org.sikuli.basics;
/**
* to activate Jython support use org.sikuli.script.SikulixForJython instead
*/
@Deprecated
public class SikulixForJython {
static {
org.sikuli.script.SikulixForJython.get();
}
}
sikulix-1.1.1/API/src/main/java/org/sikuli/basics/SplashFrame.java 0000664 0000000 0000000 00000010246 13157261304 0024657 0 ustar 00root root 0000000 0000000 /*
* Copyright (c) 2010-2016, Sikuli.org, sikulix.com
* Released under the MIT License.
*
*/
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package org.sikuli.basics;
import java.awt.Color;
import java.awt.Container;
import java.util.Date;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JSeparator;
import org.sikuli.script.RunTime;
/**
*
* @author rhocke
*/
public class SplashFrame extends JFrame {
private static JFrame splash = null;
private static long start = 0;
public static void displaySplash(String[] args) {
if (args == null) {
if (splash != null) {
splash.dispose();
}
if (start > 0) {
Debug.log(3, "Sikuli-Script startup: " + ((new Date()).getTime() - start));
start = 0;
}
return;
}
if (args.length > 0 && (args[0].contains("-testSetup") || args[0].startsWith("-i"))) {
start = (new Date()).getTime();
String[] splashArgs = new String[]{
"splash", "#", "#" + RunTime.get().SikuliVersionScript, "", "#", "#... starting - please wait ..."};
for (String e : args) {
splashArgs[3] += e + " ";
}
splashArgs[3] = splashArgs[3].trim();
splash = new SplashFrame(splashArgs);
}
}
public static void displaySplashFirstTime(String[] args) {
if (args == null) {
if (splash != null) {
splash.dispose();
}
if (start > 0) {
Debug.log(3, "Sikuli-IDE environment setup: " + ((new Date()).getTime() - start));
start = 0;
}
return;
}
start = (new Date()).getTime();
String[] splashArgs = new String[]{
"splash", "#", "#" + RunTime.get().SikuliVersionIDE, "", "#", "#... setting up environement - please wait ..."};
splash = new SplashFrame(splashArgs);
}
private JLabel lbl, txt;
private Container pane;
private int proSize;
private int fw, fh;
public SplashFrame(String type) {
init(new String[]{type});
}
public SplashFrame(String[] args) {
init(args);
}
private void init(String[] args) {
setResizable(false);
setUndecorated(true);
pane = getContentPane();
if ("download".equals(args[0])) {
pane.setLayout(new BoxLayout(pane, BoxLayout.Y_AXIS));
pane.add(new JLabel(" "));
lbl = new JLabel("");
lbl.setAlignmentX(CENTER_ALIGNMENT);
pane.add(lbl);
pane.add(new JLabel(" "));
txt = new JLabel("... waiting");
txt.setAlignmentX(CENTER_ALIGNMENT);
pane.add(txt);
fw = 350;
fh = 80;
}
if ("splash".equals(args[0])) {
pane.setLayout(new BoxLayout(pane, BoxLayout.Y_AXIS));
pane.setBackground(Color.yellow);
int n = args.length;
String e;
int l = 0;
int nlbl = 0;
for (int i = 1; i < n; i++) {
e = args[i];
if (e.length() > l) {
l = e.length();
}
if (e.length() > 1 && e.startsWith("#")) {
nlbl++;
}
}
JLabel[] lbls = new JLabel[nlbl];
nlbl = 0;
for (int i = 1; i < n; i++) {
e = args[i];
if (e.startsWith("#")) {
if (e.length() > 1) {
lbls[nlbl] = new JLabel(e.substring(1));
lbls[nlbl].setAlignmentX(CENTER_ALIGNMENT);
pane.add(lbls[nlbl]);
nlbl++;
}
pane.add(new JSeparator());
} else {
pane.add(new JLabel(e));
}
}
fw = 10 + 10*l;
fh = 10 + n*15 + nlbl*15;
}
pack();
setSize(fw, fh);
setLocationRelativeTo(null);
setVisible(true);
}
public void setProFile(String proFile) {
lbl.setText("Downloading: " + proFile);
}
public void setProSize(int proSize) {
this.proSize = proSize;
}
public void setProDone(int done) {
if (done < 0) {
txt.setText(" ..... failed !!!");
} else if (proSize > 0) {
txt.setText(done + " % out of " + proSize + " KB");
} else {
txt.setText(done + " KB out of ??? KB");
}
repaint();
}
public void closeAfter(int secs) {
try {
Thread.sleep(secs*1000);
} catch (InterruptedException ex) {
}
setVisible(false);
}
}
sikulix-1.1.1/API/src/main/java/org/sikuli/basics/VDictProxy.java 0000664 0000000 0000000 00000007343 13157261304 0024531 0 ustar 00root root 0000000 0000000 /*
* Copyright (c) 2010-2016, Sikuli.org, sikulix.com
* Released under the MIT License.
*
*/
package org.sikuli.basics;
import org.sikuli.script.RunTime;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;
public class VDictProxy {
private long _instance;
private Map _i2obj = new HashMap();
static {
RunTime.loadLibrary("VDictProxy");
}
public VDictProxy(){
_instance = getInstance();
}
private native long getInstance();
private String getAbsolutePath(String filename) throws FileNotFoundException{
if(new File(filename).exists())
return filename;
filename = Settings.BundlePath + File.separator + filename;
if(new File(filename).exists())
return filename;
throw new FileNotFoundException("No such file: " + filename);
}
// insert an (key,value) entry using an image key
public void insert(String imagekey_filename, T value) throws FileNotFoundException {
imagekey_filename = getAbsolutePath(imagekey_filename);
int hash = value.hashCode();
while(true){
if( hash != -1 && !_i2obj.containsKey(hash) ){
_i2obj.put(hash, value);
break;
}
else{
hash += (int)(Math.random()*100);
}
}
_insert(_instance, imagekey_filename, hash);
}
public native void _insert(long instance, String imagekey_filename, int value);
// lookup the entry using an image key (exact match)
public T lookup(String imagekey_filename) throws FileNotFoundException{
imagekey_filename = getAbsolutePath(imagekey_filename);
int hash = _lookup(_instance, imagekey_filename);
if(hash==-1) return null;
return _i2obj.get(hash);
}
private native int _lookup(long instance, String imagekey_filename);
// lookup the first entry with a similar image key
public T lookup_similar(String imagekey_filename, double similarity_threshold) throws FileNotFoundException{
imagekey_filename = getAbsolutePath(imagekey_filename);
int hash = _lookup_similar(_instance, imagekey_filename, similarity_threshold);
if(hash==-1) return null;
return _i2obj.get(hash);
}
private native int _lookup_similar(long instance, String imagekey_filename, double similarity_threshold);
// lookup at most n entries with keys similar to the given image (n = 0 : all)
public List lookup_similar_n(String imagekey_filename, double similarity_threshold, int n) throws FileNotFoundException{
imagekey_filename = getAbsolutePath(imagekey_filename);
int h[] = _lookup_similar_n(_instance, imagekey_filename, similarity_threshold, n);
List ret = new Vector(h.length);
for(int i=0;i