diff --git a/README.md b/README.md index 956bc71..60742fd 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,20 @@ -Expyriment Android Runtime -========================== +Expyriment Android Runtime (EAR) +================================ + +The **Expyriment Android Runtime** (EAR) is a convinient way to run experiments created with [*Expyriment*] (http://www.expyriment.org) on an Android device. *Expyriment* is an open-source and platform-independent lightweight Python library for designing and conducting behavioral experiments: https://github.com/expyriment/expyriment + *GNU General Public License v3* Florian Krause (florian@expyriment.org) & Oliver Lindemann (oliver@expyriment.org) -About ------ -The Expyriment Android Runtime is a convinient way to run experiments created with [Expyriment] (http://www.expyriment.org) on an Android device. Installation ------------ -The easiest way is to install the Expyriment Android Runtime on you Android device is to download and install the latest release of our [Android application package] (https://github.com/expyriment/expyriment-android-runtime/releases). +The easiest way is to install EAR on you Android device is to download and install the latest release of our [Android application package] (https://github.com/expyriment/expyriment-android-runtime/releases). -You can build the Expyriment Android Runtime yourself as describe below: +You can build EAR yourself as describe below: 1. Installed the JAVA JDK: http://www.oracle.com/technetwork/java/javase/downloads/index.html 2. Download PGS4A (version 0.94) from http://pygame.renpy.org/dl @@ -32,18 +32,9 @@ Alternative, you can use the makefile: `make configure` (step 2 to 8) and `make Usage ----- -Once installed, the application will look for Expyriment scripts (each in its own subdirectory) in a directory called ‘expyriment’, located at the root level of either storage device under ‘mnt’ (i.e. the internal or external SD card). Examples of correctly located Expyriment scripts include: -``` -/mnt/sdcard0/expyriment/exp1/exp1.py - -/mnt/sdcard0/expyriment/exp2/exp2.py - -/mnt/extSdCard/expyriment/exp3/exp3.py - -/mnt/extSdCard/expyriment/exp4/exp4.py -``` +The application will look for any Expyriment script in a directory called ‘expyriment’ or its subdirectories, located at the root level of either storage device under ‘mnt’ (i.e. the internal or external SD card). E.g.: +`/mnt/sdcard0/expyriment/`, `/mnt/extSdCard/expyriment/`. -Note ----- -**Expyriment** is an open-source and platform-independent lightweight Python -library for designing and conducting behavioral experiments: http://www.expyriment.org, https://github.com/expyriment/expyriment +An Expyriment script must contain the following keyword strings: `expyriment` and +`initialize(`. The filename has to end with the suffix `.py`. Filenames starting with +an underscore (`_`) will be ignored. diff --git a/expyriment_app/main.py b/expyriment_app/main.py index d0ef108..7fb7212 100644 --- a/expyriment_app/main.py +++ b/expyriment_app/main.py @@ -1,11 +1,58 @@ import sys import os import glob +from importlib import import_module import pygame import expyriment import android +def find_keyword_files(folder): + """find all files with keywords in folder and subfolders + + Returns dict of files + """ + + keywords = ["expyriment", "initialize("] + rtn = {} + for entry in glob.glob(folder+"/*"): + if os.path.isdir(entry): + rtn.update(find_keyword_files(entry)) + elif entry.endswith(".py") and not \ + os.path.split(entry)[1].startswith("_"): + try: + with open(entry) as fl: + lines = fl.readlines() + except: + lines = "" + all_keywords_found = True + for key in keywords: + if not check_keyword(lines, key): + all_keywords_found = False + break + if all_keywords_found: + rtn[os.path.split(entry)[-1][:-3]] = entry + return rtn + +def check_keyword(lines, keyword): + """check if keyword occurs in text lines""" + for l in lines: + if l.find(keyword)>=0: + return True + return False + +def launch_experiment(script, name): + expyriment.stimuli.TextScreen(heading="Starting {0}".format(name), + text="").present() + expyriment.misc.Clock().wait(1000) + expyriment.control.defaults.event_logging = 1 + expyriment.control.defaults.initialize_delay = 0 + script = os.path.abspath(script) + path, pyfile = os.path.split(script) + os.chdir(path) + sys.argv[0] = script + sys.path.insert(1, path) + import_module(os.path.splitext(pyfile)[0]) def main(): android.init() @@ -13,13 +60,7 @@ def main(): projects = {} for folder in glob.glob("/mnt/*"): if os.path.isdir(folder): - for project in glob.glob(folder + "/expyriment/*"): - if os.path.isdir(project): - path = project + "/*.py" - else: - path = folder + "expyriment/*.py" - for pyfile in glob.glob(path): - projects[os.path.split(pyfile)[-1]] = pyfile + projects.update(find_keyword_files(folder + "/expyriment")) pygame.font.init() for font in glob.glob("/system/fonts/*"): @@ -68,25 +109,22 @@ def main(): expyriment.control.defaults.event_logging = 0 exp = expyriment.control.initialize() - mouse = expyriment.io.Mouse(show_cursor=False) if projects == {}: info_box = expyriment.stimuli.TextScreen("No experiments found!", -"Please put your experiments into a folder called 'expyriment', " + -"located on the internal or external sdcard.\n\n" + -"[Touch the screen to exit]") + "Please put your experiments into a folder called 'expyriment', " + + "located on the internal or external SDcard.\n\n" + + "[Touch the screen to exit]") info_box.present() - mouse.wait_press() + exp.mouse.wait_press() + elif len(projects)==1: # started immediately if no choice + launch_experiment(projects.values()[0], projects.keys()[0]) else: items = projects.keys() items.sort() menu = expyriment.io.TextMenu("Run experiment:", items, 320, - scroll_menu=5, mouse=mouse) - py_file = projects[menu.get()] - expyriment.control.defaults.event_logging = 1 - expyriment.control.defaults.initialize_delay = 0 - os.chdir(os.path.split(py_file)[0]) - sys.argv[0] = py_file - execfile("{0}".format(py_file), globals()) + scroll_menu=5, mouse=exp.mouse) + select = menu.get() + launch_experiment(projects[select], select) if __name__ == "__main__":