From 62d202d2599da47d1934ad8d190cee825f20ebe3 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Wed, 9 Jan 2013 13:33:57 +0100 Subject: [PATCH 01/22] [FIX] linkedin: display a button to connect on linkedin if there are an error of connected linkedin module bzr revid: chm@openerp.com-20130109123357-2e2ogcy510ctqk8q --- .../web_linkedin/static/src/css/linkedin.css | 10 +++++++ addons/web_linkedin/static/src/js/linkedin.js | 28 ++++++++++++++++++- .../web_linkedin/static/src/xml/linkedin.xml | 14 ++++++---- 3 files changed, 46 insertions(+), 6 deletions(-) diff --git a/addons/web_linkedin/static/src/css/linkedin.css b/addons/web_linkedin/static/src/css/linkedin.css index 992dc48aeb8..d6e8dc5067b 100644 --- a/addons/web_linkedin/static/src/css/linkedin.css +++ b/addons/web_linkedin/static/src/css/linkedin.css @@ -42,3 +42,13 @@ color: grey; margin-bottom: 10px; } + +.openerp .oe_social_network_login { + margin-bottom: 10px; +} + +.openerp .oe_social_network_login .oe_error { + display: none; + cursor: pointer; +} + diff --git a/addons/web_linkedin/static/src/js/linkedin.js b/addons/web_linkedin/static/src/js/linkedin.js index d6237e48d51..8fca845673a 100644 --- a/addons/web_linkedin/static/src/js/linkedin.js +++ b/addons/web_linkedin/static/src/js/linkedin.js @@ -6,6 +6,13 @@ openerp.web_linkedin = function(instance) { var QWeb = instance.web.qweb; var _t = instance.web._t; + openerp.web_linkedin.onLinkedInAuth = function () { + IN.API.Profile("me") + .result( function(me) { + console.log("me", me); + }); + }; + instance.web_linkedin.LinkedinTester = instance.web.Class.extend({ init: function() { this.linkedin_added = false; @@ -15,8 +22,12 @@ openerp.web_linkedin = function(instance) { test_linkedin: function() { var self = this; return this.test_api_key().then(function() { - if (self.linkedin_added) + if (self.linkedin_added) { + if (IN.User.isAuthorized()) { + self.auth_def.resolve(); + } return self.linkedin_def.promise(); + } var tag = document.createElement('script'); tag.type = 'text/javascript'; tag.src = "http://platform.linkedin.com/in.js"; @@ -178,6 +189,7 @@ openerp.web_linkedin = function(instance) { instance.web_linkedin.LinkedinPopup = instance.web.Dialog.extend({ template: "Linkedin.popup", init: function(parent, text) { + var self = this; this._super(parent, {title:_t("LinkedIn search")}); this.text = text; this.limit = 5; @@ -189,6 +201,20 @@ openerp.web_linkedin = function(instance) { instance.web_linkedin.tester.test_authentication().done(function() { self.trigger("authentified"); }); + + this.bind_error(); + }, + bind_error: function() { + var self = this; + this.error_message = window.setTimeout(function() {self.$(".oe_social_network_login .oe_error").show();}, 500); + this.$el.on("DOMNodeInserted", function (e) { + self.$el.off("DOMNodeInserted"); + window.clearTimeout(self.error_message); + self.$(".oe_social_network_login .oe_error").hide(); + }); + this.$(".oe_social_network_login .oe_error").click(function () { + IN.User.authorize(); + }); }, authentified: function() { var self = this; diff --git a/addons/web_linkedin/static/src/xml/linkedin.xml b/addons/web_linkedin/static/src/xml/linkedin.xml index 4956fd7df5a..6230ef894fd 100644 --- a/addons/web_linkedin/static/src/xml/linkedin.xml +++ b/addons/web_linkedin/static/src/xml/linkedin.xml @@ -8,12 +8,16 @@
- -

People

-
+ +

People

+

Companies

-
+
From 60d2a36fed2aec1c876efca6bba3fab65ec136c2 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Wed, 9 Jan 2013 16:51:25 +0100 Subject: [PATCH 02/22] [IMP] linkedin: search for user company and location bzr revid: chm@openerp.com-20130109155125-ikx26yyo5gro9p22 --- .../web_linkedin/static/src/css/linkedin.css | 2 +- addons/web_linkedin/static/src/js/linkedin.js | 66 +++++++++++++------ .../web_linkedin/static/src/xml/linkedin.xml | 7 +- 3 files changed, 50 insertions(+), 25 deletions(-) diff --git a/addons/web_linkedin/static/src/css/linkedin.css b/addons/web_linkedin/static/src/css/linkedin.css index d6e8dc5067b..e251d8eca83 100644 --- a/addons/web_linkedin/static/src/css/linkedin.css +++ b/addons/web_linkedin/static/src/css/linkedin.css @@ -47,7 +47,7 @@ margin-bottom: 10px; } -.openerp .oe_social_network_login .oe_error { +.openerp .oe_social_network_login .oe_linkedin_error { display: none; cursor: pointer; } diff --git a/addons/web_linkedin/static/src/js/linkedin.js b/addons/web_linkedin/static/src/js/linkedin.js index 8fca845673a..12937473f7f 100644 --- a/addons/web_linkedin/static/src/js/linkedin.js +++ b/addons/web_linkedin/static/src/js/linkedin.js @@ -6,13 +6,6 @@ openerp.web_linkedin = function(instance) { var QWeb = instance.web.qweb; var _t = instance.web._t; - openerp.web_linkedin.onLinkedInAuth = function () { - IN.API.Profile("me") - .result( function(me) { - console.log("me", me); - }); - }; - instance.web_linkedin.LinkedinTester = instance.web.Class.extend({ init: function() { this.linkedin_added = false; @@ -31,7 +24,7 @@ openerp.web_linkedin = function(instance) { var tag = document.createElement('script'); tag.type = 'text/javascript'; tag.src = "http://platform.linkedin.com/in.js"; - tag.innerHTML = 'api_key : ' + self.api_key + '\nauthorize : true\nscope: r_network r_contactinfo'; + tag.innerHTML = 'api_key : ' + self.api_key + '\nauthorize : true\nscope: r_network r_contactinfo r_fullprofile r_emailaddress'; document.getElementsByTagName('head')[0].appendChild(tag); self.linkedin_added = true; $(tag).load(function() { @@ -146,9 +139,8 @@ openerp.web_linkedin = function(instance) { }, function() { return $.when(); })); - /* TODO + to_change.linkedinUrl = _.str.sprintf("http://www.linkedin.com/company/%d", entity.id); - */ } else { // people to_change.is_company = false; to_change.name = entity.formattedName; @@ -169,10 +161,27 @@ openerp.web_linkedin = function(instance) { } }); var positions = (entity.positions || {}).values || []; - to_change.function = positions.length > 0 ? positions[0].title : false; - /* TODO + if (positions.length && positions[0].isCurrent) { + to_change.function = positions[0].title; + var company_name = positions[0].company ? positions[0].company.name : false; + if (company_name) { + defs.push(new instance.web.DataSetSearch(this, 'res.partner').call("search", [[["name", "=", company_name]]]).then(function (data) { + to_change.parent_id = data[0] || false; + })); + } + } + to_change.linkedinUrl = entity.publicProfileUrl; - */ + to_change.linkedinId = entity.id; + to_change.linkedinId = entity.id; + var country_code = (entity.location && entity.location.country && entity.location.country.code) || false; + if (country_code) { + defs.push(new instance.web.DataSetSearch(this, 'res.country').call("search", [[["code", "=", country_code.toUpperCase()]]]).then(function (data) { + to_change.country_id = data[0] || false; + })); + } + to_change.comment = entity.summary; + } return $.when.apply($, defs).then(function() { return to_change; @@ -184,7 +193,10 @@ openerp.web_linkedin = function(instance) { var commonPeopleFields = ["id", "picture-url", "public-profile-url", "formatted-name", "location", "phone-numbers", "im-accounts", - "main-address", "headline", "positions"]; + "main-address", "headline", "positions", "summary", "specialties", + "email-address", + "languages", "skills", "certifications", "educations", "three-current-positions", "three-past-positions", + "date-of-birth", "twitter-accounts"]; instance.web_linkedin.LinkedinPopup = instance.web.Dialog.extend({ template: "Linkedin.popup", @@ -197,27 +209,39 @@ openerp.web_linkedin = function(instance) { start: function() { this._super(); var self = this; + this.$network = this.$(".oe_social_network_login"); this.on("authentified", this, this.authentified); + this.init_authentified(); + }, + init_authentified: function() { + var self = this; instance.web_linkedin.tester.test_authentication().done(function() { self.trigger("authentified"); }); - - this.bind_error(); - }, - bind_error: function() { - var self = this; + // if there are an error on loading add a button to open the linkedin session this.error_message = window.setTimeout(function() {self.$(".oe_social_network_login .oe_error").show();}, 500); this.$el.on("DOMNodeInserted", function (e) { self.$el.off("DOMNodeInserted"); window.clearTimeout(self.error_message); - self.$(".oe_social_network_login .oe_error").hide(); + self.$network.find(".oe_error").hide(); }); - this.$(".oe_social_network_login .oe_error").click(function () { + this.$network.find(".oe_error").click(function () { IN.User.authorize(); }); + this.$network.on("click", ".oe_linkedin_logout", function () { + IN.User.logout(); + self.$(".oe_linkedin_pop_p, .oe_linkedin_pop_c").empty(); + self.$network.find(".oe_linkedin_login").remove(); + }); }, authentified: function() { var self = this; + IN.API.Profile("me") + .fields(["firstName", "lastName"]) + .result(function (result) { + $(QWeb.render('LinkedIn.loginInformation', result.values[0])).appendTo(self.$network); + }) + cdef = $.Deferred(); pdef = $.Deferred(); IN.API.Raw(_.str.sprintf( diff --git a/addons/web_linkedin/static/src/xml/linkedin.xml b/addons/web_linkedin/static/src/xml/linkedin.xml index 6230ef894fd..1fa1a8edcd2 100644 --- a/addons/web_linkedin/static/src/xml/linkedin.xml +++ b/addons/web_linkedin/static/src/xml/linkedin.xml @@ -9,9 +9,7 @@

People

@@ -37,4 +35,7 @@ Please ask your administrator to configure it in Settings > Configuration > Sales > Social Network Integration.
+ + + \ No newline at end of file From 00cdc2227cecf88400b6654b73435b82cb30e66f Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Thu, 10 Jan 2013 15:03:45 +0100 Subject: [PATCH 03/22] [IMP] linkedin: fix bug off connection and improve LinkedinTester widget bzr revid: chm@openerp.com-20130110140345-79hv4urkv9zkgw77 --- .../web_linkedin/static/src/css/linkedin.css | 11 +- addons/web_linkedin/static/src/js/linkedin.js | 155 +++++++++++------- .../web_linkedin/static/src/xml/linkedin.xml | 8 +- addons/web_linkedin/web_linkedin.py | 5 + 4 files changed, 102 insertions(+), 77 deletions(-) diff --git a/addons/web_linkedin/static/src/css/linkedin.css b/addons/web_linkedin/static/src/css/linkedin.css index e251d8eca83..1185403e43a 100644 --- a/addons/web_linkedin/static/src/css/linkedin.css +++ b/addons/web_linkedin/static/src/css/linkedin.css @@ -43,12 +43,7 @@ margin-bottom: 10px; } -.openerp .oe_social_network_login { - margin-bottom: 10px; +.openerp .oe_linkedin_authentified { + font-size: 11px; + text-align: center; } - -.openerp .oe_social_network_login .oe_linkedin_error { - display: none; - cursor: pointer; -} - diff --git a/addons/web_linkedin/static/src/js/linkedin.js b/addons/web_linkedin/static/src/js/linkedin.js index 12937473f7f..e2ace2732ed 100644 --- a/addons/web_linkedin/static/src/js/linkedin.js +++ b/addons/web_linkedin/static/src/js/linkedin.js @@ -6,6 +6,13 @@ openerp.web_linkedin = function(instance) { var QWeb = instance.web.qweb; var _t = instance.web._t; + /* + * instance.web_linkedin.tester.test_authentication() + * Call check if the Linkedin session is open or open a connection popup + * return a deferrer : + * - resolve if the authentication is true + * - reject if the authentication is wrong or when the user logout + */ instance.web_linkedin.LinkedinTester = instance.web.Class.extend({ init: function() { this.linkedin_added = false; @@ -19,8 +26,17 @@ openerp.web_linkedin = function(instance) { if (IN.User.isAuthorized()) { self.auth_def.resolve(); } - return self.linkedin_def.promise(); + return self.linkedin_def.resolve(); } + + $login = $(''); + $login.appendTo("body"); + $login.on("DOMNodeInserted", function (e) { + $login.off("DOMNodeInserted"); + self.linkedin_def.resolve(); + console.debug("LinkedIn DOM node is inserted."); + }); + var tag = document.createElement('script'); tag.type = 'text/javascript'; tag.src = "http://platform.linkedin.com/in.js"; @@ -31,7 +47,10 @@ openerp.web_linkedin = function(instance) { IN.Event.on(IN, "auth", function() { self.auth_def.resolve(); }); - self.linkedin_def.resolve(); + IN.Event.on(IN, "logout", function() { + self.auth_def.reject(); + //self.auth_def = $.Deferred(); + }); }); return self.linkedin_def.promise(); }); @@ -51,6 +70,9 @@ openerp.web_linkedin = function(instance) { }); }, test_authentication: function() { + this.linkedin_def.done(function () { + IN.User.authorize(); + }); return this.auth_def.promise(); }, }); @@ -74,11 +96,18 @@ openerp.web_linkedin = function(instance) { search_linkedin: function() { var self = this; this.display_dm.add(instance.web_linkedin.tester.test_linkedin()).done(function() { - var pop = new instance.web_linkedin.LinkedinPopup(self, self.get("value")); - pop.open(); - pop.on("selected", this, function(entity) { - self.selected_entity(entity); - }); + var text = (self.get("value") || "").replace(/^\s+|\s+$/g, "").replace(/\s+/g, " "); + if (text !== "") { + instance.web_linkedin.tester.test_authentication().done(function() { + var pop = new instance.web_linkedin.LinkedinPopup(self, self.get("value")); + pop.open(); + pop.on("selected", this, function(entity) { + self.selected_entity(entity); + }); + }); + } else { + self.focus(); + } }).fail(_.bind(this.linkedin_disabled, this)); }, linkedin_disabled: function() { @@ -202,87 +231,87 @@ openerp.web_linkedin = function(instance) { template: "Linkedin.popup", init: function(parent, text) { var self = this; - this._super(parent, {title:_t("LinkedIn search")}); + if (!IN.User.isAuthorized()) { + this.destroy(); + } + this._super(parent, { 'title':_t("LinkedIn search")}); this.text = text; this.limit = 5; }, start: function() { this._super(); var self = this; - this.$network = this.$(".oe_social_network_login"); - this.on("authentified", this, this.authentified); - this.init_authentified(); - }, - init_authentified: function() { - var self = this; - instance.web_linkedin.tester.test_authentication().done(function() { - self.trigger("authentified"); - }); - // if there are an error on loading add a button to open the linkedin session - this.error_message = window.setTimeout(function() {self.$(".oe_social_network_login .oe_error").show();}, 500); - this.$el.on("DOMNodeInserted", function (e) { - self.$el.off("DOMNodeInserted"); - window.clearTimeout(self.error_message); - self.$network.find(".oe_error").hide(); - }); - this.$network.find(".oe_error").click(function () { - IN.User.authorize(); - }); - this.$network.on("click", ".oe_linkedin_logout", function () { + self.$el.parent().on("click", ".oe_linkedin_logout", function () { IN.User.logout(); - self.$(".oe_linkedin_pop_p, .oe_linkedin_pop_c").empty(); - self.$network.find(".oe_linkedin_login").remove(); + self.destroy(); }); + this.display_linkedin_account(); + this.do_search(); }, - authentified: function() { + display_linkedin_account: function() { var self = this; IN.API.Profile("me") .fields(["firstName", "lastName"]) .result(function (result) { - $(QWeb.render('LinkedIn.loginInformation', result.values[0])).appendTo(self.$network); + $(QWeb.render('LinkedIn.loginInformation', result.values[0])).appendTo(self.$el.parent().find(".ui-dialog-buttonpane")); }) - - cdef = $.Deferred(); - pdef = $.Deferred(); + }, + do_search: function() { + var self = this; + var deferrers = []; + var deferrer = $.Deferred(); + deferrers.push(deferrer); IN.API.Raw(_.str.sprintf( "company-search:(companies:" + "(id,name,logo-url,description,industry,website-url,locations))?keywords=%s&count=%d", encodeURI(this.text), this.limit)).result(function (result) { - cdef.resolve(result); - }); - var def = cdef.then(function(companies) { - var lst = companies.companies.values || []; - lst = _.first(lst, self.limit); - lst = _.map(lst, function(el) { - el.__type = "company"; - return el; - }); - console.debug("Linkedin companies found:", lst.length, lst); - return self.display_result(lst, self.$(".oe_linkedin_pop_c")); + self.do_result_companies(result); + deferrer.resolve(); }); + var deferrer = $.Deferred(); + deferrers.push(deferrer); IN.API.PeopleSearch().fields(commonPeopleFields). - params({"keywords": this.text, "count": this.limit}).result(function(result) { - pdef.resolve(result); + params({"keywords": this.text, "facet": ["network,F,S,A,O"], "count": this.limit}).result(function(result) { + self.do_result_people(result); + deferrer.resolve(); }); - var def2 = pdef.then(function(people) { - var plst = people.people.values || []; - plst = _.first(plst, self.limit); - plst = _.map(plst, function(el) { - el.__type = "people"; - return el; - }); - console.debug("Linkedin people found:", plst.length, plst); - return self.display_result(plst, self.$(".oe_linkedin_pop_p")); + // new search for pass the restriction on LinkedIn (2012: search only on first and second level if it's not the last-name and first-name search) + var deferrer = $.Deferred(); + deferrers.push(deferrer); + IN.API.PeopleSearch().fields(commonPeopleFields). + params({"first-name": this.text.split(' ')[0], "last-name": this.text.split(' ').slice(1).join(' '), "facet": ["network,F,S,A,O"], "count": this.limit}).result(function(result) { + self.do_result_people(result); + deferrer.resolve(); }); - return $.when(def, def2); + return $.when.apply($, deferrers); + }, + do_result_companies: function(companies) { + var lst = companies.companies.values || []; + lst = _.first(lst, this.limit); + lst = _.map(lst, function(el) { + el.__type = "company"; + return el; + }); + console.debug("Linkedin companies found:", companies.companies._total, '=>', lst.length, lst); + return this.display_result(lst, this.$(".oe_linkedin_pop_c")); + }, + do_result_people: function(people) { + var plst = people.people.values || []; + plst = _.first(plst, this.limit); + plst = _.map(plst, function(el) { + el.__type = "people"; + return el; + }); + console.debug("Linkedin people found:", people.numResults, '=>', plst.length, plst); + return this.display_result(plst, this.$(".oe_linkedin_pop_p")); }, display_result: function(result, $elem) { var self = this; - var i = 0; var $row; + $elem.find(".oe_no_result").remove(); _.each(result, function(el) { var pc = new instance.web_linkedin.EntityWidget(self, el); - if (i % 5 === 0) { + if (!$elem.find("div").size() || $elem.find(" > div:last > div").size() >= 5) { $row = $("
"); $row.appendTo($elem); } @@ -293,12 +322,12 @@ openerp.web_linkedin = function(instance) { self.trigger("selected", data); self.destroy(); }); - i++; }); - if (result.length === 0) { - $elem.text(_t("No results found")); + if (!$elem.find("div").size()) { + $elem.append($('
').text(_t("No results found"))); } }, + }); instance.web_linkedin.EntityWidget = instance.web.Widget.extend({ diff --git a/addons/web_linkedin/static/src/xml/linkedin.xml b/addons/web_linkedin/static/src/xml/linkedin.xml index 1fa1a8edcd2..4460c6de752 100644 --- a/addons/web_linkedin/static/src/xml/linkedin.xml +++ b/addons/web_linkedin/static/src/xml/linkedin.xml @@ -8,11 +8,7 @@
- -

People

+

People

Companies

@@ -36,6 +32,6 @@
- +
If " " is not your account on LinkedIn, please click here to logout LinkedIn.
\ No newline at end of file diff --git a/addons/web_linkedin/web_linkedin.py b/addons/web_linkedin/web_linkedin.py index dc429cd2f29..1296bb7aa28 100644 --- a/addons/web_linkedin/web_linkedin.py +++ b/addons/web_linkedin/web_linkedin.py @@ -49,3 +49,8 @@ class web_linkedin_settings(osv.osv_memory): key = self.browse(cr, uid, ids[0], context)["api_key"] or "" self.pool.get("ir.config_parameter").set_param(cr, uid, "web.linkedin.apikey", key) +class web_linkedin_fields(osv.osv_memory): + _inherit = 'res.partner' + _columns = { + 'linkedin_id': fields.char(string="LinkedIn ID", size=50), + } \ No newline at end of file From 09b2527ddb1a9ee30779a382f550ac3440cdae29 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Fri, 11 Jan 2013 14:24:38 +0100 Subject: [PATCH 04/22] [IMP] linkedin: improve the popup of linkedin search bzr revid: chm@openerp.com-20130111132438-cvoomovagqcvukvq --- .../web_linkedin/static/src/css/linkedin.css | 15 ++ addons/web_linkedin/static/src/js/linkedin.js | 151 +++++++++++------- .../web_linkedin/static/src/xml/linkedin.xml | 5 + 3 files changed, 115 insertions(+), 56 deletions(-) diff --git a/addons/web_linkedin/static/src/css/linkedin.css b/addons/web_linkedin/static/src/css/linkedin.css index 1185403e43a..6396c5c3e5b 100644 --- a/addons/web_linkedin/static/src/css/linkedin.css +++ b/addons/web_linkedin/static/src/css/linkedin.css @@ -35,6 +35,7 @@ } .openerp .oe_linkedin_entity h3 { + margin-top: 5px; margin-bottom: 5px; } @@ -47,3 +48,17 @@ font-size: 11px; text-align: center; } + +.openerp .oe_linkedin_advanced_search { + margin: auto; + position: absolute; + right: 60px; + top: 16px; + line-height: 12px; + font-size: 12px; +} + +.openerp .oe_linkedin_advanced_search button { + line-height: 12px; + font-size: 12px; +} diff --git a/addons/web_linkedin/static/src/js/linkedin.js b/addons/web_linkedin/static/src/js/linkedin.js index e2ace2732ed..8ac5ce22453 100644 --- a/addons/web_linkedin/static/src/js/linkedin.js +++ b/addons/web_linkedin/static/src/js/linkedin.js @@ -23,9 +23,6 @@ openerp.web_linkedin = function(instance) { var self = this; return this.test_api_key().then(function() { if (self.linkedin_added) { - if (IN.User.isAuthorized()) { - self.auth_def.resolve(); - } return self.linkedin_def.resolve(); } @@ -40,7 +37,7 @@ openerp.web_linkedin = function(instance) { var tag = document.createElement('script'); tag.type = 'text/javascript'; tag.src = "http://platform.linkedin.com/in.js"; - tag.innerHTML = 'api_key : ' + self.api_key + '\nauthorize : true\nscope: r_network r_contactinfo r_fullprofile r_emailaddress'; + tag.innerHTML = 'api_key : ' + self.api_key + '\nauthorize : true\nscope: r_network r_basicprofile'; // r_contactinfo r_fullprofile r_emailaddress'; document.getElementsByTagName('head')[0].appendChild(tag); self.linkedin_added = true; $(tag).load(function() { @@ -49,7 +46,7 @@ openerp.web_linkedin = function(instance) { }); IN.Event.on(IN, "logout", function() { self.auth_def.reject(); - //self.auth_def = $.Deferred(); + self.auth_def = $.Deferred(); }); }); return self.linkedin_def.promise(); @@ -70,8 +67,13 @@ openerp.web_linkedin = function(instance) { }); }, test_authentication: function() { + var self = this; this.linkedin_def.done(function () { - IN.User.authorize(); + if (IN.User.isAuthorized()) { + self.auth_def.resolve(); + } else { + IN.User.authorize(); + } }); return this.auth_def.promise(); }, @@ -91,23 +93,18 @@ openerp.web_linkedin = function(instance) { this.$(".oe_linkedin_input").append($in); this.$(".oe_linkedin_img").click(_.bind(this.search_linkedin, this)); this._super(); - }, search_linkedin: function() { var self = this; this.display_dm.add(instance.web_linkedin.tester.test_linkedin()).done(function() { var text = (self.get("value") || "").replace(/^\s+|\s+$/g, "").replace(/\s+/g, " "); - if (text !== "") { - instance.web_linkedin.tester.test_authentication().done(function() { - var pop = new instance.web_linkedin.LinkedinPopup(self, self.get("value")); - pop.open(); - pop.on("selected", this, function(entity) { - self.selected_entity(entity); - }); + instance.web_linkedin.tester.test_authentication().done(function() { + var pop = new instance.web_linkedin.LinkedinSearchPopup(self, text); + pop.open(); + pop.on("selected", this, function(entity) { + self.selected_entity(entity); }); - } else { - self.focus(); - } + }); }).fail(_.bind(this.linkedin_disabled, this)); }, linkedin_disabled: function() { @@ -200,16 +197,9 @@ openerp.web_linkedin = function(instance) { } } - to_change.linkedinUrl = entity.publicProfileUrl; - to_change.linkedinId = entity.id; - to_change.linkedinId = entity.id; - var country_code = (entity.location && entity.location.country && entity.location.country.code) || false; - if (country_code) { - defs.push(new instance.web.DataSetSearch(this, 'res.country').call("search", [[["code", "=", country_code.toUpperCase()]]]).then(function (data) { - to_change.country_id = data[0] || false; - })); - } - to_change.comment = entity.summary; + to_change.linkedinUrl = entity.publicProfileUrl || false; + to_change.linkedinId = entity.id || false; + to_change.comment = entity.summary || false; } return $.when.apply($, defs).then(function() { @@ -222,31 +212,49 @@ openerp.web_linkedin = function(instance) { var commonPeopleFields = ["id", "picture-url", "public-profile-url", "formatted-name", "location", "phone-numbers", "im-accounts", - "main-address", "headline", "positions", "summary", "specialties", - "email-address", - "languages", "skills", "certifications", "educations", "three-current-positions", "three-past-positions", - "date-of-birth", "twitter-accounts"]; + "main-address", "headline", "positions", "summary", "specialties"]; - instance.web_linkedin.LinkedinPopup = instance.web.Dialog.extend({ + instance.web_linkedin.LinkedinSearchPopup = instance.web.Dialog.extend({ template: "Linkedin.popup", init: function(parent, text) { var self = this; if (!IN.User.isAuthorized()) { + this.$buttons = $("
"); this.destroy(); } - this._super(parent, { 'title':_t("LinkedIn search")}); + this._super(parent, { 'title':_t("LinkedIn search") + ''}); this.text = text; this.limit = 5; }, start: function() { this._super(); + this.bind_event(); + this.display_linkedin_account(); + this.do_search(); + }, + bind_event: function() { var self = this; - self.$el.parent().on("click", ".oe_linkedin_logout", function () { + this.$el.parent().on("click", ".oe_linkedin_logout", function () { IN.User.logout(); self.destroy(); }); - this.display_linkedin_account(); - this.do_search(); + this.$search = this.$el.parent().find(".oe_linkedin_advanced_search" ); + this.$url = this.$search.find("input[name='url']" ); + this.$button = this.$search.find("button"); + + this.$button.on("click", function (e) { + e.stopPropagation(); + self.do_search(self.$url.val() || ''); + }); + this.$url + .on("click mousedown mouseup", function (e) { + e.stopPropagation(); + }).on("keydown", function (e) { + if(e.keyCode == 13) { + $(e.target).blur(); + self.$button.click(); + } + }); }, display_linkedin_account: function() { var self = this; @@ -256,47 +264,77 @@ openerp.web_linkedin = function(instance) { $(QWeb.render('LinkedIn.loginInformation', result.values[0])).appendTo(self.$el.parent().find(".ui-dialog-buttonpane")); }) }, - do_search: function() { + do_search: function(url) { + if (!IN.User || !IN.User.isAuthorized()) { + this.destroy(); + } var self = this; var deferrers = []; - var deferrer = $.Deferred(); - deferrers.push(deferrer); + this.$(".oe_linkedin_pop_c, .oe_linkedin_pop_p").empty(); + + if (url && url.length) { + var deferrer_c = $.Deferred(); + var deferrer_p = $.Deferred(); + deferrers.push(deferrer_c, deferrer_p); + + var url = url.replace(/\/+$/, ''); + var uid = url.replace(/(.*linkedin\.com\/[a-z]+\/)|(^.*\/company\/)|(\&.*$)/gi, ''); + + IN.API.Raw(_.str.sprintf( + "companies/universal-name=%s:(id,name,logo-url,description,industry,website-url,locations)", + encodeURIComponent(uid.toLowerCase()))).result(function (result) { + self.do_result_companies({'companies': {'values': [result]}}); + deferrer_c.resolve(); + }).error(function (error) { + self.do_result_companies({}); + deferrer_c.resolve(); + }); + + var url_public = "http://www.linkedin.com/pub/"+uid; + IN.API.Profile("url="+ encodeURI(url_public).replace(/%2F/g, '/')) + .fields(commonPeopleFields) + .result(function(result) { + console.log("public", result); + self.do_result_people({'people': result}); + deferrer_p.resolve(); + }).error(function (error) { + self.do_warn( _t("LinkedIn error"), _t("LinkedIn is temporary down for the searches by url.")); + self.do_result_people({}); + deferrer_p.resolve(); + }); + + this.text = url; + } + + var deferrer_c_k = $.Deferred(); + var deferrer_p_k = $.Deferred(); + deferrers.push(deferrer_c_k, deferrer_p_k); IN.API.Raw(_.str.sprintf( "company-search:(companies:" + "(id,name,logo-url,description,industry,website-url,locations))?keywords=%s&count=%d", encodeURI(this.text), this.limit)).result(function (result) { self.do_result_companies(result); - deferrer.resolve(); + deferrer_c_k.resolve(); }); - var deferrer = $.Deferred(); - deferrers.push(deferrer); - IN.API.PeopleSearch().fields(commonPeopleFields). - params({"keywords": this.text, "facet": ["network,F,S,A,O"], "count": this.limit}).result(function(result) { + IN.API.PeopleSearch().fields(commonPeopleFields).params({"keywords": this.text, "count": this.limit}).result(function(result) { self.do_result_people(result); - deferrer.resolve(); - }); - // new search for pass the restriction on LinkedIn (2012: search only on first and second level if it's not the last-name and first-name search) - var deferrer = $.Deferred(); - deferrers.push(deferrer); - IN.API.PeopleSearch().fields(commonPeopleFields). - params({"first-name": this.text.split(' ')[0], "last-name": this.text.split(' ').slice(1).join(' '), "facet": ["network,F,S,A,O"], "count": this.limit}).result(function(result) { - self.do_result_people(result); - deferrer.resolve(); + deferrer_p_k.resolve(); }); + return $.when.apply($, deferrers); }, do_result_companies: function(companies) { - var lst = companies.companies.values || []; + var lst = (companies.companies || {}).values || []; lst = _.first(lst, this.limit); lst = _.map(lst, function(el) { el.__type = "company"; return el; }); - console.debug("Linkedin companies found:", companies.companies._total, '=>', lst.length, lst); + console.debug("Linkedin companies found:", (companies.companies || {})._total, '=>', lst.length, lst); return this.display_result(lst, this.$(".oe_linkedin_pop_c")); }, do_result_people: function(people) { - var plst = people.people.values || []; + var plst = (people.people || {}).values || []; plst = _.first(plst, this.limit); plst = _.map(plst, function(el) { el.__type = "people"; @@ -344,6 +382,7 @@ openerp.web_linkedin = function(instance) { if (this.data.__type === "company") { this.$("h3").text(this.data.name); self.$("img").attr("src", this.data.logoUrl); + self.$(".oe_linkedin_entity_headline").text(this.data.industry); } else { // people this.$("h3").text(this.data.formattedName); self.$("img").attr("src", this.data.pictureUrl); diff --git a/addons/web_linkedin/static/src/xml/linkedin.xml b/addons/web_linkedin/static/src/xml/linkedin.xml index 4460c6de752..364208005d1 100644 --- a/addons/web_linkedin/static/src/xml/linkedin.xml +++ b/addons/web_linkedin/static/src/xml/linkedin.xml @@ -34,4 +34,9 @@
If " " is not your account on LinkedIn, please click here to logout LinkedIn.
+ + + \ No newline at end of file From 762a3635ebbdd7d0017dee237090a82193748088 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Mon, 21 Jan 2013 09:43:19 +0100 Subject: [PATCH 05/22] [IMP] linkedin bzr revid: chm@openerp.com-20130121084319-aa0tdiz2vgbql726 --- .../web_linkedin/static/src/css/linkedin.css | 4 +- addons/web_linkedin/static/src/js/linkedin.js | 63 ++++++++++++------- .../web_linkedin/static/src/xml/linkedin.xml | 8 ++- addons/web_linkedin/web_linkedin.py | 13 +++- addons/web_linkedin/web_linkedin_view.xml | 5 ++ 5 files changed, 65 insertions(+), 28 deletions(-) diff --git a/addons/web_linkedin/static/src/css/linkedin.css b/addons/web_linkedin/static/src/css/linkedin.css index 6396c5c3e5b..aa4a110a40a 100644 --- a/addons/web_linkedin/static/src/css/linkedin.css +++ b/addons/web_linkedin/static/src/css/linkedin.css @@ -49,7 +49,7 @@ text-align: center; } -.openerp .oe_linkedin_advanced_search { +.openerp .oe_network_advanced_search { margin: auto; position: absolute; right: 60px; @@ -58,7 +58,7 @@ font-size: 12px; } -.openerp .oe_linkedin_advanced_search button { +.openerp .oe_network_advanced_search button { line-height: 12px; font-size: 12px; } diff --git a/addons/web_linkedin/static/src/js/linkedin.js b/addons/web_linkedin/static/src/js/linkedin.js index 8ac5ce22453..75e0fea28ab 100644 --- a/addons/web_linkedin/static/src/js/linkedin.js +++ b/addons/web_linkedin/static/src/js/linkedin.js @@ -23,7 +23,7 @@ openerp.web_linkedin = function(instance) { var self = this; return this.test_api_key().then(function() { if (self.linkedin_added) { - return self.linkedin_def.resolve(); + return self.linkedin_def; } $login = $(''); @@ -118,6 +118,17 @@ openerp.web_linkedin = function(instance) { selected_entity: function(entity) { var self = this; this.create_on_change(entity).done(function(to_change) { + var values = self.view.get_fields_values(); + console.log(values, to_change); + _.each(to_change, function (value, key) { + if (!/linkedin/.test(key) && !!values[key]) { + if(_.isArray(values[key])) { + + } else { + delete to_change[key]; + } + } + }) self.view.set_values(to_change); }); }, @@ -142,9 +153,9 @@ openerp.web_linkedin = function(instance) { }); var children_def = $.Deferred(); IN.API.PeopleSearch().fields(commonPeopleFields).params({ - "company-name" : entity.name, + "company-name" : entity.universalName, "current-company": true, - "count": 25, + "count": 50, }).result(function(result) { children_def.resolve(result); }).error(function() { @@ -159,14 +170,16 @@ openerp.web_linkedin = function(instance) { return self.create_on_change(el); }); return $.when.apply($, defs).then(function() { - var p_to_change = _.toArray(arguments); + var p_to_change = _.map(_.toArray(arguments), function (val) { + return val.id ? [1, val.id, val] : [0, 0, val]; + }) to_change.child_ids = p_to_change; }); }, function() { return $.when(); })); - to_change.linkedinUrl = _.str.sprintf("http://www.linkedin.com/company/%d", entity.id); + to_change.linkedin_url = _.str.sprintf("http://www.linkedin.com/company/%d", entity.id); } else { // people to_change.is_company = false; to_change.name = entity.formattedName; @@ -196,10 +209,16 @@ openerp.web_linkedin = function(instance) { })); } } + to_change.linkedin_url = to_change.linkedin_public_url = entity.publicProfileUrl || false; + to_change.linkedin_id = entity.id || false; - to_change.linkedinUrl = entity.publicProfileUrl || false; - to_change.linkedinId = entity.id || false; - to_change.comment = entity.summary || false; + // find similar partners + defs.push(new instance.web.DataSetSearch(this, 'res.partner').call("search", [[ + "|", ["linkedin_id", "=", entity.id], "&", ["linkedin_id", "=", false], + "|", ["name", "ilike", entity.firstName +"%"+ entity.lastName], ["name", "ilike", entity.lastName +"%"+ entity.firstName] + ]]).then(function (data) { + to_change.id = data[0] || false; + })); } return $.when.apply($, defs).then(function() { @@ -210,26 +229,26 @@ openerp.web_linkedin = function(instance) { instance.web.form.widgets.add('linkedin', 'instance.web_linkedin.Linkedin'); - var commonPeopleFields = ["id", "picture-url", "public-profile-url", + var commonPeopleFields = ["id", "picture-url", "public-profile-url", "first-name", "last-name", "formatted-name", "location", "phone-numbers", "im-accounts", "main-address", "headline", "positions", "summary", "specialties"]; instance.web_linkedin.LinkedinSearchPopup = instance.web.Dialog.extend({ template: "Linkedin.popup", - init: function(parent, text) { + init: function(parent, search) { var self = this; if (!IN.User.isAuthorized()) { this.$buttons = $("
"); this.destroy(); } - this._super(parent, { 'title':_t("LinkedIn search") + ''}); - this.text = text; + this._super(parent, { 'title': QWeb.render('LinkedIn.AdvancedSearch', {'title': _t("LinkedIn search")}) }); + this.search = search; this.limit = 5; }, start: function() { this._super(); this.bind_event(); - this.display_linkedin_account(); + this.display_account(); this.do_search(); }, bind_event: function() { @@ -238,8 +257,8 @@ openerp.web_linkedin = function(instance) { IN.User.logout(); self.destroy(); }); - this.$search = this.$el.parent().find(".oe_linkedin_advanced_search" ); - this.$url = this.$search.find("input[name='url']" ); + this.$search = this.$el.parent().find(".oe_network_advanced_search" ); + this.$url = this.$search.find("input[name='search']" ); this.$button = this.$search.find("button"); this.$button.on("click", function (e) { @@ -256,7 +275,7 @@ openerp.web_linkedin = function(instance) { } }); }, - display_linkedin_account: function() { + display_account: function() { var self = this; IN.API.Profile("me") .fields(["firstName", "lastName"]) @@ -281,7 +300,7 @@ openerp.web_linkedin = function(instance) { var uid = url.replace(/(.*linkedin\.com\/[a-z]+\/)|(^.*\/company\/)|(\&.*$)/gi, ''); IN.API.Raw(_.str.sprintf( - "companies/universal-name=%s:(id,name,logo-url,description,industry,website-url,locations)", + "companies/universal-name=%s:(id,name,logo-url,description,industry,website-url,locations,universal-name)", encodeURIComponent(uid.toLowerCase()))).result(function (result) { self.do_result_companies({'companies': {'values': [result]}}); deferrer_c.resolve(); @@ -294,7 +313,6 @@ openerp.web_linkedin = function(instance) { IN.API.Profile("url="+ encodeURI(url_public).replace(/%2F/g, '/')) .fields(commonPeopleFields) .result(function(result) { - console.log("public", result); self.do_result_people({'people': result}); deferrer_p.resolve(); }).error(function (error) { @@ -303,7 +321,7 @@ openerp.web_linkedin = function(instance) { deferrer_p.resolve(); }); - this.text = url; + this.search = url; } var deferrer_c_k = $.Deferred(); @@ -311,12 +329,12 @@ openerp.web_linkedin = function(instance) { deferrers.push(deferrer_c_k, deferrer_p_k); IN.API.Raw(_.str.sprintf( "company-search:(companies:" + - "(id,name,logo-url,description,industry,website-url,locations))?keywords=%s&count=%d", - encodeURI(this.text), this.limit)).result(function (result) { + "(id,name,logo-url,description,industry,website-url,locations,universal-name))?keywords=%s&count=%d", + encodeURI(this.search), this.limit)).result(function (result) { self.do_result_companies(result); deferrer_c_k.resolve(); }); - IN.API.PeopleSearch().fields(commonPeopleFields).params({"keywords": this.text, "count": this.limit}).result(function(result) { + IN.API.PeopleSearch().fields(commonPeopleFields).params({"keywords": this.search, "count": this.limit}).result(function(result) { self.do_result_people(result); deferrer_p_k.resolve(); }); @@ -367,6 +385,7 @@ openerp.web_linkedin = function(instance) { }, }); +// http://api.linkedin.com/v1/companies?email-domain=apple.com&email-domain=linkedin.com&email-domain=nhl.com instance.web_linkedin.EntityWidget = instance.web.Widget.extend({ template: "Linkedin.EntityWidget", diff --git a/addons/web_linkedin/static/src/xml/linkedin.xml b/addons/web_linkedin/static/src/xml/linkedin.xml index 364208005d1..92104c2b400 100644 --- a/addons/web_linkedin/static/src/xml/linkedin.xml +++ b/addons/web_linkedin/static/src/xml/linkedin.xml @@ -32,11 +32,13 @@
-
If " " is not your account on LinkedIn, please click here to logout LinkedIn.
+
If " " is not your account, please click here to logout.
-