Changeset 04483e06aab16b4a263e657076329ba25478ba03

Show
Ignore:
Timestamp:
06/11/2011 01:17:44 AM (2 years ago)
Author:
Loic Dachary <loic@…>
Children:
ed3ed890e91aaf58ef8d04d39f956ec66a19a31c
Parents:
8179fdcc6ae6065cd69591a884834c044c08cd80
git-committer:
Loic Dachary <loic@…> (06/11/2011 01:17:44 AM)
Message:

Change the rule to load the plugin from plugin.py to plugin/plugin.py and rename all relevant files, tests and fixtures. It makes it easier to create self contained plugin directotires. The plugin constructor takes a list of plugins which contains each already loaded plugin. Implement mail notifications plugins for invite + complete + pick + vote.

Files:
35 added
12 modified
1 copied
5 moved

Legend:

Unmodified
Added
Removed
  • MANIFEST.in

    r17a763c r04483e0  
    11recursive-include static *.html *.js *.css *.png *.jpg *.gif *.svg Makefile 
     2recursive-include plugins *.html *.png *.jpg *.gif Makefile *.py *.xml 
    23recursive-include etc/cardstories *.py 
    3 recursive-include tests *.py Makefile 
     4recursive-include tests *.xml *.py Makefile 
    45include etc/default/cardstories 
    56include conf/*.conf 
    6 include plugins/*/*.py 
    7 include plugins/__init__.py 
    87include maintain.mk 
    98include LICENSE.txt 
  • README.txt

    r1fa7cef r04483e0  
    1919# display usage 
    2020PYTHONPATH=.:etc/cardstories twistd cardstories --help 
    21 # run locally with all features activated 
    22 for plugin in solo auth ; do ( cd plugins ; ln -s $plugin/$plugin.py $plugin.py ) ; done ; PYTHONPATH=.:etc/cardstories twistd --nodaemon cardstories --static $(pwd)/static --port 5000 --interface 0.0.0.0 --db /tmp/cardstories.sqlite --plugins-dir plugins --plugins 'auth solo' --plugins-pre-process 'auth solo' --plugins-post-process auth --plugins-libdir /tmp 
     21# run locally  
     22PYTHONPATH=.:etc/cardstories twistd --nodaemon cardstories --static $(pwd)/static --port 5000 --interface 0.0.0.0 --db /tmp/cardstories.sqlite --plugins-dir plugins --plugins 'auth solo' --plugins-pre-process 'auth solo' --plugins-post-process auth --plugins-libdir /tmp 
     23# run locally with mails 
     24PYTHONPATH=.:etc/cardstories twistd --nodaemon cardstories --static $(pwd)/static --port 5000 --interface 0.0.0.0 --db /tmp/cardstories.sqlite --plugins-dir plugins --plugins 'auth solo mail' --plugins-pre-process 'auth solo' --plugins-post-process auth --plugins-libdir /tmp --plugins-confdir tests 
    2325# check if the webservice replies. The following must return the {} string 
    2426curl --silent http://localhost:4923/resource 
  • cardstories/plugins.py

    r74552e0 r04483e0  
    2929        for plugin in self.settings.get('plugins', '').split(): 
    3030            module = imp.load_source("cardstories_plugin", self.path(plugin)) 
    31             self.plugins.append(getattr(module, 'Plugin')(service)) 
     31            self.plugins.append(getattr(module, 'Plugin')(service, self.plugins)) 
    3232 
    3333    def path(self, plugin): 
    3434        if os.path.exists(plugin): 
    3535            return plugin 
    36         path = os.path.join(self.settings['plugins-dir'], plugin + '.py') 
     36        path = os.path.join(self.settings['plugins-dir'], plugin, plugin + '.py') 
    3737        if os.path.exists(path): 
    3838            return path 
  • debian/control

    r88b0fb9 r04483e0  
    66               po-debconf, 
    77               python-all (>= 2.6.6-2~), 
     8               python-lxml, 
    89               python-coverage, 
    910               python-twisted-web (>= 10.1), 
     
    2728         python-twisted-web (>= 10.1), 
    2829         python-twisted-mail, 
     30         python-lxml, 
    2931         python-openssl, 
    3032         ${python:Depends} 
  • etc/default/cardstories

    rca9e144 r04483e0  
    1010 
    1111# 
    12 # White space separated list of plugins to load 
     12# White space separated list of plugins to load. 
     13# The order matters. 
    1314# 
     15#PLUGINS="auth solo mail" 
    1416PLUGINS="auth solo" 
    1517 
  • plugins/auth/auth.py

    r1690010 r04483e0  
    2525class Plugin: 
    2626 
    27     def __init__(self, service): 
     27    def __init__(self, service, plugins): 
    2828        dirname = os.path.join(service.settings['plugins-libdir'], self.name()) 
    2929        self.database = os.path.join(dirname, 'auth.sqlite') 
     
    7373    @defer.inlineCallbacks 
    7474    def postprocess(self, result): 
    75         # Convert internal game logic ids to public ones 
    7675        if result.has_key('players'): 
    7776            for player in result['players']: 
  • plugins/auth/test_auth.py

    r9f9d9e2 r04483e0  
    3535 
    3636    def test00_create(self): 
    37         auth = Plugin(FakeService({'plugins-libdir': '.'})) 
     37        auth = Plugin(FakeService({'plugins-libdir': '.'}), []) 
    3838        self.assertTrue(os.path.exists(auth.database)) 
    3939 
     
    4141 
    4242    def setUp(self): 
    43         self.auth = Plugin(FakeService({'plugins-libdir': '.'})) 
     43        self.auth = Plugin(FakeService({'plugins-libdir': '.'}), []) 
    4444        self.db = sqlite3.connect(self.auth.database) 
    4545 
  • plugins/mail/Makefile

    r1690010 r04483e0  
    11# 
    2 # Copyright (C) 2011 Loic Dachary <loic@dachary.org> 
     2# Copyright (C) 2011 Dachary <loic@dachary.org> 
    33# 
    44# This software's license gives you freedom; you can copy, convey, 
     
    1717# "AGPLv3".  If not, see <http://www.gnu.org/licenses/>. 
    1818# 
    19 class Plugin: 
    20      
    21     def __init__(self, service): 
    22         self.service = service 
     19all: 
    2320 
    24     def name(self): 
    25         return 'plugin_two' 
     21check: 
     22        python-coverage -e 
     23        PYTHONPATH=../.. python-coverage -x test_mail.py 
     24        python-coverage -m -a -r mail.py 
     25 
     26clean: 
     27        rm -fr fixture/auth 
     28        rm -fr .coverage _trial_temp* 
     29        rm -f *,cover 
     30        rm -f *.pyc 
     31 
  • plugins/solo/solo.py

    rb46525d r04483e0  
    2626class Plugin: 
    2727 
    28     def __init__(self, service): 
     28    def __init__(self, service, plugins): 
    2929        self.service = service 
    3030        self.id2info = {} 
  • plugins/solo/test_solo.py

    rb46525d r04483e0  
    8989    @defer.inlineCallbacks 
    9090    def test00_preprocess_noop(self): 
    91         solo = Plugin(self.service) 
     91        solo = Plugin(self.service, []) 
    9292        self.assertEquals(solo.name(), 'solo') 
    9393        yield self.complete_game() 
     
    130130    @defer.inlineCallbacks 
    131131    def test01_solo(self): 
    132         solo = Plugin(self.service) 
     132        solo = Plugin(self.service, []) 
    133133        yield self.complete_game() 
    134134        player_id = 200 
     
    147147    @defer.inlineCallbacks 
    148148    def test01_solo_duplicate(self): 
    149         solo = Plugin(self.service) 
     149        solo = Plugin(self.service, []) 
    150150        yield self.complete_game() 
    151151        request = Request(action = ['solo'], player_id = [self.player1]) 
  • setup.py

    rca9e144 r04483e0  
    3737data_files.append(['/usr/share/cardstories/conf', [ 'conf/apache2.conf' ]]) 
    3838 
    39 data_files.append(['/usr/share/cardstories/plugins', [ 'plugins/auth/auth.py' ]]) 
    40 data_files.append(['/usr/share/cardstories/plugins', [ 'plugins/solo/solo.py' ]]) 
     39data_files.append(['/usr/share/cardstories/plugins/auth', [ 'plugins/auth/auth.py' ]]) 
     40 
     41data_files.append(['/usr/share/cardstories/plugins/solo', [ 'plugins/solo/solo.py' ]]) 
     42 
     43data_files.append(['/usr/share/cardstories/plugins/mail', [ 'plugins/mail/mail.py' ]]) 
     44for dirpath, dirnames, filenames in os.walk('plugins/mail/templates'): 
     45            # Ignore dirnames that start with '.' 
     46            for i, dirname in enumerate(dirnames): 
     47                if dirname.startswith('.'): del dirnames[i] 
     48            if filenames: 
     49                filenames = filter(lambda f: re.match('.*.(html|png|jpg|gif)$', f), filenames) 
     50                data_files.append(['/usr/share/cardstories/' + dirpath, [os.path.join(dirpath, f) for f in filenames]]) 
     51data_files.append(['/etc/cardstories/plugins/mail', [ 'plugins/mail/mail.xml' ]]) 
    4152 
    4253setup(name='cardstories', 
  • tests/plugin/plugin.py

    r895c928 r04483e0  
    1919class Plugin: 
    2020     
    21     def __init__(self, service): 
     21    def __init__(self, service, plugins): 
    2222        self.service = service 
    2323        self.accept(None) 
  • tests/plugin_fail/plugin_fail.py

    r1690010 r04483e0  
    1919class Plugin: 
    2020     
    21     def __init__(self, service): 
     21    def __init__(self, service, plugins): 
    2222        self.service = service 
    2323 
  • tests/plugin_one/plugin_one.py

    r1690010 r04483e0  
    1919class Plugin: 
    2020     
    21     def __init__(self, service): 
     21    def __init__(self, service, plugins): 
    2222        self.service = service 
    2323 
  • tests/plugin_site/plugin_site.py

    r4f0330b r04483e0  
    1919class Plugin: 
    2020     
    21     def __init__(self, service): 
     21    def __init__(self, service, plugins): 
    2222        self.service = service 
    2323 
  • tests/plugin_two/plugin_two.py

    r1690010 r04483e0  
    1919class Plugin: 
    2020     
    21     def __init__(self, service): 
     21    def __init__(self, service, plugins): 
    2222        self.service = service 
    2323 
  • tests/test_game.py

    rca9e144 r04483e0  
    265265            result = yield self.game.participate(player_id) 
    266266            self.assertEquals([game_id], result['game_id']) 
    267         self.game.invite(invited) 
     267        yield self.game.invite(invited) 
    268268 
    269269        # invitation state, visitor point of view 
     
    293293        self.assertEquals(game_id, game_info['id']) 
    294294        self.assertEquals(invited, game_info['invited']) 
     295        self.assertNotEquals(id(invited), id(game_info['invited'])) 
    295296        self.assertEquals(owner_id, game_info['players'][0][0]) 
    296297        self.assertEquals(1, len(game_info['players'][0][4])) 
     
    377378        self.assertEquals([owner_id], self.game.get_players()) 
    378379         
    379         result = yield self.game.invite(invited) 
     380        self.checked = False 
     381        d = self.game.invite(invited) 
     382        def check(result): 
     383            self.checked = True 
     384            self.assertNotEquals(id(invited), id(result['invited'])) 
     385            return result 
     386        d.addCallback(check) 
     387        result = yield d 
     388        self.assertTrue(self.checked) 
    380389        self.assertEquals(result['type'], 'invite') 
    381390        self.assertEquals(result['invited'], invited) 
  • tests/test_plugins.py

    r74552e0 r04483e0  
    2828    def test00_path(self): 
    2929        plugins = CardstoriesPlugins({ 'plugins-dir': '..' }) 
    30         self.assertEquals(plugins.path('../plugin_one.py'), '../plugin_one.py') 
    31         self.assertEquals(plugins.path('plugin_one'), '../plugin_one.py') 
     30        self.assertEquals(plugins.path('../plugin_one/plugin_one.py'), '../plugin_one/plugin_one.py') 
     31        self.assertEquals(plugins.path('plugin_one'), '../plugin_one/plugin_one.py') 
    3232        caught = False 
    3333        try: