[ADD] Add linkedin module for integration linkedin with openerp.

bzr revid: jra@tinyerp.com-20120612124454-78zfn48kerp93c5z
This commit is contained in:
Jiten (OpenERP)
2012-06-12 18:14:54 +05:30
parent fcca76b487
commit 61b7f5034d
15 changed files with 1045 additions and 0 deletions
+2
View File
@@ -0,0 +1,2 @@
import res_config
import web_linkedin
+27
View File
@@ -0,0 +1,27 @@
{
"name" : "LinkedIn Integration",
'version': '0.1',
'category': 'Tools',
'complexity': "easy",
"description":
"""
OpenERP Web LinkedIn module.
This module provides the Integration of the LinkedIn with OpenERP.
""",
'update_xml': [
'res_partner_view.xml',
'res_config_view.xml',
],
"depends" : ["base"],
"js": [
"static/src/js/*.js"
],
"css": [
"static/src/css/*.css"
],
'qweb': [
"static/src/xml/*.xml"
],
'installable': True,
'auto_install': False,
}
+52
View File
@@ -0,0 +1,52 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Business Applications
# Copyright (C) 2004-2012 OpenERP S.A. (<http://openerp.com>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from osv import osv, fields
class base_config_settings(osv.osv_memory):
_inherit = 'base.config.settings'
_name = 'base.config.settings'
_columns = {
'default_linkedin_api_key': fields.char('LinkedIn API key', size=128, required=True, default_model='res.company',
help="""Give API key of linkedin."""),
'generate_key': fields.text('Go to URL', readonly=True,
help="""If you have not generate linkedin API Key yet than Go to URL to generate and enter it in above text field."""),
}
_defaults = {
'generate_key': "To find contact persons from LinkedIn "\
"\n====================================="\
"\n* Go to this URL : www.linkedin.com/secure/developer "\
"\n* Add New Application and fill the form,"\
"\n - JavaScript API Domain is Your domain name (e.g. abc.com),"\
"\n - You can give multiple domain (e.g. abc.com, xyz.com)"\
"\n - programming tools is Javascript"\
'\n* Copy the "API Key" and paste it in the field "LinkedIn API Key" here above".'
}
def execute(self, cr, uid, ids, context=None):
super(base_config_settings,self).execute(cr, uid, ids, context=context)
company_obj = self.pool.get('res.company')
data = self.browse(cr, uid, ids[0], context=context)
company_id = company_obj._company_default_get(cr, uid, 'res.users', context=context)
company_obj.write(cr, uid, [company_id], {'default_linkedin_api_key': data.default_linkedin_api_key}, context=context)
base_config_settings()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+26
View File
@@ -0,0 +1,26 @@
<openerp>
<data>
<record id="view_general_configuration_linkedin" model="ir.ui.view">
<field name="name">General Settings</field>
<field name="model">base.config.settings</field>
<field name="inherit_id" ref="base_setup.view_general_configuration"/>
<field name="type">form</field>
<field name="priority">20</field>
<field name="arch" type="xml">
<xpath expr="/form/group/group[@string='External Accesses']" position='replace'>
<group string="External Accesses">
<field name="module_share"/>
<field name="module_portal"/>
</group>
<group colspan="4" col="8">
<separator string="Linkedin Settings" colspan="4"/>
<newline/>
<field name="default_linkedin_api_key"/>
<newline/>
<field name="generate_key" nolabel="1" colspan="4" widget="text_html"/>
</group>
</xpath>
</field>
</record>
</data>
</openerp>
+36
View File
@@ -0,0 +1,36 @@
<?xml version="1.0"?>
<openerp>
<data>
<record id="view_linkedin_partner_form" model="ir.ui.view">
<field name="name">res.partner.linkedin.inherit</field>
<field name="model">res.partner</field>
<field name="type">form</field>
<field name="inherit_id" ref="base.view_partner_form"/>
<field name="arch" type="xml">
<field name="name" position="replace">
<field name="name" nolabel="1" widget="Linkedin" />
</field>
<field name="title" position="before">
<field name="linkedin_id" invisible="1"/>
<field name="profile_id" invisible="1"/>
<field name="twitter_id" invisible="1"/>
</field>
</field>
</record>
<record id="view_company_linkedin_field" model="ir.ui.view">
<field name="name">res.company.linkedin.inherit</field>
<field name="model">res.company</field>
<field name="type">form</field>
<field name="inherit_id" ref="base.view_company_form"/>
<field name="arch" type="xml">
<xpath expr="/form/sheet/notebook/page[@string='Configuration']" position='inside'>
<group colspan="4" col="4">
<separator string="Linkedin Settings" colspan="4"/>
<newline/>
<field name="default_linkedin_api_key" />
</group>
</xpath>
</field>
</record>
</data>
</openerp>
@@ -0,0 +1,39 @@
.ul-ldn-dropdown {
list-style: none outside none;
padding: 1px;
max-height: 500px;
margin: 0px;
background-color: rgb(255, 255, 255);
border: 1px solid rgb(153, 153, 153);
}
.li-ldn-dropdown {
margin: 0px;
display: block;
cursor: default;
padding: 3px;
border: 1px solid rgb(255, 255, 255);
background-color: transparent;
}
.li-ldn-dropdown td{
font-size:10px;
font-weight:normal;
padding: 2px 2px 0px;
}
.li-ldn-dropdown:hover {
margin: 0px;
display: block;
cursor: pointer;
border: 1px solid rgb(10, 36, 106);
background-color: rgb(182, 189, 210)
}
.search-box {
background: none repeat scroll 0 0%, -moz-linear-gradient(#EFEFEF, #D8D8D8) repeat scroll 0 0 transparent;
background: none repeat scroll 0 0%, -webkit-linear-gradient(#EFEFEF, #D8D8D8) repeat scroll 0 0 transparent;
border: 1px solid #ABABAB;
border-radius: 3px 3px 3px 3px;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 1px rgba(255, 255, 255, 0.8) inset;
max-height: 450px;
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

@@ -0,0 +1,667 @@
/*---------------------------------------------------------
* OpenERP web_linkedin (module)
*---------------------------------------------------------*/
openerp.web_linkedin = function(instance) {
var QWeb = instance.web.qweb;
var _t = instance.web._t;
instance.web.form.widgets.add(
'Linkedin', 'instance.web_linkedin.Linkedin');
instance.web_linkedin.Linkedin = instance.web.form.FieldChar.extend({
template: 'Linkedin',
isAuthorized: false,
render_value: function() {
this._super();
var self = this;
this.$element.find('#loader').hide();
if (!this.get("effective_readonly")) {
this._super();
var context = new instance.web.CompoundContext(this.build_context());
var build_context = this.build_context();
this.apikey = build_context.__contexts[0].api_key;
if(this.view.fields['linkedin_id']){
if(this.view.datarecord['linkedin_id']){
this.$element.find('#linkedindefault').hide();
this.$element.find('#linkedinrecord').show();
}else{
this.$element.find('#linkedinrecord').hide();
this.$element.find('#linkedindefault').show();
}
}
try {
IN.init({ api_key : this.apikey });
} catch(e) {
if(!this.apikey){
this.APIWarning = e;
}
if (e.type == "undefined_method") {
this.APIWarning = e;
}
}
var head = document.head || document.getElementsByTagName('head')[0];
var tag = document.createElement('script');
tag.type = 'text/javascript';
tag.src = "http://platform.linkedin.com/in.js";
if(this.apikey){
// Registered API key is necessary to integrate with LinkedIn.
tag.innerHTML = 'api_key : '+this.apikey+'\n';
}
tag.innerHTML = tag.innerHTML + 'authorize : true';
// On load script Loading text is displayed
/*if(this.$element.find("#imagediv").find('.oe_loading')){
this.$element.find("#imagediv").find('.oe_loading').remove();
}
tag.onload=this.$element.find("#imagediv").append('<span class="oe_loading">Loading....</span>');*/
var temp = 0;
$(head).find('script').each( function(i,val) {
if($(val).attr('src')=="http://platform.linkedin.com/in.js"){
temp = 1;
}
});
if(temp != 1) {
head.appendChild( tag );
}
this.notification = new instance.web.Notification(this);
this.notification.appendTo(this.$element);
this.$element.find(".linkedin_icon").click( this.do_load_linkedin );
this.removeTemplate();
if(this.view.fields['name'].get_value()!=false){
/* if value get then display button of profile url */
if (this.view.fields['profile_id'].get_value() || this.view.datarecord['profile_id']) {
this.setTemplate(this.view.datarecord['profile_id'] , false );
}
/* if value get then display button of twitter */
if (this.view.fields['twitter_id'].get_value() || this.view.datarecord['twitter_id']) {
this.setTemplate( false, this.view.datarecord['twitter_id']);
}
}
if (this.view.datarecord['linkedin_id']) {
if (this.view.datarecord['profile_id'] && !this.view.datarecord['twitter_id']) {
if (this.$element.find('#twitterid')) {
this.$element.find('#twitterid').remove();
}
}
else if (!this.view.datarecord['profile_id'] && this.view.datarecord['twitter_id']) {
if (this.$element.find('#profileid')) {
this.$element.find('#profileid').remove();
}
}
}else{
this.removeTemplate();
}
} else {
this.removeTemplate();
if(this.view.fields['name'].get_value()!=false){
var tagtr = document.createElement('tr');
tagtr.id = "profiletwittor-tr";
this.$element.append(tagtr);
/* if value get then display button of profile url */
if (this.view.fields['profile_id'] && this.view.datarecord['profile_id']) {
this.setTemplate( this.view.datarecord['profile_id'] , false );
}
/* if value get then display button of twitter */
if (this.view.fields['twitter_id'] && this.view.datarecord['twitter_id']) {
this.setTemplate( false, this.view.datarecord['twitter_id'] );
}
}
}
},
APIKeyWarning: function(e) {
e.message= "Linkedin API Key is not registerd/correct.\n Go to Settings, 'General Settings' menu and follow steps to register the LinkedIn API Key.";
instance.web.dialog($(QWeb.render("CrashManager.warning", _t(e))), {
title: _t("Linkedin API Key Warning"),
modal: true,
height: 200,
width: 500,
buttons: [
{
text: _t("Ok"),
click: function() { $(this).dialog("close"); }
}]
});
},
setTemplate: function( URL, AccountName ) {
if(AccountName){
var AccountName = AccountName.replace(/[^a-zA-Z 0-9]+/g, '');
Twitt = "https://twitter.com/intent/follow?original_referer=http%3A%2F%2Flocalhost%3A8069%2Fweb%2Fwebclient%2Fhome&screen_name="+AccountName+"&source=followbutton&variant=2.0"
this.$element.find('tr#profiletwittor-tr').append(QWeb.render('TwitterURL',{'URLID': Twitt, 'account': AccountName}))
}else if(URL){
this.$element.find('tr#profiletwittor-tr').append(QWeb.render('ProfileURL',{'URLID': URL }))
}
},
removeTemplate: function( flag ) {
if (flag) {
this.$element.find('#searchresults').remove();
} else {
if (this.$element.find('#profileid')) {
this.$element.find('#profileid').remove();
}
if (this.$element.find('#twitterid')) {
this.$element.find('#twitterid').remove();
}
}
},
/* Load Linkedin Data On search */
do_load_linkedin: function( e ) {
var self = this;
this.msg_Counter=0; /* used to display notification, when record not found on Linkedin search */
this.removeTemplate( 1 );
if(!this.apikey){
this.APIKeyWarning(this.APIWarning);
e.preventDefault();
e.stopPropagation();
e.stopImmediatePropagation();
return false;
}
if (IN.ENV.auth.oauth_token) {
if (self.$element.find("input").val()) {
self.$element.find('#loader').show();
$('.linkedin_icon').css('display', 'none');
/* People Search */
IN.API.Raw("/people-search:(people:(id,first-name,last-name,picture-url,public-profile-url,formatted-name,location,phone-numbers,im-accounts,main-address,headline))")
.params({
"first-name": self.$element.find("input").val(),
"count" : 4
})
.result( self.do_fetch_detail );
/* Company Search */
IN.API.Raw("/company-search:(companies:(id,name,description,industry,logo-url,website-url,locations,twitter-id))")
.params({
"keywords": self.$element.find("input").val(),
"count" : 4
})
.result( self.do_fetch_detail );
}else{
this.notification.warn(_t("Linkedin Search"), _t("Please Enter Required Field."));
}
}
else {
self.do_authorize();
}
e.preventDefault();
e.stopPropagation();
e.stopImmediatePropagation();
},
do_authorize: function(resultCallback){
this.check_authorized();
if (this.isAuthorized == false){
IN.User.authorize(resultCallback);
}
},
check_authorized: function(){
this.isAuthorized = IN.User.isAuthorized();
},
/* Fetch Result from Linkedin and set in searchbox */
do_fetch_detail: function(result, metadata) {
var self = this;
if (result.people) {
if (result.people._total==0) {
this.msg_Counter++;
}
var count = 0;
for (i in result.people.values) {
var temp = self.validName(result.people.values[i].firstName, result.people.values[i].lastName)
if (temp) {
count++;
}
}
if (count == 4 || count==result.people._total) {
result.people._total = 0;
}
this.resultcontact = result;
}else if (result.companies) {
if (result.companies._total == 0) {
this.msg_Counter++;
}
this.resultcompany = result;
}
this.removeTemplate( 1 );
if (this.msg_Counter == 2) {
// dialog box
/*new instance.web.dialog($(QWeb.render("SearchWarning")), {
title: _t("Linkedin Search"),
modal: true,
buttons: [
{text: _t("Ok"), click: function() { $(this).dialog("close"); }}
]
});*/
// notification
this.notification.warn(_t("Linkedin Search"), _t("Record Not Found."));
this.$element.find('#loader').hide();
if(this.view.fields['linkedin_id']){
if(this.view.datarecord['linkedin_id']){
this.$element.find('#linkedindefault').hide();
this.$element.find('#linkedinrecord').show();
}else{
this.$element.find('#linkedinrecord').hide();
this.$element.find('#linkedindefault').show();
}
}
} else {
if (this.resultcontact || this.resultcompany) {
this.$element.find('#linkedin-field-name').append(QWeb.render( 'Linkedincontact', {'result' : this.resultcontact, 'resultcompany' : this.resultcompany})) ;
}
}
if(this.$element.find('#searchresults .search-box ul li')){
this.$element.find('#loader').hide();
if(this.view.fields['linkedin_id']){
if(this.view.datarecord['linkedin_id']){
this.$element.find('#linkedindefault').hide();
this.$element.find('#linkedinrecord').show();
}else{
this.$element.find('#linkedinrecord').hide();
this.$element.find('#linkedindefault').show();
}
}
}
this.$element.find('#searchresults .search-box ul li').click( function() {
self.getdata( this );
});
$(document).click( function() {
self.removeTemplate( 1 );
});
},
/* Selected record's data fetched */
getdata: function( e ) {
var self = this;
if (this.resultcontact) {
for (i in this.resultcontact.people.values) {
if (self.resultcontact.people.values[i].id == $(e).attr('id')) {
self.removeTemplate( 1 );
this.getTwitterAccount( self.resultcontact.people.values[i] )
}
}
}
if(this.resultcompany){
for ( i in this.resultcompany.companies.values ) {
if ( self.resultcompany.companies.values[i].id == $(e).attr('id') ) {
self.removeTemplate( 1 );
self.map_values(self.resultcompany.companies.values[i]);
}
}
}
},
/* Based on Linkedin Id of record fetch Twitter Account Detail for People */
getTwitterAccount: function( values, flag, mainfield ){
var self = this;
IN.API.Profile(values.id).fields('twitter-accounts')
.result(function(acname){
values.twitterAccounts = acname.values[0].twitterAccounts
if(flag){
self.map_values(values, flag, mainfield);
}else{
self.map_values(values);
}
});
},
/* Mapping of Linkedin Fields with res.partner Fields
linkedinrecord : contains linkedin record's data
flag : indicates mapping of People search record or for company's contacts/connections (people)
if(flag) mapping for contacts of company
if(!flag) mapping for people search
mainfield : class of child_ids field
*/
map_values: function (linkedinrecord, flag, mainfield){
var self = this, tempdata = {}, temp_data = 0, id = this.view.datarecord.id;
_(this.view.fields).each(function (field, f) {
if (f=='name') {
if (!flag) {
if (linkedinrecord.formattedName) {
field.set_value(linkedinrecord['formattedName'] || false);
} else if(linkedinrecord.name) {
field.set_value(linkedinrecord['name'] || false);
}
} else {
tempdata[f] = linkedinrecord.firstName+' '+linkedinrecord.lastName;
}
}
else if (f=='property_account_payable') {
if(flag == 1)tempdata[f] = field.get_value()
}
else if (f=='property_account_receivable') {
if(flag == 1)tempdata[f] = field.get_value()
}
else if (f=='type') {
(flag == 1) ? tempdata[f] = field.get_value() : field.get_value();
}
else if (f=='linkedin_id') {
(flag == 1) ? tempdata[f] = linkedinrecord['id'] : field.set_value(linkedinrecord['id']);
}
else if (f=='profile_id') {
if (linkedinrecord.publicProfileUrl) {
(flag == 1) ? tempdata[f] = linkedinrecord.publicProfileUrl : field.set_value(linkedinrecord.publicProfileUrl);
} else {
field.set_value(false);
tempdata[f] = false;
}
}
else if (f=='twitter_id') {
if (linkedinrecord.twitterAccounts && linkedinrecord.twitterAccounts._total >= 1) {
(flag == 1) ? tempdata[f] = linkedinrecord.twitterAccounts.values[0].providerAccountName : field.set_value(linkedinrecord.twitterAccounts.values[0].providerAccountName);
}else if (linkedinrecord.twitterId) {
(flag == 1) ? tempdata[f] = linkedinrecord.twitterId : field.set_value(linkedinrecord.twitterId);
} else {
(flag == 1) ? tempdata[f] = false : field.set_value(false);
}
}
else if (f=='mobile') {
if (!flag && linkedinrecord.phoneNumbers && linkedinrecord['phoneNumbers']._total>=1 && linkedinrecord['phoneNumbers'].values[0].phoneType == "mobile") {
field.set_value( linkedinrecord['phoneNumbers'].values[0].phoneNumber || false );
}else if (flag == 1) {
tempdata[f] = field.get_value();
} else {
field.set_value(false);
}
}
else if (f=='phone') {
if (!flag && linkedinrecord.phoneNumbers && linkedinrecord['phoneNumbers']._total>=1 && linkedinrecord['phoneNumbers'].values[0].phoneType != "mobile") {
field.set_value(linkedinrecord['phoneNumbers'].values[0].phoneNumber || false);
} else if(flag == 1) {
tempdata[f] = field.get_value();
} else {
field.set_value(false);
}
}
else if (f=='email') {
if (!flag && linkedinrecord.imAccounts && linkedinrecord['imAccounts']._total>=1) {
field.set_value(linkedinrecord['imAccounts'].values[0].imAccountName);
} else if(flag == 1) {
tempdata[f] = field.get_value();
} else {
field.set_value(false);
}
}
else if (f=='photo') {
if (!flag) {
if (linkedinrecord.pictureUrl && linkedinrecord['pictureUrl']) {
/* Fetch binary data from URL for People */
self.rpc('/web_linkedin/binary/url2binary',{'url':linkedinrecord['pictureUrl']},function(data){
field.set_value(data);
});
} else if (linkedinrecord.logoUrl && linkedinrecord['logoUrl']) {
/* Fetch binary data from URL for Company */
self.rpc('/web_linkedin/binary/url2binary',{'url':linkedinrecord['logoUrl']},function(data){
field.set_value(data);
});
} else {
field.set_value(false);
}
}
else{
if (linkedinrecord['pictureUrl']) {
temp_data = 1;
/* Fetch binary data from URL for contact of Company */
self.rpc('/web_linkedin/binary/url2binary',{'url':linkedinrecord['pictureUrl']}).done(function(res){
tempdata[f] = res;
self.set_o2mdata(tempdata,mainfield)
});
} else {
tempdata[f] = "iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz AAAFMQAABTEBt+0oUgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAn6SURB VGiB1VpNjFxHEf6qf97vzGw2q921VybGJLYsRxHCxgsEiViKhBQhLpEspEggAQcOKAcQd+ML4hAp EiFHLgTlEB+TcCFAEvGTSEBIfEgcNspaylq7sb0/np/3091VHPY9MrY3xvEMimip9Hrm9av6vtfV Vd01QyKC/+dm/hdKz507t1BV1ZeJ6Igxpm+tfXNtbe3vjz/+uJu2LZrmDDzzzDNfLYri2865WCkV kiSROI5hrdVaayKitaIofv7YY48NpmVzKgSeeOKJZHZ29kdlWR4GUAIo0jStsiwLcRxTHMfWWpsC SJ1zpizL3zz66KO/n9gwADUNJXNzcz91zt2rtd4B8KFS6pLWes0Y80Ecxx+kabrW6XTWu93u1U6n U+Z5/p3nn3/+oWnYnpjAs88+e3o0Gs0z84619nIUResANojoQwCXieiy1vrDKIrWsyzbiKJo0xhT APjOk08+GU1qf6JF/PTTT/e01o8AGPb7/a3BYHBlZmZmm4gKEXEhBHHOoaoqDaDSWgfnHImIIaK5 gwcP/gTAzz41AsaYL3jvw9WrVweHDx++NjMz019bWxttbGxUURTx4uKiWGsRQgjOOR6NRhRCsCGE DECnLMuDk9ifmIC19vObm5vuoYceKhYWFkbW2uL+++93Sqlw/vx5uXDhAobDIe6+++6QJAmMMZVS arS9vT3UWhchhLmnnnrKThJeJ80DB2dnZ/3c3FytlKqVUkFrHbTWcvz4cTl58mQ7jgCwiHhmrgeD Qf3qq6/WxhiOoug+AG/fKYCJFjEzd/M8Z6WUJ6KglApKKRARiAgi0vZlTEKe5/7IkSOhKArudruH J8EwEQEiQp7nACBKKW7AS3uPiHaNKIX2XiO8b98+9t5j0jw0EQFjTDk7O9sC23NM+/0YIQHAcRxL p9NBFEVXJsFwxwReeeWV491ud9jMwHVg92pjb5paWVpa4oWFhW/dKQZgshlI7rnnnm6SJKrRo8bA /aeJSCskIu04A0AfOHDAY4IFDExAoNPp/KOu667WWgOIRMSIiG4JjAFvwZOIaBGxzfjIe58Q0euf CoETJ06UIYS3G7dJAaREFAHQ9FEbd6v2zScAMhFJqqrijY2NNz8VAgAQQvjtcDjcFpFcRDohhISZ rYgoZkYj1Ihm5khEshBCzswxMz99+vRp/tQInDp16i0Avw4hZMzcDSF0QghRA7YFDmZWzGyYOWHm PISQe+8/WF5e/uck9icmAAAnT5684L3fZuZOQyANIYzPAjGzCiFYZk4b8Akzvzap7akQAACl1Gve +4yZc+996pyzIQTNzBRCoKZvQwiJcy4tyzIKIfxpKranoaSqqj/UdW2YOWvecuS9V9571RBQ3nvr nItDCPH6+vrOsWPHimnYngqB5eXlazs7O5e890nrQt577b2H954aMiaEEG1vb9t+v/+3adgFpkQA AKIoeuvSpUvWe2+bPb9q3jw1M6Gdc+b99983WZZNlLzG29TKKlmWXRyNRoqZDQDFzIqaJNBc9crK il5YWKDBYPDOtOxOjQAz14cOHaKVlRVYa9Xi4iLa3WZVVVhZWcH8/Dzm5+fp1KlT5bTsTo2AMYbz PMfRo0dx5coVXl1dxebmJpgZcRxj//790hwxp1oKnBoBa+0BrbVPksQtLi4GrTUnSSLOOVhrudvt emutIyJ//vz5Qw888MD707A7tUXc6XS+obWuiKgkIkdEgYi4kUBETkRKIiqzLPv+tOxOTKAoivn1 9fXv5nmuAFwTkSEzVyISmFkASNMvAQzSNO3Pzc3NFkXxvaqqlia1f8cutLW19cWqqr5urT3U6/WK 0Wh01Vq76b3vO+cq730IIQgACSEEZq7jOO7neR4ppcgY8/kQwpeHw+EqM/+x2+2+DuATb+w+UW20 3+/POOcecc59SWvd0VqXIjIKIVwLIWwbY3aUUgMiKsqydGVZilIKURRRkiRWRBJrbSdJkhkAMyLS BZABSJh5pJR6zTn3uzzPt6ZKYGtr6/7RaPRNrfXn0jRlIiqMMSMRGWqtB0Q0IKIRM4+01lVd115E uNEtRERaa6W1Ns2ZIQWQN+A7zXY8E5EUgCGiCyLyUpIkb01MYHV19QcAvtLpdEpr7VBrPVBKDYlo CGCklCqIqARQA/BEFPCRK4wrJ3x09LSNxCLSHnByALmIdESkQ0SJiPw1TdNf4RaudUsCq6urP/Te n+j1eoMkSXYA7BDRQGs91FqXRFSLiCMiLyJMRNyA/jil7fFMN0Q0dtdhJCJJMwsd7LrXXUTUFZE3 siz75cdh/NhFvLGxcbSu6+O9Xm9grb2ilLoaQrhmjBkZY2oADkDYA/StplQaEmFMHICaiCoAhYgU ACoAQUQIwPHhcPiFPM/f+EQEiqJ4NM9zF0XRDhFdBbBpjBlqrWsAvgHDANoK3O1Gg/FxPHYNROQA OBEJLb4QgtVafwPA7RPY2NhIROSzWuuBiOyISD+EMEySpALgReQmH7/DCtv4Q6H5LMwM7LpXKiK5 9/5gv9/vdbvdazcq2DORlWX5tSiKyBgzAjASkYKZHRF5brTj1q5yp0RYKdW6VSEiw8Y+a60f3OvB mwisrKxYZn5Ya+2JqBKRCrvTyiICpRQaDjcVse6wXaenqSMJMwcAtYhUROSdcyfOnj17E96bvnjv vfdSEdnf+LQ0VWbdilJKe+/VWLFqWqJERDNza0u1eUR2O4fPnDkT/zcC6sCBA49EUWSJyACIsZt0 MgCZ9z4loiSEEDf32nhuGtG3Ke34/+SDRhLs+n2G3dyQikjMzEYpFa+vrz98I4HrFvHLL79MWZYd vOuuu3QURYn3vicinogsERXe+5qIHDMHZvZKKcZuBLndUEpj1/HEpgEoETHMbIkoYuYUQA/AjLU2 VUrR1tbWZ/bt23e9whujx4svvtgJIfz43nvvPTo/P19Za0fe+5GIlFrrutfr1VVV+bIsXZ7n4/F8 nMReyYxukBZ4K5aZTV3XkYhEIpJorTMRSS9duhRfvHjxjeFw+IvTp0/XtyQAAOfOnVPe+3tE5Cv3 3Xffg0tLS1mapqE5sHilVBgMBt4Y41sCRMSNr7b54cYQO169VkopaorB17lVXddaRExVVWZtbe3a 6urqnwH85Z133lk/c+bMTVuKW24lzp49q5aXl3VZlotVVT2wtLR0JMuyAzMzM71ut2uMMe1+n5vI 0W6fBQCYWZoF2pL4qOq721dNtkVd135nZ2dnMBhcXFtb+1ev13tz//79V1944QXZC/htEdhrZgDo NE11p9Ohy5cvz3rv50UkNcbEzrmYmZM4jlOlVBbHceq9BzMXzDyqqmqkta5EpGTmOkmSkfd+49ix Yzubm5v87rvvhpdeekmee+652z4XTPxfifbHvPG2V7wGgBvf5F7PftL2bxhUblkxIzmaAAAAAElF TkSuQmCC";
}
}
}
else if (f=='street') {
if (!flag && linkedinrecord.mainAddress && linkedinrecord['mainAddress']) {
field.set_value(linkedinrecord['mainAddress']);
} else if(flag == 1) {
tempdata[f] = field.get_value();
} else {
field.set_value(false);
}
}
else if (f=='country_id') {
if (!flag && linkedinrecord.location && linkedinrecord['location']) {
field.field.domain = [['code', '=', linkedinrecord['location'].country['code'].toUpperCase()]];
(new instance.web.DataSetSearch(self, field.field.relation,field.field.context,field.field.domain)).read_slice(['id','name'],{}).then(function(res){
field.original_value = [res[0].id, res[0].name];
field.set_value(res[0].id)
})
} else if (!flag && linkedinrecord.locations && linkedinrecord.locations._total>0) {
if (linkedinrecord.locations.values[0].address['country-code']) {
field.field.domain = ['code', '=', linkedinrecord.locations.values[0].address['country-code'].toUpperCase()];
(new instance.web.DataSetSearch(self, field.field.relation,field.field.context,field.field.domain)).read_slice(['id','name'],{}).then(function(res){
field.original_value = [res[0].id, res[0].name];
field.set_value(res[0].id)
})
} else {
field.set_value(false);
}
} else if(flag == 1) {
tempdata[f] = field.get_value();
} else {
field.set_value(false);
}
}
else if (f=='city') {
if (!flag && linkedinrecord.location && linkedinrecord['location']) {
field.set_value(linkedinrecord['location'].name.split(' ')[0] || false);
} else if (!flag && linkedinrecord.locations && linkedinrecord.locations._total>0) {
if (linkedinrecord.locations.values[0].address['city']) {
field.set_value(linkedinrecord.locations.values[0].address['city']);
} else {
field.set_value(false);
}
} else if (flag == 1) {
tempdata[f] = field.get_value();
} else {
field.set_value(false);
}
}
else if (f=='website') {
if (!flag && linkedinrecord.websiteUrl) {
field.set_value(linkedinrecord['websiteUrl'] || false);
} else if (flag == 1) {
tempdata[f] = field.get_value();
} else {
field.set_value(false);
}
}
else if (f=='customer') {
if(flag == 1)tempdata[f] = true;
}
else if (f=='supplier') {
}
else if (f=='active') {
(flag == 1) ? tempdata[f] = true : field.set_value(true);
}
else if (f=='is_company') {
if (!flag && linkedinrecord.formattedName) {
field.set_value(false);
} else {
field.set_value(true);
tempdata[f] = false;
}
}
else if (f=='zip') {
if (!flag && linkedinrecord.locations && linkedinrecord.locations._total>0) {
if (linkedinrecord.locations.values[0].address['postalCode']) {
field.set_value(linkedinrecord.locations.values[0].address['postalCode']);
} else {
field.set_value(false);
}
}else if (flag == 1) {
tempdata[f] = field.get_value();
} else {
field.set_value(false);
}
}
else if (f=='parent_id') {
if (!flag && linkedinrecord.formattedName) {
field.set_value(false);
} else if (!flag && linkedinrecord.name) {
field.set_value(false);
} else {
if (linkedinrecord.formattedName) {
tempdata[f] = [id,self.view.fields['name'].get_value()];
}
}
}
else if (f=='fax') {
if (!flag && linkedinrecord.locations && linkedinrecord.locations._total>0) {
if (linkedinrecord.locations.values[0].contactInfo['fax']) {
field.set_value(linkedinrecord.locations.values[0].contactInfo['fax']);
} else {
field.set_value(false);
}
} else if (flag == 1) {
tempdata[f] = field.get_value();
} else {
field.set_value(false);
}
}
else if (f=='use_parent_address') {
(flag == 1) ? tempdata[f] = true : field.set_value(false);
}
else if (f=='child_ids') {
/* For Company Set value of child_ids field */
if (!flag && linkedinrecord.name) {
self.$element.find('#loader').show();
$('.linkedin_icon').css('display', 'none');
/* Fetch contact of Company */
IN.API.Raw("/people-search:(people:(id,first-name,last-name,formatted-name,picture-url,publicProfileUrl,phone-numbers,im-accounts,main-address,location,relation-to-viewer:(related-connections)))")
//"id", "firstName", "lastName", "pictureUrl", "publicProfileUrl", "formatted-name", "headline", "location", "industry", "languages", "phone-numbers", "im-accounts", "main-address"
.params({
"company-name" : linkedinrecord.name,
"current-company": true,
"count" : 25
})
.result( function (getresult){
if(getresult.people._total==0){
self.$element.find('#loader').hide();
if(self.view.fields['linkedin_id']){
if(self.view.datarecord['linkedin_id']){
self.$element.find('#linkedindefault').hide();
self.$element.find('#linkedinrecord').show();
}else{
self.$element.find('#linkedinrecord').hide();
self.$element.find('#linkedindefault').show();
}
}
}
self.totalids = [],self.updteids = [];
_(field.dataset.ids).each( function(i) {
if (typeof(i)=="number") {
self.totalids.push(i);
var mobile = self.view.fields['mobile'].get_value();
var phone = self.view.fields['phone'].get_value();
var email = self.view.fields['email'].get_value();
var fax = self.view.fields['fax'].get_value();
var website = self.view.fields['website'].get_value();
var zip = self.view.fields['zip'].get_value();
var city = self.view.fields['city'].get_value();
var country_id = self.view.fields['country_id'].get_value();
var street = self.view.fields['street'].get_value();
field.dataset.write(i,{'mobile':mobile,'phone':phone,'email':email,'fax':fax,'website':website,'zip':zip,'city':city,'country_id':country_id,'street':street},{});
}
});
field.dataset.ids = self.totalids;
var counter = 0;/* Indicates All searched records are Invalid or valid */
self.t_count=0;
self.o2m_count = 0;
for (i in getresult.people.values) {
var connectTemp = self.validName(getresult.people.values[i].firstName, getresult.people.values[i].lastName)
if (connectTemp) {
counter++;
} else {
self.t_count++;
self.getTwitterAccount(getresult.people.values[i], 1, field);
}
}
if (getresult.people._count) {
var total_Count = getresult.people._count;
}else if (getresult.people._total) {
var total_Count = getresult.people._total;
}
/* If counter == total no. of people then all searched records are invalid */
if (counter == total_Count) {
field.dataset.to_create = [];
field.dataset.ids = [];
field.reload_current_view();
}else if(getresult.people._total == 0 || getresult.people._count == 0){
field.dataset.ids = self.totalids;
field.reload_current_view();
}
});
}
/* For People Set value of child_ids field */
else if (!flag && linkedinrecord.formattedName) {
field.set_value(false);
field.set({'invisible':true});
}
/* For Contact of company Set value of child_ids field */
else {
tempdata[f] = false;
}
}
else {
(flag == 1) ? tempdata[f] = false : field.set_value(false);
}
field._dirty_flag = true;
field.on('changed_value', self, function() {
if (!flag) {
self.view.do_onchange(field);
self.view.on_form_changed(true);
self.view.do_notify_change();
}
});
});
if (!flag) {
this.removeTemplate();
if (linkedinrecord.publicProfileUrl) {
this.setTemplate( linkedinrecord.publicProfileUrl , false );
}
if (linkedinrecord.twitterId) {
this.setTemplate( false , linkedinrecord.twitterId );
}
if (linkedinrecord.twitterAccounts && linkedinrecord.twitterAccounts._total >= 1) {
this.setTemplate( false , linkedinrecord.twitterAccounts.values[0].providerAccountName );
}
}
if (flag && temp_data == 0) {
self.set_o2mdata(tempdata, mainfield);
}
},
/* Update existing value of child_ids field */
set_childids: function( ids ) {
var self = this;
_(ids).each(function(i){
self.view.fields['child_ids'].dataset.set_ids(self.view.fields['child_ids'].dataset.ids.concat([i]));
self.view.fields['child_ids'].dataset.write(i, {"parent_id":false}, {});
});
},
/* Set/create o2m contacts of child_ids field */
set_o2mdata: function(data,field){
var self = this;
self.o2m_count++;
field.dataset.create(data).then( function(r) {
self.totalids.push(r.result);
field.dataset.set_ids(field.dataset.ids.concat([r.result]));
field.dataset.on_change();
}).then();
field.dataset.ids = self.totalids;
field.reload_current_view();
if (self.t_count == self.o2m_count) {
self.$element.find('#loader').hide();
//$('.linkedin_icon').css('display', 'block');
if(this.view.fields['linkedin_id']){
if(this.view.datarecord['linkedin_id']){
this.$element.find('#linkedindefault').hide();
this.$element.find('#linkedinrecord').show();
}else{
this.$element.find('#linkedinrecord').hide();
this.$element.find('#linkedindefault').show();
}
}
}
},
/* Name of Searched Linkedin Record is valid or Not */
validName: function(fname, lname){
if ((fname == "Private" || fname == "private") || (lname == "Private" || lname == "private") || (fname == "" && lname == "")) {
return true;
} else {
return false;
}
}
});
};
// vim:et fdc=0 fdl=0:
@@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- vim:fdl=1:
-->
<templates id="template" xml:space="preserve">
<t t-name="Linkedin">
<table cellpadding="0" cellspacing="0" border="0" width="100%">
<tr>
<td width="100%" id="linkedin-field-name">
<t t-call="FieldChar"/>
</td>
<td id="linkedindiv" class="oe_form_group_cell" style="padding:0px;">
<div id="imagediv" name="search1">
<span style="display:inline;">
<a href="#">
<img id="linkedinrecord" class="linkedin_icon" src="/web_linkedin/static/src/img/Linkedin_blue.png" width="24" height="24" alt="Search on LinkedIn"/>
<img id="linkedindefault" class="linkedin_icon" src="/web_linkedin/static/src/img/Linkedin_grey.png" width="24" height="24" alt="Search on LinkedIn"/>
</a>
<img id="loader" class="loading" src="/web_linkedin/static/src/img/loading.png" width="24" height="24"/>
</span>
</div>
</td>
</tr>
<tr id="profiletwittor-tr"></tr>
</table>
</t>
<t t-name="ProfileURL">
<td id="profileid">
<a t-att-href="URLID" target="_blank" id="profileid">
<img src="/web_linkedin/static/src/img/linkedin-profile.gif" width="130" height="24" border="0" alt="View profile on LinkedIn"/>
</a>
</td>
</t>
<t t-name="TwitterURL">
<td id="twitterid">
<a t-att-href="URLID" target="_blank">
<img src="/web_linkedin/static/src/img/twitt-follow.png" width="100" height="24" border="0" alt="Follow"/>
</a>
</td>
</t>
<t t-name="SearchWarning">
<div>Record Not Found.</div>
</t>
<t t-name="Linkedincontact">
<div id="searchresults" class="openerp" style="-webkit-margin-start:-70px; -moz-margin-start:-70px; z-index:2000; position:absolute;">
<div class="search-box" >
<table>
<t t-if="result and result.people._total>0">
<tr id="searchresultscontact">
<td width="70px;">
<span>
<label style="font-size:12px;"><b>Persons</b></label>
</span>
<br/>
</td>
<td>
<ul class="ul-ldn-dropdown">
<t t-if="result.people.values">
<li class="li-ldn-dropdown" t-foreach="result.people.values" t-as="data" t-if="(data.firstName!='' and data.firstName!='Private' and data.firstName!='private') or (data.lastName!='' and data.lastName!='Private' and data.lastName!='private')" t-att-id="data.id">
<table>
<tr>
<td>
<!-- picture url not always there, must be defensive -->
<t t-if="data.hasOwnProperty('pictureUrl')">
<img align='baseline' t-att-src="data.pictureUrl" width="30"/>
</t>
<t t-if="!data.hasOwnProperty('pictureUrl')">
<img align='baseline' width="30" src='http://static02.linkedin.com/scds/common/u/img/icon/icon_no_photo_80x80.png' />
</t>
</td>
<td>
<b><t t-esc="data.firstName+' '+data.lastName" /></b><br/>
<t t-esc="data.headline" />
</td>
</tr>
</table>
</li>
</t>
</ul>
</td>
</tr>
</t>
<t t-call="Linkedincompany" />
</table>
</div>
</div>
</t>
<t t-name="Linkedincompany">
<t t-if="resultcompany and resultcompany.companies._total>0">
<tr id="searchresultscompany">
<td width="70px;">
<span>
<label style="font-size:12px;"><b>Companies</b></label>
</span>
<br/>
</td>
<td>
<ul class="ul-ldn-dropdown">
<li class="li-ldn-dropdown" t-foreach="resultcompany.companies.values" t-as="data" t-att-id="data.id">
<table>
<tr>
<td>
<t t-if="data.hasOwnProperty('logoUrl')">
<img align='baseline' t-att-src="data.logoUrl" width="30" />
</t>
<t t-if="!data.hasOwnProperty('logoUrl')">
<img align='baseline' width="30" src='http://static02.linkedin.com/scds/common/u/img/icon/icon_no_photo_80x80.png' />
</t>
</td>
<td>
<b><t t-esc="data.name" /></b><br/>
<t t-esc="data.industry" />
</td>
</tr>
</table>
</li>
</ul>
</td>
</tr>
</t>
</t>
</templates>
+72
View File
@@ -0,0 +1,72 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import base64
import urllib2
import xmlrpclib
import zlib
from web import common
openerpweb = common.http
from osv import fields, osv
class company(osv.osv):
_inherit = 'res.company'
_columns = {
'default_linkedin_api_key': fields.char('LinkedIn API key', size=128),
}
company()
class res_partner(osv.osv):
_inherit = 'res.partner'
_columns = {
'linkedin_id': fields.char('Linkedin Id', size=64),
'twitter_id': fields.char('Twitter', size=128),
'profile_id': fields.char('Profile URL', size=240),
}
def fields_view_get(self, cr, user, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
company_obj = self.pool.get('res.company')
res = super(res_partner, self).fields_view_get(cr, user, view_id, view_type, context, toolbar=toolbar, submenu=submenu)
company_id = company_obj._company_default_get(cr, user, 'res.users', context=context)
linkedin_api_key = company_obj.browse(cr, user, company_id, context=context).default_linkedin_api_key
fields = res['fields']
if fields.get('name'):
ctx = fields.get('name').get('context')
if ctx is None:
ctx = {}
ctx.update({'api_key': linkedin_api_key})
fields.get('name')['context'] = ctx
return res
res_partner()
class Binary(openerpweb.Controller):
_cp_path = "/web_linkedin/binary"
@openerpweb.jsonrequest
def url2binary(self, req,url):
bfile = urllib2.urlopen(url)
return base64.b64encode(bfile.read())
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: