TRAC学习笔记

31 篇文章 0 订阅
23 篇文章 0 订阅

Component Architecture

What is a Component?

For our purposes, a component is an object that provides a certain type of service within the context of the application. There is at most one instance of any component: components are singletons. That implies that a component doesnot map to an entity of the application's object model; instead, components represent functional subsystems. 功能子系统, 提供service

A component can extend any number of other components and still offer its own extension points. This allows a plugin to itself offer a plugin API (i.e. extension point). This feature is the basis for a plugin-based architecture.



Public classes



http://archive.ipython.org/release/0.12/ipython-0.12.win32-setup.exe

https://pypi.python.org/pypi/pyreadline/2.0

python中基于descriptor的一些概念(上)

python中基于descriptor的一些概念(下)

Descriptor Protocol(协议)
有下面这三个方法
__get__(self, obj, type=None) --> value
__set__(self, obj, value) --> None
__delete__(self, obj) --> None
 
只要对象重写任何上面的一个方法,对象就被看作是descriptor,就可以不去采用默认的查找属性的顺序。
 
 
如果一个对象同时定义了__get__,__set__方法,被看作是data descriptor;只定义了__get__,被称
为non-data descriptor。如果实例字典中有一个key和data descriptor同名,那么查找时优先采用
data descriptor;如果实例字典中有一个key和non-data descriptor同名,那么优先采用实例字典的
方法。
 
 
创建一个只读data descriptor,只需要在同时定义__get__,__set__方法的同时,让__set__方法抛出异常
AttributeError。

Python的descriptor

The Trac Configuration File

 Trac configuration is done by editing thetrac.ini config file, located in<projectenv>/conf/trac.ini. Changes to the configuration are usually reflected immediately, though changes to the[components] or[logging] sections will require restarting the web server. You may also need to restart the web server after creating a global configuration file when none was previously present.

The trac.ini configuration file and its parent directory should be writable by the web server, as Trac currently relies on the possibility to trigger a complete environment reload to flush its caches. 



Enabling a component is done in the[components] section of trac.ini

[components]
trac.ticket.report.ReportModule = disabled
webadmin.* = enabled


Miscellaneous noPackaging plugins


TracPlugins are packaged as ​Python Eggs. You can use ​setuptools to make a setup.py script that will produce a Python egg for your plugin.
The egg needs to export an ​entry point group named trac.plugins, listing the names of the modules that Trac should import for the plugin-provided components to get registered. For example:

from setuptools import find_packages, setup

setup(
    name='TracHelloWorld', version='1.0',
    packages=find_packages(exclude=['*.tests*']),
    entry_points = {
        'trac.plugins': [
            'helloworld = myplugs.helloworld',
        ],
    },
)


This assumes that the HelloWorldPlugin example above is defined in the module helloworld.py in the myplugs package. The entry point name (in this example “helloworld”) is required by the Python egg runtime, but not currently used by Trac. In most cases, you can simply use the qualified module name there.
For backwards-compatibility reasons, Trac still supports an alternative to entry points: you can have a file named trac_plugin.txt in the EGG-INFO directory. This file should contain the names of all modules that need to be imported by Trac to register your components. Note that this method is deprecated and will be removed in a future version of Trac (probably as soon as 0.11).tes: 
Components can be marked "abstract". This is done simply by adding a member field abstract = True to the component class.
class MyAbstractComponent(Component):
    abstract = True
    # implementation stuff here
Abstract components can't be enabled and therefore don't appear in the plugin panel of Trac's web interface.
Not all components require to be enabled to work properly. Only components implementing an extension point interface (using implements) need to be enabled and therefore listed in the entry_points section of a plugin. If you just want to have the utility class (like a database manager) that takes the benefits of a component (like being a singleton and/or having access to Trac's database or configuration) that doesn't implement any extension point interfaces, it doesn't need to be enabled (or even listed in the entry_points section). Such a component should then be marked "abstract". 
Components should be listed in the entry_points section, if they define any options (from trac.config). This way trac.ini editors can find this option even if it still has its default value. Options are registered when the component is registered. The component that defines the option doesn't need to be enabled for the option to be registered and can even be abstract. 


Note that there are actually three ways to define an extension point:

  • trac.core.ExtensionPoint: This is an unordered list of all enabled components implementing a specific extension point interface.
  • trac.config.ExtensionOption: An option for trac.ini that describes exactly one enabled component implementing a specific extension point interface.
  • trac.config.OrderedExtensionsOption: An option for trac.ini that describes an ordered list of enabled components implementing a specific extension point interface. (Components that also implement the same interface but are not listed in the option can automatically be appended to the list.) 
class IPermissionRequestor(Interface):
    """Extension point interface for components that define actions."""


    def get_permission_actions():
        """Return a list of actions defined by this component."""


class PermissionSystem(Component):
    """Sub-system that manages user permissions."""


    implements(IPermissionRequestor)


    requestors = ExtensionPoint(IPermissionRequestor)


    store = ExtensionOption('trac', 'permission_store', IPermissionStore,
                            'DefaultPermissionStore',
        """Name of the component implementing `IPermissionStore`, which is used
        for managing user and group permissions.""")
    def get_all_permissions(self):
        """Return all permissions for all users.


        The permissions are returned as a list of (subject, action)
        formatted tuples."""
        return self.store.get_all_permissions()


permission_system = trac.perm.PermissionSystem(env)
actions = permission_system.get_permission_actions()

#trac.ini
[trac]
permission_store = DefaultPermissionStore

Thus, service providers are directly manipulated from Python, and are customized through the automatic aggregation of components implementing ExtensionPoints and through configuration of ExtensionOptions by Trac administrators. 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值