Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

""" Collections of extra pieces to help smooth over community divergence. """ 

 

from .widgets import Widget 

 

 

class TGStyleController(Widget): 

    """ A widget mixin that provides more advanced controller routing and 

    dispatching. 

 

    The need for this mainly sprung from a divergence of source trees 

    (unintentionally forking) between the developers of tw2 while it was still 

    alpha/beta.  One team expected users to define controllers as a 'request' 

    classmethod on the widget and another team expected users to define a 

    Controller class as a child of the widget.  Team A's pattern is now the 

    default in the main tree.  This is a shim to support Team B's approach. 

 

    Use it like this: 

 

        >>> import tw2.core 

        >>> class MyWidget(tw2.core.TGStyleController, tw2.core.Widget): 

        ...     class Controller(object): 

        ...         @jsonify 

        ...         def some_method(self, req): 

        ...             return dict(foo="bar") 

 

    """ 

 

    @classmethod 

    def dispatch(cls, req, controller): 

        path = req.path_info.strip('/').split('/')[2:] 

        if len(path) == 0: 

            method_name = 'index' 

        else: 

            method_name = path[0] 

        # later we want to better handle .ext conditions, but hey 

        # this aint TG 

        if method_name.endswith('.json'): 

            method_name = method_name[:-5] 

        method = getattr(controller, method_name, None) 

        if not method: 

            method = getattr(controller, 'default', None) 

        return method 

 

    @classmethod 

    def request(cls, req): 

        """ 

        Override this method to define your own way of handling a widget 

        request. 

 

        The default does TG-style object dispatch. 

        """ 

 

        authn = cls.attrs.get('_check_authn') 

        authz = cls.attrs.get('_check_authz') 

 

        if authn and not authn(req): 

            return util.abort(req, 401) 

 

        controller = cls.attrs.get('controller', cls.Controller) 

        if controller is None: 

            return util.abort(req, 404) 

 

        method = cls.dispatch(req, controller) 

        if method: 

            if authz and not authz(req, method): 

                return util.abort(req, 403) 

 

            controller = cls.Controller() 

            return method(controller, req) 

        return util.abort(req, 404)