Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
beat
beat.cmdline
Commits
ea940304
Commit
ea940304
authored
May 07, 2019
by
Samuel GAIST
Browse files
[common] Remove all code related to no storage asset and fix usage type keyword
parent
a830c44a
Changes
1
Show whitespace changes
Inline
Side-by-side
beat/cmdline/common.py
View file @
ea940304
...
...
@@ -59,8 +59,6 @@ from beat.core import algorithm
from
beat.core
import
toolchain
from
beat.core
import
experiment
from
beat.backend.python
import
utils
logger
=
logging
.
getLogger
(
__name__
)
TYPE_GLOB
=
{
...
...
@@ -113,10 +111,6 @@ TYPE_STORAGE = {
"experiment"
:
experiment
.
Storage
,
}
NOSTORAGE
=
[]
TYPE_NOSTORAGE
=
{}
TYPE_PLURAL
=
{
"dataformat"
:
"dataformats"
,
"database"
:
"databases"
,
...
...
@@ -185,13 +179,13 @@ class Selector(object):
def
__ensure_entries
(
self
):
"""Ensure all types have an entry"""
for
type
_
in
self
.
__versionables
:
if
type
_
not
in
self
.
__version
:
self
.
__version
[
type
_
]
=
dict
()
for
asset_
type
in
self
.
__versionables
:
if
asset_
type
not
in
self
.
__version
:
self
.
__version
[
asset_
type
]
=
dict
()
for
type
_
in
self
.
__forkables
:
if
type
_
not
in
self
.
__fork
:
self
.
__fork
[
type
_
]
=
dict
()
for
asset_
type
in
self
.
__forkables
:
if
asset_
type
not
in
self
.
__fork
:
self
.
__fork
[
asset_
type
]
=
dict
()
def
fork
(
self
,
type
,
src
,
dst
):
"""Registers that object ``dst`` is a fork of object ``src``"""
...
...
@@ -210,36 +204,36 @@ class Selector(object):
return
self
.
__fork
[
type
].
get
(
name
)
def
version
(
self
,
type
_
,
src
,
dst
):
def
version
(
self
,
asset_
type
,
src
,
dst
):
"""Registers that object ``dst`` is a new version of object ``src``"""
if
not
type_
in
self
.
__version
:
raise
RuntimeError
(
"Can't create new version of {}"
.
format
(
type
_
))
if
asset_type
not
in
self
.
__version
:
raise
RuntimeError
(
"Can't create new version of {}"
.
format
(
asset_
type
))
logger
.
info
(
"`%s/%s' is a new version of `%s/%s'"
,
TYPE_PLURAL
[
type
_
],
TYPE_PLURAL
[
asset_
type
],
dst
,
TYPE_PLURAL
[
type
_
],
TYPE_PLURAL
[
asset_
type
],
src
,
)
self
.
__version
[
type
_
][
dst
]
=
src
self
.
__version
[
asset_
type
][
dst
]
=
src
def
version_of
(
self
,
type
_
,
name
):
def
version_of
(
self
,
asset_
type
,
name
):
"""Returns the name of the originating version object or ``None``"""
if
type
_
not
in
self
.
__version
:
if
asset_
type
not
in
self
.
__version
:
return
None
return
self
.
__version
[
type
_
].
get
(
name
)
return
self
.
__version
[
asset_
type
].
get
(
name
)
def
delete
(
self
,
type
_
,
name
):
def
delete
(
self
,
asset_
type
,
name
):
"""Forgets about an object that was being tracked"""
if
name
in
self
.
__fork
[
type
_
]:
del
self
.
__fork
[
type
_
][
name
]
if
type
_
in
self
.
__version
and
name
in
self
.
__version
[
type
_
]:
del
self
.
__version
[
type
_
][
name
]
if
name
in
self
.
__fork
[
asset_
type
]:
del
self
.
__fork
[
asset_
type
][
name
]
if
asset_
type
in
self
.
__version
and
name
in
self
.
__version
[
asset_
type
]:
del
self
.
__version
[
asset_
type
][
name
]
def
load
(
self
):
"""Loads contents from file"""
...
...
@@ -273,7 +267,7 @@ class Selector(object):
simplejson
.
dump
(
data
,
f
,
indent
=
2
)
def
retrieve_remote_list
(
webapi
,
type
,
fields
):
def
retrieve_remote_list
(
webapi
,
asset_
type
,
fields
):
"""Utility function used by commands to retrieve a remote list of objects
...
...
@@ -282,7 +276,7 @@ def retrieve_remote_list(webapi, type, fields):
webapi (object): An instance of our WebAPI class, prepared to access the
BEAT server of interest
type (str): One of ``database``, ``dataformat``, ``algorithm``,
asset_
type (str): One of ``database``, ``dataformat``, ``algorithm``,
``toolchain`` or ``experiment``.
fields (:py:class:`list`): A list of fields to retrieve from the remote
...
...
@@ -296,11 +290,11 @@ def retrieve_remote_list(webapi, type, fields):
"""
logger
.
debug
(
"retrieving remote %s list..."
,
TYPE_PLURAL
[
type
])
logger
.
debug
(
"retrieving remote %s list..."
,
TYPE_PLURAL
[
asset_
type
])
fields
=
""
if
not
fields
else
"?fields=%s"
%
","
.
join
(
fields
)
url
=
"/api/v1/%s/%s"
%
(
TYPE_PLURAL
[
type
],
fields
)
url
=
"/api/v1/%s/%s"
%
(
TYPE_PLURAL
[
asset_
type
],
fields
)
(
status_code
,
content
)
=
webapi
.
get
(
url
)
if
status_code
is
None
:
...
...
@@ -309,7 +303,7 @@ def retrieve_remote_list(webapi, type, fields):
if
status_code
!=
six
.
moves
.
http_client
.
OK
:
logger
.
error
(
"failed to retrieve %s list from `%s' on behalf of `%s', "
"reason: %s"
,
TYPE_PLURAL
[
type
],
TYPE_PLURAL
[
asset_
type
],
webapi
.
platform
,
webapi
.
user
,
six
.
moves
.
http_client
.
responses
[
status_code
],
...
...
@@ -319,7 +313,7 @@ def retrieve_remote_list(webapi, type, fields):
return
simplejson
.
loads
(
content
,
object_pairs_hook
=
collections
.
OrderedDict
)
def
make_up_remote_list
(
webapi
,
type
,
requirements
):
def
make_up_remote_list
(
webapi
,
asset_
type
,
requirements
):
"""Creates a list of downloadable objects from user requirements.
This function can create a list of downloadable objects from user
...
...
@@ -334,7 +328,7 @@ def make_up_remote_list(webapi, type, requirements):
webapi (object): An instance of our WebAPI class, prepared to access the
BEAT server of interest
type (str): One of ``database``, ``dataformat``, ``algorithm``,
asset_
type (str): One of ``database``, ``dataformat``, ``algorithm``,
``toolchain`` or ``experiment``.
requirements (:py:class:`list`): A list of requirements that are used to
...
...
@@ -348,7 +342,7 @@ def make_up_remote_list(webapi, type, requirements):
"""
candidates
=
retrieve_remote_list
(
webapi
,
type
,
[
"name"
])
candidates
=
retrieve_remote_list
(
webapi
,
asset_
type
,
[
"name"
])
if
not
requirements
:
# special case, return all possible values
if
candidates
is
None
:
...
...
@@ -356,7 +350,7 @@ def make_up_remote_list(webapi, type, requirements):
return
[
c
[
"name"
]
for
c
in
candidates
]
# othewise, we need to separate filters from full-names
full_requirements
=
fnmatch
.
filter
(
requirements
,
TYPE_FNMATCH
[
type
])
full_requirements
=
fnmatch
.
filter
(
requirements
,
TYPE_FNMATCH
[
asset_
type
])
short_requirements
=
[
k
for
k
in
requirements
if
k
not
in
full_requirements
]
retval
=
[]
...
...
@@ -377,7 +371,7 @@ def make_up_remote_list(webapi, type, requirements):
return
retval
+
full_requirements
def
display_remote_list
(
webapi
,
type
):
def
display_remote_list
(
webapi
,
asset_
type
):
"""Implements a generic "list --remote" command
Parameters:
...
...
@@ -385,7 +379,7 @@ def display_remote_list(webapi, type):
webapi (object): An instance of our WebAPI class, prepared to access the
BEAT server of interest, on behalf of a pre-configured user.
type (str): One of ``database``, ``dataformat``, ``algorithm``,
asset_
type (str): One of ``database``, ``dataformat``, ``algorithm``,
``toolchain`` or ``experiment``.
...
...
@@ -397,7 +391,9 @@ def display_remote_list(webapi, type):
"""
remote_list
=
retrieve_remote_list
(
webapi
,
type
,
[
"name"
,
"short_description"
])
remote_list
=
retrieve_remote_list
(
webapi
,
asset_type
,
[
"name"
,
"short_description"
]
)
if
remote_list
is
None
:
return
1
...
...
@@ -407,14 +403,14 @@ def display_remote_list(webapi, type):
logger
.
extra
(
2
*
" "
+
item
[
"short_description"
])
if
len
(
remote_list
)
!=
1
:
logger
.
extra
(
"%d %s found"
,
len
(
remote_list
),
TYPE_PLURAL
[
type
])
logger
.
extra
(
"%d %s found"
,
len
(
remote_list
),
TYPE_PLURAL
[
asset_
type
])
else
:
logger
.
extra
(
"1 %s found"
%
type
)
logger
.
extra
(
"1 %s found"
%
asset_
type
)
return
0
def
make_up_local_list
(
prefix
,
type
,
requirements
):
def
make_up_local_list
(
prefix
,
asset_
type
,
requirements
):
"""Creates a list of uploadable objects from user requirements.
This function can create a list of uploadable objects from user requirements.
...
...
@@ -429,7 +425,7 @@ def make_up_local_list(prefix, type, requirements):
prefix (str): A string representing the root of the path in which the user
objects are stored
type (str): One of ``database``, ``dataformat``, ``algorithm``,
asset_
type (str): One of ``database``, ``dataformat``, ``algorithm``,
``toolchain`` or ``experiment``.
requirements (:py:class:`list`): A list of requirements that are used to
...
...
@@ -444,21 +440,14 @@ def make_up_local_list(prefix, type, requirements):
"""
root
=
os
.
path
.
join
(
prefix
,
TYPE_PLURAL
[
type
])
if
type
in
NOSTORAGE
:
try
:
root
=
os
.
path
.
join
(
prefix
,
TYPE_NOSTORAGE
[
type
])
except
IndexError
:
logger
.
error
(
"Selected type is not valid: %s"
,
type
)
return
1
asset_path_list
=
glob
.
glob
(
os
.
path
.
join
(
root
,
TYPE_GLOB
[
type
]))
root
=
os
.
path
.
join
(
prefix
,
TYPE_PLURAL
[
asset_type
])
asset_path_list
=
glob
.
glob
(
os
.
path
.
join
(
root
,
TYPE_GLOB
[
asset_type
]))
candidates
=
[
os
.
path
.
splitext
(
os
.
path
.
relpath
(
path
,
root
))[
0
]
for
path
in
asset_path_list
]
# adds hashed path structures
hashed_path_list
=
glob
.
glob
(
os
.
path
.
join
(
root
,
"*"
,
"*"
,
TYPE_GLOB
[
type
]))
hashed_path_list
=
glob
.
glob
(
os
.
path
.
join
(
root
,
"*"
,
"*"
,
TYPE_GLOB
[
asset_
type
]))
hashed_path_list
=
[
os
.
path
.
splitext
(
os
.
path
.
relpath
(
path
,
root
))[
0
]
for
path
in
hashed_path_list
]
...
...
@@ -469,13 +458,13 @@ def make_up_local_list(prefix, type, requirements):
use_requirements
=
[]
for
k
in
requirements
:
# remove leading plural-name
if
k
.
startswith
(
TYPE_PLURAL
[
type
]
+
os
.
sep
):
use_requirements
.
append
(
k
.
replace
(
TYPE_PLURAL
[
type
]
+
os
.
sep
,
""
))
if
k
.
startswith
(
TYPE_PLURAL
[
asset_
type
]
+
os
.
sep
):
use_requirements
.
append
(
k
.
replace
(
TYPE_PLURAL
[
asset_
type
]
+
os
.
sep
,
""
))
else
:
use_requirements
.
append
(
k
)
requirements
=
use_requirements
full_requirements
=
fnmatch
.
filter
(
requirements
,
TYPE_FNMATCH
[
type
])
full_requirements
=
fnmatch
.
filter
(
requirements
,
TYPE_FNMATCH
[
asset_
type
])
short_requirements
=
[
k
for
k
in
requirements
if
k
not
in
full_requirements
]
retval
=
oset
.
oset
()
...
...
@@ -487,7 +476,7 @@ def make_up_local_list(prefix, type, requirements):
return
list
(
retval
)
+
full_requirements
def
display_local_list
(
prefix
,
type
):
def
display_local_list
(
prefix
,
asset_
type
):
"""Implements the local "list" command
...
...
@@ -496,7 +485,7 @@ def display_local_list(prefix, type):
prefix (str): A string representing the root of the path in which the user
objects are stored
type (str): One of ``database``, ``dataformat``, ``algorithm``,
asset_
type (str): One of ``database``, ``dataformat``, ``algorithm``,
``toolchain`` or ``experiment``.
...
...
@@ -508,21 +497,12 @@ def display_local_list(prefix, type):
"""
names
=
make_up_local_list
(
prefix
,
type
,
[])
names
=
make_up_local_list
(
prefix
,
asset_
type
,
[])
for
name
in
names
:
logger
.
info
(
"%s"
,
name
)
try
:
contents
=
None
if
type
in
NOSTORAGE
:
name_path
=
os
.
path
.
join
(
prefix
,
TYPE_NOSTORAGE
[
type
],
name
)
data_json
=
utils
.
File
(
name_path
+
".json"
)
with
open
(
data_json
.
path
,
"rt"
)
as
f
:
contents
=
simplejson
.
load
(
f
,
object_pairs_hook
=
collections
.
OrderedDict
)
else
:
storage
=
TYPE_STORAGE
[
type
](
prefix
,
name
)
storage
=
TYPE_STORAGE
[
asset_type
](
prefix
,
name
)
contents
=
simplejson
.
loads
(
storage
.
json
.
load
(),
object_pairs_hook
=
collections
.
OrderedDict
)
...
...
@@ -532,14 +512,14 @@ def display_local_list(prefix, type):
logger
.
warn
(
2
*
" "
+
"(!) invalid JSON file"
)
if
len
(
names
)
!=
1
:
logger
.
extra
(
"%d %s found"
,
len
(
names
),
TYPE_PLURAL
[
type
])
logger
.
extra
(
"%d %s found"
,
len
(
names
),
TYPE_PLURAL
[
asset_
type
])
else
:
logger
.
extra
(
"1 %s found"
%
type
)
logger
.
extra
(
"1 %s found"
%
asset_
type
)
return
0
def
display_local_path
(
prefix
,
type
,
names
):
def
display_local_path
(
prefix
,
asset_
type
,
names
):
"""Implements the local "path" command
...
...
@@ -548,7 +528,7 @@ def display_local_path(prefix, type, names):
prefix (str): A string representing the root of the path in which the user
objects are stored
type (str): One of ``database``, ``dataformat``, ``algorithm``,
asset_
type (str): One of ``database``, ``dataformat``, ``algorithm``,
``toolchain`` or ``experiment``.
...
...
@@ -562,14 +542,11 @@ def display_local_path(prefix, type, names):
selected_type
=
None
if
type
not
in
NOSTORAGE
:
try
:
selected_type
=
TYPE_PLURAL
[
type
]
selected_type
=
TYPE_PLURAL
[
asset_
type
]
except
IndexError
:
logger
.
error
(
"Selected type is not valid: %s"
,
type
)
logger
.
error
(
"Selected type is not valid: %s"
,
asset_
type
)
return
1
else
:
selected_type
=
TYPE_NOSTORAGE
[
type
]
for
name
in
names
:
root
=
os
.
path
.
join
(
prefix
,
selected_type
)
...
...
@@ -598,7 +575,7 @@ def display_local_path(prefix, type, names):
return
0
def
edit_local_file
(
prefix
,
editor
,
type
,
name
):
def
edit_local_file
(
prefix
,
editor
,
asset_
type
,
name
):
"""Implements the local "path" command
...
...
@@ -607,7 +584,7 @@ def edit_local_file(prefix, editor, type, name):
prefix (str): A string representing the root of the path in which the user
objects are stored
type (str): One of ``database``, ``dataformat``, ``algorithm``,
asset_
type (str): One of ``database``, ``dataformat``, ``algorithm``,
``toolchain`` or ``experiment``.
...
...
@@ -621,14 +598,11 @@ def edit_local_file(prefix, editor, type, name):
selected_type
=
None
if
type
not
in
NOSTORAGE
:
try
:
selected_type
=
TYPE_PLURAL
[
type
]
selected_type
=
TYPE_PLURAL
[
asset_
type
]
except
IndexError
:
logger
.
error
(
"Selected type is not valid: %s"
,
type
)
logger
.
error
(
"Selected type is not valid: %s"
,
asset_
type
)
return
1
else
:
selected_type
=
TYPE_NOSTORAGE
[
type
]
python_objects
=
[
"database"
,
"library"
,
"algorithm"
,
"plotter"
]
json_objects
=
[
...
...
@@ -640,12 +614,12 @@ def edit_local_file(prefix, editor, type, name):
]
ext
=
None
if
type
in
python_objects
:
if
asset_
type
in
python_objects
:
ext
=
".py"
elif
type
in
json_objects
:
elif
asset_
type
in
json_objects
:
ext
=
".json"
else
:
logger
.
error
(
"Selected type is not valid: %s"
,
type
)
logger
.
error
(
"Selected type is not valid: %s"
,
asset_
type
)
root
=
os
.
path
.
join
(
prefix
,
selected_type
)
object_path
=
os
.
path
.
join
(
root
,
name
+
ext
)
...
...
@@ -714,10 +688,10 @@ def make_webapi(c):
def
__exit__
(
self
,
*
exc
):
pass
def
_message
(
self
,
type
,
url
,
data
=
None
):
def
_message
(
self
,
asset_
type
,
url
,
data
=
None
):
if
data
:
data
=
simplejson
.
dumps
(
data
)
retval
=
getattr
(
super
(
APIClientContext
,
self
),
type
)(
retval
=
getattr
(
super
(
APIClientContext
,
self
),
asset_
type
)(
url
,
data
,
content_type
=
"application/json"
)
return
(
retval
.
status_code
,
retval
.
content
)
...
...
@@ -743,7 +717,7 @@ def make_webapi(c):
return
WebAPI
(
c
.
platform
,
c
.
user
,
c
.
token
)
def
check_one
(
prefix
,
type
,
name
):
def
check_one
(
prefix
,
asset_
type
,
name
):
"""Implements object validation for a single, well-defined object
...
...
@@ -752,7 +726,7 @@ def check_one(prefix, type, name):
prefix (str): A string representing the root of the path in which the user
objects are stored
type (str): One of ``database``, ``dataformat``, ``algorithm``,
asset_
type (str): One of ``database``, ``dataformat``, ``algorithm``,
``toolchain`` or ``experiment``.
name (str): The name of the object, representing the unique relative path
...
...
@@ -763,20 +737,20 @@ def check_one(prefix, type, name):
"""
o
=
TYPE_VALIDATOR
[
type
](
prefix
,
name
)
o
=
TYPE_VALIDATOR
[
asset_
type
](
prefix
,
name
)
if
not
o
.
valid
:
logger
.
info
(
"%s/%s [invalid]"
,
TYPE_PLURAL
[
type
],
name
)
logger
.
info
(
"%s/%s [invalid]"
,
TYPE_PLURAL
[
asset_
type
],
name
)
for
e
in
o
.
errors
:
logger
.
warn
(
" * %s"
,
e
)
return
1
else
:
logger
.
info
(
"%s/%s [ok]"
,
TYPE_PLURAL
[
type
],
name
)
logger
.
info
(
"%s/%s [ok]"
,
TYPE_PLURAL
[
asset_
type
],
name
)
return
0
def
check
(
prefix
,
type
,
names
):
def
check
(
prefix
,
asset_
type
,
names
):
"""Implements object validation
...
...
@@ -785,7 +759,7 @@ def check(prefix, type, names):
prefix (str): A string representing the root of the path in which the user
objects are stored
type (str): One of ``database``, ``dataformat``, ``algorithm``,
asset_
type (str): One of ``database``, ``dataformat``, ``algorithm``,
``toolchain`` or ``experiment``.
names (:py:class:`list`): A list of strings, each representing the unique
...
...
@@ -801,11 +775,11 @@ def check(prefix, type, names):
"""
names
=
make_up_local_list
(
prefix
,
type
,
names
)
return
sum
([
check_one
(
prefix
,
type
,
name
)
for
name
in
names
])
names
=
make_up_local_list
(
prefix
,
asset_
type
,
names
)
return
sum
([
check_one
(
prefix
,
asset_
type
,
name
)
for
name
in
names
])
def
fetch_object
(
webapi
,
type
,
name
,
fields
):
def
fetch_object
(
webapi
,
asset_
type
,
name
,
fields
):
"""Retrieves a single well-known object from the server
Parameters:
...
...
@@ -813,7 +787,7 @@ def fetch_object(webapi, type, name, fields):
webapi (object): An instance of our WebAPI class, prepared to access the
BEAT server of interest
type (str): One of ``database``, ``dataformat``, ``algorithm``,
asset_
type (str): One of ``database``, ``dataformat``, ``algorithm``,
``toolchain`` or ``experiment``.
name (str): A string defining the name of the object to retrieve
...
...
@@ -830,9 +804,9 @@ def fetch_object(webapi, type, name, fields):
fields
=
"?object_format=string&fields=%s"
%
","
.
join
(
fields
)
if
name
is
not
None
:
url
=
"/api/v1/%s/%s/%s"
%
(
TYPE_PLURAL
[
type
],
name
,
fields
)
url
=
"/api/v1/%s/%s/%s"
%
(
TYPE_PLURAL
[
asset_
type
],
name
,
fields
)
else
:
url
=
"/api/v1/%s/%s"
%
(
TYPE_PLURAL
[
type
],
fields
)
url
=
"/api/v1/%s/%s"
%
(
TYPE_PLURAL
[
asset_
type
],
fields
)
(
status_code
,
content
)
=
webapi
.
get
(
url
)
if
status_code
is
None
:
...
...
@@ -841,7 +815,7 @@ def fetch_object(webapi, type, name, fields):
if
status_code
!=
six
.
moves
.
http_client
.
OK
:
logger
.
error
(
"failed to retrieve %s from `%s' with secret token, "
"reason: %s"
,
type
,
asset_
type
,
webapi
.
platform
,
six
.
moves
.
http_client
.
responses
[
status_code
],
)
...
...
@@ -850,7 +824,7 @@ def fetch_object(webapi, type, name, fields):
return
simplejson
.
loads
(
content
,
object_pairs_hook
=
collections
.
OrderedDict
)
def
pull
(
webapi
,
prefix
,
type
,
names
,
fields
,
force
,
indentation
):
def
pull
(
webapi
,
prefix
,
asset_
type
,
names
,
fields
,
force
,
indentation
):
"""Copies objects from the server to the local prefix
...
...
@@ -862,7 +836,7 @@ def pull(webapi, prefix, type, names, fields, force, indentation):
prefix (str): A string representing the root of the path in which the user
objects are stored
type (str): One of ``database``, ``dataformat``, ``algorithm``,
asset_
type (str): One of ``database``, ``dataformat``, ``algorithm``,
``toolchain`` or ``experiment``.
names (:py:class:`list`): A list of strings, each representing the unique
...
...
@@ -898,7 +872,7 @@ def pull(webapi, prefix, type, names, fields, force, indentation):
"""
names
=
make_up_remote_list
(
webapi
,
type
,
names
)
names
=
make_up_remote_list
(
webapi
,
asset_
type
,
names
)
if
not
names
:
return
1
,
[]
indent
=
indentation
*
" "
...
...
@@ -907,83 +881,40 @@ def pull(webapi, prefix, type, names, fields, force, indentation):
status
=
0
for
name
in
names
:
if
type
not
in
NOSTORAGE
:
# typical workflow with normal storage
storage
=
TYPE_STORAGE
[
type
](
prefix
,
name
)
storage
=
TYPE_STORAGE
[
asset_type
](
prefix
,
name
)
if
storage
.
exists
()
and
not
force
:
# exists locally, force not set
logger
.
extra
(
"%sskipping download of `%s/%s' (exists locally)"
,
indent
,
TYPE_PLURAL
[
type
],
TYPE_PLURAL
[
asset_
type
],
name
,
)
available
.
add
(
name
)
continue
else
:
logger
.
info
(
"%sretrieving `%s/%s'..."
,
indent
,
TYPE_PLURAL
[
type
],
name
)
data
=
fetch_object
(
webapi
,
type
,
name
,
fields
)
logger
.
info
(
"%sretrieving `%s/%s'..."
,
indent
,
TYPE_PLURAL
[
asset_type
],
name
)
data
=
fetch_object
(
webapi
,
asset_type
,
name
,
fields
)
if
data
is
None
:
status
+=
1
# error
continue
if
type
==
"plotterparameter"
:
if
asset_
type
==
"plotterparameter"
:
declaration
=
{
"description"
:
data
[
"short_description"
],
"plotter"
:
data
[
"plotter"
],
"data"
:
data
[
"data"
]
"data"
:
data
[
"data"
]
,
}
storage
.
save
(
declaration
)
else
:
storage
.
save
(
**
data
)
available
.
add
(
name
)
else
:
# other workflow with no storage (i.e.: plotterparameter)
# check if storage exists
path
=
os
.
path
.
join
(
prefix
,
TYPE_NOSTORAGE
[
type
],
name
.
rsplit
(
"/"
,
1
)[
0
])
if
os
.
path
.
exists
(
path
)
and
not
force
:
logger
.
extra
(
"%sskipping download of `%s/%s' (exists locally)"
,
indent
,
TYPE_PLURAL
[
type
],
name
,
)
available
.
add
(
name
)
continue
else
:
# create folder
if
not
os
.
path
.
exists
(
path
):
os
.
makedirs
(
path
)
logger
.
info
(
"%sretrieving `%s/%s'..."
,
indent
,
TYPE_PLURAL
[
type
],
name
)
data
=
fetch_object
(
webapi
,
type
,
name
,
fields
)
if
data
is
None
:
status
+=
1
# error
continue
if
"data"
in
fields
:
name_path
=
os
.
path
.
join
(
prefix
,
TYPE_NOSTORAGE
[
type
],
name
)
data_json
=
utils
.
File
(
name_path
+
".json"
)
_buf_data
=
{}
if
type
==
"plotterparameter"
:
# generate plotterparameter data
_buf_data
[
"plotter"
]
=
data
[
"plotter"
]
_buf_data
[
"data"
]
=
data
[
"data"
]
_buf_data
[
"description"
]
=
data
[
"short_description"
]
_data
=
simplejson
.
dumps
(
_buf_data
,
indent
=
4
)
else
:
_buf_data
[
"data"
]
=
data
[
"data"
]
_data
=
simplejson
.
dumps
(
_buf_data
[
"data"
],
indent
=
4
)
data_json
.
save
(
_data
)
if
"short_description"
in
fields
:
name_path
=
os
.
path
.
join
(
prefix
,
TYPE_NOSTORAGE
[
type
],
name
)
data_doc
=
utils
.
File
(
name_path
+
".rst"
)
data_doc
.
save
(
data
[
"short_description"
].
encode
(
"utf8"
))
available
.
add
(
name
)
return
status
,
list
(
available
)
def
diff
(
webapi
,
prefix
,
type
_
,
name
,
fields
):
def
diff
(
webapi
,
prefix
,
asset_
type
,
name
,
fields
):
"""Shows the differences between two objects, for each of the fields
...
...
@@ -995,7 +926,7 @@ def diff(webapi, prefix, type_, name, fields):
prefix (str): A string representing the root of the path in which the user
objects are stored
type (str): One of ``database``, ``dataformat``, ``algorithm``,
asset_
type (str): One of ``database``, ``dataformat``, ``algorithm``,
``toolchain`` or ``experiment``.
name (str): A string defining the name of the object to calculate
...
...
@@ -1028,8 +959,8 @@ def diff(webapi, prefix, type_, name, fields):
return
difflib
.
unified_diff
(
remote
.
split
(
"
\n
"
),
local
.
split
(
"
\n
"
),
os
.
path
.
join
(
"remote"
,
type
_
,
name
+
ext
),
os
.
path
.
join
(
"local"
,
type
_
,
name
+
ext
),
os
.
path
.
join
(
"remote"
,
asset_
type
,
name
+
ext
),
os
.
path
.
join
(
"local"
,
asset_
type
,
name
+
ext
),