Otter 核心开发日志

-- Zoom.Quiet [2004-08-16 00:15:40]

  • 回到 Otter 水獭(基于twisted的高速、可扩展性二进制流框架)

1. 开发难点

关注可能诞生新近项目的技术难点

1.1. Py脚本模板引擎

2. 开发节点

简述各个时期的开发重心

2.1. 040831 反复交流确认开发

  • 终于统一了认识,组织了全部代码发布 0.1.1dev 版本!

2.2. 040821 继承整理

  • 正式分枝模板引擎
  • QQ群中高人指点如何看 Python自说明的文档:

   1 >>> dir({})
   2 ['__class__', '__cmp__', '__contains__', '__delattr__', '__delitem__', '__doc__', '__eq__'
   3 , '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__iter__
   4 ', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__r
   5 epr__', '__setattr__', '__setitem__', '__str__', 'clear', 'copy', 'fromkeys', 'get', 'has_
   6 key', 'items', 'iteritems', 'iterkeys', 'itervalues', 'keys', 'pop', 'popitem', 'setdefaul
   7 t', 'update', 'values']
   8 >>> type({}.update)
   9 <type 'builtin_function_or_method'>
  10 >>> {}.update.__doc__
  11 'D.update(E) -> None.  Update D from E: for k in E.keys(): D[k] = E[k]'

2.3. 040820 标签驱动

  • 由格式化的列表数据来驱动模板的替换
    • 参考XML 结点的事务性处理!

['define', 'connect'
        , [
                ['code', '###CommandName###', 'connect']
                , ['code', '###Field###', '6s16sI8s']
                , ['loop', '###loop###Fields###'
                        , ['system_id', 'auth_source', 'version', 'time_stamp']
                        ]
                , ['loop', '###loop###Field###'
                        , ['system_id', 'auth_source', 'version', 'time_stamp']
                        ]
        ]
]

2.4. 040819 Macro

  • 试图完成新的标签系统:

   - ###XPath### 值替换标签 
        - ###start###XPath### ; ###end###XPath### 块标签,返回进一步处理后的整块文本
        - ###loop###XPath### 行标签,通过传入数值列来在行的单位中进行值替换处理
        - ###macro### ; ###macroend### 其间是可以模板处理时执行的脚本!!
    """
  • 失败!!! Macro 不能简单的 eval!

runmacro
    spli[i] = eval(spli[i]%(arg))
  File "<string>", line 2
    if "pass"=="pass":
     ^
SyntaxError: invalid syntax

   1 ###start###./Message/Commands/Command###
   2     def pack_###./Protocol/@ProtocolName###_###CommandName###(self, fields):
   3         """###CommandName###±¨ÎÄ´ò°ü"""
   4 
   5 ###macro###
   6 if "pass"=="%s":
   7     print "return None"
   8 else:
   9     print """    
  10         return struct.pack('###Field###',
  11                 ###loop###Fields###
  12                 )
  13 """
  14 ###macroend###
  15 
  16     def unpack_###./Protocol/@ProtocolName###_###CommandName###(self, packet):
  17         """###CommandName###±¨ÎĽâ°ü"""
  18 ###macro###
  19 if "pass"=="%s":
  20     print "pass"
  21 else:
  22     print """    
  23         ###loop###Field###
  24             struct.unpack('###Field###',packet)
  25 """
  26 ###macroend###
  27 
  28 ###end###./Message/Commands/Command###

2.5. 040818 Templet

  • 快速实现可嵌套模板标签的解析处理
  • 重新设计的模板标签

    设计的标签系统:
        - ###XPath### 值替换标签
        - ###start###XPath### ; ###end###XPath### 块标签,返回进一步处理后的整块文本
        - ###loop###XPath### 行标签,通过传入数值列来在行的单位中进行值替换处理
  • 我设想的模板文件:

from ###./@ProtocolName###.message import bytemsg
import struct

class ###./Protocol/@ProtocolName###Message(bytemsg.ByteMessage):
    """###./Protocol/@ProtocolName### 消息基类"""
    def __init__(self):
        # 消息头
        self.head = bytemsg.ByteMessageHead(self)
        # 消息体
        self.body = bytemsg.ByteMessageBody(self)
        # 消息工具
        self.msgutilcls = ###./Protocol/@ProtocolName###MessageUtil
        # 协议名称
        self.protocolname = '###./Protocol/@ProtocolName###'
        # 当前的消息名称
        self.msgname = ''

    ###start###./Message/Commands/Command###
    def pack_###./Protocol/@ProtocolName###_###CommandName###(self, fields):
        """###CommandName###报文打包"""
        return struct.pack('###Field###',
                ###loop###Fields###
                )
    def unpack_###./Protocol/@ProtocolName###_###CommandName###(self, packet):
        """###CommandName###报文解包"""
        ###loop###Field###
            struct.unpack('###Field###',packet)    
    ###end###./Message/Commands/Command###
    
# ###./Protocol/@ProtocolName### Message定义
###./Protocol/@ProtocolName###MessageUtil.commandinfo = {
    ###loop###commandinfo###
    }

# 通过名称查出消息ID的结构定义
###./Protocol/@ProtocolName###MessageUtil.nametoid = {}
for k in ###./Protocol/@ProtocolName###MessageUtil.commandinfo.keys():
    ###./Protocol/@ProtocolName###MessageUtil.nametoid[###./Protocol/@ProtocolName###MessageUtil.commandinfo[k]] = k


types -- Names for all built-in types

This module defines names for all object types that are used by the standard Python interpreter, but not for the types defined by various extension modules. It is safe to use "from types import *" -- the module does not export any names besides the ones listed here. New names exported by future versions of this module will all end in "Type".

   1 
   2 Typical use is for functions that do different things depending on their argument types, like the following:
   3 
   4 from types import *
   5 def delete(list, item):
   6     if type(item) is IntType:
   7        del list[item]
   8     else:
   9        list.remove(item)
  10 
  11 The module defines the following names:
  12 
  13 NoneType
  14 The type of None.
  15 
  16 
  17 ...
  18 
  19 LambdaType
  20 An alternate name for FunctionType.
  21 
  22 
  23 ...
  24 
  25 StringTypes
  • A sequence containing StringType and UnicodeType used to facilitate easier checking for any string object. Using this is more portable than using a sequence of the two string types constructed elsewhere since it only contains UnicodeType if it has been built in the running version of Python. For example: isinstance(s, types.StringTypes). New in version 2.2.

  • Names for built-in types

2.6. 040817 XML

  • 商定代码组织;
  • 完成XML 解析模块 OtXML.py
  • * 输出为一个复合列表

['###./@Version###', '0.1']

['###./@ProtocolName###', 'uss']

['###./@PersistentConnection###', 'false']

['###./@OtBaseDir###', 'OtterBaseTemplet']

['###./Message/@MessageName###', 'usspmsg']

['###./Message/@OtBaseDir###', 'message']

['###./Message/@OtBaseFile###', 'bytemsg.py']

['###./Message/Commands/Command###', [['generic_noop', '0x00000000L'], ['generic_noop_resp', '0xff000000L'], ['connect', '0x00000001L', [['system_id', '6', 's'], ['auth_source', '16', 's'], ['version', None, 'I'], ['time_stamp', '8', 's']]], ['connect_resp', '0xff000001L', [['status', None, 'I'], ['version', None, 'I']]], ['terminate', '0x00000002L'], ['terminate_resp', '0xff000002L'], ['mail_counter', '0x00000005L'], ['mail_counter_resp', '0xff000005L']], ('CommandName', 'CommandID'), ('FieldName', 'FieldSize', 'FieldType')]

['###./Protocol/@ProtocolName###', 'ussp']

['###./Protocol/@ListenPort###', '7890']

['###./Protocol/@OtBaseDir###', 'protocols']

['###./Protocol/@OtBaseFile###', 'byteprotocol.py']

['###./Protocol/ClientProtocol/Command###', [['generic_noop_resp', '0xff000000L'], ['connect_resp', '0xff000001L'], ['terminate', '0x00000002L'], ['terminate_resp', '0xff000002L'], ['mail_counter_resp', '0xff000005L']], ('CommandName', 'CommandID')]

['###./Protocol/ServerProtocol/Command###', [['generic_noop', '0x00000000L'], ['connect', '0x00000001L'], ['terminate', '0x00000002L'], ['terminate_resp', '0xff000002L'], ['mail_counter', '0x00000005L']], ('CommandName', 'CommandID')]

2.7. 040816 XSD

  • XML schema 确认,
  • 个人开始寻找,XML 解析,代码模板解析方式
    • 040816 19:50 尝试

   1 # -*- coding: utf-8 -*-
   2 # file OtterTools.py
   3 #
   4 """Otter Tools main script
   5 
   6 @version: 0.1a
   7 @author: U{Zoom.Quiet<mailto:[email protected]>}
   8 @see: http://wiki.woodpecker.org.cn/moin.cgi/Otter_2fOtterTool
   9 """
  10 import sys,string
  11 from elementtree import ElementTree
  12 if __name__ == '__main__':      # this way the module can be
  13     """
  14     应用 Elements and Element Trees 来通过XPath 迅速理解XML
  15     """
  16     file = open("uss.xml", "r")
  17     weblog = ElementTree.parse('uss.xml').getroot()
  18     commands = weblog.findall('.//Command')
  19     for node in commands:
  20         print node.attrib["CommandID"]

2.8. 040815 开始

  • QQ+Msn 与HD 讨论,明白Otter 的开发目标,方式
  • 最小特性开发,保证每一细小的特性KO先!

  • 每日保持就感!