def _update(self, searchTuples, args, objectName): """ A sub function that updates the object if it exists """ obj = Object(self.cnx, objectName) commonName = self.common[objectName] results = obj.search(searchTuples) arguments = self.__parse_options(args) if results: if isinstance(results, list): results = results else: results = [results] if len(results) == 1: if obj.write(results, arguments): return results[0] else: raise EnvironmentError("We attempted to update a " + \ + commonName + \ " , but failed.") else: string = ":" for obj in results: string += str(obj) + ", " string += " Search: " for obj in searchTuples: string += str(obj) + ", " raise ValueError("We preformed a search for a " + commonName + \ "and came back with a number greater than one." \ + string)
def _update_no_search(self, id, args, objectName): """ To update an object when we already know the id """ obj = Object(self.cnx, objectName) commonName = self.common[objectName] results = id arguments = self.__parse_options(args) if results: if isinstance(results, list): results = results else: results = [results] if len(results) == 1: if obj.write(results, arguments): return results[0] else: raise EnvironmentError("We attempted to update a " + \ + commonName + \ " , but failed.") else: string = "" for obj in results: string += obj raise ValueError("We preformed a search for a " + commonName + \ "and came back with a number greater than one." \ + string)
def execute_import(filename, connection, separator=',', transaction=False, error_stop=False): """ Read the file, and launched import_data """ model = filename.split('/').pop().replace('.csv', '') if model.find('_') > 4: model = model[model.find('-') + 1:model.find('_')] else: model = model[model.find('-') + 1:] logger.debug('model: %s' % model) obj = Object(connection, model) logger.info('Read and analyse the file content') fp = open(filename, 'r') header = False lines = [] count = 0 reader = csv.reader(fp, delimiter=separator) for line in reader: count += 1 if not header: header = line logger.debug('header: %s' % str(header)) continue lines.append(line) logger.debug('line: %s' % str(line)) logger.info('Read the file content is finished') logger.info('Start import the content in OpenERP (%d datas)' % len(lines)) count = 0 ctx = { 'defer_parent_store_computation': True, 'lang': opts.lang, 'import': True, } if opts.inactive: ctx['active_test'] = False print ctx if transaction: try: logger.info('Import %s lines in one transaction' % len(lines)) res = obj.import_data(header, lines, 'init', '', False, ctx) if res[0] == -1: logger.error('%s' % res[2]) logger.error('%s' % str(res[1])) logger.info('End transaction import') except Exception, e: logger.error(str(e)) if error_stop: raise StopError(str(e))
def readdir(self, path, offset): """ Return content of a directory : - List models for root path - List records for a model - List attachments for a record We don't have to check for the path, because getattr already returns -ENOENT if the model/record/attachment doesn't exist """ yield fuse.Direntry('.') yield fuse.Direntry('..') paths = path.split('/')[1:] # List models if path == '/': model_obj = Object(self.oerp_connection, 'ir.model') model_ids = model_obj.search([]) for model_data in model_obj.read(model_ids, ['model']): yield fuse.Direntry(model_data['model']) # List records elif len(paths) == 1: element_obj = Object(self.oerp_connection, paths[0]) element_ids = element_obj.search([]) for element_data in element_obj.read(element_ids, ['id']): yield fuse.Direntry(str(element_data['id'])) # List attachments else: attachment_obj = Object(self.oerp_connection, 'ir.attachment') attachment_ids = attachment_obj.search([('res_model', '=', paths[0]), ('res_id', '=', int(paths[1]))]) for attachment_data in attachment_obj.read(attachment_ids, ['name']): yield fuse.Direntry('%d-%s' % (attachment_data['id'], attachment_data['name']))
def _exists(self, searchTuples, objectName): """ Returns true if the search has a result. """ obj = Object(self.cnx, objectName) try: if obj.search(searchTuples): return True except: return False
def read(self, path, size, offset): """ Return the specified slide of a file Note : Only the beginning of the name is required (the ID of the attachment), we can put anything after the first '-', it will be ignored """ paths = path.split('/')[1:] # TODO : Create a module that allows to read files by slides attachment_obj = Object(self.oerp_connection, 'ir.attachment') attachment_ids = attachment_obj.search([('res_model', '=', paths[0]), ('res_id', '=', int(paths[1])), ('id', '=', self.id_from_label(paths[2]))]) attachment_data = attachment_obj.read(attachment_ids, ['datas']) return base64.b64decode(attachment_data[0]['datas'])[offset:offset + size]
def _copy_with_args(self, searchTuples, searchExists, args, objectName): """ Does a copy and then adds some extra information. """ obj = Object(self.cnx, objectName) results = obj.search(searchTuples) new_id = obj.copy(results[0]) if self._exists(searchExists, objectName): return True else: return self._update_no_search(new_id, args, objectName)
def _get_period(self, date): d = str(date.date()) obj = Object(self.cnx, 'account.period') ids = obj.search([("date_start", "<=", d), ("date_stop", ">=", d), ("state", "=", "draft"), ("special", "=", False)]) if len(ids) == 1: return ids[0] else: raise ValueError( "Did not find a single open period with that date, %s" % d)
def execute_import(filename, connection, separator=',', transaction=False, error_stop=False): """ Read the file, and launched import_data """ model = filename.split('/').pop().replace('.csv', '') if model.find('_') > 4: model = model[model.find('-') + 1:model.find('_')] else: model = model[model.find('-') + 1:] logger.debug('model: %s' % model) obj = Object(connection, model) logger.info('Read and analyse the file content') fp = open(filename, 'r') header = False lines = [] count = 0 reader = csv.reader(fp, delimiter=separator) for line in reader: count += 1 if not header: header = line logger.debug('header: %s' % str(header)) continue lines.append(line) logger.debug('line: %s' %str(line)) logger.info('Read the file content is finished') logger.info('Start import the content in OpenERP (%d datas)' % len(lines)) count = 0 ctx = { 'defer_parent_store_computation': True, 'lang': opts.lang, 'import': True, } if opts.inactive: ctx['active_test'] = False print ctx if transaction: try: logger.info('Import %s lines in one transaction' % len(lines)) res = obj.import_data(header, lines, 'init', '', False, ctx) if res[0] == -1: logger.error('%s' % res[2]) logger.error('%s' % str(res[1])) logger.info('End transaction import') except Exception, e: logger.error(str(e)) if error_stop: raise StopError(str(e))
def _get_attr(self, searchTuples, objectName, attribute): """ returns value of the attribute """ obj = Object(self.cnx, objectName) results = obj.search(searchTuples) if len(results) != 1: raise ValueError("We did not get a single " + \ self.common[objectName] + " back. " + \ str(results)) else: return obj.read(results[0])[attribute]
def _get(self, searchTuples, objectName): """ returns the object id as int iff the search returns a single result. """ obj = Object(self.cnx, objectName) results = obj.search(searchTuples) if len(results) != 1: raise ValueError("We did not get a single " + \ self.common[objectName] + " back. " + \ str(results) + str(searchTuples)) else: return results[0]
def read(self, path, size, offset): """ Return the specified slide of a file Note : Only the beginning of the name is required (the ID of the attachment), we can put anything after the first '-', it will be ignored """ paths = path.split('/')[1:] # TODO : Create a module that allows to read files by slides attachment_obj = Object(self.oerp_connection, 'ir.attachment') attachment_ids = attachment_obj.search([ ('res_model', '=', paths[0]), ('res_id', '=', int(paths[1])), ('id', '=', self.id_from_label(paths[2])) ]) attachment_data = attachment_obj.read(attachment_ids, ['datas']) return base64.b64decode(attachment_data[0]['datas'])[offset:offset + size]
def _create(self, args, objectName): """ To create a new object, pass in a dictionary of objects and use the objectName to create the object. """ arguments = self.__parse_options(args) obj = Object(self.cnx, objectName) objectCreated = obj.create(arguments) if objectCreated: return objectCreated else: raise EnvironmentError("We attempted to create a " + \ self.common[objectName] + " but failed.")
def getattr(self, path): """ Return attributes for the specified path : - Search for the model as first part - Search for an existing record as second part - Search for an existing attachment as third part - There cannot be more than 3 parts in the path """ fakeStat = fuse.Stat() fakeStat.st_mode = stat.S_IFDIR | 0400 fakeStat.st_nlink = 0 if path == '/': return fakeStat paths = path.split('/')[1:] if len(paths) > 3: return -ENOENT # Check for model existence model_obj = Object(self.oerp_connection, 'ir.model') model_ids = model_obj.search([('model', '=', paths[0])]) if not model_ids: return -ENOENT elif len(paths) == 1: return fakeStat # Check for record existence element_obj = Object(self.oerp_connection, paths[0]) element_ids = element_obj.search([('id', '=', int(paths[1]))]) if not element_ids: return -ENOENT elif len(paths) == 2: return fakeStat # Chech for attachement existence attachment_obj = Object(self.oerp_connection, 'ir.attachment') attachment_ids = attachment_obj.search([('res_model', '=', paths[0]), ('res_id', '=', int(paths[1])), ('id', '=', self.id_from_label(paths[2]))]) if not attachment_ids: return -ENOENT # Common stats fakeStat.st_mode = stat.S_IFREG | 0400 fakeStat.st_nlink = 2 # TODO : Read the file size from a dedicated field (created in a specific module) attachment_obj = Object(self.oerp_connection, 'ir.attachment') attachment_ids = attachment_obj.search([('res_model', '=', paths[0]), ('res_id', '=', int(paths[1])), ('id', '=', self.id_from_label(paths[2]))]) attachment_data = attachment_obj.read(attachment_ids, ['datas']) fakeStat.st_size = len(base64.b64decode(attachment_data[0]['datas'])) return fakeStat
def release(self, path, fh): """ Writing of the file is finished, import the contents into OpenERP """ # FIXME : Don't know why it doesn't work without rebuilding the StringIO object... value = StringIO(self.files[path].getvalue()) # Parse the CSV file contents csvFile = csv.reader(value) lines = list(csvFile) # Import data into OpenERP model = path.replace('.csv', '')[1:] oerpObject = Object(self.oerp_connection, model) oerpObject.import_data(lines[0], lines[1:], 'init', '', False, {'import': True}) # Close StringIO and free memory self.files[path].close() del self.files[path] value.close() del value return True
logger.info('Field: %s' % (opts.field,)) try: logger.info('Open connection to "%s:%s" on "%s" with user "%s" ' % (opts.server, opts.port, opts.dbname, opts.user)) cnx = Connection( server=opts.server, dbname=opts.dbname, login=opts.user, password=opts.passwd, port=opts.port) except Exception, e: logger.error('Fail to connect to the server') logger.error('%s' % str(e)) sys.exit(1) model = Object(cnx, opts.model) model_ids = model.search([]) model_lists = model.read(model_ids, [opts.field,'parent_left','parent_right']) models = dict(map(lambda x: (x['id'],x), model_lists)) try: for a in model_lists: logger.debug('id: %d' % a['id']) if a[opts.field]: assert a['parent_left'] > models[a[opts.field][0]]['parent_left'], '%s > %s' % (a['parent_left'], models[a[opts.field][0]]['parent_left']) assert a['parent_right'] < models[a[opts.field][0]]['parent_right'], '%s > %s' % (a['parent_right'], models[a[opts.field][0]]['parent_right']) assert a['parent_left'] < a['parent_right'] for a2 in model_lists: assert not ((a2['parent_right']>a['parent_left']) and (a2['parent_left']<a['parent_left']) and (a2['parent_right']<a['parent_right'])) if a2[opts.field]==a['id']:
default='', help='Enter list of companies, seprate by a comma (,)') parser.add_option_group(group) opts, args = parser.parse_args() try: cnx = Connection(server=opts.server, dbname=opts.dbname, login=opts.user, password=opts.passwd) except Exception, e: print '%s' % str(e) exit(1) user = Object(cnx, 'res.users') multi = Object(cnx, 'res.company') user_id = user.search([('login', '=', opts.user)])[0] # save company_id to restore it after curr = user.read(user_id, ['company_ids', 'company_id']) c_save_id = curr['company_id'] print 'User: %d => %s (id %d)' % (user_id, c_save_id[1], c_save_id[0]) ## # If the company argument is missing, retrieve all companies in the user form # if opts.company: companies = opts.company.split(',') else: companies = curr['company_ids']
def __init__(self, stdscr): """ Initialize the sentinel program """ # Read user configuration config = ConfigParser.SafeConfigParser(DEFAULT_CONFIG) config.read('.oerp_sentinelrc') # No configfile found, exit if not 'openerp' in config.sections(): raise Exception('Config Error', 'Config file not found !') # Connection to the OpenERP Server self.connection = Connection( server=config.get('openerp', 'host'), dbname=config.get('openerp', 'database'), login=config.get('openerp', 'user'), password=config.get('openerp', 'password'), port=config.get('openerp', 'port'), ) # Initialize translations context = Object(self.connection, 'res.users').context_get() lang = context.get('lang', I18N_DEFAULT) gettext.install(I18N_DOMAIN) try: language = gettext.translation(I18N_DOMAIN, I18N_DIR, languages=[lang]) except: language = gettext.translation(I18N_DOMAIN, I18N_DIR, languages=[I18N_DEFAULT]) language.install() # Initialize hardware self.hardware_obj = Object(self.connection, 'scanner.hardware') # Initialize window self.screen = stdscr self._set_screen_size() self._init_colors() # Get the informations for this material from server (identified by IP) self.hardware_code = '' self.scenario_id = False try: ssh_data = os.environ['SSH_CONNECTION'].split(' ') self.hardware_code = ssh_data[0] self.scenario_id = self.hardware_obj.scanner_check( self.hardware_code) except: self.hardware_code = self._input_text( _('Autoconfiguration failed !\nPlease enter terminal code')) self.scenario_id = self.hardware_obj.scanner_check( self.hardware_code) # Resize window to terminal screen size self._resize() # Reinit colors with values configured in OpenERP self._reinit_colors() # Initialize mouse events capture curses.mousemask(curses.BUTTON1_CLICKED | curses.BUTTON1_DOUBLE_CLICKED) # Load the sentinel self.main_loop()
""" import sys sys.path.append("../") from oobjlib.connection import Connection from oobjlib.component import Object from oobjlib.common import GetParser parser = GetParser("Module List", "0.1") opts, args = parser.parse_args() try: cnx = Connection(server=opts.server, dbname=opts.dbname, login=opts.user, password=opts.passwd, port=opts.port) except Exception, e: print "%s" % str(e) exit(1) modules = Object(cnx, "ir.module.module") print "--[Connection Object]---------------------" print "%s" % str(modules) ids = modules.search([("state", "=", "installed")]) print "--[Module list]---------------------------" for p in modules.read(ids, ["name"]): print "* %s" % p["name"] print "--[End]-----------------------------------" # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
try: cnx = Connection(server=opts.server, dbname=opts.dbname, login=opts.user, password=opts.passwd, port=opts.port) except Exception, e: print '%s' % str(e) exit(1) if not opts.service: print '--service argument is required!' exit(1) jasper_obj = Object(cnx, 'jasper.document') label_obj = Object(cnx, 'jasper.document.label') root = Element( 'jasperReport', { 'name': 'to_be_defined', 'language': 'groovy', 'pageWidth': '595', 'pageHeight': '842', 'columnWidth': '555', 'leftMargin': '20', 'rightMargin': '20', 'topMargin': '20', 'bottomMargin': '20' }) #root.set('name', 'to_be_defined')
try: cnx = Connection(server=opts.server, dbname=opts.dbname, login=opts.user, password=opts.passwd, port=opts.port) except Exception, e: print '%s' % str(e) exit(1) if not opts.filename: print '--file argument is required!' exit(1) jasper_obj = Object(cnx, 'jasper.document') label_obj = Object(cnx, 'jasper.document.label') fp = open(opts.filename, 'r') reader = csv.DictReader(fp, delimiter=',') service_cache = {} def format_code(code): code = code.upper() code = code.replace(' ', '_') return code for l in reader:
logger.error('%s' % str(e)) sys.exit(1) def normalize_name(name): """ Replace all non alphanumeric characters by underscores """ return re.sub(r'[^\w\d]', '_', name).lower() resid = {} opts.directory = os.path.expanduser(opts.directory) # extract scenario scenario_obj = Object(cnx, 'scanner.scenario') model_obj = Object(cnx, 'ir.model') warehouse_obj = Object(cnx, 'stock.warehouse') user_obj = Object(cnx, 'res.users') group_obj = Object(cnx, 'res.groups') scen_read = scenario_obj.read(int(opts.scenario_id), [], '_classic_read', {'active_test': False}) scen_read = scen_read and scen_read[0] if not scen_read: logger.error('Scenario ID %s not found' % opts.scenario_id) sys.exit(1) del scen_read['step_ids'] field_to_remove = [ 'create_uid', 'create_date', 'write_uid', 'write_date', '__last_update', 'display_name'
def __init__(self, stdscr): """ Initialize the sentinel program """ # Read user configuration config = ConfigParser.SafeConfigParser(DEFAULT_CONFIG) self.datadir = os.path.expanduser("~/") config.read([ '.oerp_sentinelrc', '.openerp_sentinelrc', '.odoo_sentinelrc', os.path.join(self.datadir, '.oerp_sentinelrc'), os.path.join(self.datadir, '.openerp_sentinelrc'), os.path.join(self.datadir, '.odoo_sentinelrc'), ]) # No configfile found, exit if 'openerp' not in config.sections(): raise Exception('Config Error', 'Config file not found !') # Connection to the OpenERP Server self.connection = Connection( server=config.get('openerp', 'host'), dbname=config.get('openerp', 'database'), login=config.get('openerp', 'user'), password=config.get('openerp', 'password'), port=config.get('openerp', 'port'), ) # Open the test file, if any test_file_name = config.get('openerp', 'test_file') self.test_file = None if test_file_name: self.test_file = open(test_file_name, 'r') # Initialize translations self.context = Object(self.connection, 'res.users').context_get() lang = self.context.get('lang', I18N_DEFAULT) gettext.install(I18N_DOMAIN) try: language = gettext.translation( I18N_DOMAIN, I18N_DIR, languages=[lang]) except: language = gettext.translation( I18N_DOMAIN, I18N_DIR, languages=[I18N_DEFAULT]) # Replace global dummy lambda by the translations gettext method # The install method of gettext doesn't replace the function if exists global _ _ = language.gettext # Initialize hardware self.hardware_obj = Object(self.connection, 'scanner.hardware') self.scenario_obj = Object(self.connection, 'scanner.scenario') # Initialize window self.screen = stdscr self._set_screen_size() self._init_colors() # Get the informations for this material from server (identified by IP) self.hardware_code = '' self.scenario_id = False self.scenario_name = False try: ssh_data = os.environ['SSH_CONNECTION'].split(' ') self.hardware_code = ssh_data[0] self.scanner_check() except: self.hardware_code = self._input_text( _('Autoconfiguration failed !\nPlease enter terminal code')) self.scanner_check() # Resize window to terminal screen size self._resize() # Reinit colors with values configured in OpenERP self._reinit_colors() # Initialize mouse events capture curses.mousemask( curses.BUTTON1_CLICKED | curses.BUTTON1_DOUBLE_CLICKED) # Reinitialize to the main menu when using a test file (useful when # the last run has crashed before end) if test_file_name: self.oerp_call('end') # Load the sentinel self.main_loop()
help='Indicate the version of OpenERP (5 or 6)') parser.add_option_group(group) opts, args = parser.parse_args() try: cnx = Connection( server=opts.server, dbname=opts.dbname, login=opts.user, password=opts.passwd, port=opts.port) except Exception, e: print '%s' % str(e) sys.exit(1) mod = Object(cnx, 'ir.model') if opts.oerp_version == '5': print 'version 5' model = mod.search([]) else: print 'version 6' model = mod.search([('osv_memory', '=', False)]) print 80 * '-' print '| Model | Search | Read | View XML |' print 80 * '-' footer = '--- FOOTER REPORT ---\n'
def getattr(self, path): """ Return attributes for the specified path : - Search for the model as first part - Search for an existing record as second part - Search for an existing attachment as third part - There cannot be more than 3 parts in the path """ fakeStat = fuse.Stat() fakeStat.st_mode = stat.S_IFDIR | 0400 fakeStat.st_nlink = 0 if path == '/': return fakeStat paths = path.split('/')[1:] if len(paths) > 3: return -ENOENT # Check for model existence model_obj = Object(self.oerp_connection, 'ir.model') model_ids = model_obj.search([('model', '=', paths[0])]) if not model_ids: return -ENOENT elif len(paths) == 1: return fakeStat # Check for record existence element_obj = Object(self.oerp_connection, paths[0]) element_ids = element_obj.search([('id', '=', int(paths[1]))]) if not element_ids: return -ENOENT elif len(paths) == 2: return fakeStat # Chech for attachement existence attachment_obj = Object(self.oerp_connection, 'ir.attachment') attachment_ids = attachment_obj.search([ ('res_model', '=', paths[0]), ('res_id', '=', int(paths[1])), ('id', '=', self.id_from_label(paths[2])) ]) if not attachment_ids: return -ENOENT # Common stats fakeStat.st_mode = stat.S_IFREG | 0400 fakeStat.st_nlink = 2 # TODO : Read the file size from a dedicated field (created in a specific module) attachment_obj = Object(self.oerp_connection, 'ir.attachment') attachment_ids = attachment_obj.search([ ('res_model', '=', paths[0]), ('res_id', '=', int(paths[1])), ('id', '=', self.id_from_label(paths[2])) ]) attachment_data = attachment_obj.read(attachment_ids, ['datas']) fakeStat.st_size = len(base64.b64decode(attachment_data[0]['datas'])) return fakeStat
except Exception, e: logger.error('Fail to connect to the server') logger.error('%s' % str(e)) sys.exit(1) class StopError(Exception): pass filename = opts.filename if not opts.filename: filename = '%s.csv' % opts.model # recherche du mon de l'objet dans le nom du fichier sans l'extension obj = Object(cnx, opts.model) ctx = {'lang': opts.lang} if opts.inactive: ctx['active_test'] = False if not opts.ids: # Get all ids ids = obj.search([]) else: ids = [int(x.strip()) for x in opts.ids.split(',')] if not opts.fields: # get all fields fields = obj.fields_get_keys() else:
cnx = Connection(server=opts.server, dbname=opts.dbname, login=opts.user, password=opts.passwd, port=opts.port) except Exception, e: print '%s' % str(e) exit(1) print 80 * '*' print '* A connection was established to %s on database %s with user %s ' % ( opts.server, opts.dbname, opts.user) print '* Use "cnx" variable for the current connection' print "* To create a new object: eg x = Object(cnx, 'res.partner')" print "* To call a method on this object just execute x.search([('field','operator','value')])" print '*' if opts.model: obj = Object(cnx, opts.model) print '* "obj" variable is affect to "%s" object' % opts.model print "* To call a method on this object just execute obj.search([('field','operator','value')])" print '*' print 80 * '*' print '* To exit: enter "exit()" or press "Ctrl + D"' print 80 * '*' code.interact(local=locals()) # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
sys.path.append('../') from oobjlib.connection import Connection from oobjlib.component import Object from oobjlib.common import GetParser parser = GetParser('Module List', '0.1') opts, args = parser.parse_args() try: cnx = Connection(server=opts.server, dbname=opts.dbname, login=opts.user, password=opts.passwd, port=opts.port) except Exception, e: print '%s' % str(e) exit(1) modules = Object(cnx, "ir.module.module") print '--[Connection Object]---------------------' print '%s' % str(modules) ids = modules.search([('state', '=', 'installed')]) print '--[Module list]---------------------------' for p in modules.read(ids, ['name']): print '* %s' % p['name'] print '--[End]-----------------------------------' # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
logger.info('Field: %s' % (opts.field, )) try: logger.info('Open connection to "%s:%s" on "%s" with user "%s" ' % (opts.server, opts.port, opts.dbname, opts.user)) cnx = Connection(server=opts.server, dbname=opts.dbname, login=opts.user, password=opts.passwd, port=opts.port) except Exception, e: logger.error('Fail to connect to the server') logger.error('%s' % str(e)) sys.exit(1) model = Object(cnx, opts.model) model_ids = model.search([]) model_lists = model.read(model_ids, [opts.field, 'parent_left', 'parent_right']) models = dict(map(lambda x: (x['id'], x), model_lists)) try: for a in model_lists: logger.debug('id: %d' % a['id']) if a[opts.field]: assert a['parent_left'] > models[a[ opts.field][0]]['parent_left'], '%s > %s' % ( a['parent_left'], models[a[opts.field][0]]['parent_left']) assert a['parent_right'] < models[a[ opts.field][0]]['parent_right'], '%s > %s' % ( a['parent_right'], models[a[opts.field][0]]['parent_right'])
from oobjlib.connection import Connection from oobjlib.component import Object from oobjlib.common import GetParser parser = GetParser('Create Product', '0.1') opts, args = parser.parse_args() try: cnx = Connection( server=opts.server, dbname=opts.dbname, login=opts.user, password=opts.passwd, port=opts.port) except Exception, e: print '%s' % str(e) exit(1) product = Object(cnx, 'product.product') args = { 'name': 'Import Test', 'default_code': 'ABCD-EFGH', 'categ_id': 1, } print 'Product ID %d created !' % product.create(args) # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
logger.info('Language to import data: %s' % opts.lang) try: logger.info('Open connection to "%s:%s" on "%s" with user "%s" ' % (opts.server, opts.port, opts.dbname, opts.user)) cnx = Connection( server=opts.server, dbname=opts.dbname, login=opts.user, password=opts.passwd, port=opts.port) except Exception, e: logger.error('Fail to connect to the server') logger.error('%s' % str(e)) sys.exit(1) model = Object(cnx, opts.model) mod_count = model.search_count([]) logger.info('There are %d record to export' % mod_count) fields = model.fields_get() fields_name = fields.keys() result = model.read(model.search([])) from odf.opendocument import OpenDocumentSpreadsheet from odf.style import Style, TextProperties, ParagraphProperties, TableColumnProperties from odf.text import P from odf.table import Table, TableColumn, TableRow, TableCell textdoc = OpenDocumentSpreadsheet()
try: cnx = Connection(server=opts.server, dbname=opts.dbname, login=opts.user, port=opts.port, password=opts.passwd) except Exception, e: print '%s' % str(e) exit(1) def generate_tracking_message_id(openobject_id): """Returns a string that can be used in the Message-ID RFC822 header field so we can track the replies related to a given object thanks to the "In-Reply-To" or "References" fields that Mail User Agents will set. """ s = hashlib.sha1() s.update(str(time.time())) return "<%s-openobject-%s@%s>" % (s.hexdigest(), openobject_id, 'syleam6.syleam.fr') message = Object(cnx, 'mailgate.message') message_ids = message.search([('model','=','project.issue'),('message_id','=', False)]) print '%d message to update' % len(message_ids) for m in message.read(message_ids, ['name', 'res_id']): args = {'message_id': generate_tracking_message_id(m['res_id'])} message.write([m['id']], args) # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
group.add_option('', '--follow-one2many', dest='one2many', action='store_true', default=False, help='Follow the one2many child of this record') parser.add_option_group(group) opts, args = parser.parse_args() try: cnx = Connection(server=opts.server, dbname=opts.dbname, login=opts.user, password=opts.passwd, port=opts.port) except Exception, e: print '%s' % str(e) exit(1) model = Object(cnx, opts.model) model_data = Object(cnx, 'ir.model.data') ## # Check if model exists and return all fields # try: fields = model.fields_get() f_list = [] for i in fields: f_list.append(i) f_list.sort() except Exception, e: print "Error object %s doesn't exists" % opts.model exit(2)
parser.add_option_group(group) opts, args = parser.parse_args() try: cnx = Connection(server=opts.server, dbname=opts.dbname, login=opts.user, password=opts.passwd, port=opts.port) except Exception, e: print '%s' % str(e) exit(1) if not opts.id: print '--id argument is required!' exit(1) model_view = Object(cnx, 'ir.ui.view') model_data = Object(cnx, 'ir.model.data') def Ir_Model_Data(model, id): """ Search if the record was previously register in ir_model_data """ args = [ ('model', '=', model), ('res_id', '=', id) ] ret = '%s_%d' % (model.replace('.', '_'), id) res = model_data.search(args) if res: r = model_data.read(res, ['module', 'name'])[0] ret = '%s.%s' % (r['module'], r['name'])
group.add_option('-l', '--legend', dest='legend', action="store_true", default=False, help='List the company by name and their ID') parser.add_option_group(group) opts, args = parser.parse_args() try: cnx = Connection(server=opts.server, dbname=opts.dbname, login=opts.user, password=opts.passwd) except Exception, e: print '%s' % str(e) exit(1) user = Object(cnx, 'res.users') rule = Object(cnx, 'ir.rule') user_id = user.search([('login','=', opts.user)])[0] if opts.legend: comp = Object(cnx, 'res.company') company_ids = comp.search([]) print 'List all company' print 80 * '*' for compa in comp.read(company_ids, ['name']): print '%s -> %d' % (compa['name'].ljust(20), compa['id']) print 80 * '*' company_id = user.read(user_id, ['company_id'])['company_id'] try:
sys.path.append('../') from oobjlib.connection import Connection from oobjlib.component import Object from oobjlib.common import GetParser parser = GetParser('Create Product', '0.1') opts, args = parser.parse_args() try: cnx = Connection(server=opts.server, dbname=opts.dbname, login=opts.user, password=opts.passwd, port=opts.port) except Exception, e: print '%s' % str(e) exit(1) product = Object(cnx, 'product.product') args = { 'name': 'Import Test', 'default_code': 'ABCD-EFGH', 'categ_id': 1, } print 'Product ID %d created !' % product.create(args) # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
parser.add_option_group(group) opts, args = parser.parse_args() try: cnx = Connection(server=opts.server, dbname=opts.dbname, login=opts.user, password=opts.passwd, port=opts.port) except Exception, e: print '%s' % str(e) exit(1) if not opts.filename: print '--file argument is required!' exit(1) jasper_obj = Object(cnx, 'jasper.document') label_obj = Object(cnx, 'jasper.document.label') fp = open(opts.filename, 'r') reader = csv.DictReader(fp, delimiter=',') service_cache = {} def format_code(code): code = code.upper() code = code.replace(' ', '_') return code for l in reader: #print l
def readdir(self, path, offset): """ Return content of a directory : - List models for root path - List records for a model - List attachments for a record We don't have to check for the path, because getattr already returns -ENOENT if the model/record/attachment doesn't exist """ yield fuse.Direntry('.') yield fuse.Direntry('..') paths = path.split('/')[1:] # List models if path == '/': model_obj = Object(self.oerp_connection, 'ir.model') model_ids = model_obj.search([]) for model_data in model_obj.read(model_ids, ['model']): yield fuse.Direntry(model_data['model']) # List records elif len(paths) == 1: element_obj = Object(self.oerp_connection, paths[0]) element_ids = element_obj.search([]) for element_data in element_obj.read(element_ids, ['id']): yield fuse.Direntry(str(element_data['id'])) # List attachments else: attachment_obj = Object(self.oerp_connection, 'ir.attachment') attachment_ids = attachment_obj.search([ ('res_model', '=', paths[0]), ('res_id', '=', int(paths[1])) ]) for attachment_data in attachment_obj.read(attachment_ids, ['name']): yield fuse.Direntry( '%d-%s' % (attachment_data['id'], attachment_data['name']))
parser.add_option_group(group) opts, args = parser.parse_args() try: cnx = Connection(server=opts.server, dbname=opts.dbname, login=opts.user, password=opts.passwd, port=opts.port) except Exception, e: print '%s' % str(e) exit(1) if not opts.service: print '--service argument is required!' exit(1) jasper_obj = Object(cnx, 'jasper.document') label_obj = Object(cnx, 'jasper.document.label') root = Element('jasperReport', {'name': 'to_be_defined', 'language': 'groovy', 'pageWidth': '595', 'pageHeight': '842', 'columnWidth': '555', 'leftMargin': '20', 'rightMargin': '20', 'topMargin': '20', 'bottomMargin': '20'}) #root.set('name', 'to_be_defined') #root.set('language', 'groovy') #root.set('pageWidth', '595') #root.set('pageHeight', '842') #root.set('columnWidth', '555') #root.set('leftMargin', '20') #root.set('rightMargin', '20') #root.set('topMargin', '20') #root.set('bottomMargin', '20')
group.add_option('-c', '--company', dest='company', default='', help='Enter list of companies, seprate by a comma (,)') parser.add_option_group(group) opts, args = parser.parse_args() try: cnx = Connection(server=opts.server, dbname=opts.dbname, login=opts.user, password=opts.passwd) except Exception, e: print '%s' % str(e) exit(1) user = Object(cnx, 'res.users') multi = Object(cnx, 'res.company') user_id = user.search([('login','=',opts.user)])[0] # save company_id to restore it after curr = user.read(user_id, ['company_ids','company_id']) c_save_id = curr['company_id'] print 'User: %d => %s (id %d)' % (user_id, c_save_id[1], c_save_id[0]) ## # If the company argument is missing, retrieve all companies in the user form # if opts.company: companies = opts.company.split(',') else: companies = curr['company_ids']
def _return_object(self, objectName, id): obj = Object(self.cnx, objectName) r = obj.search([("id", "=", id)]) return obj.read(r)[0]
directories = [] opts.directory = os.path.expanduser(opts.directory) if glob(opts.directory + '/scenario.xml'): directories.append(opts.directory) if opts.recursive: for root, dirs, files in os.walk(opts.directory): for directory in dirs: if glob('%s/%s/scenario.xml' % (root, directory)): directories.append('%s/%s' % (root, directory)) for directory in directories: logger.info('Importing from : %s' % directory) # extract scenario scenario_obj = Object(cnx, 'scanner.scenario') model_obj = Object(cnx, 'ir.model') company_obj = Object(cnx, 'res.company') warehouse_obj = Object(cnx, 'stock.warehouse') step_obj = Object(cnx, 'scanner.scenario.step') trans_obj = Object(cnx, 'scanner.scenario.transition') xml_file = open('%s/scenario.xml' % directory, 'r') logger.info('Scenario file found, process reading!') scenario_xml = xml_file.read() xml_file.close() xml_doc = StringIO(scenario_xml) root = parse(xml_doc).getroot() step = [] transition = [] scen_vals = {}
help='Follow the one2many child of this record') parser.add_option_group(group) opts, args = parser.parse_args() try: cnx = Connection(server=opts.server, dbname=opts.dbname, login=opts.user, password=opts.passwd, port=opts.port) except Exception, e: print '%s' % str(e) exit(1) model = Object(cnx, opts.model) model_data = Object(cnx, 'ir.model.data') ## # Check if model exists and return all fields # try: fields = model.fields_get() f_list = [] for i in fields: f_list.append(i) f_list.sort() except Exception, e: print "Error object %s doesn't exists" % opts.model exit(2)
class Sentinel(object): """ Sentinel class Manages scanner terminals """ def __init__(self, stdscr): """ Initialize the sentinel program """ # Read user configuration config = ConfigParser.SafeConfigParser(DEFAULT_CONFIG) self.datadir = os.path.expanduser("~/") config.read([ '.oerp_sentinelrc', '.openerp_sentinelrc', '.odoo_sentinelrc', os.path.join(self.datadir, '.oerp_sentinelrc'), os.path.join(self.datadir, '.openerp_sentinelrc'), os.path.join(self.datadir, '.odoo_sentinelrc'), ]) # No configfile found, exit if 'openerp' not in config.sections(): raise Exception('Config Error', 'Config file not found !') # Connection to the OpenERP Server self.connection = Connection( server=config.get('openerp', 'host'), dbname=config.get('openerp', 'database'), login=config.get('openerp', 'user'), password=config.get('openerp', 'password'), port=config.get('openerp', 'port'), ) # Open the test file, if any test_file_name = config.get('openerp', 'test_file') self.test_file = None if test_file_name: self.test_file = open(test_file_name, 'r') # Initialize translations self.context = Object(self.connection, 'res.users').context_get() lang = self.context.get('lang', I18N_DEFAULT) gettext.install(I18N_DOMAIN) try: language = gettext.translation( I18N_DOMAIN, I18N_DIR, languages=[lang]) except: language = gettext.translation( I18N_DOMAIN, I18N_DIR, languages=[I18N_DEFAULT]) # Replace global dummy lambda by the translations gettext method # The install method of gettext doesn't replace the function if exists global _ _ = language.gettext # Initialize hardware self.hardware_obj = Object(self.connection, 'scanner.hardware') self.scenario_obj = Object(self.connection, 'scanner.scenario') # Initialize window self.screen = stdscr self._set_screen_size() self._init_colors() # Get the informations for this material from server (identified by IP) self.hardware_code = '' self.scenario_id = False self.scenario_name = False try: ssh_data = os.environ['SSH_CONNECTION'].split(' ') self.hardware_code = ssh_data[0] self.scanner_check() except: self.hardware_code = self._input_text( _('Autoconfiguration failed !\nPlease enter terminal code')) self.scanner_check() # Resize window to terminal screen size self._resize() # Reinit colors with values configured in OpenERP self._reinit_colors() # Initialize mouse events capture curses.mousemask( curses.BUTTON1_CLICKED | curses.BUTTON1_DOUBLE_CLICKED) # Reinitialize to the main menu when using a test file (useful when # the last run has crashed before end) if test_file_name: self.oerp_call('end') # Load the sentinel self.main_loop() def scanner_check(self): self.scenario_id = self.hardware_obj.scanner_check( self.hardware_code, self.context) if isinstance(self.scenario_id, list): self.scenario_id, self.scenario_name = self.scenario_id def _resize(self): """ Resizes the window """ # Asks for the hardware screen size (width, height) = self.oerp_call('screen_size')[1] self._set_screen_size(width, height) def _init_colors(self): """ Initialize curses colors """ # Declare all configured color pairs for curses for (the_id, front_color, back_color) in COLOR_PAIRS.values(): curses.init_pair( the_id, COLOR_NAMES[front_color], COLOR_NAMES[back_color]) # Set the default background color self.screen.bkgd(0, self._get_color('base')) def _reinit_colors(self): """ Initializes the colors from Odoo configuration """ # Asks for the hardware screen size colors = self.oerp_call('screen_colors')[1] COLOR_PAIRS['base'] = (1, colors['base'][0], colors['base'][1]) COLOR_PAIRS['info'] = (2, colors['info'][0], colors['info'][1]) COLOR_PAIRS['error'] = (3, colors['error'][0], colors['error'][1]) self._init_colors() def _set_screen_size(self, width=18, height=6): self.window_width = width self.window_height = height self.screen.resize(height, width) def _get_color(self, name): """ Get a curses color's code """ return curses.color_pair(COLOR_PAIRS[name][0]) def _read_from_file(self): """ Emulates the getkey method of curses, reading from the supplied test file """ key = self.test_file.read(1) if key == ':': # Truncate the trailing "new line" character key = self.test_file.readline()[:-1] # End of file reached, terminate the sentinel if not key: self.test_file.close() exit(0) return key def ungetch(self, value): """ Put a value in the keyboard buffer """ curses.ungetch(value) def getkey(self): """ Get a user input and avoid Ctrl+C """ if self.test_file: # Test file supplied, read from it key = self._read_from_file() else: # Get the pushed character key = self.screen.getkey() if key == '': # Escape key : Return back to the previous step raise SentinelBackException('Back') return key def _display(self, text='', x=0, y=0, clear=False, color='base', bgcolor=False, modifier=curses.A_NORMAL, cursor=None, height=None, scroll=False, title=None): """ Display a line of text """ # Clear the sceen if needed if clear: self.screen.clear() # Display the title, if any if title is not None: y += 1 title = title.center(self.window_width) self._display( title, color='info', modifier=curses.A_REVERSE | curses.A_BOLD) # Compute the display modifiers color = self._get_color(color) | modifier # Set background to 'error' colors if bgcolor: self.screen.bkgd(0, color) # Normalize the text, because ncurses doesn't know UTF-8 with # python 2.x if isinstance(text, str): text = text.decode('utf-8') text = unicodedata.normalize( 'NFKD', unicode(text)).encode('ascii', 'ignore') text = ''.join( [char not in ('\r', '\n') and curses.ascii.unctrl(char) or char for char in text]) # Display the text if not scroll: self.screen.addstr(y, x, text, color) else: # Wrap the text to avoid splitting words text_lines = [] for line in text.splitlines(): text_lines.extend( textwrap.wrap(line, self.window_width - x - 1) or ['']) # Initialize variables first_line = 0 if height is None: height = self.window_height (cursor_y, cursor_x) = cursor or ( self.window_height - 1, self.window_width - 1) while True: # Display the menu self.screen.addstr(height - 1, x, (self.window_width - x - 1) * ' ', color) self.screen.addstr( y, x, '\n'.join( text_lines[first_line:first_line + height - y]), color) # Display arrows if first_line > 0: self.screen.addch( y, self.window_width - 1, curses.ACS_UARROW) if first_line + height < len(text_lines): self.screen.addch( min(height + y - 1, self.window_height - 2), self.window_width - 1, curses.ACS_DARROW) else: self.screen.addch( min(height + y - 1, self.window_height - 2), self.window_width - 1, ' ') # Set the cursor position if height < len(text_lines): scroll_height = len(text_lines) - height position_percent = float(first_line) / scroll_height position = y + min( int(round((height - 1) * position_percent)), self.window_height - 2) self._display( ' ', x=self.window_width - 1, y=position - 1, color='info', modifier=curses.A_REVERSE) self.screen.move(cursor_y, cursor_x) # Get the pushed key key = self.getkey() if key == 'KEY_DOWN': # Down key : Go down in the list first_line += 1 elif key == 'KEY_UP': # Up key : Go up in the list first_line -= 1 else: # Return the pressed key value return key # Avoid going out of the list first_line = min( max(0, first_line), max(0, len(text_lines) - height + 1)) def main_loop(self): """ Loops until the user asks for ending """ code = False result = None value = None while True: try: try: # No active scenario, select one if not self.scenario_id: (code, result, value) = self._select_scenario() else: # Search for a step title title = None title_key = '|' if isinstance(result, (types.NoneType, bool)): pass elif (isinstance(result, dict) and result.get(title_key, None)): title = result[title_key] del result[title_key] elif (isinstance(result[0], (tuple, list)) and result[0][0] == title_key): title = result.pop(0)[1] elif (isinstance(result[0], basestring) and result[0].startswith(title_key)): title = result.pop(0)[len(title_key):] if title is None and self.scenario_name: # If no title is defined, display the scenario name title = self.scenario_name if code == 'Q' or code == 'N': # Quantity selection quantity = self._select_quantity( '\n'.join(result), '%g' % value, integer=(code == 'N'), title=title) (code, result, value) = self.oerp_call('action', quantity) elif code == 'C': # Confirmation query confirm = self._confirm( '\n'.join(result), title=title) (code, result, value) = self.oerp_call('action', confirm) elif code == 'T': # Select arguments from value default = '' size = None if isinstance(value, dict): default = value.get('default', '') size = value.get('size', None) elif isinstance(value, str): default = value # Text input text = self._input_text( '\n'.join(result), default=default, size=size, title=title) (code, result, value) = self.oerp_call('action', text) elif code == 'R': # Critical error self.scenario_id = False self.scenario_name = False self._display_error('\n'.join(result), title=title) elif code == 'U': # Unknown action : message with return back to the # last state self._display( '\n'.join(result), clear=True, scroll=True, title=title) (code, result, value) = self.oerp_call('back') elif code == 'E': # Error message self._display_error( '\n'.join(result), title=title) # Execute transition if not value: (code, result, value) = self.oerp_call( 'action') else: # Back to the previous step required (code, result, value) = self.oerp_call( 'back') elif code == 'M': # Simple message self._display( '\n'.join(result), clear=True, scroll=True, title=title) # Execute transition (code, result, value) = self.oerp_call('action', value) elif code == 'L': if result: # Select a value in the list choice = self._menu_choice(result, title=title) # Send the result to Odoo (code, result, value) = self.oerp_call( 'action', choice) else: # Empty list supplied, display an error (code, result, value) = ( 'E', [_('No value available')], True) # Check if we are in a scenario (to retrieve the # scenario name from a submenu) self.scanner_check() if not self.scenario_id: self.scenario_id = True self.scenario_name = False elif code == 'F': # End of scenario self.scenario_id = False self.scenario_name = False self._display('\n'.join(result), clear=True, scroll=True, title=title) else: # Default call (code, result, value) = self.oerp_call('restart') except SentinelBackException: # Back to the previous step required (code, result, value) = self.oerp_call('back') # Do not display the termination message if code == 'F': self.ungetch(ord('\n')) self.screen.bkgd(0, self._get_color('base')) except Exception: # Generates log contents log_contents = """%s # %s # Hardware code : %s # ''Current scenario : %s (%s) # Current values : #\tcode : %s #\tresult : %s #\tvalue : %s %s %s """ log_contents = log_contents % ( '#' * 79, datetime.now().strftime('%Y-%m-%d %H:%M:%S'), self.hardware_code, str(self.scenario_id), self.scenario_name, code, repr(result), repr(value), '#' * 79, reduce( lambda x, y: x + y, traceback.format_exception( sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2]))) # Writes traceback in log file logfile = open(self.datadir + 'oerp_sentinel.log', 'a') logfile.write(log_contents) logfile.close() # Display error message (code, result, value) = ( 'E', [_('An error occured\n\nPlease contact your ' 'administrator')], False) except KeyboardInterrupt: # If Ctrl+C, exit (code, result, value) = self.oerp_call('end') # Restore normal background colors self.screen.bkgd(0, self._get_color('base')) def _display_error(self, error_message, title=None): """ Displays an error message, changing the background to red """ # Display error message self._display(error_message, color='error', bgcolor=True, clear=True, scroll=True, title=title) # Restore normal background colors self.screen.bkgd(0, self._get_color('base')) def oerp_call(self, action, message=False): """ Calls a method from Odoo Server """ return self.hardware_obj.scanner_call( self.hardware_code, action, message, 'keyboard', self.context) def _select_scenario(self): """ Selects a scenario from the server """ # Get the scenarios list from server values = self.oerp_call('menu')[1] # If no scenario available : return an error if not values: return ('R', [_('No scenario available !')], 0) # Select a scenario in the list choice = self._menu_choice(values, title=_('Scenarios')) ret = self.oerp_call('action', choice) # Store the scenario id and name self.scanner_check() if not self.scenario_id: self.scenario_id = True self.scenario_name = False # Send the result to OpenERP return ret def _confirm(self, message, title=None): """ Allows the user to select quantity """ confirm = False while True: # Clear the screen self._display(clear=True) # Compute Yes/No positions yes_start = 0 yes_padding = int(math.floor(self.window_width / 2)) yes_text = _('Yes').center(yes_padding) no_start = yes_padding no_padding = self.window_width - no_start - 1 no_text = _('No').center(no_padding) if confirm: # Yes selected yes_modifier = curses.A_BOLD | curses.A_REVERSE no_modifier = curses.A_NORMAL else: # No selected yes_modifier = curses.A_NORMAL no_modifier = curses.A_BOLD | curses.A_REVERSE # Display Yes self._display(yes_text, x=yes_start, y=self.window_height - 1, color='info', modifier=yes_modifier) # Display No self._display(no_text, x=no_start, y=self.window_height - 1, color='info', modifier=no_modifier) # Display the confirmation message key = self._display(message, scroll=True, height=self.window_height - 1, title=title) if key == '\n': # Return key : Validate the choice return confirm elif (key == 'KEY_DOWN' or key == 'KEY_LEFT' or key == 'KEY_UP' or key == 'KEY_RIGHT'): # Arrow key : change value confirm = not confirm elif key.upper() == 'O' or key.upper() == 'Y': # O (oui) or Y (yes) confirm = True elif key.upper() == 'N': # N (No) confirm = False elif key == 'KEY_MOUSE': # Retrieve mouse event information mouse_info = curses.getmouse() # Set the selected entry confirm = mouse_info[1] < len(yes_text) # If we double clicked, auto-validate if mouse_info[4] & curses.BUTTON1_DOUBLE_CLICKED: return confirm def _input_text(self, message, default='', size=None, title=None): """ Allows the user to input random text """ # Initialize variables value = default line = self.window_height - 1 self.screen.move(line, 0) # Flush the input curses.flushinp() # While we do not validate, store characters while True: # Clear the screen self._display(clear=True) # Display the current value if echoing is needed display_value = ''.join( [curses.ascii.unctrl(char) for char in value]) display_start = max(0, len(display_value) - self.window_width + 1) display_value = display_value[display_start:] self._display(' ' * (self.window_width - 1), 0, line) self._display( display_value, 0, line, color='info', modifier=curses.A_BOLD) key = self._display( message, scroll=True, height=self.window_height - 1, cursor=(line, min(len(value), self.window_width - 1)), title=title) # Printable character : store in value if len(key) == 1 and (curses.ascii.isprint(key) or ord(key) < 32): value += key # Backspace or del, remove the last character elif key == 'KEY_BACKSPACE' or key == 'KEY_DC': value = value[:-1] # Move cursor at end of the displayed value if key == '\n' or (size is not None and len(value) >= size): # Flush the input curses.flushinp() return value.strip() def _select_quantity(self, message, quantity='0', integer=False, title=None): """ Allows the user to select quantity """ # Erase the selected quantity on the first digit key press digit_key_pressed = False while True: # Clear the screen self._display(clear=True) # Diplays the selected quantity self._display( _('Selected : %s') % quantity, y=self.window_height - 1, color='info', modifier=curses.A_BOLD) # Display the message and get the key key = self._display( message, scroll=True, height=self.window_height - 1, title=title) if key == '\n': # Return key : Validate the choice return float(quantity) elif key.isdigit(): if not digit_key_pressed: quantity = '0' digit_key_pressed = True # Digit : Add at end if quantity == '0': quantity = key else: quantity += key elif (not integer and '.' not in quantity and (key == '.' or key == ',' or key == '*')): # Decimal point quantity += '.' elif key == 'KEY_BACKSPACE' or key == 'KEY_DC': # Backspace : Remove last digit quantity = quantity[:-1] digit_key_pressed = True elif key == 'KEY_DOWN' or key == 'KEY_LEFT': # Down key : Decrease quantity = '%g' % (float(quantity) - 1) elif key == 'KEY_UP' or key == 'KEY_RIGHT': # Up key : Increase quantity = '%g' % (float(quantity) + 1) if not quantity: quantity = '0' def _menu_choice(self, entries, title=None): """ Allows the user to choose a value in a list """ # If a dict is passed, keep the keys keys = entries if isinstance(entries, dict): keys, entries = entries.items() elif isinstance(entries[0], (tuple, list)): keys, entries = map(list, zip(*entries))[:2] # Highlighted entry highlighted = 0 first_column = 0 max_length = max([len(value) for value in entries]) # Add line numbers before text display = [] index = 0 nb_char = int(math.floor(math.log10(len(entries))) + 1) decal = nb_char + 3 for value in entries: display.append( '%s: %s' % (str(index).rjust(nb_char), value[:self.window_width - decal])) index += 1 while True: # Display the menu self._menu_display(display, highlighted, title=title) # Get the pushed key key = self.getkey() digit_key = False if key == '\n': # Return key : Validate the choice return keys[highlighted] elif key.isdigit(): # Digit : Add at end of index highlighted = highlighted * 10 + int(key) digit_key = True elif key == 'KEY_BACKSPACE' or key == 'KEY_DC': # Backspace : Remove last digit from index highlighted = int(math.floor(highlighted / 10)) elif key == 'KEY_DOWN': # Down key : Go down in the list highlighted = highlighted + 1 elif key == 'KEY_RIGHT': # Move display first_column = max( 0, min(first_column + 1, max_length - self.window_width + decal)) display = [] index = 0 for value in entries: display.append( '%s: %s' % ( str(index).rjust(nb_char), value[first_column: self.window_width - decal + first_column])) index += 1 elif key == 'KEY_UP': # Up key : Go up in the list highlighted = highlighted - 1 elif key == 'KEY_LEFT': # Move display first_column = max(0, first_column - 1) display = [] index = 0 for value in entries: display.append( '%s: %s' % ( str(index).rjust(nb_char), value[first_column: self.window_width - decal + first_column])) index += 1 elif key == 'KEY_MOUSE': # First line to be displayed first_line = 0 nb_lines = self.window_height - 1 middle = int(math.floor(nb_lines / 2)) # Change the first line if there is too much lines for the # screen if len(entries) > nb_lines and highlighted >= middle: first_line = min(highlighted - middle, len(entries) - nb_lines) # Retrieve mouse event information mouse_info = curses.getmouse() # Set the selected entry highlighted = min(max(0, first_line + mouse_info[2]), len(entries) - 1) # If we double clicked, auto-validate if mouse_info[4] & curses.BUTTON1_DOUBLE_CLICKED: return keys[highlighted] # Avoid going out of the list highlighted %= len(entries) # Auto validate if max number is reached current_nb_char = int( math.floor(math.log10(max(1, highlighted))) + 1) if highlighted and digit_key and current_nb_char >= nb_char: return keys[highlighted] def _menu_display(self, entries, highlighted, title=None): """ Display a menu, highlighting the selected entry """ # First line to be displayed first_line = 0 nb_lines = self.window_height - 1 if len(entries) > nb_lines: nb_lines -= 1 middle = int(math.floor((nb_lines - 1) / 2)) # Change the first line if there is too much lines for the screen if len(entries) > nb_lines and highlighted >= middle: first_line = min(highlighted - middle, len(entries) - nb_lines) # Display all entries, normal display self._display('\n'.join(entries[first_line:first_line + nb_lines]), clear=True, title=title) # Highlight selected entry self._display( entries[highlighted].ljust(self.window_width - 1), y=highlighted - first_line, modifier=curses.A_REVERSE | curses.A_BOLD, title=title) # Display arrows if first_line > 0: self.screen.addch(0, self.window_width - 1, curses.ACS_UARROW) if first_line + nb_lines < len(entries): self.screen.addch( nb_lines, self.window_width - 1, curses.ACS_DARROW) # Diplays number of the selected entry self._display(_('Selected : %d') % highlighted, y=self.window_height-1, color='info', modifier=curses.A_BOLD) # Set the cursor position if nb_lines < len(entries): position_percent = float(highlighted) / len(entries) position = int(round(nb_lines * position_percent)) self._display( ' ', x=self.window_width - 1, y=position, color='info', modifier=curses.A_REVERSE) self.screen.move(self.window_height - 1, self.window_width - 1)
default=False, help='List the company by name and their ID') parser.add_option_group(group) opts, args = parser.parse_args() try: cnx = Connection(server=opts.server, dbname=opts.dbname, login=opts.user, password=opts.passwd) except Exception, e: print '%s' % str(e) exit(1) user = Object(cnx, 'res.users') rule = Object(cnx, 'ir.rule') user_id = user.search([('login', '=', opts.user)])[0] if opts.legend: comp = Object(cnx, 'res.company') company_ids = comp.search([]) print 'List all company' print 80 * '*' for compa in comp.read(company_ids, ['name']): print '%s -> %d' % (compa['name'].ljust(20), compa['id']) print 80 * '*' company_id = user.read(user_id, ['company_id'])['company_id'] try:
(opts.server, opts.port, opts.dbname, opts.user)) cnx = Connection(server=opts.server, dbname=opts.dbname, login=opts.user, password=opts.passwd, port=opts.port) except Exception, e: logger.error('Fail to connect to the server') logger.error('%s' % str(e)) sys.exit(1) resid = {} opts.directory = os.path.expanduser(opts.directory) # extract scenario scenario_obj = Object(cnx, 'scanner.scenario') model_obj = Object(cnx, 'ir.model') warehouse_obj = Object(cnx, 'stock.warehouse') scen_read = scenario_obj.read(int(opts.scenario_id), [], {'active_test': False}) if not scen_read: logger.error('Scenario ID %s not found' % opts.scenario_id) sys.exit(1) del scen_read['step_ids'] del scen_read['id'] # create node and attributs root = Element('scenario') for field in scen_read: node = SubElement(root, field) if field == 'model_id': if scen_read[field]:
opts, args = parser.parse_args() try: cnx = Connection(server=opts.server, dbname=opts.dbname, login=opts.user, port=opts.port, password=opts.passwd) except Exception, e: print "%s" % str(e) exit(1) def generate_tracking_message_id(openobject_id): """Returns a string that can be used in the Message-ID RFC822 header field so we can track the replies related to a given object thanks to the "In-Reply-To" or "References" fields that Mail User Agents will set. """ s = hashlib.sha1() s.update(str(time.time())) return "<%s-openobject-%s@%s>" % (s.hexdigest(), openobject_id, "syleam6.syleam.fr") message = Object(cnx, "mailgate.message") message_ids = message.search([("model", "=", "project.issue"), ("message_id", "=", False)]) print "%d message to update" % len(message_ids) for m in message.read(message_ids, ["name", "res_id"]): args = {"message_id": generate_tracking_message_id(m["res_id"])} message.write([m["id"]], args) # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: