No longer hardcoding capabilities

* More logging
* Using getpass in dev environment to ease passwords manipulation
* Dynamic capabilities fetching for each module
This commit is contained in:
Lucas Verney 2016-09-29 05:09:14 +02:00
parent 094696a0cd
commit 905c141c13
6 changed files with 92 additions and 26 deletions

6
TODO
View File

@ -1,3 +1,7 @@
* history (Detail) vs Bill? * history (Detail) vs Bill?
* _url ? * Bill._url?
* Update modules? * Update modules?
* amazon.com is buggy
* LDLC is out of date
* Bouygues is out of date

View File

@ -0,0 +1,5 @@
from . import CapDocument
__all__ = [
"CapDocument"
]

View File

@ -1,15 +1,22 @@
#!/usr/bin/env python2 #!/usr/bin/env python2
"""
TODO
"""
from __future__ import print_function from __future__ import print_function
import getpass import getpass
import importlib
import json import json
import logging
import sys import sys
from weboob.core import Weboob from weboob.core import Weboob
from capabilities import bill
from tools.jsonwriter import pretty_json from tools.jsonwriter import pretty_json
# Dynamically load capabilities conversion modules
CAPABILITIES_CONVERSION_MODULES = importlib.import_module("capabilities")
class WeboobProxy(object): class WeboobProxy(object):
""" """
@ -70,25 +77,63 @@ def main(used_modules):
# Fetch data for the specified modules # Fetch data for the specified modules
fetched_data = {} fetched_data = {}
for module, parameters in used_modules.items(): logging.info("Start fetching from konnectors.")
# TODO for module in used_modules:
fetched_data["bills"] = bill.to_cozy( logging.info("Fetching data from module %s.", module["id"])
WeboobProxy( # Get associated backend for this module
module, backend = WeboobProxy(
parameters module["name"],
module["parameters"]
).get_backend() ).get_backend()
# List all supported capabilities
for capability in backend.iter_caps():
# Convert capability class to string name
capability = capability.__name__
try:
# Get conversion function for this capability
fetching_function = (
getattr(
getattr(
CAPABILITIES_CONVERSION_MODULES,
capability
),
"to_cozy"
) )
)
logging.info("Fetching capability %s.", capability)
# Fetch data and store them
# TODO: Ensure there is no overwrite
fetched_data[module["id"]] = fetching_function(backend)
except AttributeError:
logging.error("%s capability is not implemented.", capability)
continue
logging.info("Done fetching from konnectors.")
return fetched_data return fetched_data
if __name__ == '__main__': if __name__ == '__main__':
try:
logging.basicConfig(
format='%(levelname)s: %(message)s',
level=logging.INFO
)
try: try:
konnectors = json.load(sys.stdin) konnectors = json.load(sys.stdin)
# Handle missing passwords using getpass
for module in range(len(konnectors)):
for param in konnectors[module]["parameters"]:
if not konnectors[module]["parameters"][param]:
konnectors[module]["parameters"][param] = getpass.getpass(
"Password for module %s? " % konnectors[module]["id"]
)
except ValueError: except ValueError:
sys.exit("Invalid input") # TODO logging.error("Invalid JSON input.")
sys.exit(-1)
print( print(
pretty_json( pretty_json(
main(konnectors) main(konnectors)
) )
) )
except KeyboardInterrupt:
pass

View File

@ -1,7 +1,19 @@
[
{ {
"amazon": { "id": "amazon.fr",
"name": "amazon",
"parameters": {
"website": "www.amazon.fr", "website": "www.amazon.fr",
"email": "someone@example.com", "email": "someone@example.com",
"password": "MY_AWESOME_PASSWORD" "password": "MY_AWESOME_PASSWORD"
} }
},
{
"id": "freemobile",
"name": "freemobile",
"parameters": {
"login": "12345678",
"password": ""
} }
}
]

View File

@ -1,6 +1,6 @@
import json import json
from datetime import datetime from datetime import date, datetime
from decimal import Decimal from decimal import Decimal
@ -9,7 +9,7 @@ class CustomJSONEncoder(json.JSONEncoder):
Custom JSONEncoder to support more types. Custom JSONEncoder to support more types.
""" """
def default(self, o): def default(self, o):
if isinstance(o, datetime): if isinstance(o, datetime) or isinstance(o, date):
# Serialize datetime objects to ISO dates # Serialize datetime objects to ISO dates
return o.isoformat() return o.isoformat()
elif isinstance(o, Decimal): elif isinstance(o, Decimal):