Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F117887488
__init__.py
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
24 KB
Referenced Files
None
Subscribers
None
__init__.py
View Options
# -*- coding: utf-8 -*-
# Copyright 2010-2013 Kolab Systems AG (http://www.kolabsys.com)
#
# Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen a kolabsys.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
import
logging
import
os
import
sys
from
optparse
import
OptionParser
from
ConfigParser
import
SafeConfigParser
import
pykolab
from
pykolab.conf.defaults
import
Defaults
from
pykolab.constants
import
*
from
pykolab.translate
import
_
log
=
pykolab
.
getLogger
(
'pykolab.conf'
)
class
Conf
(
object
):
def
__init__
(
self
):
"""
self.cli_args == Arguments passed on the CLI
self.cli_keywords == Parser results (again, CLI)
self.cli_parser == The actual Parser (from OptionParser)
self.plugins == Our Kolab Plugins
"""
self
.
cli_parser
=
None
self
.
cli_args
=
None
self
.
cli_keywords
=
None
self
.
entitlement
=
None
self
.
changelog
=
{}
try
:
from
pykolab.conf.entitlement
import
Entitlement
entitlements
=
True
except
:
entitlements
=
False
pass
if
entitlements
:
self
.
entitlement
=
Entitlement
()
.
get
()
self
.
plugins
=
None
# The location where our configuration parser is going to end up
self
.
cfg_parser
=
None
# Create the options
self
.
create_options
()
def
finalize_conf
(
self
,
fatal
=
True
):
self
.
create_options_from_plugins
()
self
.
parse_options
(
fatal
=
fatal
)
# The defaults can some from;
# - a file we ship with the packages
# - a customly supplied file (by customer)
# - a file we write out
# - this python class
#
# Look, we want defaults
self
.
defaults
=
Defaults
(
self
.
plugins
)
# But, they should be available in our class as well
for
option
in
self
.
defaults
.
__dict__
.
keys
():
log
.
debug
(
_
(
"Setting
%s
to
%r
(from defaults)"
)
%
(
option
,
self
.
defaults
.
__dict__
[
option
]),
level
=
8
)
setattr
(
self
,
option
,
self
.
defaults
.
__dict__
[
option
])
# This is where we check our parser for the defaults being set there.
self
.
set_defaults_from_cli_options
()
self
.
options_set_from_config
()
# Also set the cli options
if
hasattr
(
self
,
'cli_keywords'
)
and
not
self
.
cli_keywords
==
None
:
for
option
in
self
.
cli_keywords
.
__dict__
.
keys
():
retval
=
False
if
hasattr
(
self
,
"check_setting_
%s
"
%
(
option
)):
exec
(
"retval = self.check_setting_
%s
(
%r
)"
%
(
option
,
self
.
cli_keywords
.
__dict__
[
option
]))
# The warning, error or confirmation dialog is in the check_setting_%s() function
if
not
retval
:
continue
log
.
debug
(
_
(
"Setting
%s
to
%r
(from CLI, verified)"
)
%
(
option
,
self
.
cli_keywords
.
__dict__
[
option
]),
level
=
8
)
setattr
(
self
,
option
,
self
.
cli_keywords
.
__dict__
[
option
])
else
:
log
.
debug
(
_
(
"Setting
%s
to
%r
(from CLI, not checked)"
)
%
(
option
,
self
.
cli_keywords
.
__dict__
[
option
]),
level
=
8
)
setattr
(
self
,
option
,
self
.
cli_keywords
.
__dict__
[
option
])
def
load_config
(
self
,
config
):
"""
Given a SafeConfigParser instance, loads a configuration
file and checks, then sets everything it can find.
"""
for
section
in
self
.
defaults
.
__dict__
.
keys
():
if
section
==
'testing'
:
continue
if
not
config
.
has_section
(
section
):
continue
for
key
in
self
.
defaults
.
__dict__
[
section
]
.
keys
():
retval
=
False
if
not
config
.
has_option
(
section
,
key
):
continue
if
isinstance
(
self
.
defaults
.
__dict__
[
section
][
key
],
int
):
value
=
config
.
getint
(
section
,
key
)
elif
isinstance
(
self
.
defaults
.
__dict__
[
section
][
key
],
bool
):
value
=
config
.
getboolean
(
section
,
key
)
elif
isinstance
(
self
.
defaults
.
__dict__
[
section
][
key
],
str
):
value
=
config
.
get
(
section
,
key
)
elif
isinstance
(
self
.
defaults
.
__dict__
[
section
][
key
],
list
):
value
=
eval
(
config
.
get
(
section
,
key
))
elif
isinstance
(
self
.
defaults
.
__dict__
[
section
][
key
],
dict
):
value
=
eval
(
config
.
get
(
section
,
key
))
if
hasattr
(
self
,
"check_setting_
%s
_
%s
"
%
(
section
,
key
)):
exec
(
"retval = self.check_setting_
%s
_
%s
(
%r
)"
%
(
section
,
key
,
value
))
if
not
retval
:
# We just don't set it, check_setting_%s should have
# taken care of the error messages
continue
if
not
self
.
defaults
.
__dict__
[
section
][
key
]
==
value
:
if
key
.
count
(
'password'
)
>=
1
:
log
.
debug
(
_
(
"Setting
%s
_
%s
to '****' (from configuration file)"
)
%
(
section
,
key
),
level
=
8
)
else
:
log
.
debug
(
_
(
"Setting
%s
_
%s
to
%r
(from configuration file)"
)
%
(
section
,
key
,
value
),
level
=
8
)
setattr
(
self
,
"
%s
_
%s
"
%
(
section
,
key
),
value
)
def
options_set_from_config
(
self
):
"""
Sets the default configuration options from a
configuration file. Configuration file may be
customized using the --config CLI option
"""
log
.
debug
(
_
(
"Setting options from configuration file"
),
level
=
4
)
# Check from which configuration file we should get the defaults
# Other then default?
self
.
config_file
=
self
.
defaults
.
config_file
if
hasattr
(
self
,
'cli_keywords'
)
and
not
self
.
cli_keywords
==
None
:
if
not
self
.
cli_keywords
.
config_file
==
self
.
defaults
.
config_file
:
self
.
config_file
=
self
.
cli_keywords
.
config_file
config
=
self
.
check_config
()
self
.
load_config
(
config
)
def
set_options_from_testing_section
(
self
):
"""
Go through the options in the [testing] section if it exists.
"""
config
=
self
.
check_config
()
if
not
config
.
has_section
(
'testing'
):
return
for
key
in
config
.
options
(
'testing'
):
retval
=
False
if
isinstance
(
self
.
defaults
.
__dict__
[
'testing'
][
key
],
int
):
value
=
config
.
getint
(
'testing'
,
key
)
elif
isinstance
(
self
.
defaults
.
__dict__
[
'testing'
][
key
],
bool
):
value
=
config
.
getboolean
(
'testing'
,
key
)
elif
isinstance
(
self
.
defaults
.
__dict__
[
'testing'
][
key
],
str
):
value
=
config
.
get
(
'testing'
,
key
)
elif
isinstance
(
self
.
defaults
.
__dict__
[
'testing'
][
key
],
list
):
value
=
eval
(
config
.
get
(
'testing'
,
key
))
elif
isinstance
(
self
.
defaults
.
__dict__
[
'testing'
][
key
],
dict
):
value
=
eval
(
config
.
get
(
'testing'
,
key
))
if
hasattr
(
self
,
"check_setting_
%s
_
%s
"
%
(
'testing'
,
key
)):
exec
(
"retval = self.check_setting_
%s
_
%s
(
%r
)"
%
(
'testing'
,
key
,
value
))
if
not
retval
:
# We just don't set it, check_setting_%s should have
# taken care of the error messages
continue
setattr
(
self
,
"
%s
_
%s
"
%
(
'testing'
,
key
),
value
)
if
key
.
count
(
'password'
)
>=
1
:
log
.
debug
(
_
(
"Setting
%s
_
%s
to '****' (from configuration file)"
)
%
(
'testing'
,
key
),
level
=
8
)
else
:
log
.
debug
(
_
(
"Setting
%s
_
%s
to
%r
(from configuration file)"
)
%
(
'testing'
,
key
,
value
),
level
=
8
)
def
check_config
(
self
,
val
=
None
):
"""
Checks self.config_file or the filename passed using 'val'
and returns a SafeConfigParser instance if everything is OK.
"""
if
not
val
==
None
:
config_file
=
val
else
:
config_file
=
self
.
config_file
if
not
os
.
access
(
config_file
,
os
.
R_OK
):
log
.
error
(
_
(
"Configuration file
%s
not readable"
)
%
config_file
)
config
=
SafeConfigParser
()
log
.
debug
(
_
(
"Reading configuration file
%s
"
)
%
config_file
,
level
=
8
)
try
:
config
.
read
(
config_file
)
except
:
log
.
error
(
_
(
"Invalid configuration file
%s
"
)
%
config_file
)
if
not
config
.
has_section
(
"kolab"
):
log
.
warning
(
_
(
"No master configuration section [kolab] in configuration file
%s
"
)
%
config_file
)
return
config
def
add_cli_parser_option_group
(
self
,
name
):
return
self
.
cli_parser
.
add_option_group
(
name
)
def
create_options_from_plugins
(
self
):
"""
Create options from plugins.
This function must be called separately from Conf.__init__(), or
the configuration store is not yet done initializing when the
plugins class and the plugins themselves go look for it.
"""
import
pykolab.plugins
self
.
plugins
=
pykolab
.
plugins
.
KolabPlugins
()
self
.
plugins
.
add_options
(
self
.
cli_parser
)
def
create_options
(
self
,
load_plugins
=
True
):
"""
Create the OptionParser for the options passed to us from runtime
Command Line Interface.
"""
# Enterprise Linux 5 does not have an "epilog" parameter to OptionParser
try
:
self
.
cli_parser
=
OptionParser
(
epilog
=
epilog
)
except
:
self
.
cli_parser
=
OptionParser
()
##
## Runtime Options
##
runtime_group
=
self
.
cli_parser
.
add_option_group
(
_
(
"Runtime Options"
))
runtime_group
.
add_option
(
"-c"
,
"--config"
,
dest
=
"config_file"
,
action
=
"store"
,
default
=
"/etc/kolab/kolab.conf"
,
help
=
_
(
"Configuration file to use"
))
runtime_group
.
add_option
(
"-d"
,
"--debug"
,
dest
=
"debuglevel"
,
type
=
'int'
,
default
=
0
,
help
=
_
(
"Set the debugging "
+
\
"verbosity. Maximum is 9, tracing "
+
\
"protocols like LDAP, SQL and IMAP."
))
runtime_group
.
add_option
(
"-e"
,
"--default"
,
dest
=
"answer_default"
,
action
=
"store_true"
,
default
=
False
,
help
=
_
(
"Use the default answer to all questions."
))
runtime_group
.
add_option
(
"-l"
,
dest
=
"loglevel"
,
type
=
'str'
,
default
=
"CRITICAL"
,
help
=
_
(
"Set the logging level. "
+
\
"One of info, warn, error, "
+
\
"critical or debug"
))
runtime_group
.
add_option
(
"--logfile"
,
dest
=
"logfile"
,
action
=
"store"
,
default
=
"/var/log/kolab/pykolab.log"
,
help
=
_
(
"Log file to use"
))
runtime_group
.
add_option
(
"-q"
,
"--quiet"
,
dest
=
"quiet"
,
action
=
"store_true"
,
default
=
False
,
help
=
_
(
"Be quiet."
))
runtime_group
.
add_option
(
"-y"
,
"--yes"
,
dest
=
"answer_yes"
,
action
=
"store_true"
,
default
=
False
,
help
=
_
(
"Answer yes to all questions."
))
def
parse_options
(
self
,
fatal
=
True
):
"""
Parse options passed to our call.
"""
if
fatal
:
(
self
.
cli_keywords
,
self
.
cli_args
)
=
self
.
cli_parser
.
parse_args
()
def
run
(
self
):
"""
Run Forest, RUN!
"""
exitcode
=
0
if
self
.
cli_args
:
if
len
(
self
.
cli_args
)
>=
1
:
if
hasattr
(
self
,
"command_
%s
"
%
self
.
cli_args
[
0
]
.
replace
(
'-'
,
'_'
)):
exec
(
"self.command_
%s
(
%r
)"
%
(
self
.
cli_args
[
0
]
.
replace
(
'-'
,
'_'
),
self
.
cli_args
[
1
:]))
else
:
print
>>
sys
.
stderr
,
_
(
"No command supplied"
)
def
command_dump
(
self
,
*
args
,
**
kw
):
"""
Dumps applicable, valid configuration that is not defaults.
"""
if
not
self
.
cfg_parser
:
self
.
read_config
()
if
not
self
.
cfg_parser
.
has_section
(
'kolab'
):
print
"No section found for kolab"
sys
.
exit
(
1
)
# Get the sections, and then walk through the sections in a
# sensible way.
items
=
self
.
cfg_parser
.
options
(
'kolab'
)
items
.
sort
()
for
item
in
items
:
mode
=
self
.
cfg_parser
.
get
(
'kolab'
,
item
)
print
"
%s
=
%s
"
%
(
item
,
mode
)
if
not
self
.
cfg_parser
.
has_section
(
mode
):
print
"WARNING: No configuration section
%s
for item
%s
"
%
(
mode
,
item
)
continue
keys
=
self
.
cfg_parser
.
options
(
mode
)
keys
.
sort
()
if
self
.
cfg_parser
.
has_option
(
mode
,
'leave_this_one_to_me'
):
print
"Ignoring section
%s
"
%
(
mode
,)
continue
for
key
in
keys
:
print
"
%s
_
%s
=
%s
"
%
(
mode
,
key
,
self
.
cfg_parser
.
get
(
mode
,
key
))
def
read_config
(
self
,
value
=
None
):
"""
Reads the configuration file, sets a self.cfg_parser.
"""
if
not
value
:
value
=
self
.
defaults
.
config_file
if
hasattr
(
self
,
'cli_keywords'
)
and
not
self
.
cli_keywords
==
None
:
value
=
self
.
cli_keywords
.
config_file
self
.
cfg_parser
=
SafeConfigParser
()
self
.
cfg_parser
.
read
(
value
)
if
hasattr
(
self
,
'cli_keywords'
)
and
hasattr
(
self
.
cli_keywords
,
'config_file'
):
self
.
cli_keywords
.
config_file
=
value
self
.
defaults
.
config_file
=
value
self
.
config_file
=
value
def
command_get
(
self
,
*
args
,
**
kw
):
"""
Get a configuration option.
Pass me a section and key please.
"""
exec
(
"args =
%r
"
%
args
)
print
"
%s
/
%s
:
%r
"
%
(
args
[
0
],
args
[
1
],
self
.
get
(
args
[
0
],
args
[
1
]))
# if len(args) == 3:
# # Return non-zero if no match
# # Return zero if match
# # Improvised "check" function
def
command_set
(
self
,
*
args
,
**
kw
):
"""
Set a configuration option.
Pass me a section, key and value please. Note that the section should
already exist.
TODO: Add a strict parameter
TODO: Add key value checking
"""
if
not
self
.
cfg_parser
:
self
.
read_config
()
if
not
len
(
args
)
==
3
:
log
.
error
(
_
(
"Insufficient options. Need section, key and value -in that order."
))
if
not
self
.
cfg_parser
.
has_section
(
args
[
0
]):
log
.
error
(
_
(
"No section '
%s
' exists."
)
%
(
args
[
0
]))
if
'%'
in
args
[
2
]:
value
=
args
[
2
]
.
replace
(
'%'
,
'
%%
'
)
else
:
value
=
args
[
2
]
self
.
cfg_parser
.
set
(
args
[
0
],
args
[
1
],
value
)
if
hasattr
(
self
,
'cli_keywords'
)
and
hasattr
(
self
.
cli_keywords
,
'config_file'
):
fp
=
open
(
self
.
cli_keywords
.
config_file
,
"w+"
)
self
.
cfg_parser
.
write
(
fp
)
fp
.
close
()
else
:
fp
=
open
(
self
.
config_file
,
"w+"
)
self
.
cfg_parser
.
write
(
fp
)
fp
.
close
()
def
create_logger
(
self
):
"""
Create a logger instance using cli_options.debuglevel
"""
if
not
self
.
cli_keywords
.
debuglevel
==
None
:
loglevel
=
logging
.
DEBUG
else
:
loglevel
=
logging
.
INFO
self
.
cli_keywords
.
debuglevel
=
0
self
.
debuglevel
=
self
.
cli_keywords
.
debuglevel
# Initialize logger
log
=
pykolab
.
logger
.
Logger
(
loglevel
=
loglevel
,
debuglevel
=
self
.
cli_keywords
.
debuglevel
,
logfile
=
self
.
cli_keywords
.
logfile
)
def
set_defaults_from_cli_options
(
self
):
for
long_opt
in
self
.
cli_parser
.
__dict__
[
'_long_opt'
]
.
keys
():
if
long_opt
==
"--help"
:
continue
setattr
(
self
.
defaults
,
self
.
cli_parser
.
_long_opt
[
long_opt
]
.
dest
,
self
.
cli_parser
.
_long_opt
[
long_opt
]
.
default
)
# But, they should be available in our class as well
for
option
in
self
.
cli_parser
.
defaults
.
keys
():
log
.
debug
(
_
(
"Setting
%s
to
%r
(from the default values for CLI options)"
)
%
(
option
,
self
.
cli_parser
.
defaults
[
option
]),
level
=
8
)
setattr
(
self
,
option
,
self
.
cli_parser
.
defaults
[
option
])
def
has_section
(
self
,
section
):
if
not
self
.
cfg_parser
:
self
.
read_config
()
return
self
.
cfg_parser
.
has_section
(
section
)
def
has_option
(
self
,
section
,
option
):
if
not
self
.
cfg_parser
:
self
.
read_config
()
return
self
.
cfg_parser
.
has_option
(
section
,
option
)
def
get_list
(
self
,
section
,
key
):
"""
Gets a comma and/or space separated list from the configuration file
and returns a list.
"""
values
=
[]
untrimmed_values
=
[]
setting
=
self
.
get_raw
(
section
,
key
)
if
setting
==
None
:
return
[]
raw_values
=
setting
.
split
(
','
)
if
raw_values
==
None
:
return
[]
for
raw_value
in
raw_values
:
untrimmed_values
.
extend
(
raw_value
.
split
(
' '
))
for
value
in
untrimmed_values
:
if
not
value
.
strip
()
==
""
:
values
.
append
(
value
.
strip
()
.
lower
())
return
values
def
get_raw
(
self
,
section
,
key
):
if
not
self
.
cfg_parser
:
self
.
read_config
()
if
self
.
cfg_parser
.
has_option
(
section
,
key
):
return
self
.
cfg_parser
.
get
(
section
,
key
,
1
)
def
get
(
self
,
section
,
key
,
quiet
=
False
):
"""
Get a configuration option from our store, the configuration file,
or an external source if we have some sort of function for it.
TODO: Include getting the value from plugins through a hook.
"""
retval
=
False
if
not
self
.
cfg_parser
:
self
.
read_config
()
#log.debug(_("Obtaining value for section %r, key %r") % (section, key), level=8)
if
self
.
cfg_parser
.
has_option
(
section
,
key
):
try
:
return
self
.
cfg_parser
.
get
(
section
,
key
)
except
:
self
.
read_config
()
return
self
.
cfg_parser
.
get
(
section
,
key
)
if
hasattr
(
self
,
"get_
%s
_
%s
"
%
(
section
,
key
)):
try
:
exec
(
"retval = self.get_
%s
_
%s
(quiet)"
%
(
section
,
key
))
except
Exception
,
e
:
log
.
error
(
_
(
"Could not execute configuration function:
%s
"
)
%
(
"get_
%s
_
%s
(quiet=
%r
)"
%
(
section
,
key
,
quiet
)))
return
None
return
retval
if
quiet
:
return
""
else
:
log
.
warning
(
_
(
"Option
%s
/
%s
does not exist in config file
%s
, pulling from defaults"
)
%
(
section
,
key
,
self
.
config_file
))
if
hasattr
(
self
.
defaults
,
"
%s
_
%s
"
%
(
section
,
key
)):
return
getattr
(
self
.
defaults
,
"
%s
_
%s
"
%
(
section
,
key
))
elif
hasattr
(
self
.
defaults
,
"
%s
"
%
(
section
)):
if
key
in
getattr
(
self
.
defaults
,
"
%s
"
%
(
section
)):
_dict
=
getattr
(
self
.
defaults
,
"
%s
"
%
(
section
))
return
_dict
[
key
]
else
:
log
.
warning
(
_
(
"Option does not exist in defaults."
))
return
None
else
:
log
.
warning
(
_
(
"Option does not exist in defaults."
))
return
None
def
check_setting_config_file
(
self
,
value
):
if
os
.
path
.
isfile
(
value
):
if
os
.
access
(
value
,
os
.
R_OK
):
self
.
read_config
(
value
=
value
)
self
.
config_file
=
value
return
True
else
:
log
.
error
(
_
(
"Configuration file
%s
not readable."
)
%
(
value
))
return
False
else
:
log
.
error
(
_
(
"Configuration file
%s
does not exist."
)
%
(
value
))
return
False
def
check_setting_debuglevel
(
self
,
value
):
if
value
<
0
:
log
.
info
(
_
(
"WARNING: A negative debug level value does not make this program be any more silent."
))
elif
value
==
0
:
return
True
elif
value
<=
9
:
return
True
else
:
log
.
warning
(
_
(
"This program has 9 levels of verbosity. Using the maximum of 9."
))
return
True
def
check_setting_saslauth_mode
(
self
,
value
):
if
value
:
# TODO: I suppose this is platform specific
if
os
.
path
.
isfile
(
"/var/run/saslauthd/mux"
):
if
os
.
path
.
isfile
(
"/var/run/saslauthd/saslauthd.pid"
):
log
.
error
(
_
(
"Cannot start SASL authentication daemon"
))
return
False
else
:
try
:
os
.
remove
(
"/var/run/saslauthd/mux"
)
except
IOError
,
e
:
log
.
error
(
_
(
"Cannot start SASL authentication daemon"
))
return
False
elif
os
.
path
.
isfile
(
"/var/run/sasl2/mux"
):
if
os
.
path
.
isfile
(
"/var/run/sasl2/saslauthd.pid"
):
log
.
error
(
_
(
"Cannot start SASL authentication daemon"
))
return
False
else
:
try
:
os
.
remove
(
"/var/run/sasl2/mux"
)
except
IOError
,
e
:
log
.
error
(
_
(
"Cannot start SASL authentication daemon"
))
return
False
return
True
def
check_setting_use_imap
(
self
,
value
):
if
value
:
try
:
import
imaplib
self
.
use_imap
=
value
return
True
except
ImportError
:
log
.
error
(
_
(
"No imaplib library found."
))
return
False
def
check_setting_use_lmtp
(
self
,
value
):
if
value
:
try
:
from
smtplib
import
LMTP
self
.
use_lmtp
=
value
return
True
except
ImportError
:
log
.
error
(
_
(
"No LMTP class found in the smtplib library."
))
return
False
def
check_setting_use_mail
(
self
,
value
):
if
value
:
try
:
from
smtplib
import
SMTP
self
.
use_mail
=
value
return
True
except
ImportError
:
log
.
error
(
_
(
"No SMTP class found in the smtplib library."
))
return
False
def
check_setting_test_suites
(
self
,
value
):
# Attempt to load the suite,
# Get the suite's options,
# Set them here.
if
not
hasattr
(
self
,
'test_suites'
):
self
.
test_suites
=
[]
if
"zpush"
in
value
:
selectively
=
False
for
item
in
[
'calendar'
,
'contacts'
,
'mail'
]:
if
self
.
cli_keywords
.
__dict__
[
item
]:
log
.
debug
(
_
(
"Found you specified a specific set of items to test:
%s
"
)
%
(
item
),
level
=
8
)
selectively
=
item
if
not
selectively
:
self
.
calendar
=
True
self
.
contacts
=
True
self
.
mail
=
True
else
:
log
.
debug
(
_
(
"Selectively selecting:
%s
"
)
%
(
selectively
),
level
=
8
)
setattr
(
self
,
selectively
,
True
)
self
.
test_suites
.
append
(
'zpush'
)
def
check_setting_calendar
(
self
,
value
):
if
self
.
cli_parser
.
_long_opt
[
'--calendar'
]
.
default
==
value
:
return
False
else
:
return
True
def
check_setting_contacts
(
self
,
value
):
if
self
.
cli_parser
.
_long_opt
[
'--contacts'
]
.
default
==
value
:
return
False
else
:
return
True
def
check_setting_mail
(
self
,
value
):
if
self
.
cli_parser
.
_long_opt
[
'--mail'
]
.
default
==
value
:
return
False
else
:
return
True
File Metadata
Details
Attached
Mime Type
text/x-script.python
Expires
Mon, Apr 6, 3:00 AM (2 w, 5 d ago)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
7e/16/e8a44ba9870a55afa2356ada608a
Default Alt Text
__init__.py (24 KB)
Attached To
Mode
rP pykolab
Attached
Detach File
Event Timeline