diff --git a/user_weather_map/README.rst b/user_weather_map/README.rst new file mode 100644 index 000000000..41d943f5d --- /dev/null +++ b/user_weather_map/README.rst @@ -0,0 +1,25 @@ +==================== +User Weather Map v10 +==================== + +This module provides a weather notification for every users. + +Installation +============ + +Make sure you have ``pytemperature`` Python module installed:: + +$ pip install pytemperature + +Make an account in "openweathermap.org", generate a API Key. + +Features +======== + +* User can get the weather notification. +* User can configure there weather notification. +* User's place can set by address or coordinates. + +Credits +======= +Nikhil Krishnan @ cybrosys, nikhil@cybrosys.in \ No newline at end of file diff --git a/user_weather_map/__init__.py b/user_weather_map/__init__.py new file mode 100644 index 000000000..4f61969e1 --- /dev/null +++ b/user_weather_map/__init__.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2017-TODAY Cybrosys Technologies(). +# Author: Nikhil krishnan() +# you can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# It is forbidden to publish, distribute, sublicense, or sell copies +# of the Software or modified copies of the Software. +# +# 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 . +# +############################################################################## + +import models diff --git a/user_weather_map/__manifest__.py b/user_weather_map/__manifest__.py new file mode 100644 index 000000000..c54b788ae --- /dev/null +++ b/user_weather_map/__manifest__.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- + +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2017-TODAY Cybrosys Technologies(). +# Author: Nikhil krishnan() +# you can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# It is forbidden to publish, distribute, sublicense, or sell copies +# of the Software or modified copies of the Software. +# +# 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 . +# +############################################################################## +{ + 'name': 'User Weather Map', + 'version': '10.0.1.0', + 'summary': """Get User's Weather From OpenWeatherMap Automatically.""", + 'description': """Get User's Weather and Temperature From OpenWeatherMap Automatically.""", + 'author': 'Cybrosys Techno Solutions', + 'company': 'Cybrosys Techno Solutions', + 'website': 'http://www.cybrosys.com', + 'category': 'Tools', + 'depends': ['base'], + 'external_dependencies': {'python': ['pytemperature']}, + 'license': 'LGPL-3', + 'data': [ + 'security/ir.model.access.csv', + 'views/weather_template.xml', + 'views/weather_conf.xml', + ], + 'demo': [], + 'qweb': [ + "static/src/xml/weather_topbar.xml", + ], + 'images': ['static/description/banner.jpg'], + 'installable': True, + 'auto_install': False, +} diff --git a/user_weather_map/models/__init__.py b/user_weather_map/models/__init__.py new file mode 100644 index 000000000..e8528bbd6 --- /dev/null +++ b/user_weather_map/models/__init__.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2017-TODAY Cybrosys Technologies(). +# Author: Nikhil krishnan() +# you can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# It is forbidden to publish, distribute, sublicense, or sell copies +# of the Software or modified copies of the Software. +# +# 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 . +# +############################################################################## + +import weather diff --git a/user_weather_map/models/weather.py b/user_weather_map/models/weather.py new file mode 100644 index 000000000..76bd9ee2a --- /dev/null +++ b/user_weather_map/models/weather.py @@ -0,0 +1,413 @@ +# -*- coding: utf-8 -*- +# +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2017-TODAY Cybrosys Technologies(). +# Author: Nikhil krishnan() +# you can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# It is forbidden to publish, distribute, sublicense, or sell copies +# of the Software or modified copies of the Software. +# +# 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 . +# +############################################################################## +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 diff --git a/user_weather_map/security/ir.model.access.csv b/user_weather_map/security/ir.model.access.csv new file mode 100644 index 000000000..5a2b3ffa3 --- /dev/null +++ b/user_weather_map/security/ir.model.access.csv @@ -0,0 +1,4 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink + +access_weather_user,employee.weather.user,user_weather_map.model_user_weather_map,base.group_user,1,1,1,1 +access_weather_user_config,employee.weather.user.config,user_weather_map.model_user_weather_map_config,base.group_user,1,1,1,1 \ No newline at end of file diff --git a/user_weather_map/static/description/api.png b/user_weather_map/static/description/api.png new file mode 100644 index 000000000..cca97bb04 Binary files /dev/null and b/user_weather_map/static/description/api.png differ diff --git a/user_weather_map/static/description/banner.jpg b/user_weather_map/static/description/banner.jpg new file mode 100644 index 000000000..2e8b9a6f0 Binary files /dev/null and b/user_weather_map/static/description/banner.jpg differ diff --git a/user_weather_map/static/description/config.png b/user_weather_map/static/description/config.png new file mode 100644 index 000000000..466773eab Binary files /dev/null and b/user_weather_map/static/description/config.png differ diff --git a/user_weather_map/static/description/cybro_logo.png b/user_weather_map/static/description/cybro_logo.png new file mode 100644 index 000000000..bb309114c Binary files /dev/null and b/user_weather_map/static/description/cybro_logo.png differ diff --git a/user_weather_map/static/description/fill.png b/user_weather_map/static/description/fill.png new file mode 100644 index 000000000..4b88a04ab Binary files /dev/null and b/user_weather_map/static/description/fill.png differ diff --git a/user_weather_map/static/description/icon.png b/user_weather_map/static/description/icon.png new file mode 100644 index 000000000..6fbc34cbc Binary files /dev/null and b/user_weather_map/static/description/icon.png differ diff --git a/user_weather_map/static/description/index.html b/user_weather_map/static/description/index.html new file mode 100644 index 000000000..158622eed --- /dev/null +++ b/user_weather_map/static/description/index.html @@ -0,0 +1,222 @@ +
+
+

User Weather Notification

+

Real time Weather updates

+

Cybrosys Technologies

+
+

Features:

+
    +
  •    The user will get the weather notification.
  • +
  • +    The user can configure their weather notification. +
  • +
+
+
+

Required:

+
    +
  •    Account in Open Weather Map and its API Key.
  • +
  • +    'pytemperature' python package is needed. please install in ubuntu by using ==> pip install pytemperature. +
  • +
+
+
+
+ +
+
+

Overview

+
+
+

+ As we know, many industries are depending on weather conditions like manufacturing, + Event Management, Construction etc. So we believe our concept of weather module can be used + in these industries to understand and plan their works according to the weather condition. + This module is a starter to think and explore the opportunity to bring the advanced features + in Odoo. +

+
+
+
+
+ + +
+
+

Weather notification in Odoo

+
+
+
+ +
+
+ +
+

+

+ User can easily find the weather report from a single click. Summary of the weather + conditions is displayed on the weather board. The user will easily get weather updates, + state of climate and current temperature etc.. +

+
+
+
+
+ +
+
+

Enjoy advanced and automated weather update

+

The most advanced weather notification in a very simple user interface +

+

+ Avoid search for weather updates, get it in a single click. + This module integrates the weather into the Odoo system. +

+
+
+ +

+ Users +

+
+

+ Nowadays everyone is searching temperature and weather conditions in their city or any other + location by using search engines, here we have a very flexible way to find out it easily through + our module without any surfing. +

+
+
+
+ +

+ Settings +

+
+

+ User can specify their current location or any location by providing address or coordinates. +

+
+
+
+ + + +

+ Open Weather Map +

+
+

+ openweathermap.org is providing weather APIs calls and response. Odoo is using this API and provides + you the best result by the help of our application. +

+
+
+
+ +
+
+

How to configure your weather?

+
+
+
+ +
+

+ Click on the setting () button. +

+
+
+
+ +
+
+
+

+ Users can give address of the place or coordinates by selecting the type, +

+ If you are selecting the address type, please provide the address and If it is coordinate, + then give the correct longitude and latitude. +

+

+

+ Provide the correct API key received from the OpenWeatherMap site. +

+
+ +
+
+
+ +
+
+

How to get API KEY?

+
+ Click on the Sing up (
+
+
+
+ +
+
+
+
+ It will go to the account creation page of Open Weather Map +
+
+
+
+ +
+
+
+
+ Fill the required fields and create an account. +
+
+
+
+ +
+
+
+
+ Once we created the account, we can use the default API Key providing by Open Weather Map or + else you have an option for generating your own API Key manually. +
+
+
+
+ +
+
+
+
+
+ +
+

Need Any Help?

+ +
diff --git a/user_weather_map/static/description/settings.png b/user_weather_map/static/description/settings.png new file mode 100644 index 000000000..93e6380aa Binary files /dev/null and b/user_weather_map/static/description/settings.png differ diff --git a/user_weather_map/static/description/sign up.png b/user_weather_map/static/description/sign up.png new file mode 100644 index 000000000..840de9779 Binary files /dev/null and b/user_weather_map/static/description/sign up.png differ diff --git a/user_weather_map/static/description/sign_up_weather_map.png b/user_weather_map/static/description/sign_up_weather_map.png new file mode 100644 index 000000000..59cd6840a Binary files /dev/null and b/user_weather_map/static/description/sign_up_weather_map.png differ diff --git a/user_weather_map/static/description/weather Board.png b/user_weather_map/static/description/weather Board.png new file mode 100644 index 000000000..74cc1a1c5 Binary files /dev/null and b/user_weather_map/static/description/weather Board.png differ diff --git a/user_weather_map/static/src/css/notification.css b/user_weather_map/static/src/css/notification.css new file mode 100644 index 000000000..25feb2ed7 --- /dev/null +++ b/user_weather_map/static/src/css/notification.css @@ -0,0 +1,77 @@ + +.oe_webclient_notification_action t { + color: white; +} +.oe_webclient_notification_action p { + color: white; + margin-top: 1em; +} + .label { + display: inline-block; + color: black; + max-width: 100%; + margin-bottom: 5px; + font-weight: bold; +} +.reminder-dropdown { + .o-flex(0, 1, auto); + background: #FFFFFF; + max-height: 400px; + min-height: 50px; + overflow-y: auto; + + @media (max-width: @screen-xs-max) { + max-height: none; + } +.weather_notification { + width: 100%; + background: #eeeeee; +} +.weather_settings { + float:left; + text-align: right; + width:100%; +} + +.fa-sign-in:hover { + opacity:.5; +} + +.fa-cog{ + -webkit-transition: -webkit-transform .8s ease-in-out; + transition: transform .8s ease-in-out; +} + +.fa-cog:hover{ + -webkit-transform: rotate(360deg); + transform: rotate(360deg) ; +} + +.weather_content{ + width: 100%; + float: left; + padding-left: 5%; + padding-top: 4%; + padding-bottom: 5%; + + +} +.weather_content p{ + margin:2px 0 4px 0; + color: #808080; + font-size: 11px; +} +.weather_content h1{ + margin:0px; + font-size: 26px; + padding: 3px 0 3px 0; +} +.detail-client-address-country { + color: black; + } +.warning h4{ + color: #d21010; + font-weight: 100; + font-size: 12px; +} + diff --git a/user_weather_map/static/src/img/cloud-warning.png b/user_weather_map/static/src/img/cloud-warning.png new file mode 100644 index 000000000..6fb515fbf Binary files /dev/null and b/user_weather_map/static/src/img/cloud-warning.png differ diff --git a/user_weather_map/static/src/img/cloud.png b/user_weather_map/static/src/img/cloud.png new file mode 100644 index 000000000..5de3bdfb6 Binary files /dev/null and b/user_weather_map/static/src/img/cloud.png differ diff --git a/user_weather_map/static/src/img/clouds.png b/user_weather_map/static/src/img/clouds.png new file mode 100644 index 000000000..f2fffef5d Binary files /dev/null and b/user_weather_map/static/src/img/clouds.png differ diff --git a/user_weather_map/static/src/img/haze.png b/user_weather_map/static/src/img/haze.png new file mode 100644 index 000000000..61165881f Binary files /dev/null and b/user_weather_map/static/src/img/haze.png differ diff --git a/user_weather_map/static/src/img/mist.png b/user_weather_map/static/src/img/mist.png new file mode 100644 index 000000000..4541bfebd Binary files /dev/null and b/user_weather_map/static/src/img/mist.png differ diff --git a/user_weather_map/static/src/img/rain.png b/user_weather_map/static/src/img/rain.png new file mode 100644 index 000000000..454dc507f Binary files /dev/null and b/user_weather_map/static/src/img/rain.png differ diff --git a/user_weather_map/static/src/img/snow.png b/user_weather_map/static/src/img/snow.png new file mode 100644 index 000000000..e7069d987 Binary files /dev/null and b/user_weather_map/static/src/img/snow.png differ diff --git a/user_weather_map/static/src/img/sun.png b/user_weather_map/static/src/img/sun.png new file mode 100644 index 000000000..249b0090e Binary files /dev/null and b/user_weather_map/static/src/img/sun.png differ diff --git a/user_weather_map/static/src/img/thunder.png b/user_weather_map/static/src/img/thunder.png new file mode 100644 index 000000000..529158220 Binary files /dev/null and b/user_weather_map/static/src/img/thunder.png differ diff --git a/user_weather_map/static/src/js/weather_notification.js b/user_weather_map/static/src/js/weather_notification.js new file mode 100644 index 000000000..72e02ccd0 --- /dev/null +++ b/user_weather_map/static/src/js/weather_notification.js @@ -0,0 +1,66 @@ +odoo.define('user_weather_map.weather_notification', function (require) { +"use strict"; + +var core = require('web.core'); +var SystrayMenu = require('web.SystrayMenu'); +var Widget = require('web.Widget'); +var Model = require('web.DataModel'); +var QWeb = core.qweb; + +var weather_menu = Widget.extend({ + template:'user_weather_map.weather_menu', + + events: { + "click .dropdown-toggle": "on_click_weather_board", + "click .fa-cog": "go_to_weather_settings", + }, + + init:function(parent, name){ + this.widget = {}; + this.reminder = null; + this._super(parent); + }, + + render_widget: function() { + var self = this; + var user = self.session.uid; + var weather = new Model('user.weather.map'); + new Model("user.weather.map").call("get_weather_data",['',user]).then(function(data){ + var weather = QWeb.render("WeatherDetails", {widget:self, + date_now: data.date_now, + date_weather_update: data.date_weather_update, + name: data.name, + city: data.city, + user_id: data.user_id, + weather: data.weather, + description: data.description, + temp: data.temp, + pressure: data.pressure, + humidity: data.humidity, + min_temp: data.min_temp, + max_temp: data.max_temp, + issue: data.issue, + }); + $('.weather_notification').html(weather); + }); + }, + + go_to_weather_settings: function (event) { + var action = { + type: 'ir.actions.act_window', + res_model: 'user.weather.map.config', + view_mode: 'form', + target:'inline', + views: [[false, 'form']], + }; + this.do_action(action); + }, + + on_click_weather_board: function (event) { + this.render_widget(); + }, + +}); + +SystrayMenu.Items.push(weather_menu); +}); diff --git a/user_weather_map/static/src/less/weather.less b/user_weather_map/static/src/less/weather.less new file mode 100644 index 000000000..dbce8990e --- /dev/null +++ b/user_weather_map/static/src/less/weather.less @@ -0,0 +1,120 @@ +// Navbar icon and dropdown +.o_weather_navbar_item { + > a { + opacity: 1; + float: left; + > i { + font-size: larger; + } + + } + + &.open .o_weather_navbar_dropdown { + .o-flex-display(); + .o-flex-flow(column, nowrap); + } + .weather_board{ + width: auto; + float: left; + font-size: 16px; + text-align:right; + } + .o_weather_navbar_dropdown { + width: 310px; + padding: 0; + + .o_spinner { + .o-flex-display(); + .o-align-items(center); + .o-justify-content(center); + color: @odoo-main-text-color; + height: 50px; + } + + .o_mail_navbar_dropdown_top { + .o-flex-display(); + .o-flex(0, 0, auto); + justify-content: space-between; + border-bottom: 1px solid lightgray; + + .o_filter_button, .o_new_message { + .btn-link; + padding: 5px; + } + .o_filter_button { + color: @odoo-main-color-muted; + &:hover, &.o_selected { + color: @odoo-brand-optional; + } + &.o_selected { + cursor: default; + font-weight: bold; + } + } + } + + .o_mail_navbar_dropdown_channels { + .o-flex(0, 1, auto); + max-height: 400px; + min-height: 50px; + overflow-y: auto; + + @media (max-width: @screen-xs-max) { + max-height: none; + } + + .o_mail_channel_preview { + .o-flex-display(); + height: 50px; + align-items: center; + padding: 5px; + cursor: pointer; + font-size: 12px; + overflow: hidden; + &~.o_mail_channel_preview { + border-top: 1px solid lightgray; + } + &.o_channel_unread { + background-color: lighten(lightgray, 10%); + } + &:hover { + background-color: lighten(lightgray, 5%); + } + + .o_channel_image { + .o-flex(0, 0, 36px); + max-height: 36px; + } + .o_channel_info { + .o-flex(1, 1, 100%); + margin-left: 5px; + overflow: hidden; + + .o_channel_title { + .o-flex-display(); + .o_channel_name { + .o-flex(1, 1, auto); + .o-text-overflow(); + color: @odoo-main-text-color; + } + .o_last_message_date { + .o-flex(0, 0, auto); + padding-top: 3px; + font-size: xx-small; + color: @odoo-main-color-muted; + } + } + .o_last_message_preview { + width: 100%; + color: @odoo-main-color-muted; + .o-text-overflow(); + } + } + } + } + } +} + +.o_no_chat_window .o_mail_navbar_dropdown .o_new_message { + display: none; // hide 'new message' button if chat windows are disabled +} diff --git a/user_weather_map/static/src/xml/weather_topbar.xml b/user_weather_map/static/src/xml/weather_topbar.xml new file mode 100644 index 000000000..74d99d91b --- /dev/null +++ b/user_weather_map/static/src/xml/weather_topbar.xml @@ -0,0 +1,95 @@ + + + +
  • + + + +
  • +
    + + +
    +
    +
    + +