Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
beat
beat.web
Commits
7e20665d
Commit
7e20665d
authored
Sep 09, 2020
by
Samuel GAIST
Committed by
Flavio TARSETTI
Sep 09, 2020
Browse files
[algorithms][all] Pre-commit cleanup
parent
ebbb6372
Pipeline
#42554
passed with stage
in 15 minutes and 44 seconds
Changes
7
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
beat/web/algorithms/admin.py
View file @
7e20665d
...
...
@@ -25,87 +25,72 @@
# #
###############################################################################
import
simplejson
as
json
from
django
import
forms
from
django.contrib
import
admin
from
django.core.files.base
import
ContentFile
from
..ui.forms
import
CodeMirrorPythonFileField
,
CodeMirrorRSTFileField
,
\
CodeMirrorJSONFileField
,
CodeMirrorJSONCharField
from
..common.texts
import
Messages
from
..ui.forms
import
CodeMirrorJSONCharField
from
..ui.forms
import
CodeMirrorJSONFileField
from
..ui.forms
import
CodeMirrorPythonFileField
from
..ui.forms
import
CodeMirrorRSTFileField
from
..ui.forms
import
NameField
from
.models
import
Algorithm
as
AlgorithmModel
from
.models
import
AlgorithmEndpoint
as
AlgorithmEndpointModel
from
.models
import
validate_algorithm
from
..ui.forms
import
NameField
import
simplejson
as
json
#----------------------------------------------------------
# ----------------------------------------------------------
class
AlgorithmModelForm
(
forms
.
ModelForm
):
name
=
NameField
(
widget
=
forms
.
TextInput
(
attrs
=
dict
(
size
=
80
)),
help_text
=
Messages
[
'algo_name'
],
widget
=
forms
.
TextInput
(
attrs
=
dict
(
size
=
80
)),
help_text
=
Messages
[
"algo_name"
],
)
declaration_file
=
CodeMirrorJSONFileField
(
label
=
'Declaration'
,
help_text
=
Messages
[
'json'
],
label
=
"Declaration"
,
help_text
=
Messages
[
"json"
],
)
source_code_file
=
CodeMirrorPythonFileField
(
label
=
'Source code'
,
help_text
=
Messages
[
'code'
],
label
=
"Source code"
,
help_text
=
Messages
[
"code"
],
)
description_file
=
CodeMirrorRSTFileField
(
label
=
'
Description
'
,
label
=
"
Description
"
,
required
=
False
,
allow_empty_file
=
True
,
help_text
=
Messages
[
'
description
'
],
help_text
=
Messages
[
"
description
"
],
)
parameters
=
CodeMirrorJSONCharField
(
readonly
=
True
,
required
=
False
,
)
parameters
=
CodeMirrorJSONCharField
(
readonly
=
True
,
required
=
False
,)
result_dataformat
=
CodeMirrorJSONCharField
(
readonly
=
True
,
required
=
False
,
)
result_dataformat
=
CodeMirrorJSONCharField
(
readonly
=
True
,
required
=
False
,)
class
Meta
:
model
=
AlgorithmModel
exclude
=
[]
widgets
=
{
'short_description'
:
forms
.
TextInput
(
attrs
=
dict
(
size
=
100
),
),
"short_description"
:
forms
.
TextInput
(
attrs
=
dict
(
size
=
100
),),
}
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
(
AlgorithmModelForm
,
self
).
__init__
(
*
args
,
**
kwargs
)
if
kwargs
[
'
instance
'
].
is_binary
():
del
self
.
fields
[
'
source_code_file
'
]
if
kwargs
[
"
instance
"
].
is_binary
():
del
self
.
fields
[
"
source_code_file
"
]
def
clean_declaration_file
(
self
):
"""Cleans-up the file data, make sure it is really new"""
new_declaration
=
self
.
cleaned_data
[
'
declaration_file
'
].
read
()
old_declaration
=
''
new_declaration
=
self
.
cleaned_data
[
"
declaration_file
"
].
read
()
old_declaration
=
""
if
self
.
instance
and
self
.
instance
.
declaration_file
.
name
is
not
None
:
old_declaration
=
self
.
instance
.
declaration_string
if
new_declaration
==
old_declaration
:
self
.
changed_data
.
remove
(
'
declaration_file
'
)
self
.
changed_data
.
remove
(
"
declaration_file
"
)
content_file
=
ContentFile
(
old_declaration
)
content_file
.
name
=
self
.
instance
.
declaration_file
.
name
return
content_file
...
...
@@ -118,70 +103,76 @@ class AlgorithmModelForm(forms.ModelForm):
raise
forms
.
ValidationError
(
str
(
e
))
# if that works out, then we return the passed file
self
.
cleaned_data
[
'
declaration_file
'
].
seek
(
0
)
#
reset ContentFile readout
return
self
.
cleaned_data
[
'
declaration_file
'
]
self
.
cleaned_data
[
"
declaration_file
"
].
seek
(
0
)
#
reset ContentFile readout
return
self
.
cleaned_data
[
"
declaration_file
"
]
def
clean
(
self
):
"""Cleans-up the input data, make sure it overall validates"""
if
'declaration_file'
in
self
.
data
and
\
isinstance
(
self
.
data
[
'declaration_file'
],
str
):
if
"declaration_file"
in
self
.
data
and
isinstance
(
self
.
data
[
"declaration_file"
],
str
):
mutable_data
=
self
.
data
.
copy
()
mutable_data
[
'declaration_file'
]
=
ContentFile
(
self
.
data
[
'declaration_file'
],
name
=
'unsaved'
)
mutable_data
[
"declaration_file"
]
=
ContentFile
(
self
.
data
[
"declaration_file"
],
name
=
"unsaved"
)
self
.
data
=
mutable_data
#----------------------------------------------------------
#
----------------------------------------------------------
class
AlgorithmEndpointInline
(
admin
.
TabularInline
):
model
=
AlgorithmEndpointModel
can_delete
=
False
extra
=
0
max_num
=
0
readonly_fields
=
(
'
id
'
,
'
input
'
,
'
channel
'
,
'
name
'
,
'
dataformat
'
)
ordering
=
(
'
input
'
,
'
channel
'
,
'
name
'
)
model
=
AlgorithmEndpointModel
can_delete
=
False
extra
=
0
max_num
=
0
readonly_fields
=
(
"
id
"
,
"
input
"
,
"
channel
"
,
"
name
"
,
"
dataformat
"
)
ordering
=
(
"
input
"
,
"
channel
"
,
"
name
"
)
#----------------------------------------------------------
# ----------------------------------------------------------
def
rehash_algorithm
(
modeladmin
,
request
,
queryset
):
"""Recalculates the hash of an algorithm"""
for
q
in
queryset
:
q
.
save
()
for
q
in
queryset
:
q
.
save
()
rehash_algorithm
.
short_description
=
'
Rehash selected algorithms
'
rehash_algorithm
.
short_description
=
"
Rehash selected algorithms
"
class
Algorithm
(
admin
.
ModelAdmin
):
list_display
=
(
'
id
'
,
'
author
'
,
'
name
'
,
'
version
'
,
'
splittable
'
,
'
short_description
'
,
'
creation_date
'
,
'
analysis
'
,
'
previous_version
'
,
'
fork_of
'
,
'
sharing
'
,
'
hash
'
list_display
=
(
"
id
"
,
"
author
"
,
"
name
"
,
"
version
"
,
"
splittable
"
,
"
short_description
"
,
"
creation_date
"
,
"
analysis
"
,
"
previous_version
"
,
"
fork_of
"
,
"
sharing
"
,
"
hash
"
,
)
search_fields
=
[
'
author__username
'
,
'
name
'
,
'
short_description
'
,
'
previous_version__author__username
'
,
'
previous_version__name
'
,
'
fork_of__author__username
'
,
'
fork_of__name
'
search_fields
=
[
"
author__username
"
,
"
name
"
,
"
short_description
"
,
"
previous_version__author__username
"
,
"
previous_version__name
"
,
"
fork_of__author__username
"
,
"
fork_of__name
"
,
]
list_filter
=
(
'
sharing
'
,
)
list_display_links
=
(
'
id
'
,
'
name
'
)
readonly_fields
=
(
'
hash
'
,
'
splittable
'
,
'
short_description
'
)
list_filter
=
(
"
sharing
"
,
)
list_display_links
=
(
"
id
"
,
"
name
"
)
readonly_fields
=
(
"
hash
"
,
"
splittable
"
,
"
short_description
"
)
inlines
=
[
AlgorithmEndpointInline
,
...
...
@@ -194,56 +185,77 @@ class Algorithm(admin.ModelAdmin):
form
=
AlgorithmModelForm
filter_horizontal
=
[
'
shared_with
'
,
'
shared_with_team
'
,
'
usable_by
'
,
'
usable_by_team
'
,
'
referenced_libraries
'
"
shared_with
"
,
"
shared_with_team
"
,
"
usable_by
"
,
"
usable_by_team
"
,
"
referenced_libraries
"
,
]
fieldsets
=
(
(
None
,
dict
(
fields
=
(
'name'
,
'author'
,),
),
),
(
'Documentation'
,
dict
(
classes
=
(
'collapse'
,),
fields
=
(
'short_description'
,
'description_file'
,),
),
),
(
'Versioning'
,
dict
(
classes
=
(
'collapse'
,),
fields
=
(
'version'
,
'previous_version'
,
'fork_of'
),
),
),
(
'Sharing'
,
dict
(
classes
=
(
'collapse'
,),
fields
=
(
'sharing'
,
'shared_with'
,
'shared_with_team'
,
'usable_by'
,
'usable_by_team'
),
),
),
(
'Cached Information (read-only)'
,
dict
(
classes
=
(
'collapse'
,),
fields
=
(
'parameters'
,
'result_dataformat'
,
'referenced_libraries'
),
),
),
(
'Definition'
,
dict
(
fields
=
(
'hash'
,
'splittable'
,
'declaration_file'
,
'language'
,
'source_code_file'
),
),
),
(
None
,
dict
(
fields
=
(
"name"
,
"author"
,),),),
(
"Documentation"
,
dict
(
classes
=
(
"collapse"
,),
fields
=
(
"short_description"
,
"description_file"
,),
),
),
(
"Versioning"
,
dict
(
classes
=
(
"collapse"
,),
fields
=
(
"version"
,
"previous_version"
,
"fork_of"
),
),
),
(
"Sharing"
,
dict
(
classes
=
(
"collapse"
,),
fields
=
(
"sharing"
,
"shared_with"
,
"shared_with_team"
,
"usable_by"
,
"usable_by_team"
,
),
),
),
(
"Cached Information (read-only)"
,
dict
(
classes
=
(
"collapse"
,),
fields
=
(
"parameters"
,
"result_dataformat"
,
"referenced_libraries"
),
),
),
(
"Definition"
,
dict
(
fields
=
(
"hash"
,
"splittable"
,
"declaration_file"
,
"language"
,
"source_code_file"
,
),
),
),
)
def
get_form
(
self
,
request
,
obj
=
None
,
**
kwargs
):
if
obj
.
is_binary
():
self
.
exclude
=
(
'source_code_file'
,)
fieldsets
=
[
fieldset
for
fieldset
in
self
.
fieldsets
if
fieldset
[
0
]
==
'Definition'
][
0
]
fieldsets
[
1
][
'fields'
]
=
(
'hash'
,
'splittable'
,
'declaration_file'
,
'language'
)
self
.
exclude
=
(
"source_code_file"
,)
fieldsets
=
[
fieldset
for
fieldset
in
self
.
fieldsets
if
fieldset
[
0
]
==
"Definition"
][
0
]
fieldsets
[
1
][
"fields"
]
=
(
"hash"
,
"splittable"
,
"declaration_file"
,
"language"
,
)
form
=
super
(
Algorithm
,
self
).
get_form
(
request
,
obj
,
**
kwargs
)
return
form
admin
.
site
.
register
(
AlgorithmModel
,
Algorithm
)
beat/web/algorithms/api.py
View file @
7e20665d
...
...
@@ -26,31 +26,25 @@
###############################################################################
from
django.core.files
import
File
from
rest_framework
import
exceptions
as
drf_exceptions
from
rest_framework
import
parsers
from
rest_framework
import
renderers
from
rest_framework
import
response
from
rest_framework
import
views
from
..code.api
import
DiffView
from
..code.api
import
RetrieveUpdateDestroyCodeView
from
..code.api
import
ShareCodeView
from
..code.serializers
import
CodeDiffSerializer
from
..common
import
permissions
as
beat_permissions
from
..common.api
import
CheckContributionNameView
from
..common.api
import
ListContributionView
from
..common.api
import
ListCreateContributionView
from
.models
import
Algorithm
from
.serializers
import
AlgorithmSerializer
from
.serializers
import
FullAlgorithmSerializer
from
.serializers
import
AlgorithmCreationSerializer
from
.serializers
import
AlgorithmModSerializer
from
..code.api
import
ShareCodeView
,
RetrieveUpdateDestroyCodeView
from
..code.serializers
import
CodeDiffSerializer
from
..common.api
import
(
CheckContributionNameView
,
ListContributionView
,
ListCreateContributionView
,
)
from
..common
import
permissions
as
beat_permissions
from
..code.api
import
DiffView
from
.serializers
import
AlgorithmSerializer
from
.serializers
import
FullAlgorithmSerializer
# ----------------------------------------------------------
...
...
beat/web/algorithms/apps.py
View file @
7e20665d
...
...
@@ -25,18 +25,23 @@
# #
###############################################################################
from
..common.apps
import
CommonAppConfig
from
django.utils.translation
import
ugettext_lazy
as
_
from
..common.apps
import
CommonAppConfig
class
AlgorithmsConfig
(
CommonAppConfig
):
name
=
'
beat.web.algorithms
'
verbose_name
=
_
(
'
Algorithms
'
)
name
=
"
beat.web.algorithms
"
verbose_name
=
_
(
"
Algorithms
"
)
def
ready
(
self
):
super
(
AlgorithmsConfig
,
self
).
ready
()
from
.signals
import
(
create_endpoints
,
delete_endpoints
,
auto_delete_file_on_delete
,
auto_delete_file_on_change
)
from
actstream
import
registry
registry
.
register
(
self
.
get_model
(
'Algorithm'
))
from
.signals
import
auto_delete_file_on_change
# noqa: F401
from
.signals
import
auto_delete_file_on_delete
# noqa: F401
from
.signals
import
create_endpoints
# noqa: F401
from
.signals
import
delete_endpoints
# noqa: F401
registry
.
register
(
self
.
get_model
(
"Algorithm"
))
beat/web/algorithms/models.py
View file @
7e20665d
...
...
@@ -25,31 +25,27 @@
# #
###############################################################################
from
django.db
import
models
import
collections
import
simplejson
from
django.conf
import
settings
from
django.db
import
models
from
django.urls
import
reverse
import
beat.core.algorithm
import
beat.core.library
from
beat.core.utils
import
NumpyJSONEncoder
from
..dataformats.models
import
DataFormat
from
..common.storage
import
OverwriteStorage
from
..common.exceptions
import
ShareError
from
..common.models
import
get_contribution_declaration_filename
from
..common.models
import
get_contribution_description_filename
from
..code.models
import
Code
from
..code.models
import
CodeManager
from
..code.models
import
get_contribution_source_code_filename
from
..common.exceptions
import
ShareError
from
..common.models
import
get_contribution_declaration_filename
from
..common.models
import
get_contribution_description_filename
from
..common.storage
import
OverwriteStorage
from
..dataformats.models
import
DataFormat
from
..libraries.models
import
Library
import
simplejson
import
collections
# ----------------------------------------------------------
...
...
@@ -273,10 +269,12 @@ class Algorithm(Code):
# reset referenced libraries
self
.
referenced_libraries
.
clear
()
if
wrapper
.
uses
is
not
None
:
for
l
in
set
(
wrapper
.
uses
.
values
()):
s
=
beat
.
core
.
library
.
Storage
(
settings
.
PREFIX
,
l
)
for
l
ibrary_name
in
set
(
wrapper
.
uses
.
values
()):
lib_storage
=
beat
.
core
.
library
.
Storage
(
settings
.
PREFIX
,
l
ibrary_name
)
library
=
Library
.
objects
.
get
(
author__username
=
s
.
username
,
name
=
s
.
name
,
version
=
s
.
version
author__username
=
lib_storage
.
username
,
name
=
lib_storage
.
name
,
version
=
lib_storage
.
version
,
)
self
.
referenced_libraries
.
add
(
library
)
...
...
@@ -371,10 +369,14 @@ class Algorithm(Code):
class
AlgorithmEndpoint
(
models
.
Model
):
algorithm
=
models
.
ForeignKey
(
Algorithm
,
related_name
=
"endpoints"
,
on_delete
=
models
.
CASCADE
)
algorithm
=
models
.
ForeignKey
(
Algorithm
,
related_name
=
"endpoints"
,
on_delete
=
models
.
CASCADE
)
input
=
models
.
BooleanField
(
default
=
False
)
name
=
models
.
CharField
(
max_length
=
200
)
dataformat
=
models
.
ForeignKey
(
DataFormat
,
related_name
=
"algorithm_endpoints"
,
on_delete
=
models
.
CASCADE
)
dataformat
=
models
.
ForeignKey
(
DataFormat
,
related_name
=
"algorithm_endpoints"
,
on_delete
=
models
.
CASCADE
)
channel
=
models
.
CharField
(
max_length
=
200
)
def
__str__
(
self
):
...
...
beat/web/algorithms/serializers.py
View file @
7e20665d
...
...
@@ -25,24 +25,24 @@
# #
###############################################################################
from
operator
import
itemgetter
import
simplejson
as
json
from
rest_framework
import
serializers
import
beat.core.algorithm
from
rest_framework
import
serializers
from
operator
import
itemgetter
from
..code.serializers
import
CodeSerializer
,
CodeCreationSerializer
,
CodeModSerializer
from
..libraries.serializers
import
LibraryReferenceSerializer
from
..dataformats.serializers
import
ReferencedDataFormatSerializer
from
..attestations.serializers
import
AttestationSerializer
from
..experiments.serializers
import
ExperimentSerializer
from
..experiments.models
import
Experiment
from
..backend.serializers
import
EnvironmentInfoSerializer
from
..code.serializers
import
CodeCreationSerializer
from
..code.serializers
import
CodeModSerializer
from
..code.serializers
import
CodeSerializer
from
..dataformats.serializers
import
ReferencedDataFormatSerializer
from
..experiments.models
import
Experiment
from
..experiments.serializers
import
ExperimentSerializer
from
..libraries.serializers
import
LibraryReferenceSerializer
from
.models
import
Algorithm
# ----------------------------------------------------------
...
...
beat/web/algorithms/signals.py
View file @
7e20665d
...
...
@@ -29,11 +29,10 @@ from django.db import models
from
django.dispatch
import
receiver
from
..dataformats.models
import
DataFormat
from
.models
import
Algorithm
from
.models
import
AlgorithmEndpoint
from
.models
import
Algorithm
,
AlgorithmEndpoint
#----------------------------------------------------------
# ----------------------------------------------------------
# These two auto-delete files from filesystem when they are unneeded:
...
...
@@ -82,7 +81,7 @@ def auto_delete_file_on_change(sender, instance, **kwargs):
old_code
.
delete
(
save
=
False
)
#----------------------------------------------------------
#
----------------------------------------------------------
@
receiver
(
models
.
signals
.
pre_delete
,
sender
=
Algorithm
)
...
...
@@ -90,7 +89,7 @@ def delete_endpoints(sender, instance, **kwargs):
instance
.
endpoints
.
all
().
delete
()
#----------------------------------------------------------
#
----------------------------------------------------------
@
receiver
(
models
.
signals
.
post_save
,
sender
=
Algorithm
)
...
...
@@ -104,42 +103,40 @@ def create_endpoints(sender, instance, **kwargs):
def
_create_or_reuse_endpoint
(
isinput
,
name
,
formatname
,
channel
):
(
df_author
,
df_name
,
df_version
)
=
formatname
.
split
(
'/'
)
(
df_author
,
df_name
,
df_version
)
=
formatname
.
split
(
"/"
)
df
=
DataFormat
.
objects
.
get
(
author__username
=
df_author
,
name
=
df_name
,
version
=
df_version
,
author__username
=
df_author
,
name
=
df_name
,
version
=
df_version
,
)
endpoint
=
AlgorithmEndpoint
.
objects
.
filter
(
algorithm
=
instance
,
input
=
isinput
,
name
=
name
,
#channel = channel_name,
dataformat
=
df
,
algorithm
=
instance
,
input
=
isinput
,
name
=
name
,
#
channel = channel_name,
dataformat
=
df
,
)
if
not
endpoint
:
endpoint
=
AlgorithmEndpoint
()
endpoint
.
algorithm
=
instance
endpoint
.
input
=
isinput
endpoint
.
name
=
name
endpoint
.
channel
=
channel
endpoint
=
AlgorithmEndpoint
()
endpoint
.
algorithm
=
instance
endpoint
.
input
=
isinput
endpoint
.
name
=
name
endpoint
.
channel
=
channel
endpoint
.
dataformat
=
df
endpoint
.
save
()
used_endpoints
.
append
(
endpoint
)
else
:
endpoint
[
0
].
channel
=
channel
endpoint
[
0
].
save
()
# reset channel name with new standard
endpoint
[
0
].
save
()
# reset channel name with new standard
used_endpoints
.
append
(
endpoint
[
0
])
for
group
in
wrapper
.
groups
:
group_name
=
group
.
get
(
'
name
'
,
'
__io_group_%d__
'
%
len
(
used_names
))
group_name
=
group
.
get
(
"
name
"
,
"
__io_group_%d__
"
%
len
(
used_names
))
used_names
.
add
(
group_name
)
for
name
,
details
in
group
[
'
inputs
'
].
items
():
_create_or_reuse_endpoint
(
True
,
name
,
details
[
'
type
'
],
group_name
)
for
name
,
details
in
group
.
get
(
'
outputs
'
,
{}).
items
():
_create_or_reuse_endpoint
(
False