Skip to content

Instantly share code, notes, and snippets.

@cameronp98
Created January 9, 2014 21:48
Show Gist options
  • Save cameronp98/8342669 to your computer and use it in GitHub Desktop.
Save cameronp98/8342669 to your computer and use it in GitHub Desktop.
import re
def slugify(string, delim="-"):
""" Return a (naively) normalized slug of a string"""
words = re.split(r"\W+", string.lower())
return delim.join(words).strip("-")
class Provider(object):
""" A provider holds its publishers alongside their
subscribers and can run the published content to
the appropriate subscribers"""
def __init__(self):
self.queue = []
self.publishers = {}
def notify(self, content):
self.queue.append(content)
def subscribe(self, subscriber, publisher):
self.publishers.setdefault(publisher.slug, []).append(subscriber)
def unsubscribe(self, subscriber, publisher):
self.publishers[publisher].remove(subscriber)
def update(self):
# item = (content, slug)
for item in self.queue:
for sub in self.publishers.get(item[1], []):
sub.run(item[0])
self.queue = []
class Publisher(object):
def __init__(self, name, provider):
self.name = name
self.slug = slugify(self.name)
self.provider = provider
def publish(self, content):
self.provider.notify((content, self.slug))
class Subscriber(object):
def __init__(self, name, provider):
self.name = name
self.provider = provider
def subscribe(self, publisher):
self.provider.subscribe(self, publisher)
def run(self, content):
# just a demonstration of the subscriber's capabilities
print("[{}]: I got '{}' ({})".format(self.name,
content.slug, content.publisher.name))
class Content(object):
def __init__(self, publisher, name, data={}):
self.publisher = publisher
self.name = name
self.slug = slugify(self.name)
self.data = data
def main():
# create a new provider
sky = Provider()
# add a publisher
movies = Publisher("Sky Movies", sky)
atlantic = Publisher("Sky Atlantic", sky)
# add a subscriber and give him a subscription
guy = Subscriber("guy", sky)
guy.subscribe(movies)
guy.subscribe(atlantic)
bob = Subscriber("bob", sky)
bob.subscribe(movies)
# publish some dummy content
movies.publish(Content(movies, "film"))
atlantic.publish(Content(atlantic, "american show"))
# update the provider and send the queued content
# to the appropriate subscribers
sky.update()
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment