Merge lp:~oerp.ca/account-financial-tools/add-bank-of-canada-rss into lp:~account-core-editors/account-financial-tools/7.0

Proposed by Daniel Dico (oerp.ca)
Status: Merged
Approved by: Guewen Baconnier @ Camptocamp
Approved revision: 152
Merged at revision: 164
Proposed branch: lp:~oerp.ca/account-financial-tools/add-bank-of-canada-rss
Merge into: lp:~account-core-editors/account-financial-tools/7.0
Diff against target: 124 lines (+76/-8)
1 file modified
currency_rate_update/currency_rate_update.py (+76/-8)
To merge this branch: bzr merge lp:~oerp.ca/account-financial-tools/add-bank-of-canada-rss
Reviewer Review Type Date Requested Status
Stefan Rijnhart (Opener) Approve
Pedro Manuel Baeza Approve
Review via email: mp+204377@code.launchpad.net

Commit message

Add Bank of Canada to curency_rate_update

Description of the change

Add Bank of Canada to currency_rate_update.

Suggest to add the new log "note" at the top of the log in order to allow users to see the most recent note without having to scroll down.

As this module becomes (more) international, I suggest to remove references to ECB in check_rate_date exception and log.

To post a comment you must log in.
Revision history for this message
Pedro Manuel Baeza (pedro.baeza) wrote :

Hi, Daniel, thank you very much for the contribution.

What worries me with this new source is that you are using feedparser library. This library is not detected on module install, and it will only fail if you select this source, causing the background process to fail. The alternative is to put this library as dependency, but maybe is to force user to install another library if they are not going to use this source.

What everybody thinks about this?

Regards.

review: Needs Fixing
Revision history for this message
Daniel Dico (oerp.ca) (oerp) wrote :

Hi Pedro,

Thank you for your review.

In regards with feedparser, I was under the impression that this library is required by OpenERP. Please see /openobject-server/openerpcommand/setup.py. I hope I'm not missing something here!?

From what I see, currency_rate_update in order to address the specific needs from a global perspective, will accumulate over time a number of different bank feeds (each with their own specific format) and, most likely, a potential user will only use one of the bank feeds... sure we can add a required library to the dependency... but it could be that users in Europe will not use the Canadian rates, while they will be forced to install the dependency. Maybe a different design could be used? Let's wait for other developers to add feeds from other banks so we can see what formats are required all over the world.

Best regards,
Daniel

> Hi, Daniel, thank you very much for the contribution.
>
> What worries me with this new source is that you are using feedparser library.
> This library is not detected on module install, and it will only fail if you
> select this source, causing the background process to fail. The alternative is
> to put this library as dependency, but maybe is to force user to install
> another library if they are not going to use this source.
>
> What everybody thinks about this?
>
> Regards.

Revision history for this message
Pedro Manuel Baeza (pedro.baeza) wrote :

Hi, Daniel, indeed, that library is a dependency of OpenERP itself, so it's not a problem in this version. In the future, this can change, so I think it's better to have declare python dependency on the module to prevent future problems. What do you think?

Regards.

Revision history for this message
Daniel Dico (oerp.ca) (oerp) wrote :

Hi Pedro,

Not sure what's best... if you look at the current code almost every implementation of the "Curreny_getter_interface" has various dependencies, and similar with feedparser they are required by OpenERP, but they are not listed as dependencies.

I've checked where feedparser is used in (7 and trunk) and there is only one place: /openobject-addons/email_template/html2text.py can this really go away? I would't know... probably not!?

It's up to you and the other reviewers... I can add it if you want me to... it's just one line of code.

Regards,
:Daniel

Revision history for this message
Pedro Manuel Baeza (pedro.baeza) wrote :

OK, let's stay as is for the moment and see what others think.

Thank you very much for your work and feedback!

Regards

review: Approve
Revision history for this message
Stefan Rijnhart (Opener) (stefan-opener) wrote :

Works fine, thanks! I agree with the other changes (reference to a specific service in a generic log msg, and have the most recent log on top).

About the feedparser dependency: while it is a dependency in OpenERP's setup.py, it is not a core library for OpenERP and may drop away in future versions. This may be easily missed during the upgrade of this module at that time. In fact, it is only used to guess encodings of emails in a piece of foreign code (by the late Aaron Schwartz no less). And in this code, a missing feedparser is caught by ImportError with a default to 'utf-8' so you can actually totally get away with running OpenERP without feedparser. But because like what has been said, only a part of the users of this module will check this particular service so you don't want to force an additional dependency on the other users. Fortunately, an ImportError because of feedparser will not crash the OpenERP server in this case, because of this module's strategy when running a service. instead, the error is logged in the update log for the user to see, which is perfectly acceptible.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'currency_rate_update/currency_rate_update.py'
2--- currency_rate_update/currency_rate_update.py 2013-12-13 19:33:25 +0000
3+++ currency_rate_update/currency_rate_update.py 2014-02-01 08:13:17 +0000
4@@ -59,6 +59,9 @@
5 ('Yahoo_getter','Yahoo Finance '),
6 ('PL_NBP_getter','Narodowy Bank Polski'), # Added for polish rates
7 ('Banxico_getter', 'Banco de México'), # Added for mexican rates
8+ # Bank of Canada is using RSS-CB http://www.cbwiki.net/wiki/index.php/Specification_1.1 :
9+ # This RSS format is used by other national banks (Thailand, Malaysia, Mexico...)
10+ ('CA_BOC_getter','Bank of Canada - noon rates'), # Added for canadian rates
11 ],
12 "Webservice to use",
13 required = True
14@@ -211,13 +214,16 @@
15 vals,
16 )
17
18- note = note + "\n%s currency updated. "\
19- %(datetime.strftime(datetime.today(), '%Y-%m-%d %H:%M:%S'))
20- note = note + (log_info or '')
21+ # show the most recent note at the top
22+ note = "\n%s currency updated. "\
23+ %(datetime.strftime(datetime.today(), '%Y-%m-%d %H:%M:%S'))\
24+ + note
25+ note = (log_info or '') + note
26 service.write({'note':note})
27 except Exception, e:
28- error_msg = note + "\n%s ERROR : %s"\
29- %(datetime.strftime(datetime.today(), '%Y-%m-%d %H:%M:%S'), str(e))
30+ error_msg = "\n%s ERROR : %s"\
31+ %(datetime.strftime(datetime.today(), '%Y-%m-%d %H:%M:%S'), str(e))\
32+ + note
33 _logger.info(str(e))
34 service.write({'note':error_msg})
35
36@@ -263,6 +269,7 @@
37 'Google_getter',
38 'Yahoo_getter',
39 'Banxico_getter',
40+ 'CA_BOC_getter',
41 ]
42 if class_name in allowed:
43 class_def = eval(class_name)
44@@ -340,12 +347,12 @@
45 """Check date constrains. WARN : rate_date must be of datetime type"""
46 days_delta = (datetime.today() - rate_date).days
47 if days_delta > max_delta_days:
48- raise Exception('The rate date from ECB (%s) is %d days away from today, which is over the limit (%d days). Rate not updated in OpenERP.'%(rate_date, days_delta, max_delta_days))
49+ raise Exception('The rate timestamp (%s) is %d days away from today, which is over the limit (%d days). Rate not updated in OpenERP.'%(rate_date, days_delta, max_delta_days))
50 # We always have a warning when rate_date <> today
51 rate_date_str = datetime.strftime(rate_date, '%Y-%m-%d')
52 if rate_date_str != datetime.strftime(datetime.today(), '%Y-%m-%d'):
53- self.log_info = "WARNING : the rate date from ECB (%s) is not today's date" % rate_date_str
54- _logger.warning("the rate date from ECB (%s) is not today's date", rate_date_str)
55+ self.log_info = "WARNING : the rate timestamp (%s) is not today's date" % rate_date_str
56+ _logger.warning("the rate timestamp (%s) is not today's date", rate_date_str)
57
58
59 #Yahoo ###################################################################################
60@@ -595,3 +602,64 @@
61
62 self.updated_currency[curr] = rate
63 logger.debug("Rate retrieved : " + main_currency + ' = ' + str(rate) + ' ' + curr)
64+
65+
66+##CA BOC ##### Bank of Canada ############################################################
67+class CA_BOC_getter(Curreny_getter_interface) :
68+ """Implementation of Curreny_getter_factory interface for Bank of Canada RSS service"""
69+
70+ def get_updated_currency(self, currency_array, main_currency, max_delta_days):
71+ """implementation of abstract method of Curreny_getter_interface"""
72+
73+ # as of Jan 2014 BOC is publishing noon rates for about 60 currencies
74+ url = 'http://www.bankofcanada.ca/stats/assets/rates_rss/noon/en_%s.xml'
75+ # closing rates are available as well (please note there are only 12
76+ # currencies reported):
77+ # http://www.bankofcanada.ca/stats/assets/rates_rss/closing/en_%s.xml
78+
79+ #we do not want to update the main currency
80+ if main_currency in currency_array:
81+ currency_array.remove(main_currency)
82+
83+ import feedparser
84+ import pytz
85+ from dateutil import parser
86+
87+ for curr in currency_array:
88+
89+ _logger.debug("BOC currency rate service : connecting...")
90+ dom = feedparser.parse(url % curr)
91+
92+ self.validate_cur(curr)
93+
94+ # check if BOC service is running
95+ if dom.bozo and dom.status <> 404:
96+ _logger.error("Bank of Canada - service is down - try again\
97+ later...")
98+
99+ # check if BOC sent a valid response for this currency
100+ if dom.status != 200:
101+ _logger.error("Exchange data for %s is not reported by Bank\
102+ of Canada." % curr)
103+ raise osv.except_osv('Error !', 'Exchange data for %s is not\
104+ reported by Bank of Canada.' % str(curr))
105+
106+ _logger.debug("BOC sent a valid RSS file for: " + curr)
107+
108+ # check for valid exchange data
109+ if (dom.entries[0].cb_basecurrency == main_currency) and \
110+ (dom.entries[0].cb_targetcurrency == curr):
111+ rate = dom.entries[0].cb_exchangerate.split('\n', 1)[0]
112+ rate_date_datetime = parser.parse(dom.entries[0].updated)\
113+ .astimezone(pytz.utc).replace(tzinfo=None)
114+ self.check_rate_date(rate_date_datetime, max_delta_days)
115+ self.updated_currency[curr] = rate
116+ _logger.debug("BOC Rate retrieved : 1 " + main_currency +
117+ ' = ' + str(rate) + ' ' + curr)
118+ else:
119+ _logger.error("Exchange data format error for Bank of Canada -\
120+ %s. Please check provider data format and/or source code." % curr)
121+ raise osv.except_osv('Error !', 'Exchange data format error for\
122+ Bank of Canada - %s !' % str(curr))
123+
124+ return self.updated_currency, self.log_info

Subscribers

People subscribed via source and target branches