Skip to content

Commit

Permalink
fixed selenium bug by restructuring
Browse files Browse the repository at this point in the history
  • Loading branch information
Benjamin Bichsel committed Dec 27, 2020
1 parent 437af61 commit 69fd9aa
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 97 deletions.
24 changes: 6 additions & 18 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,23 +1,11 @@
FROM selenium/standalone-firefox-debug

USER root

RUN apt-get update && apt-get install -y \
python3 \
python3-pip \
&& apt-get clean && rm -rf /var/lib/apt/lists/*

USER seluser
FROM python:3.8

RUN pip3 install \
selenium \
pandas \
xlrd

# automatically start
RUN mkdir -p /home/seluser/logs
RUN echo "/opt/bin/entry_point.sh > /home/seluser/logs/$(date +%Y-%m-%d_%H-%M-%S).log &" >> /home/seluser/.bashrc
selenium==3.141.0 \
pandas==1.1.5 \
xlrd==2.0.1

WORKDIR "/sportdb-helper"
COPY --chown=seluser . .
COPY . .

ENTRYPOINT ["python3", "./code/insert_data.py"]
26 changes: 0 additions & 26 deletions Makefile

This file was deleted.

35 changes: 14 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,23 @@ Aufgrund dieser Daten füllt SportDB Helper automatisch die Anwesenheitskontroll

Die folgende Installationsanleitung ist für Ubuntu gedacht. Andere Systeme sollten analog verwendbar sein (nicht getestet, Anpassung braucht Erfahrung).

Um SportDB Helfer zu verwenden, brauchst du [docker](https://docs.docker.com/install/), `git` und `make`:
Um SportDB Helfer zu verwenden, brauchst du
[docker](https://docs.docker.com/install/),
[docker-compose](https://docs.docker.com/compose/) und `git`:

- Um `git` und `make` zu installieren:
```
# for git
sudo apt-get install git-all
# for make
sudo apt-get install build-essential
- Um `git` zu installieren:

```bash
# git
sudo apt-get install git-all
# optional: vnc client, um den Prozess live zu beobachten
sudo apt-get install vinagre --yes
```

- Docker auf Ubuntu installieren: https://docs.docker.com/install/linux/docker-ce/ubuntu/.
- Docker auf Ubuntu installieren:
https://docs.docker.com/install/linux/docker-ce/ubuntu/.

- Docker Compose auf Ubuntu installieren: https://docs.docker.com/compose/install/#install-compose-on-linux-systems

- Herunterladen von SportDB Helper:

Expand All @@ -43,18 +48,6 @@ git clone [email protected]:bichselb/sportdb-helper.git
cd sportdb-helper
```

- Installation von SportDP Helper (fragt nach dem Passwort für die Interaktion mit docker):

```bash
make image
```

- (Optional) Cleanup nach Verwendung (fragt nach dem Passwort für die Interaktion mit docker):

```bash
make clean
```

### SportDB Helper

Um SportDB Helper laufen zu lassen (fragt nach dem Passwort für die Interaktion mit docker):
Expand All @@ -65,7 +58,7 @@ Um SportDB Helper laufen zu lassen (fragt nach dem Passwort für die Interaktion
```

ACHTUNG: Die `course-id` ist nicht dasselbe wie die "Angebot"-Nummer. Die
`course-id` findest du, wenn du in der URL deines Kurses, z.B.:
`course-id` findest du in der URL deines Kurses, z.B. 1234567 in folgender URL:

- https://www.sportdb.ch/extranet/kurs/kursEdit.do?kursId=1234567&org.apache.struts.taglib.html.TOKEN=0000000000000000000000000

Expand Down
54 changes: 30 additions & 24 deletions code/insert_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,36 +28,36 @@ def parse_data(file):

class DataInserter:

def __init__(self, data, disable_all=False, max_tries=10):
def __init__(self, data, selenium_url, disable_all=False, max_tries=10):
self.data = data
self.driver = None
self.max_tries = max_tries
self.disable_all = disable_all
self.logged_in = False

def navigate_to_page(self):
sport_db_url = 'https://www.sportdb.ch'

logger.debug('Navigating to %s', sport_db_url)
self.is_remote = True

try:
self.driver = webdriver.Firefox()
self.is_remote = False
except WebDriverException as e:
logger.info('Could not run firefox locally. Switching to remote option. Error message: ' + str(e))

n_tries = 0
logger.info("Connecting to selenium at " + selenium_url)
while self.driver is None:
try:
self.driver = webdriver.Remote("http://localhost:4444/wd/hub", DesiredCapabilities.FIREFOX)
logger.info('Successfully opened sportdb')
self.driver = webdriver.Remote(selenium_url, DesiredCapabilities.FIREFOX)
logger.info('Successfully connected to selenium')
except MaxRetryError:
n_tries += 1
logger.warning('Remote webdriver is not running yet ({}/{})...'.format(n_tries, self.max_tries))
if n_tries >= self.max_tries:
logger.warning('Remote webdriver is not running yet ({}/{})...'.format(n_tries, max_tries))
if n_tries >= max_tries:
raise Exception('Remote webdriver does not seem to be running...')
else:
time.sleep(2)
time.sleep(1)

def navigate_to_page(self):
sport_db_url = 'https://www.sportdb.ch'
logger.debug('Navigating to %s', sport_db_url)
self.driver.get(sport_db_url)
logger.debug('Navigated to %s', sport_db_url)

Expand Down Expand Up @@ -193,28 +193,29 @@ def __del__(self):
self.driver.close()


def run(data_file, username, password, course_id, disable_all):
def run(data_file, username, password, course_id, disable_all, selenium_url, test):
logger.debug("Running...")

# parse data
data = parse_data(data_file)

# navigate
ins = DataInserter(data, disable_all)
ins = DataInserter(data, selenium_url, disable_all)
ins.navigate_to_page()
ins.login(username, password)
ins.to_awk(course_id)

# enter data
while True:
logger.info('Entering data...')
ins.enter_data()
logger.info('Entered data. Going to previous page...')
more = ins.to_previous()
if not more:
break
if not test:
# enter data
while True:
logger.info('Entering data...')
ins.enter_data()
logger.info('Entered data. Going to previous page...')
more = ins.to_previous()
if not more:
break

logger.info("Einträge vollständig. Keine Garantie für Korrektheit, bitte Daten überprüfen. Vergiss nicht, den Kurs noch abzuschliessen.")
logger.info("Einträge vollständig. Keine Garantie für Korrektheit, bitte Daten überprüfen. Vergiss nicht, den Kurs noch abzuschliessen.")


if __name__ == "__main__":
Expand All @@ -230,13 +231,18 @@ def run(data_file, username, password, course_id, disable_all):
help='Kurs ID (z.B. 1234567). Kann aus der URL der Anwesenheitskontrolle abgelesen werden. Wenn nicht angegeben, wirst du interaktiv angefragt, zur korrekten Anwesenheitskontrolle zu navigieren.')
parser.add_argument('--disable-all', dest='disable_all', action='store_true', default=False,
help='Deaktiviere die Anwesenheit für alle Personen und Daten im File.')
parser.add_argument('--test', action='store_true', default=False,
help='Nur Login&Logout.')
parser.add_argument('--selenium-url', default="http://selenium:4444/wd/hub",
help='URL unter der Selenium erreicht werden kann.')

args = parser.parse_args()

if args.password is None:
password = input("Password? ")
else:
password = args.password

run(args.data_file, args.username, password, args.course_id, args.disable_all)
run(args.data_file, args.username, password, args.course_id, args.disable_all, args.selenium_url, args.test)


22 changes: 22 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
version: '2.4'
services:
selenium:
image: selenium/standalone-firefox:4.0.0-beta-1-prerelease-20201208
ports:
- "5901:5900" # port for vnc (host:container)
expose:
- "4444"
healthcheck:
test: "opt/bin/check-grid.sh" # allow waiting until started
environment:
- VNC_NO_PASSWORD=1 # disable vnc password
volumes:
- /dev/shm:/dev/shm # known workaround suggested by selenium
sportdb-helper:
build: .
#ports:
# - "4444:4444" # port of selenium
depends_on:
selenium:
condition: service_healthy # wait until selenium is ready
container_name: sportdb-helper-container
30 changes: 22 additions & 8 deletions run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
# For a list of possible arguments, run
# $ ./run.sh --help

# enable bash strict mode
set -eu

BASEDIR="$( dirname "$0")"

last="${@:$#}" # last parameter
Expand All @@ -20,15 +23,26 @@ fi

cd "$BASEDIR"

# enable display forwarding for selenium
# https://stackoverflow.com/questions/25281992/alternatives-to-ssh-x11-forwarding-for-docker-containers
xhost +si:localuser:$USER
# prepare graceful exit
function finish {
sudo docker-compose down
}
trap finish EXIT


# build
sudo docker-compose build
# start selenium
sudo docker-compose up --detach selenium
sleep 3

# start vnc (ignore errors)
echo "Starting vnc client"
vinagre 127.0.0.1:5901 2>/dev/null || true &

sudo docker run \
# run sportdb-helper
sudo docker-compose run \
--rm \
-it \
--name sportdb-helper-container \
-e DISPLAY=$DISPLAY \
-v /tmp/.X11-unix:/tmp/.X11-unix:ro \
-v $(pwd)/data:/sportdb-helper/data \
sportdb-helper $last $other
sportdb-helper $last $other

0 comments on commit 69fd9aa

Please sign in to comment.