Skip to content

Melodi Integration 0.0.1 #16

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 4 commits into
base: autosub_devel
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 58 additions & 20 deletions VELS_WEB/controllers/vels_plugins.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
def __list_plugins():
# Please verify that VELS_OB Swagger client is copied into web2py/site-packages/swagger_client
import swagger_client as api_vels_ob
from swagger_client.rest import ApiException

def __list_plugins(returnDict):

#####
# create list of all active plugins
Expand All @@ -8,15 +12,15 @@ def __list_plugins():
array=[]
unique_plugins = []
parameterDict = dict({})
returnDict = dict({})

for row in rows:
if(row.PluginName not in unique_plugins):
unique_plugins.append(row.PluginName)
current_plugin = []
current_plugin = dict({})
for subrow in rows:
if(unique_plugins[-1] == subrow.PluginName):
current_plugin.append(subrow.ParameterName)
current_plugin.update({subrow.ParameterName : subrow.Value})

parameterDict.update({row.PluginName : current_plugin})
parameterDict.update({row.PluginName : current_plugin})

Expand All @@ -25,36 +29,70 @@ def __list_plugins():

return returnDict

def __assemble_plugin(plugin_name):
def __assemble_plugin(plugin_name, returnDict):

#####
# set entries for each plugin
# plugin_active controls if plugin is visible at VELS_WEB
# plugin_active has to be set for every possible plugin
#####
returnDict={}

#if(plugin_name == 'vels_ob'):
# returnDict.update({'vels_ob_active': True})
if(plugin_name == 'vels_ob'):
returnDict.update({'vels_ob_active': True})

MelodiURL = returnDict.get("PluginParameter").get(plugin_name).get("server")
MelodiPort = returnDict.get("PluginParameter").get(plugin_name).get("port")

api_con = api_vels_ob.Configuration()
api_con.host = "{}:{}/api".format(MelodiURL, MelodiPort)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alternative would be f-string, since Python 3.6:
api_con.host = f"{MelodiURL}:{MelodiPort}/api"

task_instance = api_vels_ob.TaskApi(api_vels_ob.ApiClient(api_con))
try:
all_tasks = task_instance.list_of_tasks()
returnDict.update({'vels_ob_tasks': all_tasks})
except ApiException as e:
print("Exception: %s\n" % e)


return returnDict


@auth.requires_permission('view data')
def index():
returnDict={}
returnDict.update(__list_plugins())

returnDict.update(__assemble_plugin('vels_ob'))
__list_plugins(returnDict)
__assemble_plugin('vels_ob', returnDict)
return returnDict

#@auth.requires_permission('edit data')
#def delete():
# TaskNr= request.vars['TaskNr']
# UserId= request.vars['UserId']
# if semester( (UserTasks.TaskNr==TaskNr) & (UserTasks.UserId==UserId) ).delete():
# msg='Deletion of UserTask with UserId/TaskNr'+UserId+'/'+TaskNr+' succeded'
# else:
# msg='Deletion of UserTask with UserId/TaskNr'+UserId+'/'+TaskNr+' failed'
# redirect(URL('index'))
@auth.requires_permission('edit data')
def delete():
returnDict={}
__list_plugins(returnDict)
# HTTP Parameter
UserId= request.vars['UserId']

# Config Parameter
MelodiURL = returnDict.get("PluginParameter").get("vels_ob").get("server")
MelodiPort = returnDict.get("PluginParameter").get("vels_ob").get("port")
MelodiUser = returnDict.get("PluginParameter").get("vels_ob").get("user")
MelodiPassword = returnDict.get("PluginParameter").get("vels_ob").get("password")

# Swagger Client config
api_con = api_vels_ob.Configuration()
api_con.host = "{}:{}/api".format(MelodiURL, MelodiPort)
api_con.api_key_prefix['Authorization'] = 'Bearer'

# Swagger Client instance creation
auth_instance = api_vels_ob.AuthApi(api_vels_ob.ApiClient(api_con))
task_instance = api_vels_ob.TaskApi(api_vels_ob.ApiClient(api_con))

payload = api_vels_ob.AuthDetails(email=MelodiUser, password=MelodiPassword)
try:
result = auth_instance.user_login(payload)
api_con.api_key['Authorization'] = result.authorization

deleted_task = task_instance.delete_a_task(UserId)
except ApiException as e:
#print("Exception: %s\n" % e)
redirect(URL('index', vars=dict(error=str(e))))
redirect(URL('index'))

82 changes: 53 additions & 29 deletions VELS_WEB/views/vels_plugins/index.html
Original file line number Diff line number Diff line change
@@ -1,46 +1,70 @@
{{extend 'layout.html'}}
<h1>Active Plugins</h1>
<b>This list gives an overview of the active plugins and the corresponding parameters for this course. To change them, edit the configuration file and restart the autosub daemon.</b>
<b>This list gives an overview of the active plugins and the corresponding parameters for this course. To change them,
edit the configuration file and restart the autosub daemon.</b>
<br></br>

<table border="1">
<thead>
<tr>
<th>PluginName</th>
<th>Parameters</th>
<tr>
<th>PluginName</th>
<th>Parameters</th>

</tr>
</thead>
{{for plugin_name in ActivePlugins:}}
<tr>
<td>{{=plugin_name}}</td>
<td>{{for index,parameter in enumerate(PluginParameter[plugin_name]):}}
{{if index > 0:}}
,&nbsp;
{{pass}}
{{=parameter}}
{{pass}}
</td>
</tr>
{{pass}}
</thead>
{{for plugin_name in ActivePlugins:}}
<tr>
<td>{{=plugin_name}}</td>
<td>{{for index,(parameter, value) in enumerate(PluginParameter[plugin_name].items()):}}
{{if index > 0:}}
,&nbsp;
{{pass}}
{{=parameter}}
=
{{=value}}
{{pass}}
</td>
</tr>
{{pass}}
</table>

{{if 'vels_ob' in ActivePlugins:}}
<h1>VELS on Board</h1>
<h1>VELS on Board</h1>

<h3> Active VELS-OB users </h3>

<table border="1">
<thead>
<tr>
<th>User</th>
<th>Task</th>
<th>Status</th>
<th>Stop</th>
</tr>
</thead>
</table>
<thead>
<tr>
<th>User</th>
<th>Task</th>
<th>Status</th>
<th>Stop</th>
</tr>
</thead>
{{for task in vels_ob_tasks:}}
<tr>
<td>
{{=task.user_id}}
</td>
<td>
{{=task.hdl_file}}
</td>
<td>
{{=task.progress}}
</td>
<td>{{=BUTTON_TO('Delete',\
URL('delete?UserId=' + str(task.user_id)),\
'Really delete entry for UserId=' + str(task.user_id) + \
"? This will send a request to VELS_OB!")}}</td>
</tr>
{{pass}}

XXX Button close all XXX
</table>
{{=SCRIPT('const queryString = window.location.search; \n \
const urlParams = new URLSearchParams(queryString); \n \
const error = urlParams.get(\'error\')\n \
if(error){alert(error);} \
', _type='text/javascript' )}}

{{pass}}
{{pass}}
47 changes: 47 additions & 0 deletions src/SpecialMessages/bak_welcome.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
Welcome to the course {{ course_name }}.

The basic e-mail communication with me works exactly the same way as with VELS.

There are just a few new rules for MELODI:

1) Task Request:
You cannot request a task on your own. You will get the first task
automatically (should already be in your mailbox, cause I am fast).
After sucessful submission, you will receive the next task on the list.

2) Guided Task Version:
You will always get a guided version of any MELODI task first.
Here you have to program a certain behavior, which is analyzed by me.
I will give you behavioral feedback and only if your submission is correct,
I will forward it to my hardware.
BE AWARE that my analysis might take some time (up to a few minutes), so please
do not use me for syntax checking but only submit solutions, which you have
tested well before.

3) Open Task Version:
After finishing the guided version, you will automatically get an open version.
Here you can add any behavior you want and I will forward it to the hardware.
BE AWARE that the hardware might not react, when your submission is nonsense.
And of course: Don't be evil!

4) Web-Interface
On my web-interface you will be greeted with a loading bar and a webcam stream.
When the synthesis has finished, you can interact with your entity via the
Write-Buttons and Read-Fields. You have a maximum of 15 minutes to access the
website. After opening the website, I will block my hardware for you for
15 minutes. You have the chance to renew the timer on the website. If time
is over or if you leave the website, I will kick you out of my hardware.

5) BETA Status:
I am still in beta status, so don't hate me when I might be confused
sometimes or decide to crash.
Please always provide my human creators with feedback so that they can
flip one or two of my bits and help me to improve!

Hope this clears things on how to communicate with me! Now I am looking
forward to hearing from you in a structured and (for me!) understandable
way!



So long, and thanks for all the fish!
90 changes: 37 additions & 53 deletions src/SpecialMessages/welcome.txt
Original file line number Diff line number Diff line change
@@ -1,62 +1,46 @@
Welcome to the course {{ course_name }}.

You just sent your first e-mail to {{ submission_email }}. This way
you subscribed to this part of the course.

All e-mails sent to this address are automatically handled by me, a
stupid little computer program.
{% if allow_requests == "no" %}
When the first task is active you will receive an e-mail with it.

{% else %}
{% endif -%}

In order to submit your results, you need to know how to communicate with
me. I only accept specially formatted emails, notably the subject has to
be formatted in one of the following ways:

Results:
If you want to commit a result, the Subject of your email has to contain
the word "Result" as well as the task number this submission is concerning.
So for example, if you want to submit results for Task1 your subject
could be "Result Task1" or "I am Submitting my ReSuLtS for TAsk1"
the exact phrase does not matter, only that some form of the string
"Result" and "Task1" are in the subject.

{% if allow_requests != "no" %}Request Task:
You can request a specific task by sending an e-mail in which the
subject contains the word "Request" as well as the task you want
to get. So for example, if you want to get the Task1 your subject
could be "Request Task1" or "I want to ReQuEsT the TAsk1"
the exact phrase does not matter, only that some form of the string
"Request" and "Task1" are in the subject.

{% endif -%}
Task List:
If you want to know what tasks are configured for this course just
send an e-mail in which the subject contains the word "List".

Status:
If you want to know your current status in the course (what tasks did
you complete, how many points do you have, etc.), just send an e-mail
in which the subject contains the word "Status".

Questions:
If you have any questions that are not answered by the e-mails sent by
me, you can send me an e-mail in which the subject contains the word "Question".
If you do so, I will redirect your e-mail to a human being who will
take care of it as soon as possible.
If your question is concerning a specific task, include the task number in
the subject line, e.g.: "Question Task3".

Other:
If your subject does not follow the above explained rules, I will send
you an e-mail similar to this one, because clearly you did not understand
how to communicate with me.
The basic e-mail communication with me works exactly the same way as with VELS.

There are just a few new rules for MELODI:

1) Guided Task Version (Beginner Level):
You always get a guided version of a MELODI task first. There I have divided them
according to levels, which reflect the degree of complexity. You start with the
most minor level (level 1) and work your way up level by level.
You have to program a specific behavior at each level, which I analyze for you.
I will give you behavioral feedback, and I will forward it to my hardware only
if your submission is correct.
BE AWARE that my analysis might take some time (up to a few minutes)!
Therefore, please do not use me for syntax checking!
Only submit solutions you have tested sufficiently beforehand!

2) Open Task Version (Expert Level):
To participate in the Expert Level, you must have completed all Beginner Levels.
You can add any behaviors to these tasks, which I will then pass on to the hardware.
Let your creativity run wild and come up with outstanding solutions. We'll reward
fancy implementations with sweet bonus points! Be aware that the hardware
may not respond if your input is nonsensical.
And, of course, don't be evil!

3) Web-Interface
You will be greeted with a loading bar and webcam stream on my web interface.
When the synthesis has finished, you can interact with your entity through
the Write-Buttons and Read-Fields. You have a maximum of 15 minutes to access
the website. After you open the website, I will lock my hardware for you for
15 minutes. You have the option to extend the timer on the website.
When the time is up or you leave the website, I will kick you out of my hardware.

4) BETA Status:
I am still in beta status, so don't hate me when I might be confused
sometimes or decide to crash.
Please always provide my human creators with feedback so that they can
flip one or two of my bits and help me to improve ([email protected])!

Hope this clears things on how to communicate with me! Now I am looking
forward to hearing from you in a structured and (for me!) understandable
way!



So long, and thanks for all the fish!
2 changes: 1 addition & 1 deletion src/autosub.py
Original file line number Diff line number Diff line change
Expand Up @@ -773,7 +773,7 @@ def check_init_ressources(config_file):
config = configparser.ConfigParser()

try:
config.read_file(open(opts.configfile))
config.readfp(open(opts.configfile))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

readfp has been deprecated since Python 3.2 and was removed in Python 3.12 (October 2023). The function that shall be used is read_file

except:
print("Error reading your configfile\ndaemon exited...")
sys.exit(-1)
Expand Down
4 changes: 2 additions & 2 deletions src/autosub.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ if [ $1 = "start" ]
then
if [ -z "$2" ]
then
python3 autosub.py &
python3 autosub.py &
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uneeded extra whitespace

echo $! > autosub.pid
echo "No config file specified, using default.cfg!"
echo "Started autosub with process id $PID"
else
python3 autosub.py --config-file $2 &
python3 autosub.py --config-file $2 &
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uneeded extra whitespace

echo $! > autosub.pid
PID=$(cat autosub.pid 2> /dev/null)
echo "Started autosub with process id $PID"
Expand Down
Loading