Understand eval, exec and source in linux

September 18, 2010

eval “translates” a value buried inside a variable, and then runs the command that was buried in there

Code:
for i in 1 2 3
do
   eval myvar="$i"
   echo "$myvar"
done
# this gives 
1
2
3
# why? because there is no metavalue or special meaning to 1 or 2 or 3
Code:
for i in ls df
do
    eval myvar="$i"
    echo "$myvar"
done
# here you get output from the ls command and the df command

exec starts another process – BUT – it exits the current process when you do this kind of thing

Code:
#!/bin/bash

exec echo "leaving this script forever  $0"   # Exit from script here.

# ----------------------------------
# The following line never happens

echo "This echo will never echo."

source

When you run a command in the shell – like another script or a command like ls -
the shell creates a subprocess (called child process). Any environment variable that got defined or changed down in the child is LOST FOREVER to the parent process.

However if you source a script (there are two ways) you force the script to run in the current process. That means environment variables in the script you ran are NOT LOST.

Code:
# script1
MYVAR="HI there!"
# end script1
Code:
# script2
# first, run script 1
script1
# now is the MYVAR variable set?  No -why? it got set in the child, when the child exited it GOT LOST
echo "MYVAR= $MYVAR"
# now source script1 :: putting a lonesome dot or the command  "source" 
#  in front of the script name have the same effect
. script1
#  . script1 == source script1  these two are the SAME THING
source script1
# now is the MYVAR variable set?  This time we see that MYVAR has a value
echo "MYVAR= $MYVAR"

ERROR: language “plpgsql” does not exist

September 18, 2010

1) Create language handler

create function plpgsql_call_handler()
returns opaque
as ‘/usr/lib/postgresql/8.3/lib/plpgsql.so’
language ‘C';

2) Create language

CREATE LANGUAGE ‘plpgsql’ HANDLER plpgsql_call_handler
LANCOMPILER ‘PL/pgSQL’

3) Demo

CREATE OR REPLACE FUNCTION user_password_reset_token() RETURNS TRIGGER AS $$
  BEGIN
    NEW.token := ENCODE(DIGEST((random() * NEW.user_id )::text || now(), 'sha256'), 'hex');
    RETURN NEW;
  END
$$ LANGUAGE 'plpgsql';

September 2, 2010

My gem version is 1.3.1 and i’d like to update it into 1.3.7 version. Here the way to do it

1) get ruby gem update

http://rubygems.org/pages/download

I prefer  option 2, get the gem file, go to folder the gem locates and run

gem install <update-gem>

2) After installing the updated-gem , call

update-gem

If it does not work ( can not find update-gem )

Run

/var/lib/gems/1.8/bin/update_rubygems

It should work.

Openerp: Hide Menu Item

August 25, 2010

We don’t want to display Unit Of Measure in Product Configuration.

One way to do this

<delete model=”ir.model.data” search=”[('name','=','menu_product_uom_form_action')]” />
<delete model=”ir.model.data” search=”[('name','=','menu_product_uom_categ_form_action')]” />
<delete model=”ir.model.data” search=”[('name','=','next_id_16')]” />
<delete model=”ir.ui.menu” search=”[('name','=','Units of Measure Categories')]” />
<delete model=”ir.ui.menu” search=”[('name','=','Units of Measure')]” />
<delete model=”ir.ui.menu” search=”[('name','=','Units of Measure')]” />

But doing this will delete these data in DB. suppose my clients want to recover this feature. How to do it easily?

OpenErp: replace link by wizard

August 24, 2010

When I’m working in OpenERP, I need inherit some model/table by using new table

class evar_component(osv.osv):
_inherits = {‘product.product': ‘product_id’}
_name = “evar.component”
_table = “evar_component”

_columns = {
‘product_id': fields.many2one(‘product.product’, ‘Product’,),
}

Now client wants to add a link for this model. One way to achieve this in origin product module

<act_window
context=”{‘product_id': active_id}”
id=”act_stock_product_location_open”
name=”Stock by Location”
res_model=”stock.location”
src_model=”product.product”
/>

But with evar.component, the active_id is the id in evar_component, not product_id? Uhm How to this?

Answer: Using wizard

1) Create wizard link

<wizard
id=”wizard_component_stock_location”
model=”evar.component”
name=”component.stock.location.wizard”
string=”Stock by Location”/>
</data>

2) create wizard_component.py

def _do_component_stock_location_action(self, cr, uid, data, context):
product_ids = get_product_ids_by_model(self, cr, uid, data['ids'],”evar.component”)

result = {}
if product_ids:
result = {
‘context':”{‘product_id': “+str(product_ids[0])+”}”,
‘name': ‘Stock by Location’,
‘view_type': ‘form’,
‘view_mode': ‘tree,form’,
‘src_model': ‘evar.component’,
‘res_model': ‘stock.location’,
‘view_id': False,
‘type': ‘ir.actions.act_window’
}
return result
class component_stock_location(wizard.interface):
states = {
‘init': {
‘actions': [],
‘result': {‘type': ‘action’, ‘action': _do_component_stock_location_action, ‘state': ‘end’}
},
}
component_stock_location(“component.stock.location.wizard”)

Upgrade or install the module. It should work

Customize OpenERP workflow

August 24, 2010

1) Customize activity

<record id=”prod_act_update_sale_info” model=”workflow.activity”>
<field name=”wkf_id” ref=”mrp.wkf_prod“/>    (1)
<field name=”kind”>function</field>
<field name=”action”>update_cost_sale_order()</field>
<field name=”name”>update_sale_info</field>
</record>

2) Customize transition

<record id=“mrp.prod_trans_ready_in_production” model=”workflow.transition”>
<field name=”act_from” ref=”mrp.prod_act_ready“/>
<field name=”act_to” ref=”prod_act_update_sale_info”/>
<field name=”signal”>button_produce</field>
</record>

OpenERP: Report by using workflow

August 13, 2010

It’s easy to make a report in OpenERP.

here the steps

product_report.xml

<?xml version=”1.0″ encoding=”utf-8″?>
<openerp>
<data>
<report auto=”False” id=”product_specification” model=”product.product” name=”product.specification” rml=”template.odt” string=”Product” menu=”False”/>
<record id=”product_specification” model=”ir.actions.report.xml”>
<field name=”type”>ir.actions.report.xml</field>
<field name=”report_name”>product.specification</field>
<field name=”report_type”>oo-pdf</field>
<field name=”model”>product.product</field>
<field name=”report_rml”>template.odt</field>
<field name=”name”>Product Specification</field>
<field name=”auto”>False</field>
</record>
</data>
</openerp>

By doing this, OpenERP web client will generate a report link in the sidebar. Clicking on this, it will ask OpenOffice for the pdf. So far so good.

But now, what I want is getting report as zip file. The file will contains some attachments related to this product. To do this,we must have a way to transfer context data to web client and tell him that ” hey, I want to get report data as zip file and some attachments a long with main report”.

Currently, web client doesn’t support giving zip file but first of all, try a way to sending context data to web client report function.

See my way of using wizard.

Change report link as action link

<wizard
id=”product_spec_open_wizard”
model=”product.product”
name=”product.spec.wizard”
string=”Product Specification”/>

Hide report link

<report  id=”product_specification” menu=”False“/>

Create product_wizard.py

# -*- encoding: utf-8 -*-
import wizard
import pooler

def _do_zip_file(self, cr, uid, data, context):
attachment_ids = pooler.get_pool(cr.dbname).get(‘ir.attachment’).search(cr,uid,[(‘res_model’,’=’, data['model']),(‘res_id’,’=’,data['id']),(‘datas_fname’,’in’,['ABC','CDE'])])
data['form'] = data['form'] or {}
if attachment_ids is not None and len(attachment_ids) >0:
data['form']['report_as_zip']=True
data['form']['attachment_ids']=attachment_ids
else:
data['form']['report_as_zip']=False
return data['form']

class product_spec(wizard.interface):
states = {
‘init': {
‘actions': [_do_zip_file],
‘result': {‘type':’print’, ‘report':’product.spec.wizard’, ‘state':’end’} (1)(2)
},
}
product_spec(“product.spec.wizard”)

(1)  We starts wizard and end it at one step

(2) OpenERP provides us type=”print” and report name.

In the next post, I will show how to hack the web client to support downloading zip file

OpenERP: Custom view Cheatsheet

August 13, 2010

1)  Extends and replace

<record id=”my_view_warehouse_tree” model=”ir.ui.view”>
<field name=”name”>my.stock.warehouse.tree</field>
<field name=”model”>stock.warehouse</field>
<field name=”type”>tree</field>
<field name=”inherit_id” ref=”stock.view_warehouse_tree”/> (1) (2)
<field eval=”4″ name=”priority”/>
<field name=”arch” type=”xml”>
<field name=”partner_address_id” position=”replace”> (3)
<field name=”partner_id”/>
</field>

</field>
</record>

(1) Using inherit_id field

(2) reference name: module_name.view_id

(3) Using replace inside arch xml

2) Override view

Using priority field with smaller value

3) Hide field

<field name=”origin” select=”2″ invisible=”1″/>

4) hide group/page

<page string=”Delivery &amp; Invoices” attrs=”{‘invisible':[('state','!=','')]}”>

5) change default value

class purchase_order(osv.osv):
_inherit = ‘purchase.order’
_defaults = {
‘invoice_method': lambda *a: ‘picking’
}
purchase_order()

Read and Write binary data by using PostgeSQL and Python

August 11, 2010

Code snippet

mport psycopg2, base64, StringIO
# Connect to a DB, e.g., the test DB on your localhost, and get a cursor
conn = psycopg2.connect(database=”ec”, user=”postgres”, password=”abc”,host=”localhost”)

curs = conn.cursor()
try:
curs.execute(“CREATE TABLE test_binary (id int4, name text, img bytea)”)
except:
conn.rollback()
curs.execute(“DROP TABLE test_binary”)
curs.execute(“CREATE TABLE test_binary (id int4, name text, img bytea)”)
conn.commit()

# first we try two inserts, one with an explicit Binary call and the other
# using a buffer on a file object.

data3 = {‘id':3, ‘name':’whereareyou2.jpg’,
‘img':base64.encodestring(open(‘whereareyou2.jpg’).read())}

curs.execute(“””INSERT INTO test_binary
VALUES (%(id)s, %(name)s, %(img)s)”””, data3)

# now we try to extract the images as simple text strings

curs.execute(“SELECT * FROM test_binary”)

for row in curs.fetchall():
name, ext = row[1].split(‘.’)
new_name = name + ‘_S.’ + ext
imagedata = StringIO.StringIO(row[2]).getvalue()
open(new_name, ‘wb’).write(base64.decodestring(imagedata))

The origin source code can be found at psycopg2-2.0.14/examples.

I modified the source code to store binary data as base64 encoded string and retrieving then converting from database by using StringIO.

OpenOffice: Open port

August 4, 2010

I’m using openoffice-python library, but get the following error

Failed to connect to OpenOffice.org on port 8100. Connector : couldn’t connect to socket (Success)

to get over this error, running this command

ooffice "-accept=socket,host=localhost,port=8100;urp;"

What is urp parameter?

I don’t know


Follow

Get every new post delivered to your Inbox.