From 971d5aa57c86319f91579525040382ae130e9ed8 Mon Sep 17 00:00:00 2001 From: BizzAppDev Date: Thu, 6 Dec 2018 20:46:50 +0530 Subject: [PATCH] Sort by Download and rating (#46) * [WIP] added initial support for Google recaptcha * [WIP]added dependencies * [IMP]Added google captcha with download functionality with reset and validation * [IMP]added download count fields and increament it when donwloaded * [ADD]added missing files * [IMP]website_apps_store: add sort by download count on website * remove console and not extra space * [VER]changed version number * [FIX]website_apps_store: fix test case error * [FIX]reset only if google recaptcha is initiated --- website_apps_store/__manifest__.py | 3 +- website_apps_store/controllers/main.py | 41 +++++++++++++------ .../i18n/website_apps_store.pot | 26 ++++++++++++ website_apps_store/models/__init__.py | 1 + website_apps_store/models/product.py | 19 ++------- website_apps_store/models/product_template.py | 31 ++++++++++++++ .../static/src/js/website_sale.js | 37 ++++++++++++----- website_apps_store/views/templates.xml | 23 ++++++++++- 8 files changed, 140 insertions(+), 41 deletions(-) create mode 100644 website_apps_store/models/product_template.py diff --git a/website_apps_store/__manifest__.py b/website_apps_store/__manifest__.py index f67ebdc..9aa721b 100644 --- a/website_apps_store/__manifest__.py +++ b/website_apps_store/__manifest__.py @@ -2,13 +2,14 @@ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). { "name": "Website Apps Store", - "version": "11.0.2.2.0", + "version": "11.0.3.0.0", 'author': 'Odoo Community Association (OCA), BizzAppDev', "website": "https://github.com/OCA/apps-store", "license": "AGPL-3", "category": "Sales", "depends": [ 'website_sale', + 'website_form_recaptcha', 'apps_download', 'apps_product_creator', ], diff --git a/website_apps_store/controllers/main.py b/website_apps_store/controllers/main.py index ec2c385..08aecc1 100644 --- a/website_apps_store/controllers/main.py +++ b/website_apps_store/controllers/main.py @@ -9,6 +9,7 @@ from odoo.addons.http_routing.models.ir_http import slug from odoo.addons.website.controllers.main import QueryURL from odoo.addons.website_sale.controllers.main import WebsiteSale, TableCompute +from odoo.exceptions import ValidationError _logger = logging.getLogger(__name__) @@ -168,22 +169,34 @@ def change_product_attribute_version(self, **kwargs): } return vals - @http.route('/shop/cart/download_source', type='json', - auth="public", website=True) - def download_source_product(self, **kwargs): - product_id = kwargs.get('product_id', False) - tmpl_id = kwargs.get('product_template_id', False) - product = request.env['product.product'].sudo().browse(product_id) - if not product: - product_tmpl = request.env['product.template'].sudo().browse( - tmpl_id) - product = product_tmpl.get_version_info() - return product.id + def validate_recaptcha(self, captcha): + """ Function for validating Recaptcha """ + captcha_obj = request.env['website.form.recaptcha'] + ip_addr = request.httprequest.environ.get('HTTP_X_FORWARDED_FOR') + if ip_addr: + ip_addr = ip_addr.split(',')[0] + else: + ip_addr = request.httprequest.remote_addr + try: + captcha_obj.action_validate( + captcha, ip_addr + ) + except ValidationError: + raise ValidationError([captcha_obj.RESPONSE_ATTR]) @http.route( - '/shop/download_product_zip/', + ['/shop/download_product_zip/' + '//' + '', + '/shop/download_product_zip//' + ''], type='http', auth="public", website=True) - def download_product_zip(self, product, **kwargs): + def download_product_zip(self, product_tmpl, product=False, + google_captcha='', **kwargs): + self.validate_recaptcha(google_captcha) + if not product: + product = product_tmpl.get_version_info() + attachment = request.env['ir.attachment'].sudo().search([ ('res_id', '=', product.id), ('res_model', '=', product._name), @@ -198,6 +211,8 @@ def download_product_zip(self, product, **kwargs): if attachment: filecontent = base64.b64decode(attachment.datas) disposition = 'attachment; filename="%s"' % attachment.datas_fname + # increasing count for the product download + product.download_count = product.download_count + 1 return request.make_response( filecontent, [('Content-Type', 'application/zip, application/octet-stream'), diff --git a/website_apps_store/i18n/website_apps_store.pot b/website_apps_store/i18n/website_apps_store.pot index cf3979b..a1dcb48 100644 --- a/website_apps_store/i18n/website_apps_store.pot +++ b/website_apps_store/i18n/website_apps_store.pot @@ -81,6 +81,21 @@ msgid "Download\n" " " msgstr "" +#. module: website_apps_store +#: model:ir.model.fields,field_description:website_apps_store.field_product_product_download_count +msgid "Download Count" +msgstr "" + +#. module: website_apps_store +#: model:ir.ui.view,arch_db:website_apps_store.sort_customize +msgid "Download Count - Max to Min" +msgstr "" + +#. module: website_apps_store +#: model:ir.ui.view,arch_db:website_apps_store.sort_customize +msgid "Download Count - Min to Max" +msgstr "" + #. module: website_apps_store #: model:ir.ui.view,arch_db:website_apps_store.maturity_display msgid "Mature" @@ -96,6 +111,11 @@ msgstr "" msgid "Name, Author, Version..." msgstr "" +#. module: website_apps_store +#: model:ir.model,name:website_apps_store.model_product_product +msgid "Product" +msgstr "" + #. module: website_apps_store #: model:ir.ui.view,arch_db:website_apps_store.product msgid "Product Name" @@ -111,6 +131,12 @@ msgstr "" msgid "Production/Stable" msgstr "" +#. module: website_apps_store +#: model:ir.model.fields,field_description:website_apps_store.field_product_product_total_download_count +#: model:ir.model.fields,field_description:website_apps_store.field_product_template_total_download_count +msgid "Total Download Count" +msgstr "" + #. module: website_apps_store #: model:ir.ui.view,arch_db:website_apps_store.version_display msgid "Version :" diff --git a/website_apps_store/models/__init__.py b/website_apps_store/models/__init__.py index 9649db7..6a7d91c 100644 --- a/website_apps_store/models/__init__.py +++ b/website_apps_store/models/__init__.py @@ -1 +1,2 @@ from . import product +from . import product_template diff --git a/website_apps_store/models/product.py b/website_apps_store/models/product.py index c7fc2d7..8631ff6 100644 --- a/website_apps_store/models/product.py +++ b/website_apps_store/models/product.py @@ -1,21 +1,10 @@ # Copyright (C) 2017-Today: Odoo Community Association (OCA) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from odoo import models +from odoo import models, fields -class ProductTemplate(models.Model): - _inherit = 'product.template' +class ProductProduct(models.Model): + _inherit = 'product.product' - def get_author_details(self): - author_ids = [] - for variant in self.product_variant_ids: - for author in variant.app_author_ids: - if author not in author_ids: - author_ids.append(author) - return author_ids - - def get_version_info(self): - products = self.product_variant_ids.sorted( - lambda a: a.attribute_value_ids.sequence, reverse=True) - return products[0] + download_count = fields.Integer() diff --git a/website_apps_store/models/product_template.py b/website_apps_store/models/product_template.py new file mode 100644 index 0000000..6683e0b --- /dev/null +++ b/website_apps_store/models/product_template.py @@ -0,0 +1,31 @@ +# Copyright (C) 2017-Today: Odoo Community Association (OCA) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import models, fields, api + + +class ProductTemplate(models.Model): + _inherit = 'product.template' + + @api.multi + @api.depends('product_variant_ids', 'product_variant_ids.download_count') + def _compute_total_download_count(self): + for product in self: + product.total_download_count = sum( + product.mapped('product_variant_ids.download_count')) + + total_download_count = fields.Integer( + compute="_compute_total_download_count", store=True) + + def get_author_details(self): + author_ids = [] + for variant in self.product_variant_ids: + for author in variant.app_author_ids: + if author not in author_ids: + author_ids.append(author) + return author_ids + + def get_version_info(self): + products = self.product_variant_ids.sorted( + lambda a: a.attribute_value_ids.sequence, reverse=True) + return products[0] diff --git a/website_apps_store/static/src/js/website_sale.js b/website_apps_store/static/src/js/website_sale.js index c23f045..4d40602 100644 --- a/website_apps_store/static/src/js/website_sale.js +++ b/website_apps_store/static/src/js/website_sale.js @@ -15,6 +15,7 @@ odoo.define('website_apps_store.website_sale', function (require) { require("website.content.zoomodoo"); var _t = core._t; + $('.oe_website_sale').each(function () { var oe_website_sale = this; var $product_global; @@ -31,6 +32,7 @@ odoo.define('website_apps_store.website_sale', function (require) { return formatted.join(l10n.decimal_point); } + function update_product_image(event_source, product_id) { var $img; if ($('#o-carousel-product').length) { @@ -155,16 +157,31 @@ odoo.define('website_apps_store.website_sale', function (require) { }); $('#download_zip').on('click', function(ev){ - var product_template_id = $(this).data('tmpl-id'); - - ajax.jsonRpc("/shop/cart/download_source", 'call', { - 'product_id': $product_global, - 'product_template_id': product_template_id, - }).then(function (data) { - if(data){ - window.location.href = "/shop/download_product_zip/" + data; - } - }); + var product_template_id = $(this).data('tmpl-id'); + event.preventDefault(); + var google_captcha = $('#g-recaptcha-response').val(); + if (!google_captcha) + return ; + if (grecaptcha !== 'undefined'){ + grecaptcha.reset(); + } + if ($product_global){ + window.location.href = "/shop/download_product_zip/" + product_template_id + '/' + $product_global + '/' + google_captcha; + }else{ + window.location.href = "/shop/download_product_zip/" + product_template_id + '/' + google_captcha; + } }); + var $captchas = $('.o_website_form_recaptcha'); + ajax.post('/website/recaptcha/', {}).then( + function (result) { + var data = JSON.parse(result); + $captchas.append($( + '
' + )); + if ($captchas.length) { + $.getScript('https://www.google.com/recaptcha/api.js'); + } + } + ); }); }); diff --git a/website_apps_store/views/templates.xml b/website_apps_store/views/templates.xml index 46e1677..5609214 100644 --- a/website_apps_store/views/templates.xml +++ b/website_apps_store/views/templates.xml @@ -96,10 +96,16 @@ + + Download Count - Max to Min + Download Count - Min to Max + @@ -129,6 +135,13 @@ + + +
+ + +
+ @@ -180,7 +193,13 @@ name_product - + +
+
+ +
+