跳转至内容
  • 版块
  • 标签
  • 热门
  • 用户
  • 群组
皮肤
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • 默认(Flatly)
  • 不使用皮肤
折叠

Odoo 中文社区

左

左奕

@左奕
关于
帖子
3
主题
2
群组
0
粉丝
0
关注
0

帖子

最新 最佳 有争议的

  • 整合开发环境IDE到OE中
    左 左奕

    楼主的想法确实非常棒.
    一款好的IDE会成倍的提高开发效率(单纯Python开发的话,个人觉得WingIDE是非常好的选择).如果有一个能够集成OE系统的IDE,那将是非常美好的事情.
    但是这样的整合,需要对OE系统和IDE有非常深入的了解,还有很多精力.
    希望能有高手牵头,发起这样的项目.


  • 为OpenERP开发服务器实现自动重启
    左 左奕

    [b]注明(非常重要): 此方案并未在生产环境测试,未经过充分测试的条件下,请勿使用在生产环境.[/b]

    很多Web或Server框架都会实现一个可以自动检测文件修改后自动重启服务器的测试服务器.很遗憾OpenERP并没有提供这个功能.
    那我们就来自己实现一个.(注: 实现原理非原创,copy至django开发服务器.)


    大概说一下实现原理:
    自动重启服务器采用多进程方式实现.
    1) 主进程负责启动子进程,检测子进程是否退出,及子进程返回的退出状态. 如果子进程返回的状态是需要重启,则重启子进程.
    2) 子进程负责启动OpenERP Server,及检测py文件是否更改.如果py文件已更改,则停止自身,并返回重启状态的新号给主进程.

    原openerp-server.py中需要修改部分代码,因为openerp-server原本采用信号机制监听停止命令,但是子进程并不支持信号机制.所以改为监听KeyboardInterrupt异常.

    <br /># modify by xuwb start<br />#LST_SIGNALS = &#91;&#039;SIGINT&#039;, &#039;SIGTERM&#039;]<br />#if os.name == &#039;posix&#039;:<br />&nbsp; &nbsp; #LST_SIGNALS.extend(&#91;&#039;SIGUSR1&#039;,&#039;SIGQUIT&#039;])<br /><br /><br />#SIGNALS = dict(<br />&nbsp; &nbsp; #[(getattr(signal, sign), sign) for sign in LST_SIGNALS]<br />#)<br /><br />#def handler(signum, _):<br />&nbsp; &nbsp; #&quot;&quot;&quot;<br />&nbsp; &nbsp; #:param signum: the signal number<br />&nbsp; &nbsp; #:param _: <br />&nbsp; &nbsp; #&quot;&quot;&quot;<br />&nbsp; &nbsp; #if tools.config&#91;&#039;netrpc&#039;]:<br />&nbsp; &nbsp; &nbsp; &nbsp; #tinySocket.stop()<br />&nbsp; &nbsp; #if tools.config&#91;&#039;xmlrpc&#039;]:<br />&nbsp; &nbsp; &nbsp; &nbsp; #httpd.stop()<br />&nbsp; &nbsp; #netsvc.Agent.quit()<br />&nbsp; &nbsp; #if tools.config&#91;&#039;pidfile&#039;]:<br />&nbsp; &nbsp; &nbsp; &nbsp; #os.unlink(tools.config&#91;&#039;pidfile&#039;])<br />&nbsp; &nbsp; #logger.notifyChannel(&#039;shutdown&#039;, netsvc.LOG_INFO, <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  #&quot;Shutdown Server! - %s&quot; % ( SIGNALS[signum], ))<br />&nbsp; &nbsp; #logger.shutdown()<br />&nbsp; &nbsp; #sys.exit(0)<br /><br />#for signum in SIGNALS:<br />&nbsp; &nbsp; #signal.signal(signum, handler)<br /># modify by xuwb end<br /><br /># modify by xuwb start <br />#while True:<br />&nbsp; &nbsp; #time.sleep(1)<br /># modify by xuwb end
    



    新增代码:

    <br />try:<br />&nbsp; &nbsp; while True:<br />&nbsp; &nbsp; &nbsp; &nbsp; time.sleep(1)<br />except KeyboardInterrupt:<br />&nbsp; &nbsp; print &#039;Shutdown server ... add by xuwb&#039;<br />&nbsp; &nbsp; if tools.config&#91;&#039;netrpc&#039;]:<br />&nbsp; &nbsp; &nbsp; &nbsp; tinySocket.stop()<br />&nbsp; &nbsp; if tools.config&#91;&#039;xmlrpc&#039;]:<br />&nbsp; &nbsp; &nbsp; &nbsp; httpd.stop()<br />&nbsp; &nbsp; netsvc.Agent.quit()<br />&nbsp; &nbsp; if tools.config&#91;&#039;pidfile&#039;]:<br />&nbsp; &nbsp; &nbsp; &nbsp; os.unlink(tools.config&#91;&#039;pidfile&#039;])<br />&nbsp; &nbsp; logger.notifyChannel(&#039;shutdown&#039;, netsvc.LOG_INFO, <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  &quot;Shutdown Server! - %s&quot; % ( SIGNALS[signum], ))<br />&nbsp; &nbsp; logger.shutdown()<br />&nbsp; &nbsp; sys.exit(0)<br />
    



    在启动server时,需要更换为执行 openerp-server-autoreload.py文件.

    需要将附件中3个文件放置在${OPENERP_SERVER}/bin目录下.(注: 我使用的openerp-server.py文件的版本是5.0.10.如果不是此版本,请对openerp-server.py执行上述修改.)
    祝各位看官,开发愉快 ... ^_^


  • 从OpenOffice Report的换页问题到OE Report Tags的实现原理.
    左 左奕

    在使用OpenOffice sxw文件实现一个类似于Invoice报表的简单工资单报表时,遇见一个不能让每个工资单占据单独的一页的问题.就是需要每打印完一个工资单,如果页面还留有空白,需要产生新页,而不是在原页上继续产生内容.
    我想要的内容(两条横线之间代表一页):
    这是第一页
    -------------------------
    Payslip1
                    xxxxxxxx
                    xxxxxxxx

    (预留的空白)

    -------------------------

    这是第二页
    -------------------------
    Payslip2
                  xxxxxxxxx
                  xxxxxxxxx

    (预留的空白)
    -------------------------

    但实际的效果是挤到了一起.
    -------------------------
    Payslip1
                  xxxxxxxxxx
                  xxxxxxxxxx

    PaySlip2
                  xxxxxxxxxx
                  xxxxxxxxxx
    -------------------------
    google了一下,搜到一些老外的解决方案,但都很模糊.不能解决我的问题.
    最后找到的原因是 因为我把循环工资单对象的tag: "[[ repeatIn(objects, 'p') ]]" 放在了section(即openoffice中对应的区域,对应生成rml中的<section>标签)中间,导致所有对象都在section中[color=red]连续[/color]绘制,无法自动跳页.
    而如果把 "[[ repeatIn(objects, 'p') ]]"放在sxw文件的第一行,生成的rml中"[[ repeatIn(objects, 'p') ]]"会在<story>标签中间,OE会为每个对象自动跳页.

    OK,到这里问题解决了.但是没明白report tag这东东到底是怎样实现的,黑盒对于程序员来说太可怕了.%>_<%. 研究下怎样它怎样实现的.
    (注明: 以下内容并不一定完全正确,如果看官有兴趣一定要自己debug下代码,看看究竟.)

    OpenERP 涉及到rml使用的report tag的实现主要有两个类:

    1. ${OPENERP_PATH}/bin/report/preprocess.py::report类. 望文生义,它的主要功能是在对tag实际内容处理之前,进行预处理. 主要是 repeatIn,removeParentNode,setTag这三个tag.本质上是通过lxml对xml文件内容的更改.
    比如:
    <para>This is a test[[ setTag('para','xpre') ]]</para>
    处理之后会变成
    <para rml_tag="setTag('para','xpre')">This is a test[[ '' ]]</para>
       
    <tr>
        <td>Row 1 [[repeatIn(o.order_line,'o')]] </td>
        <td>Row 2</td>
    </tr>
    处理之后变成
    <tr rml_loop="repeatIn(o.order_line,'o')">
            <td>Row 1 [['']] </td>
            <td>Row 2</td>
    </tr>
    这里就说明了repeatIn放在<section>,<story>中会产生的效果.

    2.  ${OPENERP_PATH}/bin/report/report_sxw.py::rml_parse类. 每一个标签都对应着rml_parse类中的一个方法,使用的是模板语言的通用方法:把它们放到一个context中,在解析模板的时候去查找调用.

    self.localcontext = {<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &#039;user&#039;: user,<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &#039;company&#039;: user.company_id,<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &#039;repeatIn&#039;: self.repeatIn,<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &#039;setLang&#039;: self.setLang,<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &#039;setTag&#039;: self.setTag,<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &#039;removeParentNode&#039;: self.removeParentNode,<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &#039;format&#039;: self.format,<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &#039;formatLang&#039;: self.formatLang,<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &#039;logo&#039; : user.company_id.logo,<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &#039;lang&#039; : user.company_id.partner_id.lang,<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &#039;translate&#039; : self._translate,<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &#039;setHtmlImage&#039; : self.set_html_image<br />&nbsp; &nbsp; &nbsp; &nbsp; }
    



    举个例子 format标签的作用就是 去除字符串空格

    def format(self, text, oldtag=None):<br />&nbsp; &nbsp; &nbsp; &nbsp; return text.strip()
    



    了解了这个实现方式,甚至可以在模板中间添加自己需要的新标签.

    写的不是特别清楚明白,不对的地方请大家指正.^_^

  • 登录

  • 没有帐号? 注册

  • 登录或注册以进行搜索。
  • 第一个帖子
    最后一个帖子
0
  • 版块
  • 标签
  • 热门
  • 用户
  • 群组