Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Ideenklau erwünscht: Konzepte aus der Zope-Welt

wosc
October 05, 2011

Ideenklau erwünscht: Konzepte aus der Zope-Welt

wosc

October 05, 2011
Tweet

More Decks by wosc

Other Decks in Programming

Transcript

  1. Ideenklau erwünscht:
    Konzepte aus der Zope-Welt
    Wolfgang Schnerring
    gmbh & co. kg
    PyCon DE 2011, Leipzig
    Wolfgang Schnerring Zope-Ideen 06.10.2011 1 / 39

    View Slide

  2. Einführung
    1996 Z Object Publishing Environment:
    Application-Server als
    CGI-Alternative
    2001 Plone CMS
    2004 Rewrite: Zope 3
    2009 Zope Toolkit
    Wolfgang Schnerring Zope-Ideen 06.10.2011 2 / 39

    View Slide

  3. Agenda
    1 Traversal
    2 Erweiterbarkeit
    3 Zope Component Architecture
    4 Model-based Security
    5 Transaktionen
    6 Test-Setup
    7 Testbrowser
    http://www.sxc.hu/photo/1149105 by nkzs
    Wolfgang Schnerring Zope-Ideen 06.10.2011 3 / 39

    View Slide

  4. View Slide

  5. Traversal
    Routing
    /users/edit/14
    /users/edit/[email protected]
    /users/[email protected]/edit
    Wolfgang Schnerring Zope-Ideen 06.10.2011 5 / 39

    View Slide

  6. Traversal
    Routing
    /users/edit/14
    /users/edit/[email protected]
    /users/[email protected]/edit
    /users/{email}/edit → edit_user(email)
    Wolfgang Schnerring Zope-Ideen 06.10.2011 5 / 39

    View Slide

  7. Traversal
    Traversal
    / users / [email protected] / edit
    Wolfgang Schnerring Zope-Ideen 06.10.2011 6 / 39

    View Slide

  8. Traversal
    Traversal
    / users / [email protected] / edit
    Wolfgang Schnerring Zope-Ideen 06.10.2011 6 / 39

    View Slide

  9. View Slide

  10. Erweiterbarkeit
    Zusätzliche Views
    Wolfgang Schnerring Zope-Ideen 06.10.2011 8 / 39

    View Slide

  11. Erweiterbarkeit
    Zusätzliche Daten
    # package1
    class User(persistent.Persistent):
    pass
    user.firstname = ’Alice’
    user.lastname = ’Random’
    user.email = ’[email protected]
    # package2
    annotations = zope.annotation.interfaces.IAnnotations(user)
    annotations[’credit_card_ref’] = ’1234XAB’
    Wolfgang Schnerring Zope-Ideen 06.10.2011 9 / 39

    View Slide

  12. View Slide

  13. Zope Component Architecture
    Adapter-Pattern
    Wolfgang Schnerring Zope-Ideen 06.10.2011 11 / 39

    View Slide

  14. Zope Component Architecture
    Zusätzliche Operationen
    # package1
    class User:
    # [...]
    # package2
    class CreditCardHolder:
    adapts(User)
    implements(CreditCard)
    # client code
    CreditCard(user).add(’1234XAB’)
    Wolfgang Schnerring Zope-Ideen 06.10.2011 12 / 39

    View Slide

  15. Zope Component Architecture
    Single Dispatch
    class Shape:
    def draw(self):
    raise NotImplementedError()
    class Circle(Shape):
    def draw(self):
    # [...]
    class Square(Shape):
    def draw(self):
    # [...]
    Wolfgang Schnerring Zope-Ideen 06.10.2011 13 / 39

    View Slide

  16. Zope Component Architecture
    Multiple Dispatch
    class SVGCircle:
    adapts(Circle, SVGCanvas)
    implements(Drawable)
    class JPGCircle:
    adapts(Circle, JPGCanvas)
    implements(Drawable)
    # client code
    Drawable(shape, canvas).draw()
    Wolfgang Schnerring Zope-Ideen 06.10.2011 14 / 39

    View Slide

  17. Zope Component Architecture
    Beispiel: Views
    # client code
    EditForm(user, request).render()
    class HTMLEditForm:
    adapts(User, HTTPRequest)
    implements(EditForm)
    class JSONEditForm:
    adapts(User, JSONRequest)
    implements(EditForm)
    Wolfgang Schnerring Zope-Ideen 06.10.2011 15 / 39

    View Slide

  18. Zope Component Architecture
    Zusätzliche Views
    Wolfgang Schnerring Zope-Ideen 06.10.2011 16 / 39

    View Slide

  19. Zope Component Architecture
    Beispiel: Traversal
    # /users/[email protected]/edit
    class UserFolderTraverser:
    adapts(UserFolder)
    implements(zope.traversing.interfaces.ITraversable)
    def __init__(self, context, request):
    self.context = context
    self.request = request
    def traverse(self, name, remaining):
    return self.context.find_user_by_email(name)
    Wolfgang Schnerring Zope-Ideen 06.10.2011 17 / 39

    View Slide

  20. Zope Component Architecture
    Beispiel: Events
    zope.event.notify(ObjectCreatedEvent(user))
    # client code
    @subscribe(User, ObjectCreatedEvent)
    def send_welcome_email(user, event):
    # [...]
    Wolfgang Schnerring Zope-Ideen 06.10.2011 18 / 39

    View Slide

  21. View Slide

  22. Model-based Security
    view-based
    Wolfgang Schnerring Zope-Ideen 06.10.2011 20 / 39

    View Slide

  23. Model-based Security
    view-based
    Wolfgang Schnerring Zope-Ideen 06.10.2011 20 / 39

    View Slide

  24. Model-based Security
    model-based
    Wolfgang Schnerring Zope-Ideen 06.10.2011 21 / 39

    View Slide

  25. Model-based Security
    API
    zope.security.checker.defineChecker(class_, checker)
    proxied = zope.security.checker.ProxyFactory(object)
    class Checker(object):
    def check_getattr(self, object, name):
    def check_setattr(self, object, name):
    # permission = [...]
    getInteraction().checkPermission(permission, object)
    Wolfgang Schnerring Zope-Ideen 06.10.2011 22 / 39

    View Slide

  26. Model-based Security
    API
    class Interaction(object):
    def add(self, participation):
    def remove(self, participation):
    def checkPermission(self, permission, object):
    # [...]
    Wolfgang Schnerring Zope-Ideen 06.10.2011 23 / 39

    View Slide

  27. View Slide

  28. Transaktionen
    2-Phase-Commit
    Wolfgang Schnerring Zope-Ideen 06.10.2011 25 / 39

    View Slide

  29. Transaktionen
    2-Phase-Commit
    Wolfgang Schnerring Zope-Ideen 06.10.2011 25 / 39

    View Slide

  30. Transaktionen
    2-Phase-Commit
    Wolfgang Schnerring Zope-Ideen 06.10.2011 25 / 39

    View Slide

  31. Transaktionen
    2-Phase-Commit
    Wolfgang Schnerring Zope-Ideen 06.10.2011 25 / 39

    View Slide

  32. Transaktionen
    2-Phase-Commit
    Fehlerfall
    Wolfgang Schnerring Zope-Ideen 06.10.2011 25 / 39

    View Slide

  33. Transaktionen
    2-Phase-Commit
    Wolfgang Schnerring Zope-Ideen 06.10.2011 25 / 39

    View Slide

  34. Transaktionen
    2-Phase-Commit
    Wolfgang Schnerring Zope-Ideen 06.10.2011 25 / 39

    View Slide

  35. Transaktionen
    API
    transaction
    commit / abort
    savepoint
    get
    doom
    join
    DataManager
    tpc_begin – commit – tpc_vote – (tpc_finish | tpc_abort)
    Wolfgang Schnerring Zope-Ideen 06.10.2011 26 / 39

    View Slide

  36. Transaktionen
    Beispiel
    Wolfgang Schnerring Zope-Ideen 06.10.2011 27 / 39

    View Slide

  37. View Slide

  38. Test-Setup
    unittest.TestCase
    class ExampleTest(unittest.TestCase):
    def setUp(self):
    def tearDown(self):
    def test_something(self):
    Wolfgang Schnerring Zope-Ideen 06.10.2011 29 / 39

    View Slide

  39. Test-Setup
    gemeinsames setUp
    Wolfgang Schnerring Zope-Ideen 06.10.2011 30 / 39

    View Slide

  40. Test-Setup
    Stacking
    Wolfgang Schnerring Zope-Ideen 06.10.2011 31 / 39

    View Slide

  41. Test-Setup
    Layer
    class Layer(object):
    __bases__ = (OTHER_LAYER,)
    def setUp(self):
    def tearDown(self):
    def testSetUp(self):
    def testTearDown(self):
    Wolfgang Schnerring Zope-Ideen 06.10.2011 32 / 39

    View Slide

  42. Test-Setup
    Beispiel
    class PersistenceTest(unittest.TestCase):
    layer = DB_LAYER
    def test_serializing_document_parameters(self):
    # [...]
    class IntegrationTest(unittest.TestCase):
    layer = COMBINED_LAYER
    def test_search_displays_suggestions_from_database(self):
    # [...]
    Wolfgang Schnerring Zope-Ideen 06.10.2011 33 / 39

    View Slide

  43. Test-Setup
    Beispiel
    class DatabaseLayer(plone.testing.Layer):
    def setUp(self):
    self.connection = dbdriver.connect(os.environ[’DSN’])
    def tearDown(self):
    self.connection.close()
    DB_LAYER = DatabaseLayer()
    HTTP_LAYER = HTTPServerLayer()
    COMBINED_LAYER = plone.testing.Layer(
    bases=(DatabaseLayer, HTTPServerLayer))
    Wolfgang Schnerring Zope-Ideen 06.10.2011 34 / 39

    View Slide

  44. View Slide

  45. Testbrowser
    Beispiel
    Wolfgang Schnerring Zope-Ideen 06.10.2011 36 / 39

    View Slide

  46. Testbrowser
    Beispiel
    class SearchTest(unittest.TestCase):
    def test_advanced_search_filters_by_content_type(self):
    b = zope.testbrowser.wsgi.Browser(
    wsgi_app=my_wsgi_callable)
    b.open(’http://localhost’)
    b.getLink(’Advanced Search’).click()
    b.getControl(name=’q’).value = ’zope’
    b.getControl(’Content type’).displayValue = [’HTML’]
    b.getControl(’Search’).click()
    self.assertEqual(’10’, b.getControl(’Results per page’))
    self.assertIn(’fisch’, b.contents)
    # not released yet, unfortunately
    self.assertEllipsis(’...fisch...framework...’)
    Wolfgang Schnerring Zope-Ideen 06.10.2011 37 / 39

    View Slide

  47. Ressourcen
    http://pypi.python.org/pypi/
    http://www.sxc.hu/photo/1087620 by nkzs
    1 zope.traversing
    2 zope.configuration
    grokcore.component
    zope.annotation
    3 zope.component,
    zope.interface, zope.event
    4 zope.security
    5 zope.testrunner, plone.testing
    6 transaction, repoze.tm2
    zope.sqlalchemy,
    zope.sendmail,
    gocept.amqprun
    7 zope.testbrowser
    Wolfgang Schnerring Zope-Ideen 06.10.2011 38 / 39

    View Slide

  48. Wir suchen Mitarbeiter in Halle!
    Softwareentwicklung
    Web
    Python
    TDD
    Systemadministration
    Gentoo/KVM
    Puppet
    Nagios
    Bei Interesse: mich ansprechen oder [email protected]
    Wolfgang Schnerring Zope-Ideen 06.10.2011 39 / 39

    View Slide