@ -0,0 +1,37 @@ |
|||||
|
# World News |
||||
|
|
||||
|
Subscribe to World news Channels from listed channels under Odoo News. Joined channels will be listed under Discuss Menu. |
||||
|
|
||||
|
- Goto https://newsapi.org/ |
||||
|
- Register a new account. |
||||
|
- Get API key. |
||||
|
- Paste under news configurations under News -> Configurations -> settings -> Apply. |
||||
|
- Check the Updated News channels Under menu News |
||||
|
- Join and Read |
||||
|
|
||||
|
|
||||
|
### Depends |
||||
|
[mail] addon Odoo |
||||
|
|
||||
|
### Tech |
||||
|
|
||||
|
* [Python] - Models |
||||
|
* [XML] - Odoo views |
||||
|
|
||||
|
### Installation |
||||
|
- www.odoo.com/documentation/10.0/setup/install.html |
||||
|
- Install our custom addon |
||||
|
- set up https://newsapi.org/ account |
||||
|
|
||||
|
### Usage |
||||
|
> Join News channels under News |
||||
|
> Got Discuss |
||||
|
> Select the joined channels & Read |
||||
|
|
||||
|
License |
||||
|
---- |
||||
|
GNU LESSER GENERAL PUBLIC LICENSE, Version 3 (LGPLv3) |
||||
|
(http://www.gnu.org/licenses/agpl.html) |
||||
|
|
||||
|
|
||||
|
|
@ -0,0 +1,4 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
|
||||
|
# from . import controllers |
||||
|
from . import models |
@ -0,0 +1,45 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################## |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# Copyright (C) 2017-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). |
||||
|
# Author: Hilar AK(<hilar@cybrosys.in>) |
||||
|
# 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 <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################## |
||||
|
{ |
||||
|
'name': "World News", |
||||
|
'version': '10.0.1.0.0', |
||||
|
'summary': """ World News as Discuss Channels""", |
||||
|
'description': """ |
||||
|
Users can Maintain news channels and subscribe/unsubscribe from world news channels. |
||||
|
""", |
||||
|
'author': 'Cybrosys Techno Solutions', |
||||
|
'company': 'Cybrosys Techno Solutions', |
||||
|
'website': "https://cybrosys.com/", |
||||
|
'category': 'Discuss', |
||||
|
'depends': ['base', 'mail'], |
||||
|
'data': [ |
||||
|
'views/channel_views.xml', |
||||
|
'views/res_config_view.xml', |
||||
|
'data/data.xml', |
||||
|
], |
||||
|
'demo': [], |
||||
|
'images': ['static/description/banner.jpg'], |
||||
|
'license': 'LGPL-3', |
||||
|
'installable': True, |
||||
|
'application': False |
||||
|
} |
@ -0,0 +1,3 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
|
||||
|
# from . import controllers |
@ -0,0 +1,20 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
from odoo import http |
||||
|
|
||||
|
# class DiscussNews(http.Controller): |
||||
|
# @http.route('/discuss_news/discuss_news/', auth='public') |
||||
|
# def index(self, **kw): |
||||
|
# return "Hello, world" |
||||
|
|
||||
|
# @http.route('/discuss_news/discuss_news/objects/', auth='public') |
||||
|
# def list(self, **kw): |
||||
|
# return http.request.render('discuss_news.listing', { |
||||
|
# 'root': '/discuss_news/discuss_news', |
||||
|
# 'objects': http.request.env['discuss_news.discuss_news'].search([]), |
||||
|
# }) |
||||
|
|
||||
|
# @http.route('/discuss_news/discuss_news/objects/<model("discuss_news.discuss_news"):obj>/', auth='public') |
||||
|
# def object(self, obj, **kw): |
||||
|
# return http.request.render('discuss_news.object', { |
||||
|
# 'object': obj |
||||
|
# }) |
@ -0,0 +1,18 @@ |
|||||
|
<odoo> |
||||
|
<data noupdate="1"> |
||||
|
<record id="cron_news_channel" model="ir.cron"> |
||||
|
<field name="name">Sync News Channels </field> |
||||
|
<field name="active" eval="True" /> |
||||
|
<field name="user_id" ref="base.user_root" /> |
||||
|
<field name="interval_number">30</field> |
||||
|
<field name="interval_type">minutes</field> |
||||
|
<field name="numbercall">-1</field> |
||||
|
<field name="doal">1</field> |
||||
|
<!--<field name="nextcall" >2016-12-31 23:59:59</field>--> |
||||
|
<field name="model" eval="'mail.channel'" /> |
||||
|
<field name="function">news_sync</field> |
||||
|
<field name="args" eval="" /> |
||||
|
<!--<field name="priority" eval="5" />--> |
||||
|
</record> |
||||
|
</data> |
||||
|
</odoo> |
@ -0,0 +1,30 @@ |
|||||
|
<openerp> |
||||
|
<data> |
||||
|
<!-- --> |
||||
|
<!-- <record id="object0" model="discuss_news.discuss_news"> --> |
||||
|
<!-- <field name="name">Object 0</field> --> |
||||
|
<!-- <field name="value">0</field> --> |
||||
|
<!-- </record> --> |
||||
|
<!-- --> |
||||
|
<!-- <record id="object1" model="discuss_news.discuss_news"> --> |
||||
|
<!-- <field name="name">Object 1</field> --> |
||||
|
<!-- <field name="value">10</field> --> |
||||
|
<!-- </record> --> |
||||
|
<!-- --> |
||||
|
<!-- <record id="object2" model="discuss_news.discuss_news"> --> |
||||
|
<!-- <field name="name">Object 2</field> --> |
||||
|
<!-- <field name="value">20</field> --> |
||||
|
<!-- </record> --> |
||||
|
<!-- --> |
||||
|
<!-- <record id="object3" model="discuss_news.discuss_news"> --> |
||||
|
<!-- <field name="name">Object 3</field> --> |
||||
|
<!-- <field name="value">30</field> --> |
||||
|
<!-- </record> --> |
||||
|
<!-- --> |
||||
|
<!-- <record id="object4" model="discuss_news.discuss_news"> --> |
||||
|
<!-- <field name="name">Object 4</field> --> |
||||
|
<!-- <field name="value">40</field> --> |
||||
|
<!-- </record> --> |
||||
|
<!-- --> |
||||
|
</data> |
||||
|
</openerp> |
@ -0,0 +1,3 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
|
||||
|
from . import models |
@ -0,0 +1,186 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
|
||||
|
from odoo import models, fields, api |
||||
|
import requests |
||||
|
import logging |
||||
|
import json |
||||
|
|
||||
|
_logger = logging.getLogger(__name__) |
||||
|
|
||||
|
class NewsChannel(models.Model): |
||||
|
_inherit = 'mail.channel' |
||||
|
|
||||
|
is_news_channel = fields.Boolean(default=False, invisible=True) |
||||
|
language_id = fields.Many2one('res.lang', 'Language') |
||||
|
url = fields.Char('URL') |
||||
|
category = fields.Char('Category') |
||||
|
channel_ref = fields.Char('Channel Reference', invisible=True) |
||||
|
last_updated = fields.Datetime("Last Updated") |
||||
|
|
||||
|
def update_news_content(self, channel, contents): |
||||
|
""" |
||||
|
{ |
||||
|
'body': HTML content of the message |
||||
|
'model': u'res.partner', |
||||
|
'record_name': u'Agrolait', |
||||
|
'attachment_ids': [ |
||||
|
{ |
||||
|
'file_type_icon': u'webimage', |
||||
|
'id': 45, |
||||
|
'name': u'sample.png', |
||||
|
'filename': u'sample.png' |
||||
|
} |
||||
|
], |
||||
|
'needaction_partner_ids': [], # list of partner ids |
||||
|
'res_id': 7, |
||||
|
'tracking_value_ids': [ |
||||
|
{ |
||||
|
'old_value': "", |
||||
|
'changed_field': "Customer", |
||||
|
'id': 2965, |
||||
|
'new_value': "Axelor" |
||||
|
} |
||||
|
], |
||||
|
'author_id': (3, u'Administrator'), |
||||
|
'email_from': 'sacha@pokemon.com' # email address or False |
||||
|
'subtype_id': (1, u'Discussions'), |
||||
|
'channel_ids': [], # list of channel ids |
||||
|
'date': '2015-06-30 08:22:33', |
||||
|
'partner_ids': [[7, "Sacha Du Bourg-Palette"]], # list of partner name_get |
||||
|
'message_type': u'comment', |
||||
|
'id': 59, |
||||
|
'subject': False |
||||
|
'is_note': True # only if the subtype is internal |
||||
|
} |
||||
|
""" |
||||
|
body = contents.get('articles', False) |
||||
|
body_contents = "" |
||||
|
for data in body: |
||||
|
body_contents += """ |
||||
|
<p> |
||||
|
<p style="margin-bottom: 10px;"><img src="%s" width="300px" height="300px"/></p> |
||||
|
<p style="margin-bottom: 0px;"><b>Title:</b>%s</p> |
||||
|
<p style="margin-bottom: 0px;"><b>Description:</b>%s</p> |
||||
|
<p style="margin-bottom: 0px;"><b>Author:</b>%s <b>publishedAt:</b>%s</p> |
||||
|
<p style="margin-bottom: 0px;"><b><a href="%s">Read more.. </a></b></p> |
||||
|
<p style="padding-bottom:10px"> |
||||
|
<hr/> |
||||
|
"""%(data.get('urlToImage', False), data.get('title', False), data.get('description', False), |
||||
|
data.get('author', False), data.get('publishedAt', False), data.get('url', False),) |
||||
|
|
||||
|
data = { |
||||
|
'body': body_contents, |
||||
|
'model': u'mail.channel', |
||||
|
'record_name': channel.name, |
||||
|
'res_id': channel.id, |
||||
|
'author_id': 3, |
||||
|
'email_from': u'Administrator <admin@yourcompany.example.com>', # email address or False |
||||
|
'subtype_id': 1, |
||||
|
'channel_ids': [channel.id], # list of channel ids |
||||
|
'message_type': u'notification', |
||||
|
'subject': False, |
||||
|
'parent_id': False, |
||||
|
'reply_to': u'YourCompany <catchall@gmail.com>', |
||||
|
} |
||||
|
|
||||
|
data.update({'message_id': self.env['mail.message'].sudo()._get_message_id(data)}) |
||||
|
self.env['mail.message'].sudo().create(data) |
||||
|
|
||||
|
|
||||
|
@api.model |
||||
|
def news_sync(self): |
||||
|
""" |
||||
|
Sync the news according to the each channels, where the news api not providing a single sync for all channels, |
||||
|
so we are iterating here on each channels to sync. |
||||
|
Lets hope for a good Updated api from them in future |
||||
|
:return: |
||||
|
""" |
||||
|
default_key = self.env['news.channel.config.settings'].get_default_news_api_key([]) |
||||
|
api_key = default_key.get('news_api_key', False) |
||||
|
if api_key: |
||||
|
query = """delete from mail_message m where m.res_id in |
||||
|
(select distinct id from mail_channel c where c.is_news_channel = True)""" |
||||
|
self._cr.execute(query) |
||||
|
channels_pool = self.search([('is_news_channel', '=', True)]) |
||||
|
url = "https://newsapi.org/v1/articles" |
||||
|
querystring = { |
||||
|
"apiKey": api_key, |
||||
|
} |
||||
|
headers = { |
||||
|
'cache-control': "no-cache", |
||||
|
} |
||||
|
for channels in channels_pool: |
||||
|
querystring.update({"source": channels.channel_ref, }) |
||||
|
response = requests.request("GET", url, headers=headers, params=querystring) |
||||
|
try: |
||||
|
if response.status_code == 200: |
||||
|
contents = json.loads(response.text) |
||||
|
if contents and contents.get('status') == 'ok': |
||||
|
self.update_news_content(channels, contents) |
||||
|
except Exception as e: |
||||
|
_logger.info(e) |
||||
|
continue |
||||
|
|
||||
|
|
||||
|
|
||||
|
class NewsChannelConfigSettings(models.Model): |
||||
|
_name = 'news.channel.config.settings' |
||||
|
_inherit = 'res.config.settings' |
||||
|
|
||||
|
news_api_key = fields.Char('Api Key') |
||||
|
|
||||
|
@api.model |
||||
|
def get_default_news_api_key(self, fields): |
||||
|
ir_values = self.env['ir.values'] |
||||
|
news_api_key = ir_values.get_default('news.channel.config.settings', 'news_api_key') |
||||
|
return {'news_api_key': news_api_key} |
||||
|
|
||||
|
@api.multi |
||||
|
def set_default_news_api_key(self): |
||||
|
ir_values = self.env['ir.values'] |
||||
|
for record in self: |
||||
|
ir_values.sudo().set_default('news.channel.config.settings', 'news_api_key', record.news_api_key) |
||||
|
|
||||
|
@api.multi |
||||
|
def execute(self): |
||||
|
""" |
||||
|
Which invokes when you click on apply button on config page |
||||
|
Here we update all channels from news api, list under menu 'News' |
||||
|
Url https://newsapi.org/v1/sources lists the sources |
||||
|
:return: {'tag': 'reload', 'type': 'ir.actions.client'} |
||||
|
""" |
||||
|
print self.news_api_key, "self.news_api_keyself.news_api_key" |
||||
|
if self.news_api_key: |
||||
|
try: |
||||
|
url = "https://newsapi.org/v1/sources" |
||||
|
querystring = {"language": "en"} |
||||
|
headers = { |
||||
|
'cache-control': "no-cache" |
||||
|
} |
||||
|
response = requests.request("GET", url, headers=headers, params=querystring) |
||||
|
data = eval(response.text) |
||||
|
language_model = self.env['res.lang'] |
||||
|
Channel = self.env['mail.channel'] |
||||
|
channel_data = {} |
||||
|
if data.get('status') == 'ok': |
||||
|
for values in data['sources']: |
||||
|
channel_id = Channel.search([('channel_ref', '=', values['id'])]) |
||||
|
if not len(channel_id): |
||||
|
language = language_model.search([('iso_code', '=', values.get('language', False))]) |
||||
|
channel_data.update({ |
||||
|
'name': values['name'], |
||||
|
'channel_ref': values['id'], |
||||
|
'language_id': language and language.id, |
||||
|
'category': values['category'], |
||||
|
'url': values['url'], |
||||
|
'is_news_channel': True, |
||||
|
'description': values['description'], |
||||
|
}) |
||||
|
Channel.create(channel_data) |
||||
|
return super(NewsChannelConfigSettings, self).execute() |
||||
|
else: |
||||
|
raise Exception |
||||
|
except Exception as e: |
||||
|
_logger.info(e) |
||||
|
else: |
||||
|
return Warning("Give Proper Api Key") |
|
After Width: | Height: | Size: 58 KiB |
After Width: | Height: | Size: 8.3 KiB |
After Width: | Height: | Size: 106 KiB |
After Width: | Height: | Size: 148 KiB |
After Width: | Height: | Size: 50 KiB |
After Width: | Height: | Size: 33 KiB |
@ -0,0 +1,155 @@ |
|||||
|
<section class="oe_container oe_dark"> |
||||
|
<div class="oe_row oe_spaced"> |
||||
|
<h2 class="oe_slogan">News Channels Subscription</h2> |
||||
|
<h4 class="oe_slogan"><a href="https://www.cybrosys.com">Cybrosys Technologies</a></h4> |
||||
|
</div> |
||||
|
</section> |
||||
|
<section class="oe_container"> |
||||
|
<div class="oe_row oe_spaced"> |
||||
|
<h2 class="oe_slogan" style="color:#875A7B;">Subscribe News From listed news Channels</h2> |
||||
|
<h3 class="oe_slogan"> |
||||
|
Subscribe to various news Channels provided under custom menu "NEWS". |
||||
|
Subscribed News channels will be listed under Discuss Menu. |
||||
|
</h3> |
||||
|
</div> |
||||
|
|
||||
|
<div class="oe_container oe_dark"> |
||||
|
<div class="row mt32 o_animate o_animate_in_children o_animate_offset_min" |
||||
|
style="animation-name: none; visibility: hidden; animation-play-state: paused;"> |
||||
|
|
||||
|
<div class="col-md-5 col-md-offset-1" style="transition-delay: 0ms;"> |
||||
|
<h2 class=" mt32 mb16"><b>Get Api credentials from <a href="https://newsapi.org/">https://newsapi.org/</a></b></h2> |
||||
|
</div> |
||||
|
<div class="col-md-6" style="transition-delay: 500ms;"> |
||||
|
<div class=" oe_demo oe_picture oe_screenshot"> |
||||
|
<img style="max-width: 100%;-moz-transform: scale(1.2);-webkit-transform: scale(1.2); -o-transform: scale(1.2); -ms-transform: scale(1.2); transform: scale(1.2);" |
||||
|
src="GET.png"> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="oe_container"> |
||||
|
<div class="row mt32 o_animate o_animate_in_children o_animate_offset_min" |
||||
|
style="animation-name: none; visibility: hidden; animation-play-state: paused;"> |
||||
|
|
||||
|
<div class="col-md-5 col-md-offset-1" style="transition-delay: 0ms;"> |
||||
|
<h2 class=" mt32 mb16"><b>Registration Window</b></h2> |
||||
|
|
||||
|
</div> |
||||
|
<div class="col-md-6" style="transition-delay: 500ms;"> |
||||
|
<div class=" oe_demo oe_picture oe_screenshot"> |
||||
|
<img style="max-width: 100%;-moz-transform: scale(1.2);-webkit-transform: scale(1.2); -o-transform: scale(1.2); -ms-transform: scale(1.2); transform: scale(1.2);" |
||||
|
src="register.png"> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="oe_container oe_dark"> |
||||
|
<div class="row mt32 o_animate o_animate_in_children o_animate_offset_min" |
||||
|
style="animation-name: none; visibility: hidden; animation-play-state: paused;"> |
||||
|
|
||||
|
<div class="col-md-5 col-md-offset-1" style="transition-delay: 0ms;"> |
||||
|
<h2 class=" mt32 mb16"><b>Get API Key</b></h2> |
||||
|
</div> |
||||
|
<div class="col-md-6" style="transition-delay: 500ms;"> |
||||
|
<div class=" oe_demo oe_picture oe_screenshot"> |
||||
|
<img style="max-width: 100%;-moz-transform: scale(1.2);-webkit-transform: scale(1.2); -o-transform: scale(1.2); -ms-transform: scale(1.2); transform: scale(1.2);" |
||||
|
src="API.png"> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="oe_container"> |
||||
|
<div class="row mt32 o_animate o_animate_in_children o_animate_offset_min" |
||||
|
style="animation-name: none; visibility: hidden; animation-play-state: paused;"> |
||||
|
|
||||
|
<div class="col-md-5 col-md-offset-1" style="transition-delay: 0ms;"> |
||||
|
<h2 class=" mt32 mb16"><b>Paste API key under News -> Configurations -> settings</b></h2> |
||||
|
</div> |
||||
|
<div class="col-md-6" style="transition-delay: 500ms;"> |
||||
|
<div class=" oe_demo oe_picture oe_screenshot"> |
||||
|
<img style="max-width: 100%;-moz-transform: scale(1.2);-webkit-transform: scale(1.2); -o-transform: scale(1.2); -ms-transform: scale(1.2); transform: scale(1.2);" |
||||
|
src="res_conf.png"> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="oe_container oe_dark"> |
||||
|
<div class="row mt32 o_animate o_animate_in_children o_animate_offset_min" |
||||
|
style="animation-name: none; visibility: hidden; animation-play-state: paused;"> |
||||
|
|
||||
|
<div class="col-md-5 col-md-offset-1" style="transition-delay: 0ms;"> |
||||
|
<h2 class=" mt32 mb16"><b>Channels Updated After Apply Settings.</b></h2> |
||||
|
</div> |
||||
|
<div class="col-md-6" style="transition-delay: 500ms;"> |
||||
|
<div class=" oe_demo oe_picture oe_screenshot"> |
||||
|
<img style="max-width: 100%;-moz-transform: scale(1.2);-webkit-transform: scale(1.2); -o-transform: scale(1.2); -ms-transform: scale(1.2); transform: scale(1.2);" |
||||
|
src="channels.png"> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="oe_container"> |
||||
|
<div class="row mt32 o_animate o_animate_in_children o_animate_offset_min" |
||||
|
style="animation-name: none; visibility: hidden; animation-play-state: paused;"> |
||||
|
|
||||
|
<div class="col-md-5 col-md-offset-1" style="transition-delay: 0ms;"> |
||||
|
<h2 class=" mt32 mb16"><b>Join News Channels</b></h2> |
||||
|
</div> |
||||
|
<div class="col-md-6" style="transition-delay: 500ms;"> |
||||
|
<div class=" oe_demo oe_picture oe_screenshot"> |
||||
|
<img style="max-width: 100%;-moz-transform: scale(1.2);-webkit-transform: scale(1.2); -o-transform: scale(1.2); -ms-transform: scale(1.2); transform: scale(1.2);" |
||||
|
src="join.png"> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="oe_container oe_dark"> |
||||
|
<div class="row mt32 o_animate o_animate_in_children o_animate_offset_min" |
||||
|
style="animation-name: none; visibility: hidden; animation-play-state: paused;"> |
||||
|
|
||||
|
<div class="col-md-5 col-md-offset-1" style="transition-delay: 0ms;"> |
||||
|
<h2 class=" mt32 mb16"><b>Updated News Under Discuss / News Channel Wise</b></h2> |
||||
|
</div> |
||||
|
<div class="col-md-6" style="transition-delay: 500ms;"> |
||||
|
<div class=" oe_demo oe_picture oe_screenshot"> |
||||
|
<img style="max-width: 100%;-moz-transform: scale(1.2);-webkit-transform: scale(1.2); -o-transform: scale(1.2); -ms-transform: scale(1.2); transform: scale(1.2);" |
||||
|
src="news_discuss.png"> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
</div> |
||||
|
</div> |
||||
|
</section> |
||||
|
<section class="oe_container oe_dark"> |
||||
|
<h2 class="oe_slogan" style="margin-top:20px;" >Need Any Help?</h2> |
||||
|
<div class="oe_slogan" style="margin-top:10px !important;"> |
||||
|
<div> |
||||
|
<a class="btn btn-primary btn-lg mt8" |
||||
|
style="color: #FFFFFF !important;border-radius: 0;" href="https://www.cybrosys.com"><i |
||||
|
class="fa fa-envelope"></i> Email </a> <a |
||||
|
class="btn btn-primary btn-lg mt8" style="color: #FFFFFF !important;border-radius: 0;" |
||||
|
href="https://www.cybrosys.com/contact/"><i |
||||
|
class="fa fa-phone"></i> Contact Us </a> <a |
||||
|
class="btn btn-primary btn-lg mt8" style="color: #FFFFFF !important;border-radius: 0;" |
||||
|
href="https://www.cybrosys.com/odoo-customization-and-installation/"><i |
||||
|
class="fa fa-check-square"></i> Request Customization </a> |
||||
|
</div> |
||||
|
<br> |
||||
|
<img src="cybro_logo.png" style="width: 190px; margin-bottom: 20px;" class="center-block"> |
||||
|
<div> |
||||
|
<a href="https://twitter.com/cybrosys" target="_blank"><i class="fa fa-2x fa-twitter" style="color:white;background: #00a0d1;width:35px;"></i></a></td> |
||||
|
<a href="https://www.linkedin.com/company/cybrosys-technologies-pvt-ltd" target="_blank"><i class="fa fa-2x fa-linkedin" style="color:white;background: #31a3d6;width:35px;padding-left: 3px;"></i></a></td> |
||||
|
<a href="https://www.facebook.com/cybrosystechnologies" target="_blank"><i class="fa fa-2x fa-facebook" style="color:white;background: #3b5998;width:35px;padding-left: 8px;"></i></a></td> |
||||
|
<a href="https://plus.google.com/106641282743045431892/about" target="_blank"><i class="fa fa-2x fa-google-plus" style="color:white;background: #c53c2c;width:35px;padding-left: 3px;"></i></a></td> |
||||
|
<a href="https://in.pinterest.com/cybrosys" target="_blank"><i class="fa fa-2x fa-pinterest" style="color:white;background: #ac0f18;width:35px;padding-left: 3px;"></i></a></td> |
||||
|
</div> |
||||
|
</div> |
||||
|
</section> |
||||
|
|
After Width: | Height: | Size: 70 KiB |
After Width: | Height: | Size: 268 KiB |
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 30 KiB |
@ -0,0 +1,34 @@ |
|||||
|
<odoo> |
||||
|
<data> |
||||
|
<record id="news_channel_form_view" model="ir.ui.view"> |
||||
|
<field name="name">News Channels View</field> |
||||
|
<field name="model">mail.channel</field> |
||||
|
<field name="inherit_id" ref="mail.mail_channel_view_form"/> |
||||
|
<field name="arch" type="xml"> |
||||
|
<field name="email_send" position="before"> |
||||
|
<field name="is_news_channel" invisible="1"/> |
||||
|
<field name="language_id" widget="selection" attrs="{'invisible': [('is_news_channel', '=', False)]}"/> |
||||
|
<field name="url" attrs="{'invisible': [('is_news_channel', '=', False)]}"/> |
||||
|
<field name="category" attrs="{'invisible': [('is_news_channel', '=', False)]}"/> |
||||
|
<field name="channel_ref" attrs="{'invisible': [('is_news_channel', '=', False)]}"/> |
||||
|
<field name="last_updated" attrs="{'invisible': [('is_news_channel', '=', False)]}"/> |
||||
|
</field> |
||||
|
</field> |
||||
|
</record> |
||||
|
<record id="action_news_channel_kanban" model="ir.actions.act_window"> |
||||
|
<field name="name">News Channels</field> |
||||
|
<field name="type">ir.actions.act_window</field> |
||||
|
<field name="res_model">mail.channel</field> |
||||
|
<field name="view_mode">kanban,tree,form</field> |
||||
|
<field name="domain">[('is_news_channel', '=', True)]</field> |
||||
|
</record> |
||||
|
<menuitem id="news" |
||||
|
name="News" |
||||
|
/> |
||||
|
<menuitem name="Channels" |
||||
|
id="news_channels" |
||||
|
parent="news" |
||||
|
action="action_news_channel_kanban" |
||||
|
/> |
||||
|
</data> |
||||
|
</odoo> |
@ -0,0 +1,39 @@ |
|||||
|
<odoo> |
||||
|
<data> |
||||
|
<record id="view_news_configuration" model="ir.ui.view"> |
||||
|
<field name="name">Configure News Channels</field> |
||||
|
<field name="model">news.channel.config.settings</field> |
||||
|
<field name="inherit_id" eval="False"/> |
||||
|
<field name="arch" type="xml"> |
||||
|
<form class="oe_form_configuration"> |
||||
|
<header> |
||||
|
<button string="Apply" type="object" name="execute" class="oe_highlight"/> |
||||
|
<button string="Cancel" type="object" name="cancel" class="oe_link"/> |
||||
|
</header> |
||||
|
<group string="News" name="config_news"> |
||||
|
<label for="id" string="News API"/> |
||||
|
<div> |
||||
|
<div > |
||||
|
<p class="text-muted"> |
||||
|
Here paste the api key credential provided by https://newsapi.org/account |
||||
|
</p> |
||||
|
<field name="news_api_key" class="oe_inline"/> |
||||
|
</div> |
||||
|
</div> |
||||
|
</group> |
||||
|
</form> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="action_news_configuration" model="ir.actions.act_window"> |
||||
|
<field name="name">Configure News</field> |
||||
|
<field name="res_model">news.channel.config.settings</field> |
||||
|
<field name="view_mode">form</field> |
||||
|
<field name="target">inline</field> |
||||
|
</record> |
||||
|
<menuitem id="menu_news_configuration" name="Configurations" parent="news"/> |
||||
|
<menuitem id="menu_news_channel_config" name="Settings" |
||||
|
parent="menu_news_configuration" sequence="0" action="action_news_configuration" |
||||
|
groups="base.group_system"/> |
||||
|
</data> |
||||
|
</odoo> |
@ -0,0 +1,22 @@ |
|||||
|
<openerp> |
||||
|
<data> |
||||
|
<!-- <template id="listing"> --> |
||||
|
<!-- <ul> --> |
||||
|
<!-- <li t-foreach="objects" t-as="object"> --> |
||||
|
<!-- <a t-attf-href="#{ root }/objects/#{ object.id }"> --> |
||||
|
<!-- <t t-esc="object.display_name"/> --> |
||||
|
<!-- </a> --> |
||||
|
<!-- </li> --> |
||||
|
<!-- </ul> --> |
||||
|
<!-- </template> --> |
||||
|
<!-- <template id="object"> --> |
||||
|
<!-- <h1><t t-esc="object.display_name"/></h1> --> |
||||
|
<!-- <dl> --> |
||||
|
<!-- <t t-foreach="object._fields" t-as="field"> --> |
||||
|
<!-- <dt><t t-esc="field"/></dt> --> |
||||
|
<!-- <dd><t t-esc="object[field]"/></dd> --> |
||||
|
<!-- </t> --> |
||||
|
<!-- </dl> --> |
||||
|
<!-- </template> --> |
||||
|
</data> |
||||
|
</openerp> |