Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
weboob
Project overview
Project overview
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
177
Issues
177
List
Boards
Labels
Milestones
Merge Requests
49
Merge Requests
49
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
weboob
weboob
Commits
9f5c9aee
Commit
9f5c9aee
authored
Aug 24, 2010
by
Romain Bignon
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
renamed BackendsLoader to ModulesLoader
parent
f0ea8829
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
301 additions
and
27 deletions
+301
-27
weboob/applications/weboobcfg/weboobcfg.py
weboob/applications/weboobcfg/weboobcfg.py
+7
-7
weboob/core/backendscfg.py
weboob/core/backendscfg.py
+103
-0
weboob/core/modules.py
weboob/core/modules.py
+141
-0
weboob/core/ouiboube.py
weboob/core/ouiboube.py
+10
-9
weboob/tools/application/base.py
weboob/tools/application/base.py
+6
-1
weboob/tools/application/console.py
weboob/tools/application/console.py
+5
-2
weboob/tools/application/qt/backendcfg.py
weboob/tools/application/qt/backendcfg.py
+11
-8
weboob/tools/backend.py
weboob/tools/backend.py
+18
-0
No files found.
weboob/applications/weboobcfg/weboobcfg.py
View file @
9f5c9aee
...
...
@@ -46,8 +46,8 @@ class WeboobCfg(ConsoleApplication):
@
ConsoleApplication
.
command
(
'Add a configured backend'
)
def
command_add
(
self
,
name
,
*
options
):
self
.
weboob
.
backend
s_loader
.
load_all
()
if
name
not
in
[
_name
for
_name
,
backend
in
self
.
weboob
.
backend
s_loader
.
loaded
.
iteritems
()]:
self
.
weboob
.
module
s_loader
.
load_all
()
if
name
not
in
[
_name
for
_name
,
backend
in
self
.
weboob
.
module
s_loader
.
loaded
.
iteritems
()]:
logging
.
error
(
u'Backend "
%
s" does not exist.'
%
name
)
return
1
...
...
@@ -61,7 +61,7 @@ class WeboobCfg(ConsoleApplication):
return
1
params
[
key
]
=
value
# ask for params non-specified on command-line arguments
backend
=
self
.
weboob
.
backends_loader
.
get_or_load_backend
(
name
)
backend
=
self
.
weboob
.
modules_loader
.
get_or_load_module
(
name
)
asked_config
=
False
for
key
,
value
in
backend
.
config
.
iteritems
():
if
not
asked_config
:
...
...
@@ -105,7 +105,7 @@ class WeboobCfg(ConsoleApplication):
def
command_listconfigured
(
self
):
self
.
set_default_formatter
(
'table'
)
for
instance_name
,
name
,
params
in
sorted
(
self
.
weboob
.
backends_config
.
iter_backends
()):
backend
=
self
.
weboob
.
backends_loader
.
get_or_load_backend
(
name
)
backend
=
self
.
weboob
.
modules_loader
.
get_or_load_module
(
name
)
row
=
OrderedDict
([(
'Instance name'
,
instance_name
),
(
'Backend name'
,
name
),
(
'Configuration'
,
', '
.
join
(
'
%
s=
%
s'
%
(
key
,
(
'*****'
if
backend
.
config
[
key
]
.
is_masked
else
value
))
for
key
,
value
in
params
.
iteritems
())),
...
...
@@ -127,8 +127,8 @@ class WeboobCfg(ConsoleApplication):
@
ConsoleApplication
.
command
(
'Show available backends'
)
def
command_backends
(
self
,
*
caps
):
self
.
set_default_formatter
(
'table'
)
self
.
weboob
.
backend
s_loader
.
load_all
()
for
name
,
backend
in
sorted
(
self
.
weboob
.
backend
s_loader
.
loaded
.
iteritems
()):
self
.
weboob
.
module
s_loader
.
load_all
()
for
name
,
backend
in
sorted
(
self
.
weboob
.
module
s_loader
.
loaded
.
iteritems
()):
if
caps
and
not
self
.
caps_included
(
backend
.
iter_caps
(),
caps
):
continue
row
=
OrderedDict
([(
'Name'
,
name
),
...
...
@@ -140,7 +140,7 @@ class WeboobCfg(ConsoleApplication):
@
ConsoleApplication
.
command
(
'Display information about a backend'
)
def
command_info
(
self
,
name
):
try
:
backend
=
self
.
weboob
.
backends_loader
.
get_or_load_backend
(
name
)
backend
=
self
.
weboob
.
modules_loader
.
get_or_load_module
(
name
)
except
KeyError
:
logging
.
error
(
'No such backend: "
%
s"'
%
name
)
return
1
...
...
weboob/core/backends.py
→
weboob/core/backends
cfg
.py
View file @
9f5c9aee
...
...
@@ -18,89 +18,12 @@
from
__future__
import
with_statement
from
ConfigParser
import
RawConfigParser
import
logging
from
logging
import
debug
,
error
,
exception
,
warning
import
os
import
re
import
stat
import
os
from
ConfigParser
import
RawConfigParser
from
logging
import
warning
from
weboob.capabilities.base
import
IBaseCap
from
weboob.tools.backend
import
BaseBackend
__all__
=
[
'Backend'
,
'BackendsConfig'
,
'BackendsLoader'
]
class
Backend
(
object
):
def
__init__
(
self
,
package
):
self
.
package
=
package
self
.
klass
=
None
for
attrname
in
dir
(
self
.
package
):
attr
=
getattr
(
self
.
package
,
attrname
)
if
isinstance
(
attr
,
type
)
and
issubclass
(
attr
,
BaseBackend
)
and
attr
!=
BaseBackend
:
self
.
klass
=
attr
if
not
self
.
klass
:
raise
ImportError
(
'
%
s is not a backend (no BaseBackend class found)'
%
package
)
@
property
def
name
(
self
):
return
self
.
klass
.
NAME
@
property
def
maintainer
(
self
):
return
'
%
s <
%
s>'
%
(
self
.
klass
.
MAINTAINER
,
self
.
klass
.
EMAIL
)
@
property
def
version
(
self
):
return
self
.
klass
.
VERSION
@
property
def
description
(
self
):
return
self
.
klass
.
DESCRIPTION
@
property
def
license
(
self
):
return
self
.
klass
.
LICENSE
@
property
def
config
(
self
):
return
self
.
klass
.
CONFIG
@
property
def
website
(
self
):
if
self
.
klass
.
BROWSER
and
self
.
klass
.
BROWSER
.
DOMAIN
:
return
'
%
s://
%
s'
%
(
self
.
klass
.
BROWSER
.
PROTOCOL
,
self
.
klass
.
BROWSER
.
DOMAIN
)
else
:
return
None
@
property
def
icon_path
(
self
):
if
self
.
klass
.
ICON
is
None
:
try
:
import
xdg.IconTheme
except
ImportError
:
debug
(
u'Python xdg module was not found. Please install it to read icon files.'
)
else
:
self
.
klass
.
ICON
=
xdg
.
IconTheme
.
getIconPath
(
self
.
klass
.
NAME
)
return
self
.
klass
.
ICON
def
iter_caps
(
self
):
for
cap
in
self
.
klass
.
__bases__
:
if
issubclass
(
cap
,
IBaseCap
)
and
cap
!=
IBaseCap
:
yield
cap
def
has_caps
(
self
,
*
caps
):
for
c
in
caps
:
if
(
isinstance
(
c
,
basestring
)
and
c
in
[
cap
.
__name__
for
cap
in
self
.
iter_caps
()])
or
\
(
type
(
c
)
==
type
and
issubclass
(
self
.
klass
,
c
)):
return
True
return
False
def
create_instance
(
self
,
weboob
,
instance_name
,
config
,
storage
):
backend_instance
=
self
.
klass
(
weboob
,
instance_name
,
config
,
storage
)
debug
(
u'Created backend instance "
%
s" for backend "
%
s"'
%
(
instance_name
,
self
.
name
))
return
backend_instance
__all__
=
[
'BackendsConfig'
]
class
BackendsConfig
(
object
):
...
...
@@ -128,7 +51,7 @@ class BackendsConfig(object):
except
KeyError
:
try
:
backend_name
=
params
.
pop
(
'_type'
)
logging
.
warning
(
u'Please replace _type with _backend in your config file "
%
s", for backend "
%
s"'
%
(
warning
(
u'Please replace _type with _backend in your config file "
%
s", for backend "
%
s"'
%
(
self
.
confpath
,
backend_name
))
except
KeyError
:
warning
(
'Missing field "_backend" for configured backend "
%
s"'
,
instance_name
)
...
...
@@ -164,7 +87,7 @@ class BackendsConfig(object):
except
KeyError
:
try
:
backend_name
=
items
.
pop
(
'_type'
)
logging
.
warning
(
u'Please replace _type with _backend in your config file "
%
s"'
%
self
.
confpath
)
warning
(
u'Please replace _type with _backend in your config file "
%
s"'
%
self
.
confpath
)
except
KeyError
:
warning
(
'Missing field "_backend" for configured backend "
%
s"'
,
instance_name
)
raise
KeyError
(
u'Configured backend "
%
s" not found'
%
instance_name
)
...
...
@@ -178,48 +101,3 @@ class BackendsConfig(object):
config
.
write
(
f
)
class
BackendsLoader
(
object
):
def
__init__
(
self
):
self
.
loaded
=
{}
def
get_or_load_backend
(
self
,
backend_name
):
if
backend_name
not
in
self
.
loaded
:
self
.
load_backend
(
backend_name
)
if
backend_name
in
self
.
loaded
:
return
self
.
loaded
[
backend_name
]
else
:
return
None
def
iter_existing_backend_names
(
self
):
try
:
import
weboob.backends
except
ImportError
:
return
for
path
in
weboob
.
backends
.
__path__
:
regexp
=
re
.
compile
(
'^
%
s/([
\
w
\
d_]+)$'
%
path
)
for
root
,
dirs
,
files
in
os
.
walk
(
path
):
m
=
regexp
.
match
(
root
)
if
m
and
'__init__.py'
in
files
:
yield
m
.
group
(
1
)
def
load_all
(
self
):
for
existing_backend_name
in
self
.
iter_existing_backend_names
():
self
.
load_backend
(
existing_backend_name
)
def
load_backend
(
self
,
backend_name
):
try
:
package_name
=
'weboob.backends.
%
s'
%
backend_name
backend
=
Backend
(
__import__
(
package_name
,
fromlist
=
[
str
(
package_name
)]))
except
ImportError
,
e
:
msg
=
u'Unable to load backend "
%
s":
%
s'
%
(
backend_name
,
e
)
if
logging
.
root
.
level
==
logging
.
DEBUG
:
exception
(
msg
)
return
else
:
error
(
msg
)
return
if
backend
.
name
in
self
.
loaded
:
debug
(
'Backend "
%
s" is already loaded from
%
s'
%
(
backend_name
,
backend
.
package
.
__path__
[
0
]))
return
self
.
loaded
[
backend
.
name
]
=
backend
debug
(
'Loaded backend "
%
s" from
%
s'
%
(
backend_name
,
backend
.
package
.
__path__
[
0
]))
weboob/core/modules.py
0 → 100644
View file @
9f5c9aee
# -*- coding: utf-8 -*-
# Copyright(C) 2010 Romain Bignon
#
# 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, version 3 of the License.
#
# 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, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
from
__future__
import
with_statement
import
logging
from
logging
import
debug
,
error
,
exception
import
os
import
re
from
weboob.capabilities.base
import
IBaseCap
from
weboob.tools.backend
import
BaseBackend
__all__
=
[
'Module'
,
'ModulesLoader'
]
class
Module
(
object
):
def
__init__
(
self
,
package
):
self
.
package
=
package
self
.
klass
=
None
for
attrname
in
dir
(
self
.
package
):
attr
=
getattr
(
self
.
package
,
attrname
)
if
isinstance
(
attr
,
type
)
and
issubclass
(
attr
,
BaseBackend
)
and
attr
!=
BaseBackend
:
self
.
klass
=
attr
if
not
self
.
klass
:
raise
ImportError
(
'
%
s is not a backend (no BaseBackend class found)'
%
package
)
@
property
def
name
(
self
):
return
self
.
klass
.
NAME
@
property
def
maintainer
(
self
):
return
'
%
s <
%
s>'
%
(
self
.
klass
.
MAINTAINER
,
self
.
klass
.
EMAIL
)
@
property
def
version
(
self
):
return
self
.
klass
.
VERSION
@
property
def
description
(
self
):
return
self
.
klass
.
DESCRIPTION
@
property
def
license
(
self
):
return
self
.
klass
.
LICENSE
@
property
def
config
(
self
):
return
self
.
klass
.
CONFIG
@
property
def
website
(
self
):
if
self
.
klass
.
BROWSER
and
self
.
klass
.
BROWSER
.
DOMAIN
:
return
'
%
s://
%
s'
%
(
self
.
klass
.
BROWSER
.
PROTOCOL
,
self
.
klass
.
BROWSER
.
DOMAIN
)
else
:
return
None
@
property
def
icon_path
(
self
):
return
self
.
klass
.
ICON
def
iter_caps
(
self
):
for
cap
in
self
.
klass
.
__bases__
:
if
issubclass
(
cap
,
IBaseCap
)
and
cap
!=
IBaseCap
:
yield
cap
def
has_caps
(
self
,
*
caps
):
for
c
in
caps
:
if
(
isinstance
(
c
,
basestring
)
and
c
in
[
cap
.
__name__
for
cap
in
self
.
iter_caps
()])
or
\
(
type
(
c
)
==
type
and
issubclass
(
self
.
klass
,
c
)):
return
True
return
False
def
create_instance
(
self
,
weboob
,
instance_name
,
config
,
storage
):
backend_instance
=
self
.
klass
(
weboob
,
instance_name
,
config
,
storage
)
debug
(
u'Created backend instance "
%
s" for backend "
%
s"'
%
(
instance_name
,
self
.
name
))
return
backend_instance
class
ModulesLoader
(
object
):
def
__init__
(
self
):
self
.
loaded
=
{}
def
get_or_load_module
(
self
,
module_name
):
if
module_name
not
in
self
.
loaded
:
self
.
load_module
(
module_name
)
if
module_name
in
self
.
loaded
:
return
self
.
loaded
[
module_name
]
else
:
return
None
def
iter_existing_module_names
(
self
):
try
:
import
weboob.backends
except
ImportError
:
return
for
path
in
weboob
.
backends
.
__path__
:
regexp
=
re
.
compile
(
'^
%
s/([
\
w
\
d_]+)$'
%
path
)
for
root
,
dirs
,
files
in
os
.
walk
(
path
):
m
=
regexp
.
match
(
root
)
if
m
and
'__init__.py'
in
files
:
yield
m
.
group
(
1
)
def
load_all
(
self
):
for
existing_module_name
in
self
.
iter_existing_module_names
():
self
.
load_module
(
existing_module_name
)
def
load_module
(
self
,
module_name
):
try
:
package_name
=
'weboob.backends.
%
s'
%
module_name
module
=
Module
(
__import__
(
package_name
,
fromlist
=
[
str
(
package_name
)]))
except
ImportError
,
e
:
msg
=
u'Unable to load module "
%
s":
%
s'
%
(
module_name
,
e
)
if
logging
.
root
.
level
==
logging
.
DEBUG
:
exception
(
msg
)
return
else
:
error
(
msg
)
return
if
module
.
name
in
self
.
loaded
:
debug
(
'Module "
%
s" is already loaded from
%
s'
%
(
module_name
,
module
.
package
.
__path__
[
0
]))
return
self
.
loaded
[
module
.
name
]
=
module
debug
(
'Loaded module "
%
s" from
%
s'
%
(
module_name
,
module
.
package
.
__path__
[
0
]))
weboob/core/ouiboube.py
View file @
9f5c9aee
...
...
@@ -22,7 +22,8 @@ from logging import warning
import
os
from
weboob.core.bcall
import
BackendsCall
from
weboob.core.backends
import
BackendsConfig
,
BackendsLoader
from
weboob.core.modules
import
ModulesLoader
from
weboob.core.backendscfg
import
BackendsConfig
from
weboob.core.scheduler
import
Scheduler
from
weboob.tools.backend
import
BaseBackend
...
...
@@ -50,7 +51,7 @@ class Weboob(object):
warning
(
u'"
%
s" is not a directory'
%
self
.
workdir
)
# Backends loader
self
.
backends_loader
=
Backend
sLoader
()
self
.
modules_loader
=
Module
sLoader
()
# Backend instances config
if
not
backends_filename
:
...
...
@@ -73,25 +74,25 @@ class Weboob(object):
if
storage
is
None
:
storage
=
self
.
storage
for
instance_name
,
backend
_name
,
params
in
self
.
backends_config
.
iter_backends
():
for
instance_name
,
module
_name
,
params
in
self
.
backends_config
.
iter_backends
():
if
'_enabled'
in
params
and
not
params
[
'_enabled'
]
or
\
names
is
not
None
and
instance_name
not
in
names
or
\
modules
is
not
None
and
backend
_name
not
in
modules
:
modules
is
not
None
and
module
_name
not
in
modules
:
continue
backend
=
self
.
backends_loader
.
get_or_load_backend
(
backend
_name
)
if
backend
is
None
:
module
=
self
.
modules_loader
.
get_or_load_module
(
module
_name
)
if
module
is
None
:
warning
(
u'Backend "
%
s" is referenced in ~/.weboob/backends '
'configuration file, but was not found. '
'Hint: is it installed?'
%
backend
_name
)
'Hint: is it installed?'
%
module
_name
)
continue
if
caps
is
not
None
and
not
backend
.
has_caps
(
caps
):
if
caps
is
not
None
and
not
module
.
has_caps
(
caps
):
continue
if
instance_name
in
self
.
backend_instances
:
warning
(
u'Oops, the backend "
%
s" is already loaded. Unload it before reloading...'
%
instance_name
)
self
.
unload_backends
(
instance_name
)
backend_instance
=
backend
.
create_instance
(
self
,
instance_name
,
params
,
storage
)
backend_instance
=
module
.
create_instance
(
self
,
instance_name
,
params
,
storage
)
self
.
backend_instances
[
instance_name
]
=
loaded
[
instance_name
]
=
backend_instance
return
loaded
...
...
weboob/tools/application/base.py
View file @
9f5c9aee
...
...
@@ -77,7 +77,10 @@ class BaseApplication(object):
# Default storage tree
STORAGE
=
{}
# Synopsis
SYNOPSIS
=
'Usage:
%
prog [options (-h for help)] ...'
SYNOPSIS
=
'Usage:
%
prog [-h] [-dqv] [-b backends] ...'
SYNOPSIS
+=
'
%
prog [--help] [--version]'
# Description
DESCRIPTION
=
None
# Version
VERSION
=
None
# Copyright
...
...
@@ -109,6 +112,8 @@ class BaseApplication(object):
self
.
_parser
=
OptionParser
(
self
.
SYNOPSIS
,
version
=
self
.
_get_optparse_version
())
else
:
self
.
_parser
=
option_parser
if
self
.
DESCRIPTION
:
self
.
_parser
.
description
=
self
.
DESCRIPTION
self
.
_parser
.
add_option
(
'-b'
,
'--backends'
,
help
=
'what backend(s) to enable (comma separated)'
)
logging_options
=
OptionGroup
(
self
.
_parser
,
'Logging Options'
)
logging_options
.
add_option
(
'-d'
,
'--debug'
,
action
=
'store_true'
,
help
=
'display debug messages'
)
...
...
weboob/tools/application/console.py
View file @
9f5c9aee
...
...
@@ -28,7 +28,7 @@ import subprocess
import
sys
from
weboob.core
import
CallErrors
from
weboob.core.backends
import
BackendsConfig
from
weboob.core.backends
cfg
import
BackendsConfig
from
.base
import
BackendNotFound
,
BaseApplication
from
.formatters.load
import
formatters
,
load_formatter
...
...
@@ -44,7 +44,8 @@ class ConsoleApplication(BaseApplication):
Base application class for CLI applications.
"""
SYNOPSIS
=
'Usage:
%
prog [options (-h for help)] command [parameters...]'
SYNOPSIS
=
'Usage:
%
prog [-dqv] [-b backends] [-cnfs] command [arguments..]
\n
'
SYNOPSIS
+=
'
%
prog [--help] [--version]'
def
__init__
(
self
):
option_parser
=
OptionParser
(
self
.
SYNOPSIS
,
version
=
self
.
_get_optparse_version
())
...
...
@@ -62,6 +63,8 @@ class ConsoleApplication(BaseApplication):
if
self
.
_parser
.
description
is
None
:
self
.
_parser
.
description
=
''
else
:
self
.
_parser
.
description
+=
'
\n\n
'
self
.
_parser
.
description
+=
'Available commands:
\n
'
for
name
,
arguments
,
doc_string
in
self
.
_commands
:
command
=
'
%
s
%
s'
%
(
name
,
arguments
)
...
...
weboob/tools/application/qt/backendcfg.py
View file @
9f5c9aee
...
...
@@ -45,12 +45,12 @@ class BackendCfg(QDialog):
# is_enabling is a counter to prevent race conditions.
self
.
is_enabling
=
0
self
.
weboob
.
backend
s_loader
.
load_all
()
self
.
weboob
.
module
s_loader
.
load_all
()
self
.
ui
.
configuredBackendsList
.
header
()
.
setResizeMode
(
QHeaderView
.
ResizeToContents
)
self
.
ui
.
configFrame
.
hide
()
for
name
,
backend
in
self
.
weboob
.
backend
s_loader
.
loaded
.
iteritems
():
for
name
,
backend
in
self
.
weboob
.
module
s_loader
.
loaded
.
iteritems
():
if
not
self
.
caps
or
backend
.
has_caps
(
*
self
.
caps
):
item
=
QListWidgetItem
(
name
.
capitalize
())
...
...
@@ -74,10 +74,8 @@ class BackendCfg(QDialog):
def
loadConfiguredBackendsList
(
self
):
self
.
ui
.
configuredBackendsList
.
clear
()
for
instance_name
,
name
,
params
in
self
.
weboob
.
backends_config
.
iter_backends
():
if
name
not
in
self
.
weboob
.
backends_loader
.
loaded
:
continue
backend
=
self
.
weboob
.
backends_loader
.
loaded
[
name
]
if
self
.
caps
and
not
backend
.
has_caps
(
*
self
.
caps
):
backend
=
self
.
weboob
.
modules_loader
.
get_or_load_module
(
name
)
if
not
backend
or
self
.
caps
and
not
backend
.
has_caps
(
*
self
.
caps
):
continue
item
=
QTreeWidgetItem
(
None
,
[
instance_name
,
name
])
...
...
@@ -195,7 +193,12 @@ class BackendCfg(QDialog):
self
.
tr
(
'Please select a backend'
))
return
backend
=
self
.
weboob
.
backends_loader
.
loaded
[
unicode
(
selection
[
0
]
.
text
())
.
lower
()]
backend
=
self
.
weboob
.
modules_loader
.
get_or_load_module
(
unicode
(
selection
[
0
]
.
text
())
.
lower
())
if
not
backend
:
QMessageBox
.
critical
(
self
,
self
.
tr
(
'Unable to add a configured backend'
),
self
.
tr
(
'The selected backend does not exist.'
))
return
params
=
{}
missing
=
[]
...
...
@@ -261,7 +264,7 @@ class BackendCfg(QDialog):
if
not
selection
:
return
backend
=
self
.
weboob
.
backend
s_loader
.
loaded
[
unicode
(
selection
[
0
]
.
text
())
.
lower
()]
backend
=
self
.
weboob
.
module
s_loader
.
loaded
[
unicode
(
selection
[
0
]
.
text
())
.
lower
()]
if
backend
.
icon_path
:
img
=
QImage
(
backend
.
icon_path
)
...
...
weboob/tools/backend.py
View file @
9f5c9aee
...
...
@@ -147,6 +147,24 @@ class BaseBackend(object):
"""
pass
class
classprop
(
object
):
def
__init__
(
self
,
fget
):
self
.
fget
=
fget
def
__get__
(
self
,
inst
,
objtype
=
None
):
if
inst
:
return
self
.
fget
(
inst
)
else
:
return
self
.
fget
(
objtype
)
@
classprop
def
ICON
(
self
):
try
:
import
xdg.IconTheme
except
ImportError
:
debug
(
u'Python xdg module was not found. Please install it to read icon files.'
)
else
:
return
xdg
.
IconTheme
.
getIconPath
(
self
.
NAME
)
@
property
def
browser
(
self
):
"""
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment