Skip to content

Commit

Permalink
code-style related fixes. (partly auto pep8)
Browse files Browse the repository at this point in the history
  • Loading branch information
katyukha committed Mar 10, 2016
1 parent 1f22a1d commit 88ff0f4
Show file tree
Hide file tree
Showing 27 changed files with 813 additions and 373 deletions.
62 changes: 42 additions & 20 deletions openerp_proxy/core.py
@@ -1,32 +1,42 @@
# -*- coding: utf8 -*-
""" This module provides some classes to simplify acces to Odoo server via xmlrpc.
Some of these classes are may be not safe enough and should be used with carefully
"""
This module provides some classes to simplify access to Odoo server via xmlrpc.
Example ussage of this module
Example ussage of this module:
.. code:: python
>>> erp_db = Client('server.com', 'dbname', 'some_user', 'mypassword')
>>> sale_obj = erp_db['sale_order']
>>> cl = Client('server.com', 'dbname', 'some_user', 'mypassword')
>>> sale_obj = cl['sale_order']
>>> sale_ids = sale_obj.search([('state','not in',['done','cancel'])])
>>> sale_data = sale_obj.read(sale_ids, ['name'])
>>> for order in sale_data:
... print("%5s : %s" % (order['id'],order['name']))
>>> tmpl_ids = erp_db['product.template'].search([('name','ilike','template_name')])
>>> print(erp_db['product.product'].search([('product_tmpl_id','in',tmpl_ids)]))
>>> product_tmpl_obj = cl['product.template']
>>> product_obj = cl['product.product']
>>> tmpl_ids = product_tmpl_obj.search([('name','ilike','template_name')])
>>> print(product_obj.search([('product_tmpl_id','in',tmpl_ids)]))
>>> db = Client('erp.host.com', 'dbname='db0', user='your_user')
>>> so = db['sale.order']
>>> order_ids = so.search([('state','=','done')])
>>> order = so.read(order_ids[0])
Also You can call any method (beside private ones starting with underscore(_)) of any model.
For example to check availability of stock move all You need is:
Also You can call any method (beside private
ones starting with underscore(_)) of any model.
For example following code allows to check
availability of stock moves:
.. code:: python
>>> db = session.connect()
>>> move_obj = db['stock.move']
>>> move_ids = [1234] # IDs of stock moves to be checked
>>> move_obj.check_assign(move_ids)
Ability to use Record class as analog to browse_record:
Ability to use Record class as analog to browse_record:
.. code:: python
>>> move_obj = db['stock.move']
>>> move = move_obj.browse(1234)
Expand Down Expand Up @@ -73,7 +83,8 @@ class Client(Extensible):
:param str user: username to login as
:param str pwd: password to log-in with
:param int port: port number of server
:param str protocol: protocol used to connect. To get list of available protcols call:
:param str protocol: protocol used to connect.
To get list of available protcols call:
``openerp_proxy.connection.get_connector_names()``
any other keyword arguments will be directly passed to connector
Expand All @@ -90,7 +101,8 @@ class Client(Extensible):
Object ('sale.order')
"""

def __init__(self, host, dbname=None, user=None, pwd=None, port=8069, protocol='xml-rpc', **extra_args):
def __init__(self, host, dbname=None, user=None, pwd=None, port=8069,
protocol='xml-rpc', **extra_args):
self._dbname = dbname
self._username = user
self._pwd = pwd
Expand Down Expand Up @@ -141,7 +153,10 @@ def services(self):
db.services.report # report service
db.services.object # object service (model related actions)
db.services.common # used for login (db.services.common.login(dbname, username, password)
db.services.common # used for login
# (db.services.common.login(dbname,
# username,
# password)
db.services.db # database management service
"""
Expand Down Expand Up @@ -225,10 +240,11 @@ def connect(self, **kwargs):
self instance and update them with passed keyword arguments,
and call Proxy class constructor passing result as arguments.
Note, that if You pass any keyword arguments, You also should pass
'pwd' keyword argument with user password
Note, that if You pass any keyword arguments,
You also should pass 'pwd' keyword argument with user password
:return: Id of user logged in or new Client instance (if kwargs passed)
:return: Id of user logged in or new Client
instance (if kwargs passed)
:rtype: int|Client
:raises LoginException: if wrong login or password
"""
Expand All @@ -240,9 +256,12 @@ def connect(self, **kwargs):

# Get the uid
if self._pwd is None or self.username is None or self.dbname is None:
raise LoginException("User login and password required for this operation")
raise LoginException("User login and password required "
"for this operation")

uid = self.services['common'].login(self.dbname, self.username, self._pwd)
uid = self.services['common'].login(self.dbname,
self.username,
self._pwd)

if not uid:
raise LoginException("Bad login or password")
Expand Down Expand Up @@ -288,11 +307,14 @@ def execute_wkf(self, object_name, signal, object_id):
:param object_id: ID of document (record) to send signal to
:type obejct_id: int
"""
result_wkf = self.services['object'].execute_wkf(object_name, signal, object_id)
result_wkf = self.services['object'].execute_wkf(object_name,
signal,
object_id)
return result_wkf

def get_obj(self, object_name):
""" Returns wraper around Odoo object 'object_name' which is instance of Object
""" Returns wraper around Odoo object 'object_name'
which is instance of orm.object.Object class
:param object_name: name of an object to get wraper for
:return: instance of Object which wraps choosen object
Expand Down
48 changes: 39 additions & 9 deletions openerp_proxy/ext/repr/generic.py
Expand Up @@ -67,12 +67,14 @@ def toHField(field):


class FieldNotFoundException(Exception):

""" Exception raised when HField cannot find field in object been processed
:param obj: object to field not found in
:param name: field that is not found in object *obj*
:param original_exc: Exception that was raised on attempt to get field
"""

def __init__(self, obj, name, original_exc=None):
self.name = name
self.obj = obj
Expand All @@ -98,6 +100,7 @@ def __repr__(self):

@six.python_2_unicode_compatible
class HField(object):

""" Describes how to get a field.
Primaraly used in html representation logic.
Expand Down Expand Up @@ -133,7 +136,15 @@ class HField(object):
:param dict kwargs: same as *args* but for keyword arguments
"""

def __init__(self, field, name=None, silent=False, default=None, parent=None, args=None, kwargs=None):
def __init__(
self,
field,
name=None,
silent=False,
default=None,
parent=None,
args=None,
kwargs=None):
if callable(field):
field = normalizeSField(field)

Expand Down Expand Up @@ -199,7 +210,8 @@ def _get_field(self, obj, name):
def get_field(self, record):
""" Returns requested value from specified record (object)
:param record: Record instance to get field from (also should work on any other object)
:param record: Record instance to get field from
(also should work on any other object)
:type record: Record
:return: requested value
"""
Expand All @@ -218,16 +230,17 @@ def get_field(self, record):
field = fields.pop(0)
try:
r = self._get_field(r, field)
if callable(r) and fields: # and if attribute is callable and
# and if attribute is callable and
if callable(r) and fields:
# it is not last field then call
# it without arguments
r = r()
elif callable(r) and not fields: # it is last field and it is callable
# it is last field and it is callable
elif callable(r) and not fields:
r = r(*self._args, **self._kwargs)
except Exception as exc:
if not self._silent: # reraise exception if not silent
raise (exc if isinstance(exc, FieldNotFoundException)
else FieldNotFoundException(r, field, exc))
raise exc
else: # or return default value
r = self._default
break
Expand Down Expand Up @@ -259,10 +272,12 @@ def __repr__(self):


class PrettyTable(object):

""" Just a simple warapper around tabulate.tabulate to show IPython displayable table
Only 'pretty' representation, yet.
"""

def __init__(self, *args, **kwargs):
self._args = args
self._kwargs = kwargs
Expand All @@ -277,6 +292,7 @@ def _repr_pretty_(self, printer, cycle):


class BaseTable(object):

""" Base class for table representation
:param data: record list (or iterable of anything other) to create represetation for
Expand All @@ -287,6 +303,7 @@ class BaseTable(object):
tuple(field_path|callable, field_name)
:type fields: list(str | callable | HField instance | tuple(field, name))
"""

def __init__(self, data, fields):
self._data = data
self._fields = []
Expand Down Expand Up @@ -347,13 +364,18 @@ def to_csv(self):
fmode = 'wb'
adapt = lambda s: _(s).encode('utf-8')

tmp_file = tempfile.NamedTemporaryFile(mode=fmode, dir=CSV_PATH, suffix='.csv', delete=False)
tmp_file = tempfile.NamedTemporaryFile(
mode=fmode,
dir=CSV_PATH,
suffix='.csv',
delete=False)
with tmp_file as csv_file:
csv_writer = csv.writer(csv_file)
csv_writer.writerow(tuple((adapt(h) for h in self.fields)))
for row in self:
csv_writer.writerow(tuple((adapt(val) for val in row)))
return FileLink(os.path.join(CSV_PATH, os.path.split(tmp_file.name)[-1]))
return FileLink(
os.path.join(CSV_PATH, os.path.split(tmp_file.name)[-1]))

def _repr_pretty_(self, printer, cycle):
return printer.text(PrettyTable(self, headers=self.fields).table)
Expand All @@ -362,6 +384,7 @@ def _repr_pretty_(self, printer, cycle):
# TODO: also implement vertical table orientation, which could be usefult for
# comparing few records or reuse same code for displaying single record.
class HTMLTable(BaseTable):

""" HTML Table representation object for RecordList
:param data: record list (or iterable of anything other) to create represetation for
Expand Down Expand Up @@ -418,7 +441,14 @@ class HTMLTable(BaseTable):
<div>
""")

def __init__(self, data, fields, caption=None, highlighters=None, display_help=True, **kwargs):
def __init__(
self,
data,
fields,
caption=None,
highlighters=None,
display_help=True,
**kwargs):
self._caption = u"HTMLTable"
self._highlighters = {}
self._display_help = display_help
Expand Down
3 changes: 2 additions & 1 deletion openerp_proxy/main.py
Expand Up @@ -56,7 +56,8 @@ def main():
for aliase, url in session.aliases.items():
header_aliases += " - %s: %s\n" % (aliase_tmpl % aliase, url)

header = HELP_HEADER % {'databases': header_databases, 'aliases': header_aliases}
header = HELP_HEADER % {'databases': header_databases,
'aliases': header_aliases}

_locals = {
'Client': Client,
Expand Down
16 changes: 8 additions & 8 deletions openerp_proxy/orm/__init__.py
@@ -1,8 +1,8 @@
from .cache import empty_cache
from .object import (get_object,
Object)
from .record import (get_record,
get_record_list,
Record,
RecordList)
from .service import Service
from .cache import empty_cache # noqa
from .object import (get_object, # noqa
Object) # noqa
from .record import (get_record, # noqa
get_record_list, # noqa
Record, # noqa
RecordList) # noqa
from .service import Service # noqa
24 changes: 15 additions & 9 deletions openerp_proxy/orm/cache.py
@@ -1,4 +1,3 @@
#import openerp_proxy.orm.record
import six
import numbers
import collections
Expand Down Expand Up @@ -36,13 +35,15 @@ def update_keys(self, keys):
# and difference calls)
self.update({cid: {'id': cid} for cid in keys})
else:
self.update({cid: {'id': cid} for cid in set(keys).difference(six.viewkeys(self))})
self.update({cid: {'id': cid}
for cid in set(keys).difference(six.viewkeys(self))})
return self

def update_context(self, new_context):
""" Updates or sets new context for thes ObjectCache instance
:param dict new_context: context dictionary to update cached context with
:param dict new_context: context dictionary to update cached
context with
:return: updated context
"""
if new_context is not None:
Expand All @@ -68,14 +69,18 @@ def cache_field(self, rid, ftype, field_name, value):
"""
self[rid][field_name] = value
if value and ftype == 'many2one':
rcache = self._root_cache[self._object.columns_info[field_name]['relation']]
rcache = self._root_cache[self._object.
columns_info[field_name]['relation']]

if isinstance(value, numbers.Integral): # pragma: no cover
rcache[value] # internal dict {'id': key} will be created by default (see ObjectCache)
# internal dict {'id': key} will be created by default
# (see ObjectCache)
rcache[value]
elif isinstance(value, collections.Iterable):
rcache[value[0]]['__name_get_result'] = value[1]
elif value and ftype in ('many2many', 'one2many'):
rcache = self._root_cache[self._object.columns_info[field_name]['relation']]
rcache = self._root_cache[self._object.
columns_info[field_name]['relation']]
rcache.update_keys(value)

def parse_prefetch_fields(self, fields):
Expand All @@ -88,7 +93,8 @@ def parse_prefetch_fields(self, fields):
:return: tuple(prefetch_fields, related_fields),
where prefetch_fields is list of fields, to be read for
current object, and related_fields is dictionary of form
``{'related.object': ['relatedfield1', 'relatedfield2.relatedfield']}``
``{'related.object': ['relatedfield1',
'relatedfield2.relatedfield']}``
"""
rel_fields = collections.defaultdict(list)
prefetch_fields = []
Expand All @@ -100,7 +106,8 @@ def parse_prefetch_fields(self, fields):
prefetch_fields.append(xfield)
relation = xfield_info.get('relation', False)
if field_path and relation:
rel_fields[relation].append(field_path[0]) # only one item left
# only one item left
rel_fields[relation].append(field_path[0])

return prefetch_fields, rel_fields

Expand Down Expand Up @@ -176,4 +183,3 @@ def empty_cache(client):
"""
return Cache(client)

0 comments on commit 88ff0f4

Please sign in to comment.