#!/usr/bin/env python # Usage: # ./odoo-export.py [ [ []]] from __future__ import print_function import os import sys import json import odoorpc # pip install odoorpc def eprint(*args, **kwargs): print(*args, file=sys.stderr, **kwargs) # CONFIG FOLDER = '/home/dig/odoo-export/datas' PARAMS = sys.argv[1:] MODEL_IGNORE = [] with open(".modelignore", "r") as file: for line in file: MODEL_IGNORE.append(line.strip()) eprint( len(sys.argv), 'argument(s):', str(sys.argv) ) eprint( MODEL_IGNORE ) # TABLE VIEW COLUMNS cols = { '': [ 'id', 'name' ], # default 'ir.model': [ 'id', 'model' ], 'ir.model.fields': [ 'id', 'name', 'ttype', 'create_uid', 'relation', 'display_name', 'complete_name' ], } def jlog( obj ): print( json.dumps(obj, indent=4) ) #"\t") ) def ensure_dir(d): if not os.path.exists(d): os.makedirs(d) def args2domains( list ): domains = [] while len(list) > 0: str = list[0] if str == '&' or str == '|' or str == '!': domains.append( str ) list = list[1:] else: domains.append( (list[0], list[1], list[2]) ) list = list[3:] return domains eprint( args2domains(sys.argv[3:]) ) #quit() odoo = None def autolog(): # Then, use the odoorpc.ODOO.load() class method: odoo = odoorpc.ODOO.load('session') # Or, if you have saved your configuration in another file: # odoo = odoorpc.ODOO.load('tutorial', '~/my_own_odoorpcrc') # You can check available sessions with odoorpc.ODOO.list(), and remove them with odoorpc.ODOO.remove(): # odoorpc.ODOO.list() # ['session'] # odoorpc.ODOO.remove('tutorial') # 'tutorial' not in odoorpc.ODOO.list() # True # Current user user = odoo.env.user eprint( 'User: ', user.name ) # name of the user connected eprint( 'Company: ', user.company_id.name ) # the name of its company eprint( '_________________________' ) return odoo # Prepare the connection to the server # odoo = odoorpc.ODOO('localhost', port=8069) # Check available databases # eprint( 'Databases: ', odoo.db.list() ) #jlog( odoo.db.list() ) # Simple 'raw' query #user_data = odoo.execute('res.users', 'read', [user.id]) #print(user_data) # Use all methods of a model #if 'sale.order' in odoo.env: # Order = odoo.env['sale.order'] # order_ids = Order.search([]) # for order in Order.browse(order_ids): # print(order.name) # products = [line.product_id.name for line in order.order_line] # print(products) # Update data through a record #user.name = "Brian Jones" def get_schema( name ): eprint( 'get_schema' ) Model = odoo.env['ir.model'] ids = Model.search([( 'model', '=', name )]) #print( ids ) for model in Model.browse( ids ): obj = model.read()[0] fields = [ field.read()[0] for field in model.field_id ] #jlog( fields ) obj['field_id'] = fields jlog( transform_model(obj) ) eprint( "%s/schemas/%s.json" % ( FOLDER, model.model ) ) def transform_model( obj ): return { "name": obj['model'], "modules": obj['modules'], 'fields': [ {} for field in obj['field_id'] ] } def rel_fields( model ): Model = odoo.env['ir.model.fields'] ids = Model.search([( 'model_id.model', '=', model ), ('relation','!=','false')]) return Model.browse( ids ) def tsv( *fields ): print( *fields, sep='\t' ) def render_tsv( model, list ): if model in cols: _cols = cols[model] else: _cols = cols[''] tsv( *_cols ) for obj in list: tsv( *[ obj[col] for col in _cols] ) #def render_json( model, obj ): # COMMANDS def login( server = None, port = None, db = None, user = None, passwd = None ): if server: tsv( 'Server:', server ) else: server = raw_input('Server address: ') if port: tsv( 'Port:', port ) else: port = raw_input('Port: ') odoo = odoorpc.ODOO( server, port=port ) print( 'Connected to ' + server + ':' + port ) print( 'Available databases:' ) for _db in odoo.db.list(): print( _db ) if db: tsv( 'Database:', db ) else: db = raw_input('Choose database: ') if user: tsv( 'User:', user ) else: user = raw_input('User: ') if passwd: tsv( 'Password:', '****************' ) else: passwd = raw_input('Password: ') eprint( server, port, user, passwd ) user = odoo.login( db, user, passwd ) odoo.save('session') # # By default, these informations are stored in the ~/.odoorpcrc file. You can however use another file: # # odoo.save('tutorial', '~/my_own_odoorpcrc') def search( model, domains ): Model = odoo.env[model] ids = Model.search( domains ) render_tsv( model, Model.browse(ids) ) # print( 'id', 'name', sep='\t' ) # for inst in Model.browse( ids ): # render_tsv( model, inst ) def fields( model, domains ): Model = odoo.env['ir.model.fields'] ids = Model.search([( 'model_id.model', '=', MODEL )]) render_tsv( MODEL, Model.browse(ids) ) current_exports = [] def export_json( model, domains ): print( "Export to json: %s %s" % (model,domains) ) if model in MODEL_IGNORE: print( 'IGNORED' ) return Model = odoo.env[model] ids = Model.search( domains ) ensure_dir( "%s/%s" % (FOLDER, model) ) rfields = rel_fields( model ) eprint( rfields ) for inst in Model.browse( ids ): data = inst.read()[0] filename = "%s/%s/%s.json" % ( FOLDER, model, inst.id ) if filename in current_exports: continue print( 'Preparing data for %s' % (filename) ) current_exports.append( filename ) # Write pretty print JSON data to file with open( filename, "w") as write_file: json.dump(data, write_file, indent=4) print( "%s written" % (filename) ) for field in rfields: #data[field.name] = inst[field.name].read()[0] #eprint( data[field.name] ) if field.relation in MODEL_IGNORE: continue if data[field.name]: tsv( 'Field: ', field.ttype, field.name, field.relation, data[field.name] ) if field.ttype == 'many2one': id = data[field.name][0] _filename = "%s/%s/%s.json" % ( FOLDER, field.relation, id ) print( field.ttype, field.relation, id, _filename ) if not os.path.exists( _filename ): export_json( field.relation, [('id','=',id)] ) else: print('Already exists %s' % (_filename) ) if field.ttype == 'one2many': for id in data[field.name]: _filename = "%s/%s/%s.json" % ( FOLDER, field.relation, id ) print( field.ttype, field.relation, id, _filename ) if not os.path.exists( _filename ): export_json( field.relation, [('id','=',id)] ) else: print('Already exists %s' % (_filename) ) # AUTO EXEC MODEL = PARAMS[0] if len(PARAMS) > 1: METHOD = PARAMS[1] if PARAMS[0] == 'login': login( *PARAMS[1:] ) quit() else: odoo = autolog() if MODEL in odoo.env: Model = odoo.env[MODEL] if METHOD == 'search': search( MODEL, args2domains(sys.argv[3:]) ) #ids = Model.search( args2domains(sys.argv[3:]) ) #print( 'id', 'name', sep='\t' ) #for inst in Model.browse( ids ): # render_tsv( MODEL, inst ) if METHOD == 'browse': ids = sys.argv[3:] ids = [ int(s) for s in ids ] #print( ids ) for inst in Model.browse( ids ): jlog( inst.read()[0] ) if METHOD == 'export-json': export_json( MODEL, args2domains(sys.argv[3:]) ) if METHOD == 'fields_get': jlog( Model.fields_get() ) if METHOD == 'fields': Model = odoo.env['ir.model.fields'] ids = Model.search([( 'model_id.model', '=', MODEL )]) render_tsv( MODEL, Model.browse(ids) ) #for inst in Field.browse( ids ): # render_tsv( 'ir.model.fields', inst ) elif MODEL == 'db': if METHOD == 'list': jlog( odoo.db.list() ) elif MODEL == 'schema': get_schema( METHOD )