2008-07-23 15:01:27 +00:00
# -*- encoding: utf-8 -*-
2006-12-07 13:41:40 +00:00
##############################################################################
#
2008-11-03 18:27:16 +00:00
# OpenERP, Open Source Management Solution
2009-01-04 22:13:29 +00:00
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
2008-11-03 18:27:16 +00:00
# $Id$
2008-06-16 11:00:21 +00:00
#
2008-11-03 18:27:16 +00:00
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
2006-12-07 13:41:40 +00:00
#
2008-11-03 18:27:16 +00:00
# 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 General Public License for more details.
2006-12-07 13:41:40 +00:00
#
2008-11-03 18:27:16 +00:00
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
2006-12-07 13:41:40 +00:00
#
##############################################################################
import tarfile
import re
import urllib
import os
import tools
2006-12-28 11:06:46 +00:00
from osv import fields , osv , orm
2007-04-21 13:32:18 +00:00
import zipfile
2007-07-30 13:35:27 +00:00
import release
2008-01-15 14:01:08 +00:00
import zipimport
2007-07-30 13:35:27 +00:00
2008-06-20 11:49:23 +00:00
import wizard
2008-07-16 09:07:15 +00:00
import addons
2008-09-04 13:54:32 +00:00
import pooler
import netsvc
2008-06-20 11:49:23 +00:00
2008-12-02 16:47:26 +00:00
from tools . parse_version import parse_version
2006-12-07 13:41:40 +00:00
2008-12-08 07:51:31 +00:00
2006-12-07 13:41:40 +00:00
class module_repository ( osv . osv ) :
2008-07-22 14:24:36 +00:00
_name = " ir.module.repository "
_description = " Module Repository "
_columns = {
' name ' : fields . char ( ' Name ' , size = 128 ) ,
' url ' : fields . char ( ' Url ' , size = 256 , required = True ) ,
' sequence ' : fields . integer ( ' Sequence ' , required = True ) ,
' filter ' : fields . char ( ' Filter ' , size = 128 , required = True ,
help = ' Regexp to search module on the repository webpage: \n '
' - The first parenthesis must match the name of the module. \n '
' - The second parenthesis must match all the version number. \n '
' - The last parenthesis must match the extension of the module. ' ) ,
' active ' : fields . boolean ( ' Active ' ) ,
}
_defaults = {
' sequence ' : lambda * a : 5 ,
2008-12-02 16:47:26 +00:00
' filter ' : lambda * a : ' href= " ([a-zA-Z0-9_]+)-( ' + release . major_version + ' .( \\ d+)(( \\ . \\ d+)*)([a-z]?)((_(pre|p|beta|alpha|rc) \\ d*)*)(-r( \\ d+))?)( \ .zip) " ' ,
2008-07-22 14:24:36 +00:00
' active ' : lambda * a : 1 ,
}
_order = " sequence "
2006-12-07 13:41:40 +00:00
module_repository ( )
class module_category ( osv . osv ) :
2008-07-22 14:24:36 +00:00
_name = " ir.module.category "
_description = " Module Category "
def _module_nbr ( self , cr , uid , ids , prop , unknow_none , context ) :
cr . execute ( ' select category_id,count(*) from ir_module_module where category_id in ( ' + ' , ' . join ( map ( str , ids ) ) + ' ) or category_id in (select id from ir_module_category where parent_id in ( ' + ' , ' . join ( map ( str , ids ) ) + ' )) group by category_id ' )
result = dict ( cr . fetchall ( ) )
for id in ids :
2008-12-09 12:37:22 +00:00
cr . execute ( ' select id from ir_module_category where parent_id= %s ' , ( id , ) )
2008-07-22 14:24:36 +00:00
childs = [ c for c , in cr . fetchall ( ) ]
result [ id ] = reduce ( lambda x , y : x + y , [ result . get ( c , 0 ) for c in childs ] , result . get ( id , 0 ) )
return result
_columns = {
' name ' : fields . char ( " Name " , size = 128 , required = True ) ,
' parent_id ' : fields . many2one ( ' ir.module.category ' , ' Parent Category ' , select = True ) ,
' child_ids ' : fields . one2many ( ' ir.module.category ' , ' parent_id ' , ' Parent Category ' ) ,
' module_nr ' : fields . function ( _module_nbr , method = True , string = ' # of Modules ' , type = ' integer ' )
}
_order = ' name '
2006-12-07 13:41:40 +00:00
module_category ( )
class module ( osv . osv ) :
2008-07-22 14:24:36 +00:00
_name = " ir.module.module "
_description = " Module "
def get_module_info ( self , name ) :
try :
f = tools . file_open ( os . path . join ( name , ' __terp__.py ' ) )
data = f . read ( )
info = eval ( data )
if ' version ' in info :
2008-12-02 16:47:26 +00:00
info [ ' version ' ] = release . major_version + ' . ' + info [ ' version ' ]
2008-07-22 14:24:36 +00:00
f . close ( )
except :
return { }
return info
2008-12-11 11:44:13 +00:00
def _get_latest_version ( self , cr , uid , ids , field_name = None , arg = None , context = { } ) :
2008-12-11 12:20:07 +00:00
res = dict . fromkeys ( ids , ' ' )
2008-07-22 14:24:36 +00:00
for m in self . browse ( cr , uid , ids ) :
2008-12-11 11:44:13 +00:00
res [ m . id ] = self . get_module_info ( m . name ) . get ( ' version ' , ' ' )
2008-07-22 14:24:36 +00:00
return res
2008-10-24 10:41:31 +00:00
def _get_views ( self , cr , uid , ids , field_name = None , arg = None , context = { } ) :
res = { }
model_data_obj = self . pool . get ( ' ir.model.data ' )
view_obj = self . pool . get ( ' ir.ui.view ' )
2008-12-11 08:19:31 +00:00
report_obj = self . pool . get ( ' ir.actions.report.xml ' )
menu_obj = self . pool . get ( ' ir.ui.menu ' )
mlist = self . browse ( cr , uid , ids , context = context )
mnames = { }
for m in mlist :
mnames [ m . name ] = m . id
res [ m . id ] = {
' menus_by_module ' : ' ' ,
' reports_by_module ' : ' ' ,
' views_by_module ' : ' '
}
view_id = model_data_obj . search ( cr , uid , [ ( ' module ' , ' in ' , mnames . keys ( ) ) ,
( ' model ' , ' in ' , ( ' ir.ui.view ' , ' ir.actions.report.xml ' , ' ir.ui.menu ' ) ) ] )
for data_id in model_data_obj . browse ( cr , uid , view_id , context ) :
2008-12-14 16:46:47 +00:00
# We use try except, because views or menus may not exist
try :
key = data_id [ ' model ' ]
if key == ' ir.ui.view ' :
v = view_obj . browse ( cr , uid , data_id . res_id )
aa = v . inherit_id and ' * INHERIT ' or ' '
res [ mnames [ data_id . module ] ] [ ' views_by_module ' ] + = aa + v . name + ' ( ' + v . type + ' ) \n '
elif key == ' ir.actions.report.xml ' :
res [ mnames [ data_id . module ] ] [ ' reports_by_module ' ] + = report_obj . browse ( cr , uid , data_id . res_id ) . name + ' \n '
elif key == ' ir.ui.menu ' :
res [ mnames [ data_id . module ] ] [ ' menus_by_module ' ] + = menu_obj . browse ( cr , uid , data_id . res_id ) . complete_name + ' \n '
except KeyError , e :
pass
2008-10-24 10:41:31 +00:00
return res
2008-07-22 14:24:36 +00:00
_columns = {
' name ' : fields . char ( " Name " , size = 128 , readonly = True , required = True ) ,
' category_id ' : fields . many2one ( ' ir.module.category ' , ' Category ' , readonly = True ) ,
2008-10-07 05:08:51 +00:00
' shortdesc ' : fields . char ( ' Short description ' , size = 256 , readonly = True , translate = True ) ,
' description ' : fields . text ( " Description " , readonly = True , translate = True ) ,
2008-07-22 14:24:36 +00:00
' author ' : fields . char ( " Author " , size = 128 , readonly = True ) ,
' website ' : fields . char ( " Website " , size = 256 , readonly = True ) ,
2008-12-11 11:44:13 +00:00
# attention: Incorrect field names !!
# installed_version refer the latest version (the one on disk)
# latest_version refer the installed version (the one in database)
# published_version refer the version available on the repository
' installed_version ' : fields . function ( _get_latest_version , method = True ,
string = ' Latest version ' , type = ' char ' ) ,
' latest_version ' : fields . char ( ' Installed version ' , size = 64 , readonly = True ) ,
2008-07-22 14:24:36 +00:00
' published_version ' : fields . char ( ' Published Version ' , size = 64 , readonly = True ) ,
2008-12-11 11:44:13 +00:00
2008-07-22 14:24:36 +00:00
' url ' : fields . char ( ' URL ' , size = 128 ) ,
' dependencies_id ' : fields . one2many ( ' ir.module.module.dependency ' ,
' module_id ' , ' Dependencies ' , readonly = True ) ,
' state ' : fields . selection ( [
( ' uninstallable ' , ' Not Installable ' ) ,
( ' uninstalled ' , ' Not Installed ' ) ,
( ' installed ' , ' Installed ' ) ,
( ' to upgrade ' , ' To be upgraded ' ) ,
( ' to remove ' , ' To be removed ' ) ,
( ' to install ' , ' To be installed ' )
] , string = ' State ' , readonly = True ) ,
' demo ' : fields . boolean ( ' Demo data ' ) ,
2008-11-03 18:19:28 +00:00
' license ' : fields . selection ( [
( ' GPL-2 ' , ' GPL-2 ' ) ,
( ' GPL-2 or any later version ' , ' GPL-2 or later version ' ) ,
( ' GPL-3 ' , ' GPL-3 ' ) ,
( ' GPL-3 or any later version ' , ' GPL-3 or later version ' ) ,
( ' Other proprietary ' , ' Other proprietary ' )
] , string = ' License ' , readonly = True ) ,
2008-12-13 06:01:18 +00:00
' menus_by_module ' : fields . function ( _get_views , method = True , string = ' Menus ' , type = ' text ' , multi = " meta " , store = True ) ,
' reports_by_module ' : fields . function ( _get_views , method = True , string = ' Reports ' , type = ' text ' , multi = " meta " , store = True ) ,
' views_by_module ' : fields . function ( _get_views , method = True , string = ' Views ' , type = ' text ' , multi = " meta " , store = True ) ,
2009-01-06 14:36:21 +00:00
' certificat ' : fields . char ( ' Certificat ' , size = 64 , readonly = True ) ,
2008-07-22 14:24:36 +00:00
}
_defaults = {
' state ' : lambda * a : ' uninstalled ' ,
' demo ' : lambda * a : False ,
' license ' : lambda * a : ' GPL-2 ' ,
}
_order = ' name '
_sql_constraints = [
2009-01-06 14:36:21 +00:00
( ' name_uniq ' , ' unique (name) ' , ' The name of the module must be unique ! ' ) ,
( ' certificat_uniq ' , ' unique (certificat) ' , ' The certificat ID of the module must be unique ! ' )
]
def _check_certificat ( self , cr , uid , ids ) :
if not ids :
return True
logger = netsvc . Logger ( )
for mod in self . browse ( cr , uid , ids ) :
if not mod . certificat :
logger . notifyChannel ( ' ' , netsvc . LOG_WARNING , ' module %s : no certificat ' % mod . name )
else :
try :
val = long ( mod . certificat ) % 97 == 29
if not val :
raise Exception ( ' Invalid Certificat ' )
except Exception , ex :
return False
return True
_constraints = [
( _check_certificat , " Your certificat is wrong ! " , [ ' certificat ' ] ) ,
2008-07-22 14:24:36 +00:00
]
def unlink ( self , cr , uid , ids , context = None ) :
if not ids :
return True
if isinstance ( ids , ( int , long ) ) :
ids = [ ids ]
for mod in self . read ( cr , uid , ids , [ ' state ' ] , context ) :
if mod [ ' state ' ] in ( ' installed ' , ' to upgrade ' , ' to remove ' , ' to install ' ) :
raise orm . except_orm ( _ ( ' Error ' ) ,
_ ( ' You try to remove a module that is installed or will be installed ' ) )
return super ( module , self ) . unlink ( cr , uid , ids , context = context )
2008-09-23 08:15:37 +00:00
2008-12-08 07:51:31 +00:00
def state_update ( self , cr , uid , ids , newstate , states_to_update , context = { } , level = 100 ) :
2008-07-22 14:24:36 +00:00
if level < 1 :
2008-08-20 12:00:54 +00:00
raise orm . except_orm ( _ ( ' Error ' ) , _ ( ' Recursion error in modules dependencies ! ' ) )
2008-09-03 08:06:01 +00:00
demo = False
2008-07-22 14:24:36 +00:00
for module in self . browse ( cr , uid , ids ) :
2008-09-03 08:06:01 +00:00
mdemo = False
2008-07-22 14:24:36 +00:00
for dep in module . dependencies_id :
2008-08-20 12:00:54 +00:00
if dep . state == ' unknown ' :
2008-09-01 19:29:02 +00:00
raise orm . except_orm ( _ ( ' Error ' ) , _ ( ' You try to install a module that depends on the module: %s . \n But this module is not available in your system. ' ) % ( dep . name , ) )
2008-09-15 12:52:00 +00:00
ids2 = self . search ( cr , uid , [ ( ' name ' , ' = ' , dep . name ) ] )
2008-08-20 12:00:54 +00:00
if dep . state != newstate :
2008-09-03 08:06:01 +00:00
mdemo = self . state_update ( cr , uid , ids2 , newstate , states_to_update , context , level - 1 , ) or mdemo
2008-09-15 12:52:00 +00:00
else :
od = self . browse ( cr , uid , ids2 ) [ 0 ]
mdemo = od . demo or mdemo
if not module . dependencies_id :
2008-07-22 14:24:36 +00:00
mdemo = module . demo
2008-08-20 12:00:54 +00:00
if module . state in states_to_update :
2008-07-22 14:24:36 +00:00
self . write ( cr , uid , [ module . id ] , { ' state ' : newstate , ' demo ' : mdemo } )
2008-09-03 08:06:01 +00:00
demo = demo or mdemo
2008-07-22 14:24:36 +00:00
return demo
def button_install ( self , cr , uid , ids , context = { } ) :
2008-08-20 12:00:54 +00:00
return self . state_update ( cr , uid , ids , ' to install ' , [ ' uninstalled ' ] , context )
2008-07-22 14:24:36 +00:00
def button_install_cancel ( self , cr , uid , ids , context = { } ) :
self . write ( cr , uid , ids , { ' state ' : ' uninstalled ' , ' demo ' : False } )
return True
def button_uninstall ( self , cr , uid , ids , context = { } ) :
for module in self . browse ( cr , uid , ids ) :
cr . execute ( ''' select m.state,m.name
from
ir_module_module_dependency d
join
ir_module_module m on ( d . module_id = m . id )
where
d . name = % s and
m . state not in ( ' uninstalled ' , ' uninstallable ' , ' to remove ' ) ''' , (module.name,))
res = cr . fetchall ( )
if res :
2008-10-25 08:53:56 +00:00
raise orm . except_orm ( _ ( ' Error ' ) , _ ( ' Some installed modules depends on the module you plan to desinstall : \n %s ' ) % ' \n ' . join ( map ( lambda x : ' \t %s : %s ' % ( x [ 0 ] , x [ 1 ] ) , res ) ) )
2008-07-22 14:24:36 +00:00
self . write ( cr , uid , ids , { ' state ' : ' to remove ' } )
return True
def button_uninstall_cancel ( self , cr , uid , ids , context = { } ) :
self . write ( cr , uid , ids , { ' state ' : ' installed ' } )
return True
2008-09-17 15:55:18 +00:00
2008-07-22 14:24:36 +00:00
def button_upgrade ( self , cr , uid , ids , context = None ) :
2008-09-17 15:55:18 +00:00
depobj = self . pool . get ( ' ir.module.module.dependency ' )
todo = self . browse ( cr , uid , ids , context = context )
i = 0
while i < len ( todo ) :
mod = todo [ i ]
i + = 1
if mod . state not in ( ' installed ' , ' to upgrade ' ) :
raise orm . except_orm ( _ ( ' Error ' ) ,
_ ( " Can not upgrade module ' %s ' . It is not installed. " ) % ( mod . name , ) )
iids = depobj . search ( cr , uid , [ ( ' name ' , ' = ' , mod . name ) ] , context = context )
for dep in depobj . browse ( cr , uid , iids , context = context ) :
2008-12-12 14:14:36 +00:00
if dep . module_id . state == ' installed ' and dep . module_id not in todo :
2008-09-17 15:55:18 +00:00
todo . append ( dep . module_id )
2008-12-11 16:07:46 +00:00
2008-12-11 14:54:20 +00:00
ids = map ( lambda x : x . id , todo )
self . write ( cr , uid , ids , { ' state ' : ' to upgrade ' } , context = context )
2008-12-11 16:07:46 +00:00
to_install = [ ]
for mod in todo :
for dep in mod . dependencies_id :
if dep . state == ' unknown ' :
raise orm . except_orm ( _ ( ' Error ' ) , _ ( ' You try to upgrade a module that depends on the module: %s . \n But this module is not available in your system. ' ) % ( dep . name , ) )
if dep . state == ' uninstalled ' :
ids2 = self . search ( cr , uid , [ ( ' name ' , ' = ' , dep . name ) ] )
to_install . extend ( ids2 )
2008-12-12 14:14:36 +00:00
2008-12-11 16:07:46 +00:00
self . button_install ( cr , uid , to_install , context = context )
2008-09-17 15:55:18 +00:00
return True
2008-07-22 14:24:36 +00:00
def button_upgrade_cancel ( self , cr , uid , ids , context = { } ) :
self . write ( cr , uid , ids , { ' state ' : ' installed ' } )
return True
2008-09-04 13:54:32 +00:00
def button_update_translations ( self , cr , uid , ids , context = None ) :
self . update_translations ( cr , uid , ids )
2008-07-22 14:24:36 +00:00
return True
# update the list of available packages
def update_list ( self , cr , uid , context = { } ) :
robj = self . pool . get ( ' ir.module.repository ' )
res = [ 0 , 0 ] # [update, add]
# iterate through installed modules and mark them as being so
2008-12-15 12:36:33 +00:00
for mod_name in addons . get_modules ( ) :
2008-07-22 14:24:36 +00:00
ids = self . search ( cr , uid , [ ( ' name ' , ' = ' , mod_name ) ] )
if ids :
id = ids [ 0 ]
mod = self . browse ( cr , uid , id )
terp = self . get_module_info ( mod_name )
if terp . get ( ' installable ' , True ) and mod . state == ' uninstallable ' :
self . write ( cr , uid , id , { ' state ' : ' uninstalled ' } )
2008-12-01 15:04:04 +00:00
if parse_version ( terp . get ( ' version ' , ' ' ) ) > parse_version ( mod . latest_version or ' ' ) :
2008-12-15 12:36:33 +00:00
self . write ( cr , uid , id , { ' url ' : ' ' } )
2008-07-22 14:24:36 +00:00
res [ 0 ] + = 1
self . write ( cr , uid , id , {
' description ' : terp . get ( ' description ' , ' ' ) ,
' shortdesc ' : terp . get ( ' name ' , ' ' ) ,
' author ' : terp . get ( ' author ' , ' Unknown ' ) ,
' website ' : terp . get ( ' website ' , ' ' ) ,
' license ' : terp . get ( ' license ' , ' GPL-2 ' ) ,
2009-01-06 14:36:21 +00:00
' certificat ' : terp . get ( ' certificat ' , ' ' ) ,
2008-07-22 14:24:36 +00:00
} )
2008-12-15 12:36:33 +00:00
cr . execute ( ' DELETE FROM ir_module_module_dependency WHERE module_id = %s ' , ( id , ) )
self . _update_dependencies ( cr , uid , ids [ 0 ] , terp . get ( ' depends ' , [ ] ) )
self . _update_category ( cr , uid , ids [ 0 ] , terp . get ( ' category ' , ' Uncategorized ' ) )
2008-07-22 14:24:36 +00:00
continue
2008-12-15 12:36:33 +00:00
mod_path = addons . get_module_path ( mod_name )
if mod_path :
2008-07-22 14:24:36 +00:00
terp = self . get_module_info ( mod_name )
if not terp or not terp . get ( ' installable ' , True ) :
continue
2008-11-18 10:35:11 +00:00
2008-07-22 14:24:36 +00:00
id = self . create ( cr , uid , {
' name ' : mod_name ,
' state ' : ' uninstalled ' ,
' description ' : terp . get ( ' description ' , ' ' ) ,
' shortdesc ' : terp . get ( ' name ' , ' ' ) ,
' author ' : terp . get ( ' author ' , ' Unknown ' ) ,
' website ' : terp . get ( ' website ' , ' ' ) ,
' license ' : terp . get ( ' license ' , ' GPL-2 ' ) ,
2009-01-06 14:36:21 +00:00
' certificat ' : terp . get ( ' certificat ' , ' ' ) ,
2008-07-22 14:24:36 +00:00
} )
res [ 1 ] + = 1
self . _update_dependencies ( cr , uid , id , terp . get ( ' depends ' , [ ] ) )
self . _update_category ( cr , uid , id , terp . get ( ' category ' , ' Uncategorized ' ) )
for repository in robj . browse ( cr , uid , robj . search ( cr , uid , [ ] ) ) :
try :
index_page = urllib . urlopen ( repository . url ) . read ( )
except IOError , e :
if e . errno == 21 :
raise orm . except_orm ( _ ( ' Error ' ) ,
_ ( " This url ' %s ' must provide an html file with links to zip modules " ) % ( repository . url ) )
else :
raise
modules = re . findall ( repository . filter , index_page , re . I + re . M )
mod_sort = { }
for m in modules :
2008-12-15 12:36:33 +00:00
name , version , extension = m [ 0 ] , m [ 1 ] , m [ - 1 ]
2008-12-26 10:14:34 +00:00
if not version or version == ' x ' : # 'x' version was a mistake
2008-07-22 14:24:36 +00:00
version = ' 0 '
if name in mod_sort :
2008-12-01 15:04:04 +00:00
if parse_version ( version ) < = parse_version ( mod_sort [ name ] [ 0 ] ) :
2008-07-22 14:24:36 +00:00
continue
mod_sort [ name ] = [ version , extension ]
for name in mod_sort . keys ( ) :
version , extension = mod_sort [ name ]
url = repository . url + ' / ' + name + ' - ' + version + extension
ids = self . search ( cr , uid , [ ( ' name ' , ' = ' , name ) ] )
if not ids :
self . create ( cr , uid , {
' name ' : name ,
' published_version ' : version ,
' url ' : url ,
' state ' : ' uninstalled ' ,
} )
res [ 1 ] + = 1
else :
id = ids [ 0 ]
2008-12-11 11:44:13 +00:00
installed_version = self . read ( cr , uid , id , [ ' latest_version ' ] ) [ ' latest_version ' ]
2008-12-26 10:14:34 +00:00
if not installed_version or installed_version == ' x ' : # 'x' version was a mistake
2008-12-11 11:44:13 +00:00
installed_version = ' 0 '
if parse_version ( version ) > parse_version ( installed_version ) :
2008-12-15 12:36:33 +00:00
self . write ( cr , uid , id , { ' url ' : url } )
2008-07-22 14:24:36 +00:00
res [ 0 ] + = 1
2008-12-11 11:44:13 +00:00
published_version = self . read ( cr , uid , id , [ ' published_version ' ] ) [ ' published_version ' ]
2008-07-22 14:24:36 +00:00
if published_version == ' x ' or not published_version :
published_version = ' 0 '
2008-12-01 15:04:04 +00:00
if parse_version ( version ) > parse_version ( published_version ) :
2008-12-15 12:36:33 +00:00
self . write ( cr , uid , id , { ' published_version ' : version } )
2008-07-22 14:24:36 +00:00
return res
def download ( self , cr , uid , ids , download = True , context = None ) :
res = [ ]
for mod in self . browse ( cr , uid , ids , context = context ) :
if not mod . url :
continue
match = re . search ( ' -([a-zA-Z0-9 \ ._-]+)( \ .zip) ' , mod . url , re . I )
version = ' 0 '
if match :
2008-09-23 08:15:37 +00:00
version = match . group ( 1 )
2008-12-01 15:04:04 +00:00
if parse_version ( mod . installed_version or ' 0 ' ) > = parse_version ( version ) :
2008-07-22 14:24:36 +00:00
continue
res . append ( mod . url )
if not download :
continue
zipfile = urllib . urlopen ( mod . url ) . read ( )
2008-09-23 08:15:37 +00:00
fname = addons . get_module_path ( mod . name + ' .zip ' )
2008-07-22 14:24:36 +00:00
try :
fp = file ( fname , ' wb ' )
fp . write ( zipfile )
fp . close ( )
except IOError , e :
raise orm . except_orm ( _ ( ' Error ' ) , _ ( ' Can not create the module file: \n %s ' ) % ( fname , ) )
terp = self . get_module_info ( mod . name )
self . write ( cr , uid , mod . id , {
' description ' : terp . get ( ' description ' , ' ' ) ,
' shortdesc ' : terp . get ( ' name ' , ' ' ) ,
' author ' : terp . get ( ' author ' , ' Unknown ' ) ,
' website ' : terp . get ( ' website ' , ' ' ) ,
' license ' : terp . get ( ' license ' , ' GPL-2 ' ) ,
2009-01-06 14:36:21 +00:00
' certificat ' : terp . get ( ' certificat ' , ' ' ) ,
2008-07-22 14:24:36 +00:00
} )
cr . execute ( ' DELETE FROM ir_module_module_dependency ' \
2008-12-09 12:37:22 +00:00
' WHERE module_id = %s ' , ( mod . id , ) )
2008-07-22 14:24:36 +00:00
self . _update_dependencies ( cr , uid , mod . id , terp . get ( ' depends ' ,
[ ] ) )
self . _update_category ( cr , uid , mod . id , terp . get ( ' category ' ,
' Uncategorized ' ) )
# Import module
zimp = zipimport . zipimporter ( fname )
zimp . load_module ( mod . name )
return res
def _update_dependencies ( self , cr , uid , id , depends = [ ] ) :
for d in depends :
2008-12-09 12:37:22 +00:00
cr . execute ( ' INSERT INTO ir_module_module_dependency (module_id, name) values ( %s , %s ) ' , ( id , d ) )
2008-07-22 14:24:36 +00:00
def _update_category ( self , cr , uid , id , category = ' Uncategorized ' ) :
categs = category . split ( ' / ' )
p_id = None
while categs :
if p_id is not None :
2008-12-09 12:37:22 +00:00
cr . execute ( ' select id from ir_module_category where name= %s and parent_id= %s ' , ( categs [ 0 ] , p_id ) )
2008-07-22 14:24:36 +00:00
else :
cr . execute ( ' select id from ir_module_category where name= %s and parent_id is NULL ' , ( categs [ 0 ] , ) )
c_id = cr . fetchone ( )
if not c_id :
cr . execute ( ' select nextval( \' ir_module_category_id_seq \' ) ' )
c_id = cr . fetchone ( ) [ 0 ]
2008-12-09 12:37:22 +00:00
cr . execute ( ' insert into ir_module_category (id, name, parent_id) values ( %s , %s , %s ) ' , ( c_id , categs [ 0 ] , p_id ) )
2008-07-22 14:24:36 +00:00
else :
c_id = c_id [ 0 ]
p_id = c_id
categs = categs [ 1 : ]
self . write ( cr , uid , [ id ] , { ' category_id ' : p_id } )
2008-08-26 10:41:13 +00:00
2008-09-04 13:54:32 +00:00
def update_translations ( self , cr , uid , ids , filter_lang = None ) :
logger = netsvc . Logger ( )
if not filter_lang :
pool = pooler . get_pool ( cr . dbname )
2008-10-24 15:07:43 +00:00
lang_obj = pool . get ( ' res.lang ' )
lang_ids = lang_obj . search ( cr , uid , [ ( ' translatable ' , ' = ' , True ) ] )
filter_lang = [ lang . code for lang in lang_obj . browse ( cr , uid , lang_ids ) ]
2008-09-04 13:54:32 +00:00
elif not isinstance ( filter_lang , ( list , tuple ) ) :
filter_lang = [ filter_lang ]
for mod in self . browse ( cr , uid , ids ) :
if mod . state != ' installed ' :
continue
2008-09-23 08:15:37 +00:00
2008-09-04 13:54:32 +00:00
for lang in filter_lang :
2008-12-22 11:18:26 +00:00
f = os . path . join ( addons . get_module_path ( mod . name ) , ' i18n ' , lang + ' .po ' )
2008-09-04 13:54:32 +00:00
if os . path . exists ( f ) :
2008-12-17 09:42:22 +00:00
logger . notifyChannel ( " init " , netsvc . LOG_INFO , ' module %s : loading translation file for language %s ' % ( mod . name , lang ) )
2008-09-04 13:54:32 +00:00
tools . trans_load ( cr . dbname , f , lang , verbose = False )
2008-12-22 23:58:21 +00:00
def write ( self , cr , uid , ids , vals , context = None ) :
# Override the write method because we want to show a warning when the description field is empty !
if isinstance ( ids , ( long , int ) ) :
ids = [ ids ]
if ' description ' in vals and not vals [ ' description ' ] :
logger = netsvc . Logger ( )
for mod in self . browse ( cr , uid , ids ) :
logger . notifyChannel ( " init " , netsvc . LOG_WARNING , ' module %s : description is empty ! ' % ( mod . name ) )
return super ( module , self ) . write ( cr , uid , ids , vals , context = context )
def create ( self , cr , uid , vals , context = None ) :
# Override the create method because we want to show a warning when the description field is empty !
module_id = super ( module , self ) . create ( cr , uid , vals , context = context )
if ' description ' in vals and not vals [ ' description ' ] :
logger = netsvc . Logger ( )
for mod in self . browse ( cr , uid , [ module_id ] ) :
logger . notifyChannel ( " init " , netsvc . LOG_WARNING , ' module %s : description is empty ! ' % ( mod . name ) )
2009-01-06 14:36:21 +00:00
return module_id
2008-12-22 23:58:21 +00:00
2006-12-07 13:41:40 +00:00
module ( )
class module_dependency ( osv . osv ) :
2008-07-22 14:24:36 +00:00
_name = " ir.module.module.dependency "
_description = " Module dependency "
def _state ( self , cr , uid , ids , name , args , context = { } ) :
result = { }
mod_obj = self . pool . get ( ' ir.module.module ' )
for md in self . browse ( cr , uid , ids ) :
ids = mod_obj . search ( cr , uid , [ ( ' name ' , ' = ' , md . name ) ] )
if ids :
result [ md . id ] = mod_obj . read ( cr , uid , [ ids [ 0 ] ] , [ ' state ' ] ) [ 0 ] [ ' state ' ]
else :
result [ md . id ] = ' unknown '
return result
_columns = {
' name ' : fields . char ( ' Name ' , size = 128 ) ,
' module_id ' : fields . many2one ( ' ir.module.module ' , ' Module ' , select = True , ondelete = ' cascade ' ) ,
' state ' : fields . function ( _state , method = True , type = ' selection ' , selection = [
( ' uninstallable ' , ' Uninstallable ' ) ,
( ' uninstalled ' , ' Not Installed ' ) ,
( ' installed ' , ' Installed ' ) ,
( ' to upgrade ' , ' To be upgraded ' ) ,
( ' to remove ' , ' To be removed ' ) ,
( ' to install ' , ' To be installed ' ) ,
( ' unknown ' , ' Unknown ' ) ,
] , string = ' State ' , readonly = True ) ,
}
2006-12-07 13:41:40 +00:00
module_dependency ( )
2008-09-15 12:52:00 +00:00
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: