You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

128 lines
4.9 KiB

  1. # -*- encoding: utf-8 -*-
  2. ##############################################################################
  3. #
  4. # Base Location Geonames Import module for OpenERP
  5. # Copyright (C) 2014 Akretion (http://www.akretion.com)
  6. # @author Alexis de Lattre <alexis.delattre@akretion.com>
  7. # Copyright (C) 2014 Agile Business Group (http://www.agilebg.com)
  8. # @author Lorenzo Battistini <lorenzo.battistini@agilebg.com>
  9. #
  10. # This program is free software: you can redistribute it and/or modify
  11. # it under the terms of the GNU Affero General Public License as
  12. # published by the Free Software Foundation, either version 3 of the
  13. # License, or (at your option) any later version.
  14. #
  15. # This program is distributed in the hope that it will be useful,
  16. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. # GNU Affero General Public License for more details.
  19. #
  20. # You should have received a copy of the GNU Affero General Public License
  21. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  22. #
  23. ##############################################################################
  24. from openerp import models, fields, api, _
  25. from openerp.exceptions import Warning
  26. import requests
  27. import tempfile
  28. import StringIO
  29. import unicodecsv
  30. import zipfile
  31. import os
  32. import logging
  33. logger = logging.getLogger(__name__)
  34. class better_zip_geonames_import(models.TransientModel):
  35. _name = 'better.zip.geonames.import'
  36. _description = 'Import Better Zip from Geonames'
  37. _rec_name = 'country_id'
  38. country_id = fields.Many2one('res.country', 'Country', required=True)
  39. @api.model
  40. def _prepare_better_zip(self, row, country_id):
  41. state = self.select_or_create_state(row, country_id)
  42. vals = {
  43. 'name': row[1],
  44. 'city': row[2],
  45. 'state_id': state.id,
  46. 'country_id': country_id,
  47. }
  48. return vals
  49. @api.model
  50. def create_better_zip(
  51. self, row, country_id, country_code):
  52. bzip_id = False
  53. if row[0] != country_code:
  54. raise Warning(
  55. _('Error:'),
  56. _("The country code inside the file (%s) doesn't "
  57. "correspond to the selected country (%s).")
  58. % (row[0], country_code))
  59. logger.debug('ZIP = %s - City = %s' % (row[1], row[2]))
  60. if row[1] and row[2]:
  61. vals = self._prepare_better_zip(row, country_id)
  62. if vals:
  63. bzip_id = self.env['res.better.zip'].create(vals)
  64. return bzip_id
  65. @api.model
  66. def select_or_create_state(
  67. self, row, country_id, code_row_index=4, name_row_index=3
  68. ):
  69. states = self.env['res.country.state'].search([
  70. ('country_id', '=', country_id),
  71. ('code', '=', row[code_row_index]),
  72. ])
  73. if len(states) > 1:
  74. raise Warning(
  75. _("Too many states with code %s for counrty %s")
  76. % (row[code_row_index], country_id))
  77. if len(states) == 1:
  78. return states[0]
  79. else:
  80. return self.env['res.country.state'].create({
  81. 'name': row[name_row_index],
  82. 'code': row[code_row_index],
  83. 'country_id': country_id
  84. })
  85. @api.one
  86. def run_import(self):
  87. bzip_obj = self.env['res.better.zip']
  88. country_id = self.country_id.id
  89. country_code = self.country_id.code.upper()
  90. url = 'http://download.geonames.org/export/zip/%s.zip' % country_code
  91. logger.info('Starting to download %s' % url)
  92. res_request = requests.get(url)
  93. if res_request.status_code != requests.codes.ok:
  94. raise Warning(
  95. _('Error:'),
  96. _('Got an error %d when trying to download the file %s.')
  97. % (res_request.status_code, url))
  98. bzip_ids_to_delete = bzip_obj.search([('country_id', '=', country_id)])
  99. if bzip_ids_to_delete:
  100. bzip_obj.unlink(bzip_ids_to_delete)
  101. logger.info(
  102. '%d better zip entries deleted for country %s'
  103. % (len(bzip_ids_to_delete), self.country_id.name))
  104. f_geonames = zipfile.ZipFile(StringIO.StringIO(res_request.content))
  105. tempdir = tempfile.mkdtemp(prefix='openerp')
  106. f_geonames.extract('%s.txt' % country_code, tempdir)
  107. logger.info('The geonames zipfile has been decompressed')
  108. data_file = open(os.path.join(tempdir, '%s.txt' % country_code), 'r')
  109. data_file.seek(0)
  110. logger.info(
  111. 'Starting to create the better zip entries')
  112. for row in unicodecsv.reader(
  113. data_file, encoding='utf-8', delimiter=' '):
  114. self.create_better_zip(row, country_id, country_code)
  115. data_file.close()
  116. logger.info(
  117. 'The wizard to create better zip entries from geonames '
  118. 'has been successfully completed.')
  119. return True