def execute_report(name, **data):
    """Executes a report with the given data, on success returns `application/pdf` data

    @param name: name of the report
    @param data: report data

    @return: `application/pdf` data
    """
    datas = data.copy()
    ids = datas['ids']
    del datas['ids']

    if not ids:
        ids = rpc.session.execute('object', 'execute', datas['model'],
                                  'search', [])
        if not ids:
            raise common.message(_('Nothing to print'))

        datas['id'] = ids[0]

    try:
        ctx = dict(rpc.session.context)
        ctx.update(datas.get('context', {}))
        report_id = rpc.session.execute('report', 'report', name, ids, datas,
                                        ctx)
        state = False
        attempt = 0
        max_attempt = cherrypy.config.get('openerp.server.timeout') or 200
        val = None
        while not state:
            val = rpc.session.execute('report', 'report_get', report_id)
            if not val:
                return False
            state = val['state']
            if not state:
                time.sleep(1)
                attempt += 1
            if attempt > max_attempt:
                raise common.message(_('Printing aborted, too long delay'))

        # report name
        report_name = 'report'
        report_type = val['format']

        if name != 'custom':
            proxy = rpc.RPCProxy('ir.actions.report.xml')
            res = proxy.search([('report_name', '=', name)])
            if res:
                report_name = proxy.read(res[0], ['name'])['name']

        report_name = report_name.replace('Print ', '')
        cherrypy.response.headers[
            'Content-Disposition'] = 'filename="' + report_name + '.' + report_type + '"'

        return _print_data(val)

    except rpc.RPCException, e:
        raise e
Пример #2
0
def execute_report(name, **data):
    """Executes a report with the given data, on success returns `application/pdf` data

    @param name: name of the report
    @param data: report data

    @return: `application/pdf` data
    """
    datas = data.copy()
    ids = datas['ids']
    del datas['ids']

    if not ids:
        ids =  rpc.session.execute('object', 'execute', datas['model'], 'search', [])
        if not ids:
            raise common.message(_('Nothing to print'))

        datas['id'] = ids[0]

    try:
        ctx = dict(rpc.session.context)
        ctx.update(datas.get('context', {}))
        report_id = rpc.session.execute('report', 'report', name, ids, datas, ctx)
        state = False
        attempt = 0
        max_attempt = cherrypy.config.get('openerp.server.timeout') or 200
        val = None
        while not state:
            val = rpc.session.execute('report', 'report_get', report_id)
            if not val:
                return False
            state = val['state']
            if not state:
                time.sleep(1)
                attempt += 1
            if attempt>max_attempt:
                raise common.message(_('Printing aborted, too long delay'))

        # report name
        report_name = 'report'
        report_type = val['format']

        if name != 'custom':
            proxy = rpc.RPCProxy('ir.actions.report.xml')
            res = proxy.search([('report_name','=', name)])
            if res:
                report_name = proxy.read(res[0], ['name'])['name']

        report_name = report_name.replace('Print ', '')
        cherrypy.response.headers['Content-Disposition'] = 'filename="' + report_name + '.' + report_type + '"'

        return _print_data(val)

    except rpc.RPCException, e:
        raise e
Пример #3
0
    def default(self, view_id):

        try:
            view_id = eval(view_id)
        except:
            pass

        if isinstance(view_id, basestring) or not view_id:
            raise common.message(_("Invalid view id."))

        res = rpc.RPCProxy('ir.ui.view').read([view_id], ['model', 'type'])[0]

        model = res['model']
        view_type = res['type']

        headers = [{'string' : 'Name', 'name' : 'string', 'type' : 'char'},
                   {'string' : '', 'name': 'add', 'type' : 'image', 'width': 2},
                   {'string' : '', 'name': 'delete', 'type' : 'image', 'width': 2},
                   {'string' : '', 'name': 'edit', 'type' : 'image', 'width': 2},
                   {'string' : '', 'name': 'up', 'type' : 'image', 'width': 2},
                   {'string' : '', 'name': 'down', 'type' : 'image', 'width': 2}]

        tree = widgets.treegrid.TreeGrid('view_tree', model=model, headers=headers, url=url('/openerp/viewed/data?view_id='+str(view_id)))
        tree.showheaders = False
        tree.onselection = 'onSelect'
        tree.onbuttonclick = 'onButtonClick'
        tree.expandall = True

        return dict(view_id=view_id, view_type=view_type, model=model, tree=tree)
Пример #4
0
    def do_action(self, name, adds={}, datas={}):
        params, data = TinyDict.split(datas)

        model = params.model
        context = params._terp_context or {}
        ids = data.get('ids') or []

        ctx = rpc.session.context.copy()
        ctx.update(context)

        if ids:
            ids = map(int, ids.split(','))

        id = (ids or False) and ids[0]

        if ids:
            return actions.execute_by_keyword(name,
                                              adds=adds,
                                              model=model,
                                              id=id,
                                              ids=ids,
                                              context=ctx,
                                              report_type='pdf')
        else:
            raise common.message(_("No record selected"))
Пример #5
0
    def do_action(self, name, adds={}, datas={}):
        params, data = TinyDict.split(datas)

        model = params.model

        id = params.id or False
        ids = params.selection or params.ids or []

        if params.view_type == 'form':
            #TODO: save current record
            ids = (id or []) and [id]

        if id and not ids:
            ids = [id]

        if len(ids):
            import actions
            return actions.execute_by_keyword(name,
                                              adds=adds,
                                              model=model,
                                              id=id,
                                              ids=ids,
                                              report_type='pdf')
        else:
            raise common.message(_("No record selected"))
Пример #6
0
def export_csv(fields, result):
    try:
        fp = StringIO.StringIO()
        writer = csv.writer(fp, quoting=csv.QUOTE_ALL)

        writer.writerow(fields)

        for data in result:
            row = []
            for d in data:
                if isinstance(d, basestring):
                    d = d.replace('\n', ' ').replace('\t', ' ')
                    try:
                        d = d.encode('utf-8')
                    except:
                        pass
                if d is False: d = None
                row.append(d)

            writer.writerow(row)

        fp.seek(0)
        data = fp.read()
        fp.close()

        return data
    except IOError, (errno, strerror):
        raise common.message(
            _("Operation failed\nI/O error") + "(%s)" % (errno, ))
Пример #7
0
    def default(self, view_id):

        try:
            view_id = eval(view_id)
        except:
            pass

        if isinstance(view_id, basestring) or not view_id:
            raise common.message(_("Invalid view id."))

        res = rpc.RPCProxy('ir.ui.view').read([view_id], ['model', 'type'])[0]

        model = res['model']
        view_type = res['type']

        headers = [{
            'string': 'Name',
            'name': 'string',
            'type': 'char'
        }, {
            'string': '',
            'name': 'add',
            'type': 'image',
            'width': 2
        }, {
            'string': '',
            'name': 'delete',
            'type': 'image',
            'width': 2
        }, {
            'string': '',
            'name': 'edit',
            'type': 'image',
            'width': 2
        }, {
            'string': '',
            'name': 'up',
            'type': 'image',
            'width': 2
        }, {
            'string': '',
            'name': 'down',
            'type': 'image',
            'width': 2
        }]

        tree = widgets.treegrid.TreeGrid(
            'view_tree',
            model=model,
            headers=headers,
            url=url('/openerp/viewed/data?view_id=' + str(view_id)))
        tree.showheaders = False
        tree.onselection = 'onSelect'
        tree.onbuttonclick = 'onButtonClick'
        tree.expandall = True

        return dict(view_id=view_id,
                    view_type=view_type,
                    model=model,
                    tree=tree)
Пример #8
0
def export_csv(fields, result):
    try:
        fp = StringIO.StringIO()
        writer = csv.writer(fp, quoting=csv.QUOTE_ALL)

        writer.writerow(fields)

        for data in result:
            row = []
            for d in data:
                if isinstance(d, basestring):
                    d = d.replace('\n',' ').replace('\t',' ')
                    try:
                        d = d.encode('utf-8')
                    except:
                        pass
                if d is False: d = None
                row.append(d)

            writer.writerow(row)

        fp.seek(0)
        data = fp.read()
        fp.close()

        return data
    except IOError, (errno, strerror):
        raise common.message(_("Operation failed\nI/O error")+"(%s)" % (errno,))
Пример #9
0
    def switch(self, **kw):
        params, data = TinyDict.split(kw)

        ids = params.selection or []
        if ids:
            import actions
            return actions.execute_window(False, res_id=ids, model=params.model, domain=params.domain)
        else:
            raise common.message(_('No resource selected'))
Пример #10
0
def execute_window(view_ids, model, res_id=False, domain=None, view_type='form', context=None,
                   mode='form,tree', name=None, target=None, limit=None, search_view=None,
                   context_menu=False, display_menu_tip=False, action_id=None):
    """Performs `actions.act_window` action.

    @param view_ids: view ids
    @param model: a model for which the action should be performed
    @param res_id: resource id
    @param domain: domain
    @param view_type: view type, eigther `form` or `tree`
    @param context: the context
    @param mode: view mode, eigther `form,tree` or `tree,form` or None

    @return: view (mostly XHTML code)
    """

    params = TinyDict()

    params.model = model
    params.ids = res_id
    params.view_ids = view_ids
    params.domain = domain or []
    params.context = context or {}
    params.limit = limit
    params.search_view = search_view
    params['context_menu'] = context_menu
    params['display_menu_tip'] = display_menu_tip
    params['target'] = target or None
    cherrypy.request._terp_view_name = name or None
    cherrypy.request._terp_view_target = target or None

    if action_id:
        params.action_id = action_id

    if name:
         params.context['_terp_view_name'] = name
    else:
        if params.context.get('_terp_view_name'):
            del params.context['_terp_view_name']
    
    if params.ids and not isinstance(params.ids, list):
        params.ids = [params.ids]

    params.id = (params.ids or False) and params.ids[0]

    mode = mode or view_type
    if view_type == 'form':
        mode = mode.split(',')
        params.view_mode=mode

        return Form().create(params)

    elif view_type == 'tree':
        return Tree().create(params)

    else:
        raise common.message(_("Invalid View"))
Пример #11
0
    def switch(self, **kw):
        params, data = TinyDict.split(kw)

        ids = params.selection or []
        if ids:
            import actions
            return actions.execute_window(False,
                                          res_id=ids,
                                          model=params.model,
                                          domain=params.domain)
        else:
            raise common.message(_('No resource selected'))
Пример #12
0
def _print_data(data):

    if 'result' not in data:
        raise common.message(_('Error no report'))

    if data.get('code', 'normal') == 'zlib':
        import zlib
        content = zlib.decompress(base64.decodestring(data['result']))
    else:
        content = base64.decodestring(data['result'])

    cherrypy.response.headers['Content-Type'] = PRINT_FORMATS[data['format']]
    return content
Пример #13
0
def _print_data(data):

    if 'result' not in data:
        raise common.message(_('Error no report'))

    if data.get('code','normal')=='zlib':
        import zlib
        content = zlib.decompress(base64.decodestring(data['result']))
    else:
        content = base64.decodestring(data['result'])

    cherrypy.response.headers['Content-Type'] = PRINT_FORMATS[data['format']]
    return content
Пример #14
0
    def save(self, translate='fields', **kw):
        params, data = TinyDict.split(kw)

        ctx = dict((params.context or {}), **rpc.session.context)
        params['context'] = ustr(ctx)

        if translate == 'fields':
            if not params.id:
                raise common.message(
                    _("You need to save the resource before adding translations."
                      ))

            for lang, value in data.items():

                context = copy.copy(ctx)
                context['lang'] = adapt_context(lang)

                for name, val in value.items():
                    if isinstance(val, basestring):
                        val = [val]

                    for v in val:
                        rpc.session.execute('object', 'execute', params.model,
                                            'write', [params.id], {name: v},
                                            context)

        if translate == 'labels':
            for lang, value in data.items():
                for name, val in value.items():
                    rpc.session.execute('object', 'execute', params.model,
                                        'write_string', False, [lang],
                                        {name: val})

        if translate == 'relates':
            for lang, value in data.items():
                for name, val in value.items():
                    rpc.session.execute('object', 'execute',
                                        params.models[name], 'write',
                                        [int(name)], {'name': val},
                                        {'lang': lang})

        if translate == 'view':
            for lang, value in data.items():
                for id, val in value.items():
                    rpc.session.execute('object', 'execute', 'ir.translation',
                                        'write', [int(id)], {'value': val})

        return self.index(translate=translate,
                          _terp_model=params.model,
                          _terp_id=params.id,
                          ctx=params.context)
Пример #15
0
def get_action_type(act_id):
    """Get the action type for the given action id.

    @param act_id: the action id
    @return: action type
    """

    proxy = rpc.RPCProxy("ir.actions.actions")
    res = proxy.read([act_id], ["type"], rpc.session.context)[0]

    if not (res and len(res)):
        raise common.message(_('Action not found'))

    return res['type']
Пример #16
0
def get_action_type(act_id):
    """Get the action type for the given action id.

    @param act_id: the action id
    @return: action type
    """

    proxy = rpc.RPCProxy("ir.actions.actions")
    res = proxy.read([act_id], ["type"], rpc.session.context)[0]

    if not (res and len(res)):
        raise common.message(_('Action not found'))

    return res['type']
Пример #17
0
    def index(self, model, rec_id=None):

        proxy = rpc.RPCProxy("workflow")
        result = proxy.get_active_workitems(model, rec_id)
        wkf = result['wkf']

        if not wkf:
            raise common.message(_('No workflow associated!'))

        params = TinyDict()
        params.update(_terp_view_type='diagram',
                      _terp_model='workflow',
                      _terp_ids=[wkf['id']],
                      _terp_editable=True,
                      _terp_id=wkf['id'],
                      _terp_view_mode=['tree', 'form', 'diagram'])
        return self.create(params)
Пример #18
0
def _print_data(data):
    if 'result' not in data and 'path' not in data:
        raise common.message(_('Error no report'))

    cherrypy.response.headers['Content-Type'] = PRINT_FORMATS[data['format']]
    if data.get('code','normal')=='zlib':
        import zlib
        content = zlib.decompress(base64.decodestring(data['result']))
    else:
        if not data.get('result') and data.get('path'):
            try:
                return serve_file.serve_file(data['path'], "application/x-download", 'attachment', delete=data.get('delete', False))
            except Exception, e:
                cherrypy.response.headers['Content-Type'] = 'text/html'
                if 'Content-Disposition' in cherrypy.response.headers:
                    del(cherrypy.response.headers['Content-Disposition'])
                raise common.warning(e)
            finally:
Пример #19
0
    def index(self, model, id):

        id = int(id)

        if id:
            ctx = dict(rpc.get_session().context)

            action = dict(
                rpc.RPCProxy('ir.attachment').action_get(ctx),
                domain=[('res_model', '=', model), ('res_id', '=', id)],
                context=dict(ctx,
                             default_res_model=model,
                             default_res_id=id
            ))

            return actions.execute(action)
        else:
            raise common.message(_('No record selected, You can only attach to existing record...'))
Пример #20
0
    def index(self, model, rec_id=None):

        proxy = rpc.RPCProxy("workflow")
        result = proxy.get_active_workitems(model, rec_id)
        wkf = result['wkf']

        if not wkf:
            raise common.message(_('No workflow associated!'))

        params = TinyDict()
        params.update(
            _terp_view_type='diagram',
            _terp_model='workflow',
            _terp_ids=[wkf['id']],
            _terp_editable=True,
            _terp_id=wkf['id'],
            _terp_view_mode=['tree', 'form', 'diagram']
        )
        return self.create(params)
Пример #21
0
    def index(self, model, id):

        id = int(id)

        if id:
            ctx = dict(rpc.session.context)

            action = dict(rpc.RPCProxy('ir.attachment').action_get(ctx),
                          domain=[('res_model', '=', model),
                                  ('res_id', '=', id)],
                          context=dict(ctx,
                                       default_res_model=model,
                                       default_res_id=id))

            return actions.execute(action)
        else:
            raise common.message(
                _('No record selected, You can only attach to existing record...'
                  ))
Пример #22
0
    def do_action(self, name, adds={}, datas={}):
        params, data = TinyDict.split(datas)

        model = params.model

        id = params.id or False
        ids = params.selection or params.ids or []

        if params.view_type == 'form':
            #TODO: save current record
            ids = (id or []) and [id]

        if id and not ids:
            ids = [id]

        if len(ids):
            import actions
            return actions.execute_by_keyword(name, adds=adds, model=model, id=id, ids=ids, report_type='pdf')
        else:
            raise common.message(_("No record selected"))    
Пример #23
0
def execute_url(**data):
    url = data.get('url') or ''
    parsed = urlparse.urlsplit(url)
    if not (parsed.netloc or parsed.path.startswith('/')):
        raise common.message(_('Relative URLs are not supported'))

    if parsed.netloc:
        # external URL

        # determine target for openAction()
        target = {'new': 'popup'}.get(data['target'], 'iframe')

        return """<script type="text/javascript">
                      openAction('%s', '%s')
                  </script>
                """ % (url, target)

    return """<script type="text/javascript">
                  openLink('%s')
              </script>
            """ % url
Пример #24
0
    def do_action(self, name, adds={}, datas={}):
        params, data = TinyDict.split(datas)

        model = params.model
        context = params._terp_context or {}
        ids = data.get('ids') or []

        ctx = rpc.session.context.copy()
        ctx.update(context)

        if ids:
            ids = map(int, ids.split(','))

        id = (ids or False) and ids[0]

        if ids:
            return actions.execute_by_keyword(
                    name, adds=adds, model=model, id=id, ids=ids, context=ctx,
                    report_type='pdf')
        else:
            raise common.message(_("No record selected"))
Пример #25
0
def execute_url(**data):
    url = data.get('url') or ''
    parsed = urlparse.urlsplit(url)
    if not (parsed.netloc or parsed.path.startswith('/')):
        raise common.message(_('Relative URLs are not supported'))

    if parsed.netloc:
        # external URL

        # determine target for openAction()
        target = {'new': 'popup'}.get(data['target'], 'iframe')

        return """<script type="text/javascript">
                      openAction('%s', '%s')
                  </script>
                """ % (url, target)

    return """<script type="text/javascript">
                  openLink('%s')
              </script>
            """ % url
Пример #26
0
    def save(self, translate='fields', **kw):
        params, data = TinyDict.split(kw)
        
        ctx = dict((params.context or {}), **rpc.session.context)
        params['context'] = ustr(ctx)

        if translate == 'fields':
            if not params.id:
                raise common.message(_("You need to save the resource before adding translations."))

            for lang, value in data.items():

                context = copy.copy(ctx)
                context['lang'] = adapt_context(lang)

                for name, val in value.items():
                    if isinstance(val, basestring):
                        val = [val]

                    for v in val:
                        rpc.session.execute('object', 'execute', params.model, 'write', [params.id], {name : v}, context)

        if translate == 'labels':
            for lang, value in data.items():
                for name, val in value.items():
                    rpc.session.execute('object', 'execute', params.model, 'write_string', False, [lang], {name: val})

        if translate == 'relates':
            for lang, value in data.items():
                for name, val in value.items():
                    rpc.session.execute('object', 'execute', params.models[name], 'write', [int(name)], {'name': val}, {'lang': lang})

        if translate == 'view':
            for lang, value in data.items():
                for id, val in value.items():
                    rpc.session.execute('object', 'execute', 'ir.translation', 'write', [int(id)], {'value': val})

        return self.index(translate=translate, _terp_model=params.model, _terp_id=params.id, ctx=params.context)
Пример #27
0
    def __init__(self, **attrs):

        super(Action, self).__init__(**attrs)
        self.nolabel = True

        self.act_id= self.name
        
        proxy = rpc.RPCProxy("ir.actions.actions")
        res = proxy.read([self.act_id], ['type'], rpc.session.context)
        if not res:
            raise common.message(_('Action not found'))

        _type=res[0]['type']
        self.action = rpc.session.execute('object', 'execute', _type, 'read', [self.act_id], False, rpc.session.context)[0]

        if 'view_mode' in attrs:
            self.action['view_mode'] = attrs['view_mode']

        if self.action['type']=='ir.actions.act_window':

            if not self.action.get('domain', False):
                self.action['domain']='[]'

            ctx = dict(rpc.session.context,
                       active_id=False,
                       active_ids=[])

            self.context = expr_eval(self.action.get('context', '{}'), ctx)
            self.domain = expr_eval(self.action['domain'], ctx)
            views = dict(map(lambda x: (x[1], x[0]), self.action['views']))
            view_mode = self.action.get('view_mode', 'tree,form').split(',')
            view_ids = map(lambda x: views.get(x, False), view_mode)
            
            if views.keys() != view_mode:
                view_mode = map(lambda x: x[1], self.action['views'])
                view_ids = map(lambda x: x[0], self.action['views'])
            
            if self.action['view_type'] == 'form':

                params = TinyDict()
                params.updateAttrs(
                    model=self.action['res_model'],
                    id=False,
                    ids=None,
                    view_ids=view_ids,
                    view_mode=view_mode,
                    context=self.context,
                    domain=self.domain,
                    offset = 0,
                    limit = 50
                )

                # get pager vars if set
                if hasattr(cherrypy.request, 'terp_params'):
                    current = cherrypy.request.terp_params
                    current = current.chain_get(self.name or '') or current

                    params.updateAttrs(
                        offset=current.offset,
                        limit=current.limit
                    )

                self.screen = screen.Screen(params, prefix=self.name, editable=True, selectable=3)

            elif self.action['view_type']=='tree':
                pass #TODO
Пример #28
0
            actions = rpc.session.execute('object', 'execute', 'ir.values',
                                          'get', 'action', keyword,
                                          [(data['model'], id)], False, ctx)
            actions = map(lambda x: x[2], actions)
        except rpc.RPCException, e:
            raise e

    keyact = {}
    action = None
    for action in actions:
        keyact[action['name']] = action

    keyact.update(adds or {})

    if not keyact:
        raise common.message(_('No action defined'))

    if len(keyact) == 1:
        key = keyact.keys()[0]
        if data.get('context'):
            data['context'].update(rpc.session.context)
        return execute(keyact[key], **data)
    else:
        return Selection().create(keyact, **data)


@tools.expose(template="/openerp/controllers/templates/closepopup.mako")
def close_popup(reload=True):
    """ Closes an opened dialog box or popup.

    :param reload: whether the background view should be reloaded when closing the popup
Пример #29
0
def execute_window(view_ids,
                   model,
                   res_id=False,
                   domain=None,
                   view_type='form',
                   context=None,
                   mode='form,tree',
                   name=None,
                   target=None,
                   limit=None,
                   search_view=None,
                   context_menu=False,
                   display_menu_tip=False,
                   action_id=None):
    """Performs `actions.act_window` action.

    @param view_ids: view ids
    @param model: a model for which the action should be performed
    @param res_id: resource id
    @param domain: domain
    @param view_type: view type, eigther `form` or `tree`
    @param context: the context
    @param mode: view mode, eigther `form,tree` or `tree,form` or None

    @return: view (mostly XHTML code)
    """

    params = TinyDict()

    params.model = model
    params.ids = res_id
    params.view_ids = view_ids
    params.domain = domain or []
    params.context = context or {}
    params.limit = limit
    params.search_view = search_view
    params['context_menu'] = context_menu
    params['display_menu_tip'] = display_menu_tip
    params['target'] = target or None
    cherrypy.request._terp_view_name = name or None
    cherrypy.request._terp_view_target = target or None

    if action_id:
        params.action_id = action_id

    if name:
        params.context['_terp_view_name'] = name
    else:
        if params.context.get('_terp_view_name'):
            del params.context['_terp_view_name']

    if params.ids and not isinstance(params.ids, list):
        params.ids = [params.ids]

    params.id = (params.ids or False) and params.ids[0]

    mode = mode or view_type
    if view_type == 'form':
        mode = mode.split(',')
        params.view_mode = mode

        return Form().create(params)

    elif view_type == 'tree':
        return Tree().create(params)

    else:
        raise common.message(_("Invalid View"))
Пример #30
0
            id = data.get('id', False)
            if (id): id = int(id)
            actions = rpc.session.execute('object', 'execute', 'ir.values', 'get', 'action', keyword, [(data['model'], id)], False, ctx)
            actions = map(lambda x: x[2], actions)
        except rpc.RPCException, e:
            raise e

    keyact = {}
    action = None
    for action in actions:
        keyact[action['name']] = action

    keyact.update(adds or {})

    if not keyact:
        raise common.message(_('No action defined'))

    if len(keyact) == 1:
        key = keyact.keys()[0]
        if data.get('context'):
            data['context'].update(rpc.session.context)
        return execute(keyact[key], **data)
    else:
        return Selection().create(keyact, **data)


@tools.expose(template="/openerp/controllers/templates/closepopup.mako")
def close_popup(reload=True, o2m_refresh=False):
    """ Closes an opened dialog box or popup.

    :param reload: whether the background view should be reloaded when closing the popup
Пример #31
0
def execute_report(name, **data):
    """Executes a report with the given data, on success returns `application/pdf` data

    @param name: name of the report
    @param data: report data

    @return: `application/pdf` data
    """
    datas = data.copy()
    ids = datas['ids']
    del datas['ids']

    if not ids:
        ids =  rpc.session.execute('object', 'execute', datas['model'], 'search', [])
        if not ids:
            raise common.message(_('Nothing to print'))

        datas['id'] = ids[0]

    try:
        ctx = dict(rpc.session.context)
        ctx.update(datas.get('context', {}))
        if is_server_local():
            ctx['report_fromfile'] = 1
        report_id = rpc.session.execute('report', 'report', name, ids, datas, ctx)
        state = False
        attempt = 0
        val = None
        bg_report = False
        background_id = ctx.get('background_id')
        max_attempt = ctx.get('background_time', 200)
        report_name = 'report'

        if name != 'custom':
            proxy = rpc.RPCProxy('ir.actions.report.xml')
            res = proxy.search([('report_name','=', name)])
            if res:
                read_ctx = datas.copy()
                read_ctx.setdefault('context', {}).update(ctx)
                report_name = proxy.read(res[0], ['filename'], read_ctx)['filename']

        report_name = report_name.replace('Print ', '')
        if not ids or not datas.get('id') or not datas.get('model'):
            if datas.get('target_filename'):
                report_name = datas['target_filename']
            elif datas.get('context', {}).get('_terp_view_name'):
                report_name = datas['context']['_terp_view_name']
        attachment = ''
        if datas.get('force_attach'):
            attachment = 'attachment;'
        if background_id:
            bg_report = rpc.session.execute('object', 'execute', 'memory.background.report', 'write', [background_id], {'report_id': report_id, 'report_name': report_name})

        while not state:
            val = rpc.session.execute('report', 'report_get', report_id)
            if not val:
                return False
            state = val['state']
            if not state:
                time.sleep(1)
                attempt += 1
            if attempt>max_attempt:
                if bg_report:
                    cherrypy.response.headers['Content-Type'] = 'text/html'
                    raise tools.redirect('/openerp/downloadbg', res_id=bg_report)
#                    return execute_window(False, 'memory.background.report', res_id=bg_report, domain=[], view_type='form', mode='form', target='new')
                else:
                    raise common.message(_('Printing aborted, too long delay'))

        cherrypy.response.headers['Content-Type'] = 'application/octet-stream'
        report_type = val['format']

        try:
            report_name = report_name.decode('utf-8')
        except UnicodeEncodeError:
            # replace all compatibility characters with their equivalents ("e with accent" becomes "e"...)
            report_name = unicodedata.normalize('NFKD', report_name).encode('ascii','ignore')
        cherrypy.response.headers['Content-Disposition'] = '%sfilename="' % attachment + report_name + '.' + report_type + '"'

        return _print_data(val)

    except rpc.RPCException, e:
        raise e