Changeset 04483e06aab16b4a263e657076329ba25478ba03
- 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
-
|
r17a763c
|
r04483e0
|
|
| 1 | 1 | recursive-include static *.html *.js *.css *.png *.jpg *.gif *.svg Makefile |
| | 2 | recursive-include plugins *.html *.png *.jpg *.gif Makefile *.py *.xml |
| 2 | 3 | recursive-include etc/cardstories *.py |
| 3 | | recursive-include tests *.py Makefile |
| | 4 | recursive-include tests *.xml *.py Makefile |
| 4 | 5 | include etc/default/cardstories |
| 5 | 6 | include conf/*.conf |
| 6 | | include plugins/*/*.py |
| 7 | | include plugins/__init__.py |
| 8 | 7 | include maintain.mk |
| 9 | 8 | include LICENSE.txt |
-
|
r1fa7cef
|
r04483e0
|
|
| 19 | 19 | # display usage |
| 20 | 20 | PYTHONPATH=.: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 |
| | 22 | 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 |
| | 23 | # run locally with mails |
| | 24 | 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 mail' --plugins-pre-process 'auth solo' --plugins-post-process auth --plugins-libdir /tmp --plugins-confdir tests |
| 23 | 25 | # check if the webservice replies. The following must return the {} string |
| 24 | 26 | curl --silent http://localhost:4923/resource |
-
|
r74552e0
|
r04483e0
|
|
| 29 | 29 | for plugin in self.settings.get('plugins', '').split(): |
| 30 | 30 | 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)) |
| 32 | 32 | |
| 33 | 33 | def path(self, plugin): |
| 34 | 34 | if os.path.exists(plugin): |
| 35 | 35 | 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') |
| 37 | 37 | if os.path.exists(path): |
| 38 | 38 | return path |
-
|
r88b0fb9
|
r04483e0
|
|
| 6 | 6 | po-debconf, |
| 7 | 7 | python-all (>= 2.6.6-2~), |
| | 8 | python-lxml, |
| 8 | 9 | python-coverage, |
| 9 | 10 | python-twisted-web (>= 10.1), |
| … |
… |
|
| 27 | 28 | python-twisted-web (>= 10.1), |
| 28 | 29 | python-twisted-mail, |
| | 30 | python-lxml, |
| 29 | 31 | python-openssl, |
| 30 | 32 | ${python:Depends} |
-
|
rca9e144
|
r04483e0
|
|
| 10 | 10 | |
| 11 | 11 | # |
| 12 | | # White space separated list of plugins to load |
| | 12 | # White space separated list of plugins to load. |
| | 13 | # The order matters. |
| 13 | 14 | # |
| | 15 | #PLUGINS="auth solo mail" |
| 14 | 16 | PLUGINS="auth solo" |
| 15 | 17 | |
-
|
r1690010
|
r04483e0
|
|
| 25 | 25 | class Plugin: |
| 26 | 26 | |
| 27 | | def __init__(self, service): |
| | 27 | def __init__(self, service, plugins): |
| 28 | 28 | dirname = os.path.join(service.settings['plugins-libdir'], self.name()) |
| 29 | 29 | self.database = os.path.join(dirname, 'auth.sqlite') |
| … |
… |
|
| 73 | 73 | @defer.inlineCallbacks |
| 74 | 74 | def postprocess(self, result): |
| 75 | | # Convert internal game logic ids to public ones |
| 76 | 75 | if result.has_key('players'): |
| 77 | 76 | for player in result['players']: |
-
|
r9f9d9e2
|
r04483e0
|
|
| 35 | 35 | |
| 36 | 36 | def test00_create(self): |
| 37 | | auth = Plugin(FakeService({'plugins-libdir': '.'})) |
| | 37 | auth = Plugin(FakeService({'plugins-libdir': '.'}), []) |
| 38 | 38 | self.assertTrue(os.path.exists(auth.database)) |
| 39 | 39 | |
| … |
… |
|
| 41 | 41 | |
| 42 | 42 | def setUp(self): |
| 43 | | self.auth = Plugin(FakeService({'plugins-libdir': '.'})) |
| | 43 | self.auth = Plugin(FakeService({'plugins-libdir': '.'}), []) |
| 44 | 44 | self.db = sqlite3.connect(self.auth.database) |
| 45 | 45 | |
-
|
r1690010
|
r04483e0
|
|
| 1 | 1 | # |
| 2 | | # Copyright (C) 2011 Loic Dachary <loic@dachary.org> |
| | 2 | # Copyright (C) 2011 Dachary <loic@dachary.org> |
| 3 | 3 | # |
| 4 | 4 | # This software's license gives you freedom; you can copy, convey, |
| … |
… |
|
| 17 | 17 | # "AGPLv3". If not, see <http://www.gnu.org/licenses/>. |
| 18 | 18 | # |
| 19 | | class Plugin: |
| 20 | | |
| 21 | | def __init__(self, service): |
| 22 | | self.service = service |
| | 19 | all: |
| 23 | 20 | |
| 24 | | def name(self): |
| 25 | | return 'plugin_two' |
| | 21 | check: |
| | 22 | python-coverage -e |
| | 23 | PYTHONPATH=../.. python-coverage -x test_mail.py |
| | 24 | python-coverage -m -a -r mail.py |
| | 25 | |
| | 26 | clean: |
| | 27 | rm -fr fixture/auth |
| | 28 | rm -fr .coverage _trial_temp* |
| | 29 | rm -f *,cover |
| | 30 | rm -f *.pyc |
| | 31 | |
-
|
rb46525d
|
r04483e0
|
|
| 26 | 26 | class Plugin: |
| 27 | 27 | |
| 28 | | def __init__(self, service): |
| | 28 | def __init__(self, service, plugins): |
| 29 | 29 | self.service = service |
| 30 | 30 | self.id2info = {} |
-
|
rb46525d
|
r04483e0
|
|
| 89 | 89 | @defer.inlineCallbacks |
| 90 | 90 | def test00_preprocess_noop(self): |
| 91 | | solo = Plugin(self.service) |
| | 91 | solo = Plugin(self.service, []) |
| 92 | 92 | self.assertEquals(solo.name(), 'solo') |
| 93 | 93 | yield self.complete_game() |
| … |
… |
|
| 130 | 130 | @defer.inlineCallbacks |
| 131 | 131 | def test01_solo(self): |
| 132 | | solo = Plugin(self.service) |
| | 132 | solo = Plugin(self.service, []) |
| 133 | 133 | yield self.complete_game() |
| 134 | 134 | player_id = 200 |
| … |
… |
|
| 147 | 147 | @defer.inlineCallbacks |
| 148 | 148 | def test01_solo_duplicate(self): |
| 149 | | solo = Plugin(self.service) |
| | 149 | solo = Plugin(self.service, []) |
| 150 | 150 | yield self.complete_game() |
| 151 | 151 | request = Request(action = ['solo'], player_id = [self.player1]) |
-
|
rca9e144
|
r04483e0
|
|
| 37 | 37 | data_files.append(['/usr/share/cardstories/conf', [ 'conf/apache2.conf' ]]) |
| 38 | 38 | |
| 39 | | data_files.append(['/usr/share/cardstories/plugins', [ 'plugins/auth/auth.py' ]]) |
| 40 | | data_files.append(['/usr/share/cardstories/plugins', [ 'plugins/solo/solo.py' ]]) |
| | 39 | data_files.append(['/usr/share/cardstories/plugins/auth', [ 'plugins/auth/auth.py' ]]) |
| | 40 | |
| | 41 | data_files.append(['/usr/share/cardstories/plugins/solo', [ 'plugins/solo/solo.py' ]]) |
| | 42 | |
| | 43 | data_files.append(['/usr/share/cardstories/plugins/mail', [ 'plugins/mail/mail.py' ]]) |
| | 44 | for 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]]) |
| | 51 | data_files.append(['/etc/cardstories/plugins/mail', [ 'plugins/mail/mail.xml' ]]) |
| 41 | 52 | |
| 42 | 53 | setup(name='cardstories', |
-
|
r895c928
|
r04483e0
|
|
| 19 | 19 | class Plugin: |
| 20 | 20 | |
| 21 | | def __init__(self, service): |
| | 21 | def __init__(self, service, plugins): |
| 22 | 22 | self.service = service |
| 23 | 23 | self.accept(None) |
-
|
r1690010
|
r04483e0
|
|
| 19 | 19 | class Plugin: |
| 20 | 20 | |
| 21 | | def __init__(self, service): |
| | 21 | def __init__(self, service, plugins): |
| 22 | 22 | self.service = service |
| 23 | 23 | |
-
|
r1690010
|
r04483e0
|
|
| 19 | 19 | class Plugin: |
| 20 | 20 | |
| 21 | | def __init__(self, service): |
| | 21 | def __init__(self, service, plugins): |
| 22 | 22 | self.service = service |
| 23 | 23 | |
-
|
r4f0330b
|
r04483e0
|
|
| 19 | 19 | class Plugin: |
| 20 | 20 | |
| 21 | | def __init__(self, service): |
| | 21 | def __init__(self, service, plugins): |
| 22 | 22 | self.service = service |
| 23 | 23 | |
-
|
r1690010
|
r04483e0
|
|
| 19 | 19 | class Plugin: |
| 20 | 20 | |
| 21 | | def __init__(self, service): |
| | 21 | def __init__(self, service, plugins): |
| 22 | 22 | self.service = service |
| 23 | 23 | |
-
|
rca9e144
|
r04483e0
|
|
| 265 | 265 | result = yield self.game.participate(player_id) |
| 266 | 266 | self.assertEquals([game_id], result['game_id']) |
| 267 | | self.game.invite(invited) |
| | 267 | yield self.game.invite(invited) |
| 268 | 268 | |
| 269 | 269 | # invitation state, visitor point of view |
| … |
… |
|
| 293 | 293 | self.assertEquals(game_id, game_info['id']) |
| 294 | 294 | self.assertEquals(invited, game_info['invited']) |
| | 295 | self.assertNotEquals(id(invited), id(game_info['invited'])) |
| 295 | 296 | self.assertEquals(owner_id, game_info['players'][0][0]) |
| 296 | 297 | self.assertEquals(1, len(game_info['players'][0][4])) |
| … |
… |
|
| 377 | 378 | self.assertEquals([owner_id], self.game.get_players()) |
| 378 | 379 | |
| 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) |
| 380 | 389 | self.assertEquals(result['type'], 'invite') |
| 381 | 390 | self.assertEquals(result['invited'], invited) |
-
|
r74552e0
|
r04483e0
|
|
| 28 | 28 | def test00_path(self): |
| 29 | 29 | 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') |
| 32 | 32 | caught = False |
| 33 | 33 | try: |