weboob-devel/weboob/applications/boobill/boobill.py
Laurent Bachelier 74a4ef6723 Use the print function everywhere
python modernize.py --no-six -f libmodernize.fixes.fix_print -w

With manual fixes as the import was put always on top.
2014-10-06 17:00:17 +02:00

234 lines
8 KiB
Python

# -*- coding: utf-8 -*-
# Copyright(C) 2012-2013 Florent Fourcot
#
# This file is part of weboob.
#
# weboob is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# weboob 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
from __future__ import print_function
from decimal import Decimal
from weboob.capabilities.bill import CapBill, Detail, Subscription
from weboob.tools.application.repl import ReplApplication, defaultcount
from weboob.tools.application.formatters.iformatter import PrettyFormatter
from weboob.tools.application.base import MoreResultsAvailable
from weboob.core import CallErrors
__all__ = ['Boobill']
class SubscriptionsFormatter(PrettyFormatter):
MANDATORY_FIELDS = ('id', 'label')
def get_title(self, obj):
if obj.renewdate:
return u"%s - %s" % (obj.label, obj.renewdate.strftime('%d/%m/%y'))
return obj.label
class Boobill(ReplApplication):
APPNAME = 'boobill'
VERSION = '1.0'
COPYRIGHT = 'Copyright(C) 2012 Florent Fourcot'
DESCRIPTION = 'Console application allowing to get and download bills.'
SHORT_DESCRIPTION = "get and download bills"
CAPS = CapBill
COLLECTION_OBJECTS = (Subscription, )
EXTRA_FORMATTERS = {'subscriptions': SubscriptionsFormatter,
}
DEFAULT_FORMATTER = 'table'
COMMANDS_FORMATTERS = {'subscriptions': 'subscriptions',
'ls': 'subscriptions',
}
def main(self, argv):
self.load_config()
return ReplApplication.main(self, argv)
def exec_method(self, id, method):
l = []
id, backend_name = self.parse_id(id)
if not id:
for subscrib in self.get_object_list('iter_subscription'):
l.append((subscrib.id, subscrib.backend))
else:
l.append((id, backend_name))
more_results = []
not_implemented = []
self.start_format()
for id, backend in l:
names = (backend,) if backend is not None else None
try:
for backend, result in self.do(method, id, backends=names):
self.format(result)
except CallErrors as errors:
for backend, error, backtrace in errors:
if isinstance(error, MoreResultsAvailable):
more_results.append(id + u'@' + backend.name)
elif isinstance(error, NotImplementedError):
if backend not in not_implemented:
not_implemented.append(backend)
else:
self.bcall_error_handler(backend, error, backtrace)
if len(more_results) > 0:
print('Hint: There are more results available for %s (use option -n or count command)' % (', '.join(more_results)), file=self.stderr)
for backend in not_implemented:
print(u'Error(%s): This feature is not supported yet by this backend.' % backend.name, file=self.stderr)
def do_subscriptions(self, line):
"""
subscriptions
List all subscriptions.
"""
self.start_format()
for subscription in self.get_object_list('iter_subscription'):
self.format(subscription)
def do_details(self, id):
"""
details [ID]
Get details of subscriptions.
If no ID given, display all details of all backends.
"""
l = []
id, backend_name = self.parse_id(id)
if not id:
for subscrib in self.get_object_list('iter_subscription'):
l.append((subscrib.id, subscrib.backend))
else:
l.append((id, backend_name))
for id, backend in l:
names = (backend,) if backend is not None else None
# XXX: should be generated by backend? -Flo
# XXX: no, but you should do it in a specific formatter -romain
# TODO: do it, and use exec_method here. Code is obsolete
mysum = Detail()
mysum.label = u"Sum"
mysum.infos = u"Generated by boobill"
mysum.price = Decimal("0.")
self.start_format()
for backend, detail in self.do('get_details', id, backends=names):
self.format(detail)
mysum.price = detail.price + mysum.price
self.format(mysum)
def do_balance(self, id):
"""
balance [ID]
Get balance of subscriptions.
If no ID given, display balance of all backends.
"""
self.exec_method(id, 'get_balance')
@defaultcount(10)
def do_history(self, id):
"""
history [ID]
Get the history of subscriptions.
If no ID given, display histories of all backends.
"""
self.exec_method(id, 'iter_bills_history')
@defaultcount(10)
def do_bills(self, id):
"""
bills [ID]
Get the list of bills documents for subscriptions.
If no ID given, display bills of all backends
"""
self.exec_method(id, 'iter_bills')
def do_download(self, line):
"""
download [ID | all] [FILENAME]
download ID [FILENAME]
download the bill
id is the identifier of the bill (hint: try bills command)
FILENAME is where to write the file. If FILENAME is '-',
the file is written to stdout.
download all [ID]
You can use special word "all" and download all bills of
subscription identified by ID.
If Id not given, download bills of all subscriptions.
"""
id, dest = self.parse_command_args(line, 2, 1)
id, backend_name = self.parse_id(id)
if not id:
print('Error: please give a bill ID (hint: use bills command)', file=self.stderr)
return 2
names = (backend_name,) if backend_name is not None else None
# Special keywords, download all bills of all subscriptions
if id == "all":
if dest is None:
for backend, subscription in self.do('iter_subscription', backends=names):
self.download_all(subscription.id, names)
return
else:
self.download_all(dest, names)
return
if dest is None:
for backend, bill in self.do('get_bill', id, backends=names):
dest = id + "." + bill.format
for backend, buf in self.do('download_bill', id, backends=names):
if buf:
if dest == "-":
print(buf)
else:
try:
with open(dest, 'w') as f:
f.write(buf)
except IOError as e:
print('Unable to write bill in "%s": %s' % (dest, e), file=self.stderr)
return 1
return
def download_all(self, id, names):
id, backend_name = self.parse_id(id)
for backend, bill in self.do('iter_bills', id, backends=names):
dest = bill.id + "." + bill.format
for backend2, buf in self.do('download_bill', bill.id, backends=names):
if buf:
if dest == "-":
print(buf)
else:
try:
with open(dest, 'w') as f:
f.write(buf)
except IOError as e:
print('Unable to write bill in "%s": %s' % (dest, e), file=self.stderr)
return 1
return