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.
 
 
 
 
 

410 lines
17 KiB

# -*- coding: utf-8 -*-
#
##############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
# Copyright (C) 2017-TODAY Cybrosys Technologies(<http://www.cybrosys.com>).
# Author: Nikhil krishnan(<http://www.cybrosys.com>)
# you can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
# This program 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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# GENERAL PUBLIC LICENSE (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import pytz
from pytz import timezone
from dateutil.relativedelta import relativedelta
from datetime import datetime
try:
import pytemperature
except ImportError:
print 'pytemperature, this python package is not available. please install by using ' \
'==> pip install pytemperature'
pass
try:
import simplejson as json
except ImportError:
import json # noqa
import urllib
import odoo
from odoo import models, fields, api
from odoo import tools
from odoo.tools.translate import _
class UserWeatherMap(models.Model):
_name = 'user.weather.map'
date_weather_update = fields.Datetime(string='Last update')
name = fields.Char(string='City Name')
city = fields.Char(string='Original City')
user_id = fields.Many2one('res.users', string='User Name')
weather = fields.Char(string='Weather')
description = fields.Char(string='Description')
temp = fields.Char(string='Temperature')
pressure = fields.Char(string='Pressure')
humidity = fields.Char(string='Humidity')
min_temp = fields.Char(string='Minimum')
max_temp = fields.Char(string='Maximum')
sunset = fields.Char(string='Sunset')
sunrise = fields.Char(string='Sunrise')
def get_weather_data(self, user_id):
user_list = self.env['res.users'].search([('id', '=', user_id)])
if user_list.partner_id.tz:
rec = self.search([('user_id', '=', user_id)], limit=1)
tz = pytz.timezone(user_list.partner_id.tz)
now_utc = datetime.now(timezone('UTC'))
now_pacific = now_utc.astimezone(timezone(str(tz)))
current_time = now_pacific.strftime('%d %B %Y, %I:%M%p')
current_date = now_pacific.strftime('%d %B %Y')
if rec:
current_date_time = datetime.strptime(current_time, '%d %B %Y, %I:%M%p')
last_update = datetime.strptime(rec.date_weather_update, '%Y-%m-%d %H:%M:%S')
new_update_allowed_time = last_update + relativedelta(minutes=1)
if current_date_time > new_update_allowed_time:
get_weather = self.get_weather(user_id)
if get_weather:
if get_weather['issue'] == 'bad_request':
return {
'issue': 'Bad Request'
}
elif get_weather['issue'] == 'internet':
return {
'issue': 'Connection ERROR.!'
}
elif get_weather['issue'] == 'localization':
return {
'issue': 'longitude and latitude or address issue.'
}
elif get_weather['issue'] == 'config':
return {
'issue': 'Weather configuration not set yet.'
}
elif get_weather['issue'] == 'timezone':
return {
'issue': 'Timezone is not available'
}
else:
rec = self.search([('user_id', '=', user_id)], limit=1)
else:
pass
if rec:
vals = {
'date_now': current_date,
'date_weather_update': rec.date_weather_update,
'name': rec.name,
'city': rec.city,
'user_id': rec.user_id.id,
'weather': rec.weather,
'description': rec.description,
'temp': rec.temp,
'pressure': rec.pressure,
'humidity': rec.humidity,
'min_temp': rec.min_temp,
'max_temp': rec.max_temp,
'issue': '',
}
return vals
else:
get_weather = self.get_weather(user_id)
if get_weather['issue'] == 'bad_request':
return {
'issue': 'Bad Request'
}
elif get_weather['issue'] == 'internet':
return {
'issue': 'Connection ERROR.!'
}
elif get_weather['issue'] == 'localization':
return {
'issue': 'Set correct Location'
}
elif get_weather['issue'] == 'config':
return {
'issue': 'Weather configuration not set yet.'
}
elif get_weather['issue'] == 'timezone':
return {
'issue': 'Timezone is not available'
}
else:
rec = self.search([('user_id', '=', user_id)], limit=1)
if rec:
vals = {
'date_now': current_date,
'date_weather_update': rec.date_weather_update,
'name': rec.name,
'city': rec.city,
'user_id': rec.user_id.id,
'weather': rec.weather,
'description': rec.description,
'temp': rec.temp,
'pressure': rec.pressure,
'humidity': rec.humidity,
'min_temp': rec.min_temp,
'max_temp': rec.max_temp,
'issue': '',
}
return vals
else:
return {
'issue': 'Bad request'
}
else:
return {
'issue': 'Timezone is not available'
}
def get_weather(self, user_id):
rec = self.env['user.weather.map.config'].search([('user_id', '=', user_id)], limit=1)
if rec:
weather_path = 'http://api.openweathermap.org/data/2.5/weather?'
if rec.u_longitude and rec.u_latitude:
params = urllib.urlencode(
{'lat': rec.u_latitude, 'lon': rec.u_longitude, 'APPID': rec.appid})
elif rec.city:
params = urllib.urlencode(
{'q': rec.city, 'APPID': rec.appid})
else:
return {
'issue': 'localization'
}
url = weather_path + params
try:
f = urllib.urlopen(url)
except Exception:
f = False
if f:
ret = f.read().decode('utf-8')
result = json.loads(ret)
if result:
if "cod" in result.keys():
if result['cod'] == 200:
city = False
city2 = False
if "name" in result.keys():
city = result['name']
if not city:
if rec.method == 'address':
city = rec.city
if rec.method == 'address':
city2 = rec.city
temp = pytemperature.k2c(result['main']['temp'])
min_temp = pytemperature.k2c(result['main']['temp_min'])
max_temp = pytemperature.k2c(result['main']['temp_max'])
weather_rec = self.search([('user_id', '=', rec.user_id.id)])
now_utc = datetime.now(timezone('UTC'))
user_list = self.env['res.users'].search([('id', '=', user_id)])
if user_list.partner_id.tz:
tz = pytz.timezone(user_list.partner_id.tz)
now_pacific = now_utc.astimezone(timezone(str(tz)))
current_time = now_pacific.strftime('%d %B %Y, %I:%M%p')
vals = {
'date_weather_update': current_time,
'name': city,
'city': city2,
'user_id': user_id,
'weather': result['weather'][0]['main'],
'description': result['weather'][0]['description'],
'temp': temp,
'pressure': result['main']['pressure'],
'humidity': result['main']['humidity'],
'min_temp': min_temp,
'max_temp': max_temp,
}
if weather_rec:
weather_rec.write(vals)
return {
'issue': ''
}
else:
weather_rec.create(vals)
return {
'issue': ''
}
else:
return {
'issue': 'timezone'
}
else:
return {
'issue': 'localization'
}
else:
return {
'issue': 'bad_request'
}
else:
return {
'issue': 'internet'
}
else:
return {
'issue': 'config'
}
class UserWeatherMapConfig(models.Model):
_name = 'user.weather.map.config'
_inherit = 'res.config.settings'
_rec_name = 'user_id'
def _default_street(self):
rec = self.search([('user_id', '=', self.env.user.id)])
if rec:
return rec.street
def _default_city(self):
rec = self.search([('user_id', '=', self.env.user.id)])
if rec:
return rec.city
def _default_state_id(self):
rec = self.search([('user_id', '=', self.env.user.id)])
if rec:
return rec.state_id.id
def _default_country_id(self):
rec = self.search([('user_id', '=', self.env.user.id)])
if rec:
return rec.country_id.id
def _default_zip(self):
rec = self.search([('user_id', '=', self.env.user.id)])
if rec:
return rec.zip
def _default_appid(self):
rec = self.search([('user_id', '=', self.env.user.id)])
if rec:
return rec.appid
def _default_method(self):
rec = self.search([('user_id', '=', self.env.user.id)])
if rec:
return rec.method
else:
return 'address'
def _default_longitude(self):
rec = self.search([('user_id', '=', self.env.user.id)])
if rec:
if rec.method == 'coordinates':
return rec.u_longitude
else:
return ''
def _default_latitude(self):
rec = self.search([('user_id', '=', self.env.user.id)])
if rec:
if rec.method == 'coordinates':
return rec.u_latitude
else:
return ''
user_id = fields.Many2one('res.users', string='User Name', readonly=True, default=lambda self: self.env.user.id)
u_longitude = fields.Char(string='Longitude', default=_default_longitude)
u_latitude = fields.Char(string='Latitude', default=_default_latitude)
street = fields.Char('Street', default=_default_street)
zip = fields.Char('Zip', size=24, change_default=True, default=_default_zip)
city = fields.Char('City', default=_default_city)
state_id = fields.Many2one("res.country.state", string='State', ondelete='restrict', default=_default_state_id)
country_id = fields.Many2one('res.country', string='Country', ondelete='restrict', default=_default_country_id)
appid = fields.Char('App id', default=_default_appid, required=True,
help="Just sign up the OpenWeatherMap. Generate a Weather Key and provide here.")
method = fields.Selection([('address', 'By Address'),
('coordinates', 'By geolocation')], string='Type', default=_default_method)
@api.multi
def onchange_state(self, state_id):
if state_id:
state = self.env['res.country.state'].browse(state_id)
return {'value': {'country_id': state.country_id.id}}
return {}
@api.multi
def execute_weather(self):
val = 0
recs = self.search([('user_id', '=', self.user_id.id)])
for rec1 in recs:
if val < rec1.id:
val = rec1.id
for rec2 in recs:
if val != rec2.id:
rec2.unlink()
if self.method == 'address':
self.geo_localize()
else:
pass
self.env['user.weather.map'].get_weather(self.user_id.id)
return {
'type': 'ir.actions.act_url',
'url': '/web',
'target': 'self',
}
def geo_query_address(self, street=None, zip=None, city=None, state=None, country=None):
if country and ',' in country and (country.endswith(' of') or country.endswith(' of the')):
# put country qualifier in front, otherwise GMap gives wrong results,
# e.g. 'Congo, Democratic Republic of the' => 'Democratic Republic of the Congo'
country = '{1} {0}'.format(*country.split(',', 1))
return tools.ustr(', '.join(filter(None, [street,
("%s %s" % (zip or '', city or '')).strip(),
state,
country])))
def geo_find(self, addr):
url = 'https://maps.googleapis.com/maps/api/geocode/json?sensor=false&address='
url += urllib.quote(addr.encode('utf8'))
try:
result = json.load(urllib.urlopen(url))
except Exception, e:
raise odoo.exceptions.except_orm(_('Network error'),
_('Cannot contact geolocation servers. '
'Please make sure that your internet connection is up and running (%s).') % e)
if result['status'] != 'OK':
return None
try:
geo = result['results'][0]['geometry']['location']
return float(geo['lat']), float(geo['lng'])
except (KeyError, ValueError):
return None
@api.one
def geo_localize(self):
# Don't pass context to browse()! We need country names in english below
result = self.geo_find(self.geo_query_address(street=self.street,
zip=self.zip,
city=self.city,
state=self.state_id.name,
country=self.country_id.name))
if result:
self.write({
'u_latitude': result[0],
'u_longitude': result[1],
}, )
else:
if self.method == 'address':
self.write({
'u_latitude': '',
'u_longitude': '',
}, )
return True