Skip to content

Commit

Permalink
moved code
Browse files Browse the repository at this point in the history
  • Loading branch information
Beni Bichsel committed Dec 28, 2018
1 parent 29a3c7f commit 2a8e54a
Show file tree
Hide file tree
Showing 10 changed files with 406 additions and 52 deletions.
8 changes: 8 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/code/env
/__pycache__
/.idea
/code/*.log

/.git
/data
/images
2 changes: 0 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
/env
/__pycache__
/.idea
/*.log
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ RUN echo "/opt/bin/entry_point.sh > /home/seluser/logs/$(date +%Y-%m-%d_%H-%M-%S

WORKDIR "/sportdb-helper"
COPY --chown=seluser . .
ENTRYPOINT ["python3", "./insert-data.py"]
ENTRYPOINT ["python3", "./code/insert_data.py"]
2 changes: 2 additions & 0 deletions code/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/*.log
/env
190 changes: 190 additions & 0 deletions code/geckodriver.log

Large diffs are not rendered by default.

81 changes: 46 additions & 35 deletions insert-data.py → code/insert_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,7 @@

# UTILS

def get_week_difference(d1, d2):
monday1 = (d1 - datetime.timedelta(days=d1.weekday()))
monday2 = (d2 - datetime.timedelta(days=d2.weekday()))

return int((monday2 - monday1).days / 7)


# allow computation of the week id
epoch = datetime.datetime(1980, 1, 6)
specific_week_difference = get_week_difference(epoch, datetime.datetime(2018, 1, 22))
off_by = 43328566 - specific_week_difference


def get_week_id(d):
return get_week_difference(epoch, d) + off_by

date_regex = re.compile("^[0-9]+\.[0-9]+\.[0-9]+$")

# PARSE DATA

Expand Down Expand Up @@ -92,44 +77,68 @@ def to_awk(self, course_id):
if 'Error' in self.driver.title:
raise Exception('Something went wrong. Most likely, you entered the wrong course id.')

def insert_attendance(self, date, js_id, name, attended):
week_id = get_week_id(date)
xpath = ".//*[@name='kursAktivitaetTeilnehmerMap({})']".format(week_id)
boxes = self.driver.find_elements_by_xpath(xpath)
for box in boxes:
value = box.get_property("value")
pattern = re.compile("^I-{}\\|[0-9]+$".format(js_id))
if pattern.match(value):
if attended and not box.is_selected():
print('{} attended on {}'.format(name, date))
box.click()
if not attended and box.is_selected():
print('{} did not attend on {}'.format(name, date))
box.click()
@staticmethod
def set_attendance(attended, box, name, date):

if attended and not box.is_selected():
print('{} attended on {}'.format(name, date))
box.click()
return True
if not attended and box.is_selected():
print('{} did not attend on {}'.format(name, date))
box.click()
return True

return False

def enter_data(self):
changed = False

# match ids and days
days = self.driver.find_elements_by_xpath(".//*[contains(@class, 'awkDay')]//span")
days = [d.text for d in days if date_regex.match(d.text)]
day_ids = self.driver.find_elements_by_xpath(".//*[contains(@class, 'select-all leiter')]")
day_ids = [d.get_attribute('name') for d in day_ids]
assert(len(days) == len(day_ids))
day_to_id = {day: day_id for day, day_id in zip(days, day_ids)}
print('Found days:', day_to_id)

# enter data
for column in self.data:
date = column.to_pydatetime()
date = column.to_pydatetime().strftime('%d.%m.%Y')
for key, val in self.data[column].iteritems():
js_id = key[0]
name = key[2]
attended = val == 'x'
self.insert_attendance(date, js_id, name, attended)

save = self.driver.find_element_by_id('formSave')
save.click()
if date in day_to_id:
day_id = day_to_id[date]
box = self.driver.find_element_by_xpath(
".//input[contains(@name, 'kursAktivitaetTeilnehmerMap({})')][contains(@name, 'I-{}')]"
.format(day_id, js_id)
)
changed = changed or self.set_attendance(attended, box, name, date)

# save
if changed:
save = self.driver.find_element_by_id('formSave')
save.click()

def to_previous(self):
previous = self.driver.find_element_by_id('previousLink')
c = previous.get_attribute("class")
if 'disabled' not in c:
# reload to prevent stale elements (a bit of a hack)
previous = self.driver.find_element_by_id('previousLink')
previous.click()
return True
else:
return False

def __del__(self):
if self.driver is not None:
logout = self.driver.find_element_by_id('logout')
logout.click()
self.driver.close()


Expand All @@ -145,7 +154,9 @@ def run(data_file, username, password, course_id):

# enter data
while True:
print('Entering data...')
ins.enter_data()
print('Entered data. Going to previous page...')
more = ins.to_previous()
if not more:
break
Expand All @@ -159,7 +170,7 @@ def run(data_file, username, password, course_id):
type=str, default=None,
help='Passwort für sportdb (default: interaktive Eingabe)')
parser.add_argument('--course-id', dest='course_id', action='store', default=None, type=str,
help='Kurs ID (z.B. 1234567). Wenn nicht angegeben, wirst du interaktiv angefragt, zur korrekten Anwesenheitskontrolle zu navigieren.')
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('--data-file', dest='data_file', action='store',
type=str, default='data/attendance.xls',
help='File mit Daten. Siehe data/reference.xls für ein Referenzfile')
Expand Down
43 changes: 43 additions & 0 deletions code/log.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
[loggers]
keys=root,sLogger

[handlers]
keys=fileHandler,consoleHandler,slackHandler

[formatters]
keys=consoleFormatter,messageFormatter

[logger_root]
level=DEBUG
handlers=consoleHandler

[logger_sLogger]
level=DEBUG
handlers=fileHandler,consoleHandler,slackHandler
qualname=sLogger
propagate=0

[handler_consoleHandler]
class=StreamHandler
level=INFO
formatter=messageFormatter
args=(sys.stdout,)

[handler_fileHandler]
class=FileHandler
level=DEBUG
formatter=consoleFormatter
args=('%(logfile)s',)

[handler_slackHandler]
class=mylogging.SlackHandler
level=ERROR
formatter=messageFormatter
args=()

[formatter_messageFormatter]
format=%(message)s

[formatter_consoleFormatter]
format=[%(asctime)s] %(levelname)s [%(name)s.%(funcName)s:%(lineno)d] %(message)s
datefmt='%Y-%m-%d %H:%M:%S
114 changes: 114 additions & 0 deletions code/mylogging.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
from logging import *
from logging.config import fileConfig, dictConfig
import os
import json
from collections import OrderedDict

dir_path = os.path.dirname(os.path.realpath(__file__))
log_path = os.path.join(dir_path, '../ci-output/script-logs')
log_file = os.path.join(log_path, 'logs.log')
log_ini_file = os.path.join(dir_path, 'log.ini')

def get_list(filename):
with open(filename, 'r', encoding='iso-8859-1') as f:
lines = f.read().splitlines()
lines = [l for l in lines if not l.startswith('#')]
return lines

class SlackHandler(Handler):
def __init__(self, *args, **kwargs):
super(SlackHandler, self).__init__(*args, **kwargs)
self.buffer = []
self.slack_url = self.get_environment_variable('SLACK_TOKEN')
self.details = {
'commit' : self.get_environment_variable('CI_COMMIT_SHA'),
'message': self.get_environment_variable('CI_COMMIT_MESSAGE'),
'user' : self.get_environment_variable('GITLAB_USER_NAME'),
'user-email' : self.get_environment_variable('GITLAB_USER_EMAIL'),
'job-URL': self.get_environment_variable('CI_JOB_URL')
}
if self.details['message'] is not None:
self.details['message'] = self.details['message'].rstrip()
for k in list(self.details.keys()):
if self.details[k] is None:
del self.details[k]

# parse slack user IDs
self.slack_id_dict = {}
slack_ids_file = os.path.join(dir_path, 'slack-user-ids.txt')
ids_list = get_list(slack_ids_file)
for d in ids_list:
splits = d.split(",")
email = splits[0]
slack_id = splits[1]
self.slack_id_dict[email] = slack_id

def get_environment_variable(self, name):
return os.environ.get(name, None)

def emit(self, record):
msg = self.format(record)
logger.debug('Slack message: %s', msg)
self.buffer.append(msg)

def post_to_slack(self, msg):
if self.slack_url is None:
logger.info('Not sending message to slack because slack url is not set...')

else:
logger.info('Sending message to slack...')

payload = json.dumps({'text': msg})
logger.debug('Sending payload to slack %s: %s', self.slack_url, payload)
r = requests.post(self.slack_url, data=payload, headers={'Content-Type': 'application/json'})
logger.debug("Slack Response: %s %s", r.status_code, r.text.encode('utf-8'))

def format_slack_mention(self, user_email):
if user_email in self.slack_id_dict:
return "<@%s>" % self.slack_id_dict[user_email]
return ""

def flush(self):
if len(self.buffer) > 0:
labels = OrderedDict([
('commit', 'Commit'),
('message', 'Commit message'),
('user', 'Who'),
('job-URL', 'Details')
])
details = ['> ' + l + ': ' + self.details[k] for k, l in labels.items() if k in self.details]
context = 'The latest commit contains errors. Please fix them. ' + '\n' + '\n'.join(details)
if "user-email" in self.details:
context = self.format_slack_mention(self.details["user-email"]) + ' ' + context

msgs = '\n\n'.join([context] + self.buffer)
self.post_to_slack(msgs)
self.buffer = []


fileConfig(log_ini_file, defaults={'logfile': log_file})
logger = getLogger('sLogger')


def report_error(error, details=None, solutions=None):
"""
:param error: string
:param details: list of strings
:param solutions: list of strings
"""
# details
if details is not None:
details = ['> ' + s for s in details]
details = ['[DETAILS]:'] + details
details = '\n'.join(details)
# solutions
if solutions is not None:
solutions = ['> ' + s for s in solutions]
solutions = ['[SOLUTIONS]:'] + solutions
solutions = '\n'.join(solutions)
msg = '[ERROR]: ' + error
if details is not None:
msg += '\n' + details
if solutions is not None:
msg += '\n' + solutions
logger.error(msg)
2 changes: 1 addition & 1 deletion setup.sh → code/setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ ENVNAME=env
# ENVIRONMENT #
###############
if [ -d "$ENVNAME" ]; then
echo "$ENVNAME already exists"
echo "$ENVNAME already exists..."
else
python3 -m venv $ENVNAME
fi
Expand Down
14 changes: 1 addition & 13 deletions run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,8 @@ xhost +si:localuser:$USER

sudo docker run \
--rm \
-p 5901:5900 \
-v /dev/shm:/dev/shm \
-e VNC_NO_PASSWORD=1 \
-it \
--name sportdb-helper-container \
-e DISPLAY=$DISPLAY \
-v /tmp/.X11-unix:/tmp/.X11-unix:ro \
sportdb-helper "$@"

exit

sudo docker run \
--rm \
-p 5901:5900 \
-v /dev/shm:/dev/shm \
-e VNC_NO_PASSWORD=1 \
--name sportdb-helper-container \
sportdb-helper "$@"

0 comments on commit 2a8e54a

Please sign in to comment.