| 1 | from zope.interface import implements |
|---|
| 2 | |
|---|
| 3 | from axiom.attributes import integer |
|---|
| 4 | from axiom.item import Item |
|---|
| 5 | |
|---|
| 6 | from eridanus import errors |
|---|
| 7 | from eridanus.plugin import getPluginByName |
|---|
| 8 | from eridanus.ieridanus import IIRCAvatar |
|---|
| 9 | |
|---|
| 10 | |
|---|
| 11 | class _AvatarMixin(object): |
|---|
| 12 | """ |
|---|
| 13 | A simple mixin to handle common avatar functions. |
|---|
| 14 | """ |
|---|
| 15 | implements(IIRCAvatar) |
|---|
| 16 | |
|---|
| 17 | def locateCommand(self, plugin, params): |
|---|
| 18 | cmd = plugin |
|---|
| 19 | while params: |
|---|
| 20 | cmd, params = cmd.locateCommand(params) |
|---|
| 21 | |
|---|
| 22 | return cmd |
|---|
| 23 | |
|---|
| 24 | def getAllCommands(self, protocol, params): |
|---|
| 25 | pluginName = params.pop(0) |
|---|
| 26 | for plugin in self.locatePlugins(protocol, pluginName): |
|---|
| 27 | yield self.locateCommand(plugin, params[:]) |
|---|
| 28 | |
|---|
| 29 | |
|---|
| 30 | class AnonymousAvatar(_AvatarMixin): |
|---|
| 31 | """ |
|---|
| 32 | The avatar given to unauthenticated users. |
|---|
| 33 | """ |
|---|
| 34 | def locatePlugins(self, protocol, name): |
|---|
| 35 | yield protocol.locatePlugin(name) |
|---|
| 36 | |
|---|
| 37 | def getCommand(self, protocol, params): |
|---|
| 38 | plugin = self.locatePlugins(protocol, params.pop(0)).next() |
|---|
| 39 | return self.locateCommand(plugin, params) |
|---|
| 40 | |
|---|
| 41 | |
|---|
| 42 | class AuthenticatedAvatar(Item, _AvatarMixin): |
|---|
| 43 | """ |
|---|
| 44 | The avatar used for authenticated users. |
|---|
| 45 | |
|---|
| 46 | The primary difference between this avatar and L{AnonymousAvatar} is the |
|---|
| 47 | user-store plugin searching. If a plugin cannot be found in the user-store |
|---|
| 48 | then the regular plugin location method is used. This allows plugins to be |
|---|
| 49 | endowed on a single user, useful for things like a GodOfTheBot plugin that |
|---|
| 50 | you probably don't want the rest of the world being able to use. |
|---|
| 51 | """ |
|---|
| 52 | typeName = 'eridanus_avatar_authenticatedavatar' |
|---|
| 53 | schemaVersion = 1 |
|---|
| 54 | |
|---|
| 55 | dummy = integer() |
|---|
| 56 | |
|---|
| 57 | def locatePlugins(self, protocol, name): |
|---|
| 58 | def _plugins(): |
|---|
| 59 | try: |
|---|
| 60 | yield getPluginByName(self.store, name) |
|---|
| 61 | except errors.PluginNotInstalled: |
|---|
| 62 | pass |
|---|
| 63 | try: |
|---|
| 64 | yield protocol.locatePlugin(name) |
|---|
| 65 | except errors.PluginNotInstalled: |
|---|
| 66 | pass |
|---|
| 67 | |
|---|
| 68 | plugins = list(_plugins()) |
|---|
| 69 | if not plugins: |
|---|
| 70 | raise errors.PluginNotInstalled(name) |
|---|
| 71 | |
|---|
| 72 | return plugins |
|---|
| 73 | |
|---|
| 74 | def getCommand(self, protocol, params): |
|---|
| 75 | pluginName = params.pop(0) |
|---|
| 76 | plugins = list(self.locatePlugins(protocol, pluginName)) |
|---|
| 77 | |
|---|
| 78 | while plugins: |
|---|
| 79 | try: |
|---|
| 80 | plugin = plugins.pop() |
|---|
| 81 | return self.locateCommand(plugin, params[:]) |
|---|
| 82 | except errors.UsageError: |
|---|
| 83 | # XXX: this isn't great |
|---|
| 84 | if not plugins: |
|---|
| 85 | raise |
|---|