python modernize.py --no-six -f libmodernize.fixes.fix_print -w With manual fixes as the import was put always on top.
234 lines
8 KiB
Python
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
|