Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
bliss
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
492
Issues
492
List
Boards
Labels
Service Desk
Milestones
Jira
Jira
Merge Requests
134
Merge Requests
134
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Bliss
bliss
Commits
e16f4398
Commit
e16f4398
authored
Dec 08, 2017
by
Sebastien Petitdemange
Committed by
Vincent Michel
Jan 12, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
pep8
parent
1caf9975
Changes
23
Hide whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
1541 additions
and
1295 deletions
+1541
-1295
bliss/common/data_file_manager.py
bliss/common/data_file_manager.py
+28
-21
bliss/common/utils.py
bliss/common/utils.py
+48
-34
bliss/config/settings.py
bliss/config/settings.py
+255
-220
bliss/data/lima.py
bliss/data/lima.py
+50
-49
bliss/data/node.py
bliss/data/node.py
+73
-55
bliss/data/scan.py
bliss/data/scan.py
+24
-16
bliss/data/zerod.py
bliss/data/zerod.py
+22
-16
bliss/scanning/acquisition/calc.py
bliss/scanning/acquisition/calc.py
+5
-2
bliss/scanning/acquisition/counter.py
bliss/scanning/acquisition/counter.py
+36
-25
bliss/scanning/acquisition/lima.py
bliss/scanning/acquisition/lima.py
+87
-85
bliss/scanning/acquisition/mca.py
bliss/scanning/acquisition/mca.py
+2
-2
bliss/scanning/acquisition/motor.py
bliss/scanning/acquisition/motor.py
+79
-66
bliss/scanning/acquisition/musst.py
bliss/scanning/acquisition/musst.py
+81
-79
bliss/scanning/acquisition/test.py
bliss/scanning/acquisition/test.py
+36
-33
bliss/scanning/acquisition/timer.py
bliss/scanning/acquisition/timer.py
+17
-11
bliss/scanning/chain.py
bliss/scanning/chain.py
+130
-69
bliss/scanning/scan.py
bliss/scanning/scan.py
+113
-86
bliss/scanning/writer/hdf5.py
bliss/scanning/writer/hdf5.py
+16
-14
tests/conftest.py
tests/conftest.py
+1
-1
tests/continuous_scan/client.py
tests/continuous_scan/client.py
+2
-4
tests/continuous_scan/test.py
tests/continuous_scan/test.py
+363
-343
tests/scans/test_step_by_step.py
tests/scans/test_step_by_step.py
+50
-45
tests/test_default_scan_chain.py
tests/test_default_scan_chain.py
+23
-19
No files found.
bliss/common/data_file_manager.py
View file @
e16f4398
import
os
,
errno
import
os
import
errno
import
h5py
from
bliss.scanning.chain
import
AcquisitionDevice
,
AcquisitionMaster
from
bliss.scanning.chain
import
AcquisitionDevice
,
AcquisitionMaster
class
FileOrganizer
(
object
):
def
__init__
(
self
,
root_path
,
def
__init__
(
self
,
root_path
,
windows_path_mapping
=
None
,
detector_temporay_path
=
None
,
**
keys
):
detector_temporay_path
=
None
,
**
keys
):
""" A default way to organize file structure
windows_path_mapping -- transform unix path to windows
...
...
@@ -16,36 +18,41 @@ class FileOrganizer(object):
self
.
_root_path
=
root_path
self
.
_windows_path_mapping
=
windows_path_mapping
or
dict
()
self
.
_detector_temporay_path
=
detector_temporay_path
or
dict
()
class
Hdf5Organizer
(
FileOrganizer
):
def
__init__
(
self
,
root_path
,
**
keys
):
FileOrganizer
.
__init__
(
self
,
root_path
,
**
keys
)
def
__init__
(
self
,
root_path
,
**
keys
):
FileOrganizer
.
__init__
(
self
,
root_path
,
**
keys
)
self
.
file
=
None
def
_acq_device_event
(
self
,
event_dict
=
None
,
signal
=
None
,
sender
=
None
):
print
'received'
,
signal
,
'from'
,
sender
,
":"
,
event_dict
def
prepare
(
self
,
scan_recorder
,
scan_info
,
devices_tree
):
path_suffix
=
scan_recorder
.
node
.
db_name
().
replace
(
':'
,
os
.
path
.
sep
)
full_path
=
os
.
path
.
join
(
self
.
_root_path
,
path_suffix
)
def
prepare
(
self
,
scan_recorder
,
scan_info
,
devices_tree
):
path_suffix
=
scan_recorder
.
node
.
db_name
().
replace
(
':'
,
os
.
path
.
sep
)
full_path
=
os
.
path
.
join
(
self
.
_root_path
,
path_suffix
)
try
:
os
.
makedirs
(
full_path
)
except
OSError
as
exc
:
# Python >2.5
except
OSError
as
exc
:
# Python >2.5
if
exc
.
errno
==
errno
.
EEXIST
and
os
.
path
.
isdir
(
path
):
pass
else
:
raise
else
:
raise
self
.
file
=
h5py
.
File
(
os
.
path
.
join
(
full_path
,
'data.h5'
))
scan_entry
=
h5py
.
Group
(
self
.
file
,
scan_recorder
.
name
,
create
=
True
)
self
.
file
=
h5py
.
File
(
os
.
path
.
join
(
full_path
,
'data.h5'
))
scan_entry
=
h5py
.
Group
(
self
.
file
,
scan_recorder
.
name
,
create
=
True
)
scan_entry
.
attrs
[
'NX_class'
]
=
'NXentry'
measurement
=
h5py
.
Group
(
scan_entry
,
'measurement'
,
create
=
True
)
measurement
=
h5py
.
Group
(
scan_entry
,
'measurement'
,
create
=
True
)
master_id
=
0
for
dev
,
node
in
scan_recorder
.
nodes
.
iteritems
():
if
isinstance
(
dev
,
AcquisitionMaster
):
master_entry
=
h5py
.
Group
(
measurement
,
'master%d'
%
master_id
,
create
=
True
)
for
dev
,
node
in
scan_recorder
.
nodes
.
iteritems
():
if
isinstance
(
dev
,
AcquisitionMaster
):
master_entry
=
h5py
.
Group
(
measurement
,
'master%d'
%
master_id
,
create
=
True
)
master_id
+=
1
for
slave
in
dev
.
slaves
:
if
isinstance
(
slave
,
AcquisitionDevice
):
for
signal
in
(
'start'
,
'end'
,
'new_ref'
,
'new_data'
):
dispatcher
.
connect
(
self
.
_acq_device_event
,
signal
,
dev
)
if
isinstance
(
slave
,
AcquisitionDevice
):
for
signal
in
(
'start'
,
'end'
,
'new_ref'
,
'new_data'
):
dispatcher
.
connect
(
self
.
_acq_device_event
,
signal
,
dev
)
bliss/common/utils.py
View file @
e16f4398
...
...
@@ -11,26 +11,27 @@ import itertools
import
functools
try
:
from
collections
import
OrderedDict
from
collections
import
OrderedDict
except
ImportError
:
# python2.6 compatibility
from
ordereddict
import
OrderedDict
from
ordereddict
import
OrderedDict
class
WrappedMethod
(
object
):
def
__init__
(
self
,
control
,
method_name
):
self
.
method_name
=
method_name
self
.
control
=
control
def
__init__
(
self
,
control
,
method_name
):
self
.
method_name
=
method_name
self
.
control
=
control
def
__call__
(
self
,
this
,
*
args
,
**
kwargs
):
return
getattr
(
self
.
control
,
self
.
method_name
)(
*
args
,
**
kwargs
)
def
__call__
(
self
,
this
,
*
args
,
**
kwargs
):
return
getattr
(
self
.
control
,
self
.
method_name
)(
*
args
,
**
kwargs
)
def
wrap_methods
(
from_object
,
target_object
):
for
name
in
dir
(
from_object
):
if
inspect
.
ismethod
(
getattr
(
from_object
,
name
)):
if
hasattr
(
target_object
,
name
)
and
inspect
.
ismethod
(
getattr
(
target_object
,
name
)):
continue
setattr
(
target_object
,
name
,
types
.
MethodType
(
WrappedMethod
(
from_object
,
name
),
target_object
,
target_object
.
__class__
))
for
name
in
dir
(
from_object
):
if
inspect
.
ismethod
(
getattr
(
from_object
,
name
)):
if
hasattr
(
target_object
,
name
)
and
inspect
.
ismethod
(
getattr
(
target_object
,
name
)):
continue
setattr
(
target_object
,
name
,
types
.
MethodType
(
WrappedMethod
(
from_object
,
name
),
target_object
,
target_object
.
__class__
))
def
add_conversion_function
(
obj
,
method_name
,
function
):
...
...
@@ -40,7 +41,7 @@ def add_conversion_function(obj, method_name, function):
def
new_method
(
*
args
,
**
kwargs
):
values
=
meth
(
*
args
,
**
kwargs
)
return
function
(
values
)
setattr
(
obj
,
method_name
,
new_method
)
setattr
(
obj
,
method_name
,
new_method
)
else
:
raise
ValueError
(
"conversion function must be callable"
)
else
:
...
...
@@ -48,25 +49,29 @@ def add_conversion_function(obj, method_name, function):
def
add_property
(
inst
,
name
,
method
):
cls
=
type
(
inst
)
if
not
hasattr
(
cls
,
'__perinstance'
):
cls
=
type
(
cls
.
__name__
,
(
cls
,),
{})
cls
.
__perinstance
=
True
inst
.
__class__
=
cls
setattr
(
cls
,
name
,
property
(
method
))
cls
=
type
(
inst
)
if
not
hasattr
(
cls
,
'__perinstance'
):
cls
=
type
(
cls
.
__name__
,
(
cls
,),
{})
cls
.
__perinstance
=
True
inst
.
__class__
=
cls
setattr
(
cls
,
name
,
property
(
method
))
def
grouped
(
iterable
,
n
):
"s -> (s0,s1,s2,...sn-1), (sn,sn+1,sn+2,...s2n-1), (s2n,s2n+1,s2n+2,...s3n-1), ..."
return
itertools
.
izip
(
*
[
iter
(
iterable
)]
*
n
)
return
itertools
.
izip
(
*
[
iter
(
iterable
)]
*
n
)
def
all_equal
(
iterable
):
g
=
itertools
.
groupby
(
iterable
)
return
next
(
g
,
True
)
and
not
next
(
g
,
False
)
"""
functions to add custom attributes and commands to an object.
"""
def
add_object_method
(
obj
,
method
,
pre_call
,
name
=
None
,
args
=
[],
types_info
=
(
None
,
None
)):
if
name
is
None
:
...
...
@@ -98,27 +103,31 @@ def object_method(method=None, name=None, args=[], types_info=(None, None), filt
# Returns a method where _object_method_ attribute is filled with a
# dict of elements to characterize it.
method
.
_object_method_
=
dict
(
name
=
name
,
args
=
args
,
types_info
=
types_info
,
filter
=
filter
)
method
.
_object_method_
=
dict
(
name
=
name
,
args
=
args
,
types_info
=
types_info
,
filter
=
filter
)
return
method
def
object_method_type
(
method
=
None
,
name
=
None
,
args
=
[],
types_info
=
(
None
,
None
),
type
=
None
):
f
=
lambda
x
:
isinstance
(
x
,
type
)
def
f
(
x
):
return
isinstance
(
x
,
type
)
return
object_method
(
method
=
method
,
name
=
name
,
args
=
args
,
types_info
=
types_info
,
filter
=
f
)
def
add_object_attribute
(
obj
,
name
=
None
,
fget
=
None
,
fset
=
None
,
args
=
[],
type_info
=
None
,
filter
=
None
):
obj
.
_add_custom_attribute
(
name
,
fget
,
fset
,
type_info
)
"""
decorators for set/get methods to access to custom attributes
"""
def
object_attribute_type_get
(
get_method
=
None
,
name
=
None
,
args
=
[],
type_info
=
None
,
type
=
None
):
f
=
lambda
x
:
isinstance
(
x
,
type
)
def
f
(
x
):
return
isinstance
(
x
,
type
)
return
object_attribute_get
(
get_method
=
get_method
,
name
=
name
,
args
=
args
,
type_info
=
type_info
,
filter
=
f
)
def
object_attribute_get
(
get_method
=
None
,
name
=
None
,
args
=
[],
type_info
=
None
,
filter
=
None
):
if
get_method
is
None
:
return
functools
.
partial
(
object_attribute_get
,
name
=
name
,
args
=
args
,
...
...
@@ -128,21 +137,24 @@ def object_attribute_get(get_method=None, name=None, args=[], type_info=None, fi
name
=
get_method
.
func_name
attr_name
=
name
if
attr_name
.
startswith
(
"get_"
):
attr_name
=
attr_name
[
4
:]
# removes leading "get_"
attr_name
=
attr_name
[
4
:]
# removes leading "get_"
get_method
.
_object_method_
=
dict
(
name
=
name
,
args
=
args
,
types_info
=
(
"None"
,
type_info
),
filter
=
filter
)
get_method
.
_object_method_
=
dict
(
name
=
name
,
args
=
args
,
types_info
=
(
"None"
,
type_info
),
filter
=
filter
)
if
not
hasattr
(
get_method
,
"_object_attribute_"
):
get_method
.
_object_attribute_
=
dict
()
get_method
.
_object_attribute_
.
update
(
name
=
attr_name
,
fget
=
get_method
,
args
=
args
,
type_info
=
type_info
,
filter
=
filter
)
get_method
.
_object_attribute_
.
update
(
name
=
attr_name
,
fget
=
get_method
,
args
=
args
,
type_info
=
type_info
,
filter
=
filter
)
return
get_method
def
object_attribute_type_set
(
set_method
=
None
,
name
=
None
,
args
=
[],
type_info
=
None
,
type
=
None
):
f
=
lambda
x
:
isinstance
(
x
,
type
)
def
f
(
x
):
return
isinstance
(
x
,
type
)
return
object_attribute_set
(
set_method
=
set_method
,
name
=
name
,
args
=
args
,
type_info
=
type_info
,
filter
=
f
)
def
object_attribute_set
(
set_method
=
None
,
name
=
None
,
args
=
[],
type_info
=
None
,
filter
=
None
):
if
set_method
is
None
:
return
functools
.
partial
(
object_attribute_set
,
name
=
name
,
args
=
args
,
...
...
@@ -152,13 +164,15 @@ def object_attribute_set(set_method=None, name=None, args=[], type_info=None, fi
name
=
set_method
.
func_name
attr_name
=
name
if
attr_name
.
startswith
(
"set_"
):
attr_name
=
attr_name
[
4
:]
# removes leading "set_"
attr_name
=
attr_name
[
4
:]
# removes leading "set_"
set_method
.
_object_method_
=
dict
(
name
=
name
,
args
=
args
,
types_info
=
(
type_info
,
"None"
),
filter
=
filter
)
set_method
.
_object_method_
=
dict
(
name
=
name
,
args
=
args
,
types_info
=
(
type_info
,
"None"
),
filter
=
filter
)
if
not
hasattr
(
set_method
,
"_object_attribute_"
):
set_method
.
_object_attribute_
=
dict
()
set_method
.
_object_attribute_
.
update
(
name
=
attr_name
,
fset
=
set_method
,
args
=
args
,
type_info
=
type_info
,
filter
=
filter
)
set_method
.
_object_attribute_
.
update
(
name
=
attr_name
,
fset
=
set_method
,
args
=
args
,
type_info
=
type_info
,
filter
=
filter
)
return
set_method
...
...
@@ -174,7 +188,7 @@ def set_custom_members(src_obj, target_obj, pre_call=None):
attribute_info
=
dict
(
member
.
_object_attribute_
)
filter
=
attribute_info
.
pop
(
'filter'
,
None
)
if
filter
is
None
or
filter
(
target_obj
):
add_object_attribute
(
target_obj
,
**
member
.
_object_attribute_
)
add_object_attribute
(
target_obj
,
**
member
.
_object_attribute_
)
# For each method of <src_obj>: try to add it as a
# custom method or as methods to set/get custom
...
...
@@ -237,7 +251,8 @@ def with_custom_members(klass):
access_mode
=
'r'
if
fget
else
''
access_mode
+=
'w'
if
fset
else
''
if
fget
is
None
and
fset
is
None
:
raise
RuntimeError
(
"impossible case: must have fget or fset..."
)
raise
RuntimeError
(
"impossible case: must have fget or fset..."
)
custom_attrs
[
name
]
=
type_info
,
access_mode
klass
.
_get_custom_methods
=
_get_custom_methods
...
...
@@ -250,7 +265,6 @@ def with_custom_members(klass):
return
klass
class
Null
(
object
):
__slots__
=
[]
...
...
bliss/config/settings.py
View file @
e16f4398
...
...
@@ -11,33 +11,39 @@ from bliss import setup_globals
import
weakref
import
pickle
class
InvalidValue
(
Null
):
def
__str__
(
self
):
raise
ValueError
def
__repr__
(
self
):
return
'#ERR'
def
get_cache
():
return
client
.
get_cache
(
db
=
0
)
def
boolify
(
s
,
**
keys
):
def
boolify
(
s
,
**
keys
):
if
s
==
'True'
or
s
==
'true'
:
return
True
return
True
if
s
==
'False'
or
s
==
'false'
:
return
False
return
False
raise
ValueError
(
'Not Boolean Value!'
)
def
auto_conversion
(
var
):
'''guesses the str representation of the variables type'''
if
var
is
None
:
return
None
for
caster
in
(
boolify
,
int
,
float
):
for
caster
in
(
boolify
,
int
,
float
):
try
:
return
caster
(
var
)
except
(
ValueError
,
TypeError
):
except
(
ValueError
,
TypeError
):
pass
return
var
def
pickle_loads
(
var
):
if
var
is
None
:
return
None
...
...
@@ -46,24 +52,26 @@ def pickle_loads(var):
except
Exception
:
return
InvalidValue
()
def
ttl_func
(
cnx
,
name
,
value
=
-
1
):
def
ttl_func
(
cnx
,
name
,
value
=-
1
):
if
value
is
None
:
return
cnx
.
persist
(
name
)
elif
value
is
-
1
:
return
cnx
.
ttl
(
name
)
else
:
return
cnx
.
expire
(
name
,
value
)
return
cnx
.
expire
(
name
,
value
)
def
read_decorator
(
func
):
def
_read
(
self
,
*
args
,
**
keys
):
value
=
func
(
self
,
*
args
,
**
keys
)
def
_read
(
self
,
*
args
,
**
keys
):
value
=
func
(
self
,
*
args
,
**
keys
)
if
self
.
_read_type_conversion
:
if
isinstance
(
value
,
list
):
if
isinstance
(
value
,
list
):
value
=
[
self
.
_read_type_conversion
(
x
)
for
x
in
value
]
elif
isinstance
(
value
,
dict
):
for
k
,
v
in
value
.
iteritems
():
elif
isinstance
(
value
,
dict
):
for
k
,
v
in
value
.
iteritems
():
value
[
k
]
=
self
.
_read_type_conversion
(
v
)
if
hasattr
(
self
,
'default_values'
)
and
isinstance
(
self
.
default_values
,
dict
):
if
hasattr
(
self
,
'default_values'
)
and
isinstance
(
self
.
default_values
,
dict
):
tmp
=
dict
(
self
.
_default_values
)
tmp
.
update
(
value
)
value
=
tmp
...
...
@@ -71,60 +79,65 @@ def read_decorator(func):
if
value
is
not
None
:
value
=
self
.
_read_type_conversion
(
value
)
if
value
is
None
:
if
hasattr
(
self
,
'_default_value'
):
if
hasattr
(
self
,
'_default_value'
):
value
=
self
.
_default_value
elif
(
hasattr
(
self
,
'_default_values'
)
and
hasattr
(
self
.
_default_values
,
'get'
)):
elif
(
hasattr
(
self
,
'_default_values'
)
and
hasattr
(
self
.
_default_values
,
'get'
)):
value
=
self
.
_default_values
.
get
(
args
[
0
])
return
value
return
_read
def
write_decorator_dict
(
func
):
def
_write
(
self
,
values
,
**
keys
):
def
_write
(
self
,
values
,
**
keys
):
if
self
.
_write_type_conversion
:
if
not
isinstance
(
values
,
dict
)
and
values
is
not
None
:
if
not
isinstance
(
values
,
dict
)
and
values
is
not
None
:
raise
TypeError
(
'can only be dict'
)
if
values
is
not
None
:
for
k
,
v
in
values
.
iteritems
():
for
k
,
v
in
values
.
iteritems
():
values
[
k
]
=
self
.
_write_type_conversion
(
v
)
return
func
(
self
,
values
,
**
keys
)
return
func
(
self
,
values
,
**
keys
)
return
_write
def
write_decorator_multiple
(
func
):
def
_write
(
self
,
values
,
**
keys
):
def
_write
(
self
,
values
,
**
keys
):
if
self
.
_write_type_conversion
:
if
not
isinstance
(
values
,
(
list
,
tuple
))
and
values
is
not
None
:
if
not
isinstance
(
values
,
(
list
,
tuple
))
and
values
is
not
None
:
raise
TypeError
(
'can only be tuple or list'
)
if
values
is
not
None
:
values
=
[
self
.
_write_type_conversion
(
x
)
for
x
in
values
]
return
func
(
self
,
values
,
**
keys
)
return
func
(
self
,
values
,
**
keys
)
return
_write
def
write_decorator
(
func
):
def
_write
(
self
,
value
,
**
keys
):
def
_write
(
self
,
value
,
**
keys
):
if
self
.
_write_type_conversion
and
value
is
not
None
:
value
=
self
.
_write_type_conversion
(
value
)
return
func
(
self
,
value
,
**
keys
)
return
func
(
self
,
value
,
**
keys
)
return
_write
def
scan
(
match
=
'*'
,
count
=
1000
,
connection
=
None
):
def
scan
(
match
=
'*'
,
count
=
1000
,
connection
=
None
):
if
connection
is
None
:
connection
=
get_cache
()
cursor
=
0
while
1
:
cursor
,
values
=
connection
.
scan
(
cursor
=
cursor
,
match
=
match
,
count
=
count
)
cursor
,
values
=
connection
.
scan
(
cursor
=
cursor
,
match
=
match
,
count
=
count
)
for
val
in
values
:
yield
val
if
int
(
cursor
)
==
0
:
break
class
SimpleSetting
(
object
):
def
__init__
(
self
,
name
,
connection
=
None
,
read_type_conversion
=
auto_conversion
,
write_type_conversion
=
None
,
default_value
=
None
):
def
__init__
(
self
,
name
,
connection
=
None
,
read_type_conversion
=
auto_conversion
,
write_type_conversion
=
None
,
default_value
=
None
):
if
connection
is
None
:
connection
=
get_cache
()
self
.
_cnx
=
weakref
.
ref
(
connection
)
...
...
@@ -140,71 +153,72 @@ class SimpleSetting(object):
return
value
@
write_decorator
def
set
(
self
,
value
):
def
set
(
self
,
value
):
cnx
=
self
.
_cnx
()
cnx
.
set
(
self
.
_name
,
value
)
cnx
.
set
(
self
.
_name
,
value
)
def
ttl
(
self
,
value
=-
1
):
return
ttl_func
(
self
.
_cnx
(),
self
.
_name
,
value
)
def
ttl
(
self
,
value
=
-
1
):
return
ttl_func
(
self
.
_cnx
(),
self
.
_name
,
value
)
def
clear
(
self
):
cnx
=
self
.
_cnx
()
cnx
.
delete
(
self
.
_name
)
def
__add__
(
self
,
other
):
def
__add__
(
self
,
other
):
value
=
self
.
get
()
if
isinstance
(
other
,
SimpleSetting
):
if
isinstance
(
other
,
SimpleSetting
):
other
=
other
.
get
()
return
value
+
other
def
__iadd__
(
self
,
other
):
def
__iadd__
(
self
,
other
):
cnx
=
self
.
_cnx
()
if
cnx
is
not
None
:
if
isinstance
(
other
,
int
):
if
isinstance
(
other
,
int
):
if
other
==
1
:
cnx
.
incr
(
self
.
_name
)
else
:
cnx
.
incrby
(
self
.
_name
,
other
)
elif
isinstance
(
other
,
float
):
cnx
.
incrbyfloat
(
self
.
_name
,
other
)
cnx
.
incrby
(
self
.
_name
,
other
)
elif
isinstance
(
other
,
float
):
cnx
.
incrbyfloat
(
self
.
_name
,
other
)
else
:
cnx
.
append
(
self
.
_name
,
other
)
cnx
.
append
(
self
.
_name
,
other
)
return
self
def
__isub__
(
self
,
other
):
if
isinstance
(
other
,
basestring
):
raise
TypeError
(
"unsupported operand type(s) for -=: %s"
%
type
(
other
).
__name__
)
def
__isub__
(
self
,
other
):
if
isinstance
(
other
,
basestring
):
raise
TypeError
(
"unsupported operand type(s) for -=: %s"
%
type
(
other
).
__name__
)
return
self
.
__iadd__
(
-
other
)
def
__getitem__
(
self
,
ran
):
def
__getitem__
(
self
,
ran
):
cnx
=
self
.
_cnx
()
if
cnx
is
not
None
:
step
=
None
if
isinstance
(
ran
,
slice
):
i
,
j
=
ran
.
start
,
ran
.
stop
if
isinstance
(
ran
,
slice
):
i
,
j
=
ran
.
start
,
ran
.
stop
step
=
ran
.
step
elif
isinstance
(
ran
,
int
):
elif
isinstance
(
ran
,
int
):
i
=
j
=
ran
else
:
raise
TypeError
(
'indices must be integers'
)
value
=
cnx
.
getrange
(
self
.
_name
,
i
,
j
)
value
=
cnx
.
getrange
(
self
.
_name
,
i
,
j
)
if
step
is
not
None
:
value
=
value
[
0
:
-
1
:
step
]
return
value
def
__repr__
(
self
):
cnx
=
self
.
_cnx
()
value
=
cnx
.
get
(
self
.
_name
)
return
'<SimpleSetting name=%s value=%s>'
%
(
self
.
_name
,
value
)
return
'<SimpleSetting name=%s value=%s>'
%
(
self
.
_name
,
value
)
class
SimpleSettingProp
(
object
):
def
__init__
(
self
,
name
,
connection
=
None
,
read_type_conversion
=
auto_conversion
,
write_type_conversion
=
None
,
default_value
=
None
,
use_object_name
=
True
):
def
__init__
(
self
,
name
,
connection
=
None
,
read_type_conversion
=
auto_conversion
,
write_type_conversion
=
None
,
default_value
=
None
,
use_object_name
=
True
):
self
.
_name
=
name
self
.
_cnx
=
connection
or
get_cache
()
self
.
_read_type_conversion
=
read_type_conversion
...
...
@@ -212,18 +226,19 @@ class SimpleSettingProp(object):
self
.
_default_value
=
default_value
self
.
_use_object_name
=
use_object_name
def
__get__
(
self
,
obj
,
type
=
None
):
def
__get__
(
self
,
obj
,
type
=
None
):
if
self
.
_use_object_name
:
name
=
obj
.
name
+
':'
+
self
.
_name
else
:
name
=
self
.
_name
return
SimpleSetting
(
name
,
self
.
_cnx
,
return
SimpleSetting
(
name
,
self
.
_cnx
,
self
.
_read_type_conversion
,
self
.
_write_type_conversion
,
self
.
_default_value
)
def
__set__
(
self
,
obj
,
value
):
if
isinstance
(
value
,
SimpleSetting
):
return
def
__set__
(
self
,
obj
,
value
):
if
isinstance
(
value
,
SimpleSetting
):
return
if
self
.
_use_object_name
:
name
=
obj
.
name
+
':'
+
self
.
_name
...
...
@@ -235,67 +250,69 @@ class SimpleSettingProp(object):
else
:
if
self
.
_write_type_conversion
:
value
=
self
.
_write_type_conversion
(
value
)
self
.
_cnx
.
set
(
name
,
value
)
self
.
_cnx
.
set
(
name
,
value
)
class
QueueSetting
(
object
):
def
__init__
(
self
,
name
,
connection
=
None
,
read_type_conversion
=
auto_conversion
,
write_type_conversion
=
None
):
if
connection
is
None
:
connection
=
get_cache
()
def
__init__
(
self
,
name
,
connection
=
None
,
read_type_conversion
=
auto_conversion
,
write_type_conversion
=
None
):
if
connection
is
None
:
connection
=
get_cache
()
self
.
_cnx
=
weakref
.
ref
(
connection
)
self
.
_name
=
name
self
.
_read_type_conversion
=
read_type_conversion
self
.
_write_type_conversion
=
write_type_conversion
@
read_decorator
def
get
(
self
,
first
=
0
,
last
=-
1
):
def
get
(
self
,
first
=
0
,
last
=-
1
):
cnx
=
self
.
_cnx
()
if
first
==
last
:
l
=
cnx
.
lindex
(
self
.
_name
,
first
)
l
=
cnx
.
lindex
(
self
.
_name
,
first
)
else
:
if
last
!=
-
1
:
last
-=
1
l
=
cnx
.
lrange
(
self
.
_name
,
first
,
last
)
l
=
cnx
.
lrange
(
self
.
_name
,
first
,
last
)
return
l
@
write_decorator
def
append
(
self
,
value
):
def
append
(
self
,
value
):
cnx
=
self
.
_cnx
()
return
cnx
.
rpush
(
self
.
_name
,
value
)
return
cnx
.
rpush
(
self
.
_name
,
value
)
def
clear
(
self
):
cnx
=
self
.
_cnx
()
cnx
.
delete
(
self
.
_name
)
@
write_decorator
def
prepend
(
self
,
value
):
def
prepend
(
self
,
value
):
cnx
=
self
.
_cnx
()
return
cnx
.
lpush
(
self
.
_name
,
value
)
return
cnx
.
lpush
(
self
.
_name
,
value
)
@
write_decorator_multiple
def
extend
(
self
,
values
):