)]}'
{"horizon/tabs/base.py":[{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"a53ead5be745e7ba5d86499fa176caa3a85d1c10","unresolved":false,"context_lines":[{"line_number":384,"context_line":"    def post(self, request, *args, **kwargs):"},{"line_number":385,"context_line":"        \"\"\""},{"line_number":386,"context_line":"        Default method to handle POSTs to tabs that don\u0027t define a post method"},{"line_number":387,"context_line":"        \"\"\""},{"line_number":388,"context_line":"        pass"},{"line_number":389,"context_line":""},{"line_number":390,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"AAAAS3%2F%2FJ8Y%3D","line":387,"updated":"2013-10-03 11:46:01.000000000","message":"This class is a base class. The docstring should describe the role of the method first, and then describe the default behavior (above).","commit_id":"2ba68987a66a3152f2f70f90e0f00b1a3aed57f8"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"096181ce2e86214f527a6ef407f479066860f989","unresolved":false,"context_lines":[{"line_number":384,"context_line":"    def post(self, request, *args, **kwargs):"},{"line_number":385,"context_line":"        \"\"\""},{"line_number":386,"context_line":"        Default method to handle POSTs to tabs that don\u0027t define a post method"},{"line_number":387,"context_line":"        \"\"\""},{"line_number":388,"context_line":"        pass"},{"line_number":389,"context_line":""},{"line_number":390,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"AAAAS3%2F%2FHEo%3D","line":387,"in_reply_to":"AAAAS3%2F%2FJ8Y%3D","updated":"2013-10-04 09:45:35.000000000","message":"Done","commit_id":"2ba68987a66a3152f2f70f90e0f00b1a3aed57f8"}],"horizon/tabs/views.py":[{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"925cba22a3b30fd4f85a7642e2dfcca601093fc3","unresolved":false,"context_lines":[{"line_number":142,"context_line":"        tabs \u003d self.get_tabs(self.request, **self.kwargs).get_tabs()"},{"line_number":143,"context_line":"        matches \u003d [tab for tab in tabs if tab.slug \u003d\u003d targetslug]"},{"line_number":144,"context_line":"        if matches:"},{"line_number":145,"context_line":"            matches[0].post(request, *args, **kwargs)"},{"line_number":146,"context_line":""},{"line_number":147,"context_line":"        # GET and POST handling are the same"},{"line_number":148,"context_line":"        return self.get(request, *args, **kwargs)"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAQn%2F%2FI1c%3D","line":145,"updated":"2013-08-06 16:39:56.000000000","message":"it would be better to add a comment why it is enough that we call \"post\" for the first element of matches. Though I don\u0027t think there is a case where len(matches) \u003e 1,  a comment would be helpful.","commit_id":"0290ee0b52151ea8d730f7bcc427b1bccb3016ef"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"f4bdd07070cfe1f604c70fd5e79cb1a0b565028e","unresolved":false,"context_lines":[{"line_number":142,"context_line":"        tabs \u003d self.get_tabs(self.request, **self.kwargs).get_tabs()"},{"line_number":143,"context_line":"        matches \u003d [tab for tab in tabs if tab.slug \u003d\u003d targetslug]"},{"line_number":144,"context_line":"        if matches:"},{"line_number":145,"context_line":"            matches[0].post(request, *args, **kwargs)"},{"line_number":146,"context_line":""},{"line_number":147,"context_line":"        # GET and POST handling are the same"},{"line_number":148,"context_line":"        return self.get(request, *args, **kwargs)"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAQn%2F%2FIlg%3D","line":145,"in_reply_to":"AAAAQn%2F%2FI1c%3D","updated":"2013-08-06 21:01:08.000000000","message":"Done","commit_id":"0290ee0b52151ea8d730f7bcc427b1bccb3016ef"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"52bd747658ec549f394dc675e1a862322c677396","unresolved":false,"context_lines":[{"line_number":147,"context_line":"            # could lead to unpredictable behavior."},{"line_number":148,"context_line":"            matches[0].post(request, *args, **kwargs)"},{"line_number":149,"context_line":""},{"line_number":150,"context_line":"        # GET and POST handling are the same"},{"line_number":151,"context_line":"        return self.get(request, *args, **kwargs)"}],"source_content_type":"text/x-python","patch_set":23,"id":"AAAATH%2F%2Fk3k%3D","line":150,"updated":"2013-10-14 10:52:09.000000000","message":"nit: I think this comment is no longer correct.","commit_id":"c895c513f7c454da2bef2e88c0a96216b6ecbb0c"}],"openstack_dashboard/dashboards/admin/routers/extensions/__init__.py":[{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"0bed8660fd259c101e0f2b48323ac3388c24da30","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# vim: tabstop\u003d4 shiftwidth\u003d4 softtabstop\u003d4"},{"line_number":2,"context_line":""},{"line_number":3,"context_line":"# Copyright 2013,  Big Switch Networks,  Inc."},{"line_number":4,"context_line":"#"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAQn%2F%2FbK8%3D","line":1,"updated":"2013-07-31 12:38:32.000000000","message":"In Horizon convention, __init__.py contains no comments.\nIt applies to all __init__","commit_id":"a672d052332a9d4b9914a815228c9a1677df93aa"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"ce3bfb815309711f3888b6d8210a27a4f8c9f2a7","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# vim: tabstop\u003d4 shiftwidth\u003d4 softtabstop\u003d4"},{"line_number":2,"context_line":""},{"line_number":3,"context_line":"# Copyright 2013,  Big Switch Networks,  Inc."},{"line_number":4,"context_line":"#"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAQn%2F%2FZ2E%3D","line":1,"in_reply_to":"AAAAQn%2F%2FbK8%3D","updated":"2013-07-31 22:11:01.000000000","message":"Done","commit_id":"a672d052332a9d4b9914a815228c9a1677df93aa"}],"openstack_dashboard/dashboards/admin/routers/extensions/routerrules/tables.py":[{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"0bed8660fd259c101e0f2b48323ac3388c24da30","unresolved":false,"context_lines":[{"line_number":20,"context_line":""},{"line_number":21,"context_line":"from horizon import tables"},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"class RouterRulesTable(tables.DataTable):"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAQn%2F%2FbKs%3D","line":23,"updated":"2013-07-31 12:38:32.000000000","message":"Not used.","commit_id":"a672d052332a9d4b9914a815228c9a1677df93aa"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"ce3bfb815309711f3888b6d8210a27a4f8c9f2a7","unresolved":false,"context_lines":[{"line_number":20,"context_line":""},{"line_number":21,"context_line":"from horizon import tables"},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"class RouterRulesTable(tables.DataTable):"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAQn%2F%2FZ18%3D","line":23,"in_reply_to":"AAAAQn%2F%2FbKs%3D","updated":"2013-07-31 22:11:01.000000000","message":"Done","commit_id":"a672d052332a9d4b9914a815228c9a1677df93aa"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"925cba22a3b30fd4f85a7642e2dfcca601093fc3","unresolved":false,"context_lines":[{"line_number":20,"context_line":""},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"class RouterRulesTable(tables.DataTable):"},{"line_number":23,"context_line":"    source \u003d tables.Column(\"source\", verbose_name\u003d_(\"Source\"))"},{"line_number":24,"context_line":"    destination \u003d tables.Column(\"destination\", verbose_name\u003d_(\"Destination\"))"},{"line_number":25,"context_line":"    action \u003d tables.Column(\"action\", verbose_name\u003d_(\"Action\"))"},{"line_number":26,"context_line":"    nexthops \u003d tables.Column(\"nexthops\", verbose_name\u003d_(\"Next Hops\"))"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAQn%2F%2FI1A%3D","line":23,"updated":"2013-08-06 16:39:56.000000000","message":"\"Source CIDR\" is better if the length of the field name does not matter since the field name is the form is \"Source CIDR\" and it is better to keep consitency for field names.\n\nAnother reason is that \"Source\" is a generic word and it has several meaning depending on its context. This makes difficult to translate.","commit_id":"0290ee0b52151ea8d730f7bcc427b1bccb3016ef"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"f4bdd07070cfe1f604c70fd5e79cb1a0b565028e","unresolved":false,"context_lines":[{"line_number":20,"context_line":""},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"class RouterRulesTable(tables.DataTable):"},{"line_number":23,"context_line":"    source \u003d tables.Column(\"source\", verbose_name\u003d_(\"Source\"))"},{"line_number":24,"context_line":"    destination \u003d tables.Column(\"destination\", verbose_name\u003d_(\"Destination\"))"},{"line_number":25,"context_line":"    action \u003d tables.Column(\"action\", verbose_name\u003d_(\"Action\"))"},{"line_number":26,"context_line":"    nexthops \u003d tables.Column(\"nexthops\", verbose_name\u003d_(\"Next Hops\"))"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAQn%2F%2FIlE%3D","line":23,"in_reply_to":"AAAAQn%2F%2FI1A%3D","updated":"2013-08-06 21:01:08.000000000","message":"Done","commit_id":"0290ee0b52151ea8d730f7bcc427b1bccb3016ef"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"925cba22a3b30fd4f85a7642e2dfcca601093fc3","unresolved":false,"context_lines":[{"line_number":21,"context_line":""},{"line_number":22,"context_line":"class RouterRulesTable(tables.DataTable):"},{"line_number":23,"context_line":"    source \u003d tables.Column(\"source\", verbose_name\u003d_(\"Source\"))"},{"line_number":24,"context_line":"    destination \u003d tables.Column(\"destination\", verbose_name\u003d_(\"Destination\"))"},{"line_number":25,"context_line":"    action \u003d tables.Column(\"action\", verbose_name\u003d_(\"Action\"))"},{"line_number":26,"context_line":"    nexthops \u003d tables.Column(\"nexthops\", verbose_name\u003d_(\"Next Hops\"))"},{"line_number":27,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAQn%2F%2FI08%3D","line":24,"updated":"2013-08-06 16:39:56.000000000","message":"Destination CIDR.","commit_id":"0290ee0b52151ea8d730f7bcc427b1bccb3016ef"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"f4bdd07070cfe1f604c70fd5e79cb1a0b565028e","unresolved":false,"context_lines":[{"line_number":21,"context_line":""},{"line_number":22,"context_line":"class RouterRulesTable(tables.DataTable):"},{"line_number":23,"context_line":"    source \u003d tables.Column(\"source\", verbose_name\u003d_(\"Source\"))"},{"line_number":24,"context_line":"    destination \u003d tables.Column(\"destination\", verbose_name\u003d_(\"Destination\"))"},{"line_number":25,"context_line":"    action \u003d tables.Column(\"action\", verbose_name\u003d_(\"Action\"))"},{"line_number":26,"context_line":"    nexthops \u003d tables.Column(\"nexthops\", verbose_name\u003d_(\"Next Hops\"))"},{"line_number":27,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAQn%2F%2FIlA%3D","line":24,"in_reply_to":"AAAAQn%2F%2FI08%3D","updated":"2013-08-06 21:01:08.000000000","message":"Done","commit_id":"0290ee0b52151ea8d730f7bcc427b1bccb3016ef"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"925cba22a3b30fd4f85a7642e2dfcca601093fc3","unresolved":false,"context_lines":[{"line_number":29,"context_line":"        name \u003d \"routerrules\""},{"line_number":30,"context_line":"        verbose_name \u003d _(\"Router Rules\")"},{"line_number":31,"context_line":"        table_actions \u003d ()"},{"line_number":32,"context_line":"        row_actions \u003d ()"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAQn%2F%2FIz0%3D","line":32,"updated":"2013-08-06 16:39:56.000000000","message":"L.31-32 are unnecessary. [] is the default value for these attributes (horizon/tables/base.py)","commit_id":"0290ee0b52151ea8d730f7bcc427b1bccb3016ef"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"f4bdd07070cfe1f604c70fd5e79cb1a0b565028e","unresolved":false,"context_lines":[{"line_number":29,"context_line":"        name \u003d \"routerrules\""},{"line_number":30,"context_line":"        verbose_name \u003d _(\"Router Rules\")"},{"line_number":31,"context_line":"        table_actions \u003d ()"},{"line_number":32,"context_line":"        row_actions \u003d ()"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAQn%2F%2FIk0%3D","line":32,"in_reply_to":"AAAAQn%2F%2FIz0%3D","updated":"2013-08-06 21:01:08.000000000","message":"Done","commit_id":"0290ee0b52151ea8d730f7bcc427b1bccb3016ef"}],"openstack_dashboard/dashboards/project/routers/extensions/routerrules/forms.py":[{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"0bed8660fd259c101e0f2b48323ac3388c24da30","unresolved":false,"context_lines":[{"line_number":29,"context_line":""},{"line_number":30,"context_line":""},{"line_number":31,"context_line":"class AddRouterRule(forms.SelfHandlingForm):"},{"line_number":32,"context_line":"    source \u003d forms.CharField(label\u003d_(\"Source\"),"},{"line_number":33,"context_line":"                                  widget\u003dforms.TextInput(), required\u003dTrue)"},{"line_number":34,"context_line":"    destination \u003d forms.CharField(label\u003d_(\"Destination\"),"},{"line_number":35,"context_line":"                                  widget\u003dforms.TextInput(), required\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAQn%2F%2FbHU%3D","line":32,"updated":"2013-07-31 12:38:32.000000000","message":"Is the expected string CIDR format? If so, use IPField.\n\n\"Source\" is too generic. Can\u0027t you make the label more descriptive? (e.g. \"Source IP Address\" ?)\nToo generic strings should be avoided from the perspective of translations too.","commit_id":"a672d052332a9d4b9914a815228c9a1677df93aa"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"ce3bfb815309711f3888b6d8210a27a4f8c9f2a7","unresolved":false,"context_lines":[{"line_number":29,"context_line":""},{"line_number":30,"context_line":""},{"line_number":31,"context_line":"class AddRouterRule(forms.SelfHandlingForm):"},{"line_number":32,"context_line":"    source \u003d forms.CharField(label\u003d_(\"Source\"),"},{"line_number":33,"context_line":"                                  widget\u003dforms.TextInput(), required\u003dTrue)"},{"line_number":34,"context_line":"    destination \u003d forms.CharField(label\u003d_(\"Destination\"),"},{"line_number":35,"context_line":"                                  widget\u003dforms.TextInput(), required\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAQn%2F%2FZ1Q%3D","line":32,"in_reply_to":"AAAAQn%2F%2FbHU%3D","updated":"2013-07-31 22:11:01.000000000","message":"I\u0027ve updated the label; however, I didn\u0027t change to IPField because the keyword \u0027any\u0027 is allowed.","commit_id":"a672d052332a9d4b9914a815228c9a1677df93aa"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"0bed8660fd259c101e0f2b48323ac3388c24da30","unresolved":false,"context_lines":[{"line_number":31,"context_line":"class AddRouterRule(forms.SelfHandlingForm):"},{"line_number":32,"context_line":"    source \u003d forms.CharField(label\u003d_(\"Source\"),"},{"line_number":33,"context_line":"                                  widget\u003dforms.TextInput(), required\u003dTrue)"},{"line_number":34,"context_line":"    destination \u003d forms.CharField(label\u003d_(\"Destination\"),"},{"line_number":35,"context_line":"                                  widget\u003dforms.TextInput(), required\u003dTrue)"},{"line_number":36,"context_line":"    action \u003d forms.ChoiceField(label\u003d_(\"Action\"), required\u003dTrue)"},{"line_number":37,"context_line":"    nexthops \u003d forms.CharField(label\u003d_(\"Optional: Next Hop \""}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAQn%2F%2FbHI%3D","line":34,"updated":"2013-07-31 12:38:32.000000000","message":"Ditto","commit_id":"a672d052332a9d4b9914a815228c9a1677df93aa"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"ce3bfb815309711f3888b6d8210a27a4f8c9f2a7","unresolved":false,"context_lines":[{"line_number":31,"context_line":"class AddRouterRule(forms.SelfHandlingForm):"},{"line_number":32,"context_line":"    source \u003d forms.CharField(label\u003d_(\"Source\"),"},{"line_number":33,"context_line":"                                  widget\u003dforms.TextInput(), required\u003dTrue)"},{"line_number":34,"context_line":"    destination \u003d forms.CharField(label\u003d_(\"Destination\"),"},{"line_number":35,"context_line":"                                  widget\u003dforms.TextInput(), required\u003dTrue)"},{"line_number":36,"context_line":"    action \u003d forms.ChoiceField(label\u003d_(\"Action\"), required\u003dTrue)"},{"line_number":37,"context_line":"    nexthops \u003d forms.CharField(label\u003d_(\"Optional: Next Hop \""}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAQn%2F%2FZ1I%3D","line":34,"in_reply_to":"AAAAQn%2F%2FbHI%3D","updated":"2013-07-31 22:11:01.000000000","message":"Done","commit_id":"a672d052332a9d4b9914a815228c9a1677df93aa"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"0bed8660fd259c101e0f2b48323ac3388c24da30","unresolved":false,"context_lines":[{"line_number":34,"context_line":"    destination \u003d forms.CharField(label\u003d_(\"Destination\"),"},{"line_number":35,"context_line":"                                  widget\u003dforms.TextInput(), required\u003dTrue)"},{"line_number":36,"context_line":"    action \u003d forms.ChoiceField(label\u003d_(\"Action\"), required\u003dTrue)"},{"line_number":37,"context_line":"    nexthops \u003d forms.CharField(label\u003d_(\"Optional: Next Hop \""},{"line_number":38,"context_line":"                                       \"Addresses (comma delimited)\"),"},{"line_number":39,"context_line":"                               widget\u003dforms.TextInput(), required\u003dFalse)"},{"line_number":40,"context_line":"    router_id \u003d forms.CharField(label\u003d_(\"Router ID\"),"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAQn%2F%2FbHg%3D","line":37,"updated":"2013-07-31 12:38:32.000000000","message":"IPField","commit_id":"a672d052332a9d4b9914a815228c9a1677df93aa"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"ce3bfb815309711f3888b6d8210a27a4f8c9f2a7","unresolved":false,"context_lines":[{"line_number":34,"context_line":"    destination \u003d forms.CharField(label\u003d_(\"Destination\"),"},{"line_number":35,"context_line":"                                  widget\u003dforms.TextInput(), required\u003dTrue)"},{"line_number":36,"context_line":"    action \u003d forms.ChoiceField(label\u003d_(\"Action\"), required\u003dTrue)"},{"line_number":37,"context_line":"    nexthops \u003d forms.CharField(label\u003d_(\"Optional: Next Hop \""},{"line_number":38,"context_line":"                                       \"Addresses (comma delimited)\"),"},{"line_number":39,"context_line":"                               widget\u003dforms.TextInput(), required\u003dFalse)"},{"line_number":40,"context_line":"    router_id \u003d forms.CharField(label\u003d_(\"Router ID\"),"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAQn%2F%2FZpY%3D","line":37,"in_reply_to":"AAAAQn%2F%2FbHg%3D","updated":"2013-07-31 22:11:01.000000000","message":"I had to extend IPField to make a new MultiIPField class that allows comma-separated lists","commit_id":"a672d052332a9d4b9914a815228c9a1677df93aa"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"0bed8660fd259c101e0f2b48323ac3388c24da30","unresolved":false,"context_lines":[{"line_number":44,"context_line":""},{"line_number":45,"context_line":"    def __init__(self, request, *args, **kwargs):"},{"line_number":46,"context_line":"        super(AddRouterRule, self).__init__(request, *args, **kwargs)"},{"line_number":47,"context_line":"        self.fields[\u0027action\u0027].choices \u003d [(\u0027permit\u0027, \u0027Permit\u0027),"},{"line_number":48,"context_line":"                                         (\u0027deny\u0027, \u0027Deny\u0027)]"},{"line_number":49,"context_line":""},{"line_number":50,"context_line":"    def handle(self, request, data):"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAQn%2F%2FbGU%3D","line":47,"updated":"2013-07-31 12:38:32.000000000","message":"_(\"Permit\")","commit_id":"a672d052332a9d4b9914a815228c9a1677df93aa"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"ce3bfb815309711f3888b6d8210a27a4f8c9f2a7","unresolved":false,"context_lines":[{"line_number":44,"context_line":""},{"line_number":45,"context_line":"    def __init__(self, request, *args, **kwargs):"},{"line_number":46,"context_line":"        super(AddRouterRule, self).__init__(request, *args, **kwargs)"},{"line_number":47,"context_line":"        self.fields[\u0027action\u0027].choices \u003d [(\u0027permit\u0027, \u0027Permit\u0027),"},{"line_number":48,"context_line":"                                         (\u0027deny\u0027, \u0027Deny\u0027)]"},{"line_number":49,"context_line":""},{"line_number":50,"context_line":"    def handle(self, request, data):"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAQn%2F%2FZos%3D","line":47,"in_reply_to":"AAAAQn%2F%2FbGU%3D","updated":"2013-07-31 22:11:01.000000000","message":"Done","commit_id":"a672d052332a9d4b9914a815228c9a1677df93aa"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"0bed8660fd259c101e0f2b48323ac3388c24da30","unresolved":false,"context_lines":[{"line_number":45,"context_line":"    def __init__(self, request, *args, **kwargs):"},{"line_number":46,"context_line":"        super(AddRouterRule, self).__init__(request, *args, **kwargs)"},{"line_number":47,"context_line":"        self.fields[\u0027action\u0027].choices \u003d [(\u0027permit\u0027, \u0027Permit\u0027),"},{"line_number":48,"context_line":"                                         (\u0027deny\u0027, \u0027Deny\u0027)]"},{"line_number":49,"context_line":""},{"line_number":50,"context_line":"    def handle(self, request, data):"},{"line_number":51,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAQn%2F%2FbGQ%3D","line":48,"updated":"2013-07-31 12:38:32.000000000","message":"_(\"Deny\")","commit_id":"a672d052332a9d4b9914a815228c9a1677df93aa"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"ce3bfb815309711f3888b6d8210a27a4f8c9f2a7","unresolved":false,"context_lines":[{"line_number":45,"context_line":"    def __init__(self, request, *args, **kwargs):"},{"line_number":46,"context_line":"        super(AddRouterRule, self).__init__(request, *args, **kwargs)"},{"line_number":47,"context_line":"        self.fields[\u0027action\u0027].choices \u003d [(\u0027permit\u0027, \u0027Permit\u0027),"},{"line_number":48,"context_line":"                                         (\u0027deny\u0027, \u0027Deny\u0027)]"},{"line_number":49,"context_line":""},{"line_number":50,"context_line":"    def handle(self, request, data):"},{"line_number":51,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAQn%2F%2FZoo%3D","line":48,"in_reply_to":"AAAAQn%2F%2FbGQ%3D","updated":"2013-07-31 22:11:01.000000000","message":"Done","commit_id":"a672d052332a9d4b9914a815228c9a1677df93aa"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"925cba22a3b30fd4f85a7642e2dfcca601093fc3","unresolved":false,"context_lines":[{"line_number":33,"context_line":"    source \u003d forms.CharField(label\u003d_(\"Source CIDR\"),"},{"line_number":34,"context_line":"                                  widget\u003dforms.TextInput(), required\u003dTrue)"},{"line_number":35,"context_line":"    destination \u003d forms.CharField(label\u003d_(\"Destination CIDR\"),"},{"line_number":36,"context_line":"                                  widget\u003dforms.TextInput(), required\u003dTrue)"},{"line_number":37,"context_line":"    action \u003d forms.ChoiceField(label\u003d_(\"Action\"), required\u003dTrue)"},{"line_number":38,"context_line":"    nexthops \u003d fields.MultiIPField(label\u003d_(\"Optional: Next Hop \""},{"line_number":39,"context_line":"                                       \"Addresses (comma delimited)\"),"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAQn%2F%2FIzA%3D","line":36,"updated":"2013-08-06 16:39:56.000000000","message":"According to your comment in patch set 8, CharField is used as the value of this field can be a string \"any\".\nIf so, we need to implement a validator for this field. In Horizon, other IP address fields are validated when a form is posted.","commit_id":"0290ee0b52151ea8d730f7bcc427b1bccb3016ef"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"f4bdd07070cfe1f604c70fd5e79cb1a0b565028e","unresolved":false,"context_lines":[{"line_number":33,"context_line":"    source \u003d forms.CharField(label\u003d_(\"Source CIDR\"),"},{"line_number":34,"context_line":"                                  widget\u003dforms.TextInput(), required\u003dTrue)"},{"line_number":35,"context_line":"    destination \u003d forms.CharField(label\u003d_(\"Destination CIDR\"),"},{"line_number":36,"context_line":"                                  widget\u003dforms.TextInput(), required\u003dTrue)"},{"line_number":37,"context_line":"    action \u003d forms.ChoiceField(label\u003d_(\"Action\"), required\u003dTrue)"},{"line_number":38,"context_line":"    nexthops \u003d fields.MultiIPField(label\u003d_(\"Optional: Next Hop \""},{"line_number":39,"context_line":"                                       \"Addresses (comma delimited)\"),"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAQn%2F%2FIgY%3D","line":36,"in_reply_to":"AAAAQn%2F%2FIzA%3D","updated":"2013-08-06 21:01:08.000000000","message":"Done","commit_id":"0290ee0b52151ea8d730f7bcc427b1bccb3016ef"}],"openstack_dashboard/dashboards/project/routers/extensions/routerrules/rulemanager.py":[{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"0bed8660fd259c101e0f2b48323ac3388c24da30","unresolved":false,"context_lines":[{"line_number":34,"context_line":""},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"def remove_rules(request, rule_ids, **kwargs):"},{"line_number":37,"context_line":"    LOG.debug(\"router_remove_routerrule(): param\u003d%s\" % (kwargs))"},{"line_number":38,"context_line":"    router_id \u003d kwargs[\u0027router_id\u0027]"},{"line_number":39,"context_line":"    if \u0027reset_rules\u0027 in kwargs:"},{"line_number":40,"context_line":"        newrules \u003d [{\u0027source\u0027: \u0027any\u0027, \u0027destination\u0027: \u0027any\u0027,"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAQn%2F%2FbHw%3D","line":37,"updated":"2013-07-31 12:38:32.000000000","message":"It is better to use a comma rather than %.\n(kwargs) -\u003e kwags","commit_id":"a672d052332a9d4b9914a815228c9a1677df93aa"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"ce3bfb815309711f3888b6d8210a27a4f8c9f2a7","unresolved":false,"context_lines":[{"line_number":34,"context_line":""},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"def remove_rules(request, rule_ids, **kwargs):"},{"line_number":37,"context_line":"    LOG.debug(\"router_remove_routerrule(): param\u003d%s\" % (kwargs))"},{"line_number":38,"context_line":"    router_id \u003d kwargs[\u0027router_id\u0027]"},{"line_number":39,"context_line":"    if \u0027reset_rules\u0027 in kwargs:"},{"line_number":40,"context_line":"        newrules \u003d [{\u0027source\u0027: \u0027any\u0027, \u0027destination\u0027: \u0027any\u0027,"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAQn%2F%2FZm0%3D","line":37,"in_reply_to":"AAAAQn%2F%2FbHw%3D","updated":"2013-07-31 22:11:01.000000000","message":"Done","commit_id":"a672d052332a9d4b9914a815228c9a1677df93aa"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"c0302124f8c2fe2f26472ede41d69ee434c7ad39","unresolved":false,"context_lines":[{"line_number":29,"context_line":"    else:"},{"line_number":30,"context_line":"        router \u003d api.router_get(request, params[\u0027device_id\u0027])"},{"line_number":31,"context_line":"    try:"},{"line_number":32,"context_line":"        rules \u003d getattr(router, \u0027router_rules\u0027)"},{"line_number":33,"context_line":"    except AttributeError:"},{"line_number":34,"context_line":"        return (False, [])"},{"line_number":35,"context_line":"    return (True, rules)"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAASn%2F%2FZbo%3D","line":32,"updated":"2013-09-05 08:20:34.000000000","message":"router.router_rules or router[\u0027router_rules\u0027] must work.","commit_id":"2f8636e98417b662152189520296dd7a304dbaf2"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"e55328ed66c1cf05edfa6bb81d31e8e248d0023d","unresolved":false,"context_lines":[{"line_number":29,"context_line":"    else:"},{"line_number":30,"context_line":"        router \u003d api.router_get(request, params[\u0027device_id\u0027])"},{"line_number":31,"context_line":"    try:"},{"line_number":32,"context_line":"        rules \u003d getattr(router, \u0027router_rules\u0027)"},{"line_number":33,"context_line":"    except AttributeError:"},{"line_number":34,"context_line":"        return (False, [])"},{"line_number":35,"context_line":"    return (True, rules)"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAASn%2F%2FZMg%3D","line":32,"in_reply_to":"AAAASn%2F%2FZbo%3D","updated":"2013-09-05 09:40:21.000000000","message":"Done","commit_id":"2f8636e98417b662152189520296dd7a304dbaf2"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"c0302124f8c2fe2f26472ede41d69ee434c7ad39","unresolved":false,"context_lines":[{"line_number":38,"context_line":"def remove_rules(request, rule_ids, **kwargs):"},{"line_number":39,"context_line":"    LOG.debug(\"remove_rules(): param\u003d%s\", kwargs)"},{"line_number":40,"context_line":"    router_id \u003d kwargs[\u0027router_id\u0027]"},{"line_number":41,"context_line":"    if \u0027reset_rules\u0027 in kwargs:"},{"line_number":42,"context_line":"        newrules \u003d [{\u0027source\u0027: \u0027any\u0027, \u0027destination\u0027: \u0027any\u0027,"},{"line_number":43,"context_line":"                     \u0027action\u0027: \u0027permit\u0027}]"},{"line_number":44,"context_line":"        currentrules \u003d []"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAASn%2F%2FZXQ%3D","line":41,"updated":"2013-09-05 08:20:34.000000000","message":"question about a spec.\n\nWhen reset_rules is specified and there is some rules, newrules is as follows at L.54. Is it correct?\n\n   [{\u0027source\u0027: \u0027any\u0027, \u0027destination\u0027: \u0027any\u0027, \u0027action\u0027: \u0027permit\u0027},\n    \u003ccurrent rule1 not included in rule_ids\u003e,\n    \u003ccurrent_rule2 not included in rule_ids\u003e,\n    ....]","commit_id":"2f8636e98417b662152189520296dd7a304dbaf2"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"2566b7ed3074b72b021ff15854657e62c0ba20be","unresolved":false,"context_lines":[{"line_number":38,"context_line":"def remove_rules(request, rule_ids, **kwargs):"},{"line_number":39,"context_line":"    LOG.debug(\"remove_rules(): param\u003d%s\", kwargs)"},{"line_number":40,"context_line":"    router_id \u003d kwargs[\u0027router_id\u0027]"},{"line_number":41,"context_line":"    if \u0027reset_rules\u0027 in kwargs:"},{"line_number":42,"context_line":"        newrules \u003d [{\u0027source\u0027: \u0027any\u0027, \u0027destination\u0027: \u0027any\u0027,"},{"line_number":43,"context_line":"                     \u0027action\u0027: \u0027permit\u0027}]"},{"line_number":44,"context_line":"        currentrules \u003d []"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAASn%2F%2FXro%3D","line":41,"in_reply_to":"AAAASn%2F%2FYrc%3D","updated":"2013-09-05 15:37:20.000000000","message":"Done","commit_id":"2f8636e98417b662152189520296dd7a304dbaf2"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"33182c8d34304a58dd08e6f307feaf16db810528","unresolved":false,"context_lines":[{"line_number":38,"context_line":"def remove_rules(request, rule_ids, **kwargs):"},{"line_number":39,"context_line":"    LOG.debug(\"remove_rules(): param\u003d%s\", kwargs)"},{"line_number":40,"context_line":"    router_id \u003d kwargs[\u0027router_id\u0027]"},{"line_number":41,"context_line":"    if \u0027reset_rules\u0027 in kwargs:"},{"line_number":42,"context_line":"        newrules \u003d [{\u0027source\u0027: \u0027any\u0027, \u0027destination\u0027: \u0027any\u0027,"},{"line_number":43,"context_line":"                     \u0027action\u0027: \u0027permit\u0027}]"},{"line_number":44,"context_line":"        currentrules \u003d []"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAASn%2F%2FYrc%3D","line":41,"in_reply_to":"AAAASn%2F%2FZMQ%3D","updated":"2013-09-05 11:45:23.000000000","message":"I see. That is exactly same as what i expected as a spec.\nYou set currentrules to an empty list below.\n\nThis raises another suggestion. it is better to move L.51-52  into else-clause and remove L.44 from if-clause.","commit_id":"2f8636e98417b662152189520296dd7a304dbaf2"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"e55328ed66c1cf05edfa6bb81d31e8e248d0023d","unresolved":false,"context_lines":[{"line_number":38,"context_line":"def remove_rules(request, rule_ids, **kwargs):"},{"line_number":39,"context_line":"    LOG.debug(\"remove_rules(): param\u003d%s\", kwargs)"},{"line_number":40,"context_line":"    router_id \u003d kwargs[\u0027router_id\u0027]"},{"line_number":41,"context_line":"    if \u0027reset_rules\u0027 in kwargs:"},{"line_number":42,"context_line":"        newrules \u003d [{\u0027source\u0027: \u0027any\u0027, \u0027destination\u0027: \u0027any\u0027,"},{"line_number":43,"context_line":"                     \u0027action\u0027: \u0027permit\u0027}]"},{"line_number":44,"context_line":"        currentrules \u003d []"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAASn%2F%2FZMQ%3D","line":41,"in_reply_to":"AAAASn%2F%2FZXQ%3D","updated":"2013-09-05 09:40:21.000000000","message":"Yes, when reset_rules is present, currentrules is set to an empty list so all of the existing rules are discarded.","commit_id":"2f8636e98417b662152189520296dd7a304dbaf2"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"c0302124f8c2fe2f26472ede41d69ee434c7ad39","unresolved":false,"context_lines":[{"line_number":49,"context_line":"            return"},{"line_number":50,"context_line":"        newrules \u003d []"},{"line_number":51,"context_line":"    for oldrule in currentrules:"},{"line_number":52,"context_line":"        if oldrule[\u0027source\u0027] + oldrule[\u0027destination\u0027] not in rule_ids:"},{"line_number":53,"context_line":"            newrules.append(oldrule)"},{"line_number":54,"context_line":"    body \u003d {\u0027router_rules\u0027: format_for_api(newrules)}"},{"line_number":55,"context_line":"    new \u003d api.router_update(request, router_id, **body)"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAASn%2F%2FZoQ%3D","line":52,"updated":"2013-09-05 08:20:34.000000000","message":"rule id is defined in RuleObject in tabs.py. This means this module is not aware of how rule_id is constructed. At least rule_id construction should be in the same module.\n\nThis module provides API layer for managing rules. It is better to define RuleObject here.","commit_id":"2f8636e98417b662152189520296dd7a304dbaf2"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"e55328ed66c1cf05edfa6bb81d31e8e248d0023d","unresolved":false,"context_lines":[{"line_number":49,"context_line":"            return"},{"line_number":50,"context_line":"        newrules \u003d []"},{"line_number":51,"context_line":"    for oldrule in currentrules:"},{"line_number":52,"context_line":"        if oldrule[\u0027source\u0027] + oldrule[\u0027destination\u0027] not in rule_ids:"},{"line_number":53,"context_line":"            newrules.append(oldrule)"},{"line_number":54,"context_line":"    body \u003d {\u0027router_rules\u0027: format_for_api(newrules)}"},{"line_number":55,"context_line":"    new \u003d api.router_update(request, router_id, **body)"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAASn%2F%2FZKI%3D","line":52,"in_reply_to":"AAAASn%2F%2FZoQ%3D","updated":"2013-09-05 09:40:21.000000000","message":"Done","commit_id":"2f8636e98417b662152189520296dd7a304dbaf2"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"c0302124f8c2fe2f26472ede41d69ee434c7ad39","unresolved":false,"context_lines":[{"line_number":62,"context_line":"    body \u003d {\u0027router_rules\u0027: []}"},{"line_number":63,"context_line":"    kwargs[\u0027router_id\u0027] \u003d router_id"},{"line_number":64,"context_line":"    body[\u0027router_rules\u0027].append(newrule)"},{"line_number":65,"context_line":"    supported, currentrules \u003d routerrule_list(request, **kwargs)"},{"line_number":66,"context_line":"    body[\u0027router_rules\u0027].extend(currentrules)"},{"line_number":67,"context_line":"    body[\u0027router_rules\u0027] \u003d format_for_api(body[\u0027router_rules\u0027])"},{"line_number":68,"context_line":"    new \u003d api.router_update(request, router_id, **body)"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAASn%2F%2FZas%3D","line":65,"updated":"2013-09-05 08:20:34.000000000","message":"It is better to have a check for supported as remove_rules does.","commit_id":"2f8636e98417b662152189520296dd7a304dbaf2"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"e55328ed66c1cf05edfa6bb81d31e8e248d0023d","unresolved":false,"context_lines":[{"line_number":62,"context_line":"    body \u003d {\u0027router_rules\u0027: []}"},{"line_number":63,"context_line":"    kwargs[\u0027router_id\u0027] \u003d router_id"},{"line_number":64,"context_line":"    body[\u0027router_rules\u0027].append(newrule)"},{"line_number":65,"context_line":"    supported, currentrules \u003d routerrule_list(request, **kwargs)"},{"line_number":66,"context_line":"    body[\u0027router_rules\u0027].extend(currentrules)"},{"line_number":67,"context_line":"    body[\u0027router_rules\u0027] \u003d format_for_api(body[\u0027router_rules\u0027])"},{"line_number":68,"context_line":"    new \u003d api.router_update(request, router_id, **body)"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAASn%2F%2FZKE%3D","line":65,"in_reply_to":"AAAASn%2F%2FZas%3D","updated":"2013-09-05 09:40:21.000000000","message":"Done","commit_id":"2f8636e98417b662152189520296dd7a304dbaf2"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"c0302124f8c2fe2f26472ede41d69ee434c7ad39","unresolved":false,"context_lines":[{"line_number":64,"context_line":"    body[\u0027router_rules\u0027].append(newrule)"},{"line_number":65,"context_line":"    supported, currentrules \u003d routerrule_list(request, **kwargs)"},{"line_number":66,"context_line":"    body[\u0027router_rules\u0027].extend(currentrules)"},{"line_number":67,"context_line":"    body[\u0027router_rules\u0027] \u003d format_for_api(body[\u0027router_rules\u0027])"},{"line_number":68,"context_line":"    new \u003d api.router_update(request, router_id, **body)"},{"line_number":69,"context_line":"    if \u0027router\u0027 in request.META:"},{"line_number":70,"context_line":"        request.META[\u0027router\u0027] \u003d new"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAASn%2F%2FZXw%3D","line":67,"updated":"2013-09-05 08:20:34.000000000","message":"Please consider changing L.64-67 to the following:\n\n   supported, currentrules \u003d routerrule_list(...)\n   body[\u0027router_rules\u0027] \u003d format_for_api(currentrules + newrule)\n \nextend() is a cost operation.","commit_id":"2f8636e98417b662152189520296dd7a304dbaf2"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"e55328ed66c1cf05edfa6bb81d31e8e248d0023d","unresolved":false,"context_lines":[{"line_number":64,"context_line":"    body[\u0027router_rules\u0027].append(newrule)"},{"line_number":65,"context_line":"    supported, currentrules \u003d routerrule_list(request, **kwargs)"},{"line_number":66,"context_line":"    body[\u0027router_rules\u0027].extend(currentrules)"},{"line_number":67,"context_line":"    body[\u0027router_rules\u0027] \u003d format_for_api(body[\u0027router_rules\u0027])"},{"line_number":68,"context_line":"    new \u003d api.router_update(request, router_id, **body)"},{"line_number":69,"context_line":"    if \u0027router\u0027 in request.META:"},{"line_number":70,"context_line":"        request.META[\u0027router\u0027] \u003d new"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAASn%2F%2FZJ0%3D","line":67,"in_reply_to":"AAAASn%2F%2FZXw%3D","updated":"2013-09-05 09:40:21.000000000","message":"Done","commit_id":"2f8636e98417b662152189520296dd7a304dbaf2"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"c0302124f8c2fe2f26472ede41d69ee434c7ad39","unresolved":false,"context_lines":[{"line_number":76,"context_line":"    for r in rules:"},{"line_number":77,"context_line":"        flattened \u003d r.copy()"},{"line_number":78,"context_line":"        # nexthops should only be present if there are nexthop addresses"},{"line_number":79,"context_line":"        try:"},{"line_number":80,"context_line":"            cleanednh \u003d [nh.strip()"},{"line_number":81,"context_line":"                         for nh in flattened[\u0027nexthops\u0027]"},{"line_number":82,"context_line":"                         if nh.strip()]"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAASn%2F%2FZU0%3D","line":79,"updated":"2013-09-05 08:20:34.000000000","message":"try/except can be :\n\n  if \u0027nexthops\u0027 in flattened:","commit_id":"2f8636e98417b662152189520296dd7a304dbaf2"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"e55328ed66c1cf05edfa6bb81d31e8e248d0023d","unresolved":false,"context_lines":[{"line_number":76,"context_line":"    for r in rules:"},{"line_number":77,"context_line":"        flattened \u003d r.copy()"},{"line_number":78,"context_line":"        # nexthops should only be present if there are nexthop addresses"},{"line_number":79,"context_line":"        try:"},{"line_number":80,"context_line":"            cleanednh \u003d [nh.strip()"},{"line_number":81,"context_line":"                         for nh in flattened[\u0027nexthops\u0027]"},{"line_number":82,"context_line":"                         if nh.strip()]"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAASn%2F%2FZJs%3D","line":79,"in_reply_to":"AAAASn%2F%2FZU0%3D","updated":"2013-09-05 09:40:21.000000000","message":"Done","commit_id":"2f8636e98417b662152189520296dd7a304dbaf2"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"c0302124f8c2fe2f26472ede41d69ee434c7ad39","unresolved":false,"context_lines":[{"line_number":79,"context_line":"        try:"},{"line_number":80,"context_line":"            cleanednh \u003d [nh.strip()"},{"line_number":81,"context_line":"                         for nh in flattened[\u0027nexthops\u0027]"},{"line_number":82,"context_line":"                         if nh.strip()]"},{"line_number":83,"context_line":"            if cleanednh:"},{"line_number":84,"context_line":"                flattened[\u0027nexthops\u0027] \u003d \u0027+\u0027.join(cleanednh)"},{"line_number":85,"context_line":"            else:"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAASn%2F%2FZfk%3D","line":82,"updated":"2013-09-05 08:20:34.000000000","message":"why is \u0027if nh.strip()\u0027 needed? nh.strip() returns a string even when it returns the same string.\n\n   cleanednh \u003d [nh.strip() for nh in flattened[\u0027nexthops\u0027]]","commit_id":"2f8636e98417b662152189520296dd7a304dbaf2"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"7e274453a17604c3b903ae74ceb13a547ef6e56d","unresolved":false,"context_lines":[{"line_number":79,"context_line":"        try:"},{"line_number":80,"context_line":"            cleanednh \u003d [nh.strip()"},{"line_number":81,"context_line":"                         for nh in flattened[\u0027nexthops\u0027]"},{"line_number":82,"context_line":"                         if nh.strip()]"},{"line_number":83,"context_line":"            if cleanednh:"},{"line_number":84,"context_line":"                flattened[\u0027nexthops\u0027] \u003d \u0027+\u0027.join(cleanednh)"},{"line_number":85,"context_line":"            else:"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAASn%2F%2FXlI%3D","line":82,"in_reply_to":"AAAASn%2F%2FXqg%3D","updated":"2013-09-05 15:55:46.000000000","message":"I got it. We need to filter out a string which consists of only whitespace(s).","commit_id":"2f8636e98417b662152189520296dd7a304dbaf2"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"2566b7ed3074b72b021ff15854657e62c0ba20be","unresolved":false,"context_lines":[{"line_number":79,"context_line":"        try:"},{"line_number":80,"context_line":"            cleanednh \u003d [nh.strip()"},{"line_number":81,"context_line":"                         for nh in flattened[\u0027nexthops\u0027]"},{"line_number":82,"context_line":"                         if nh.strip()]"},{"line_number":83,"context_line":"            if cleanednh:"},{"line_number":84,"context_line":"                flattened[\u0027nexthops\u0027] \u003d \u0027+\u0027.join(cleanednh)"},{"line_number":85,"context_line":"            else:"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAASn%2F%2FXqg%3D","line":82,"in_reply_to":"AAAASn%2F%2FYro%3D","updated":"2013-09-05 15:37:20.000000000","message":"Without the strip() it would return true if someone left an extra space in the nexthops field.","commit_id":"2f8636e98417b662152189520296dd7a304dbaf2"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"33182c8d34304a58dd08e6f307feaf16db810528","unresolved":false,"context_lines":[{"line_number":79,"context_line":"        try:"},{"line_number":80,"context_line":"            cleanednh \u003d [nh.strip()"},{"line_number":81,"context_line":"                         for nh in flattened[\u0027nexthops\u0027]"},{"line_number":82,"context_line":"                         if nh.strip()]"},{"line_number":83,"context_line":"            if cleanednh:"},{"line_number":84,"context_line":"                flattened[\u0027nexthops\u0027] \u003d \u0027+\u0027.join(cleanednh)"},{"line_number":85,"context_line":"            else:"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAASn%2F%2FYro%3D","line":82,"in_reply_to":"AAAASn%2F%2FZI4%3D","updated":"2013-09-05 11:45:23.000000000","message":"I think this comes from an empty string is evaluated as False.\n\n\u003e\u003e\u003e True if \u0027AAAAA\u0027 else False\nTrue\n\n strip() returns a stripped string. i.e.  \"if nh.strip()\" is same as \"if nh\".","commit_id":"2f8636e98417b662152189520296dd7a304dbaf2"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"e55328ed66c1cf05edfa6bb81d31e8e248d0023d","unresolved":false,"context_lines":[{"line_number":79,"context_line":"        try:"},{"line_number":80,"context_line":"            cleanednh \u003d [nh.strip()"},{"line_number":81,"context_line":"                         for nh in flattened[\u0027nexthops\u0027]"},{"line_number":82,"context_line":"                         if nh.strip()]"},{"line_number":83,"context_line":"            if cleanednh:"},{"line_number":84,"context_line":"                flattened[\u0027nexthops\u0027] \u003d \u0027+\u0027.join(cleanednh)"},{"line_number":85,"context_line":"            else:"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAASn%2F%2FZI4%3D","line":82,"in_reply_to":"AAAASn%2F%2FZfk%3D","updated":"2013-09-05 09:40:21.000000000","message":"Checking the truthiness of nh.strip() will return False when someone just left an empty space in the nexthops field. This makes sure no blank next hops get added.\n\n~/code/horizon$ python\n\nPython 2.7.3 (default, Apr 10 2013, 06:20:15)\n[GCC 4.6.3] on linux2\nType \"help\", \"copyright\", \"credits\" or \"license\" for more information.\n\n\u003e\u003e\u003e True if \u0027 \u0027.strip() else False\n\nFalse\n\n\u003e\u003e\u003e","commit_id":"2f8636e98417b662152189520296dd7a304dbaf2"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"07f823bcdd2f0c856160016206e9e777cff06858","unresolved":false,"context_lines":[{"line_number":86,"context_line":"def format_for_api(rules):"},{"line_number":87,"context_line":"    apiformrules \u003d []"},{"line_number":88,"context_line":"    for r in rules:"},{"line_number":89,"context_line":"        flattened \u003d r.copy()"},{"line_number":90,"context_line":"        # nexthops should only be present if there are nexthop addresses"},{"line_number":91,"context_line":"        if \u0027nexthops\u0027 in flattened:"},{"line_number":92,"context_line":"            cleanednh \u003d [nh.strip()"}],"source_content_type":"text/x-python","patch_set":16,"id":"AAAASn%2F%2FYrM%3D","line":89,"updated":"2013-09-05 11:44:48.000000000","message":"I understand r.copy is needed since this changes the dict and original \"rules\" is used in the caller.\nIt is better to add a comment to explain this. It helps us when we update the code future.\n\n(Nit question) what does \"flattened\" mean? I don\u0027t see any \"flattened\" value. The code just removes unnecessary fields (nexthops and id).","commit_id":"2a9e0f2c07cb34c2d43d0c04051ff2bce2f6b39d"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"53138b583c29ce515d370a5eb85adfe91e83c923","unresolved":false,"context_lines":[{"line_number":86,"context_line":"def format_for_api(rules):"},{"line_number":87,"context_line":"    apiformrules \u003d []"},{"line_number":88,"context_line":"    for r in rules:"},{"line_number":89,"context_line":"        flattened \u003d r.copy()"},{"line_number":90,"context_line":"        # nexthops should only be present if there are nexthop addresses"},{"line_number":91,"context_line":"        if \u0027nexthops\u0027 in flattened:"},{"line_number":92,"context_line":"            cleanednh \u003d [nh.strip()"}],"source_content_type":"text/x-python","patch_set":16,"id":"AAAASn%2F%2FXmM%3D","line":89,"in_reply_to":"AAAASn%2F%2FXpo%3D","updated":"2013-09-05 15:56:13.000000000","message":"I see. Thanks.","commit_id":"2a9e0f2c07cb34c2d43d0c04051ff2bce2f6b39d"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"70cf0ca330aa5bfd34fe7efbe23fae918cea8680","unresolved":false,"context_lines":[{"line_number":86,"context_line":"def format_for_api(rules):"},{"line_number":87,"context_line":"    apiformrules \u003d []"},{"line_number":88,"context_line":"    for r in rules:"},{"line_number":89,"context_line":"        flattened \u003d r.copy()"},{"line_number":90,"context_line":"        # nexthops should only be present if there are nexthop addresses"},{"line_number":91,"context_line":"        if \u0027nexthops\u0027 in flattened:"},{"line_number":92,"context_line":"            cleanednh \u003d [nh.strip()"}],"source_content_type":"text/x-python","patch_set":16,"id":"AAAASn%2F%2FXpo%3D","line":89,"in_reply_to":"AAAASn%2F%2FYrM%3D","updated":"2013-09-05 15:40:15.000000000","message":"flattened refers to the nexthops field. It\u0027s flattened from a list to a  \u0027+\u0027 separated string.","commit_id":"2a9e0f2c07cb34c2d43d0c04051ff2bce2f6b39d"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"07f823bcdd2f0c856160016206e9e777cff06858","unresolved":false,"context_lines":[{"line_number":91,"context_line":"        if \u0027nexthops\u0027 in flattened:"},{"line_number":92,"context_line":"            cleanednh \u003d [nh.strip()"},{"line_number":93,"context_line":"                         for nh in flattened[\u0027nexthops\u0027]"},{"line_number":94,"context_line":"                         if nh.strip()]"},{"line_number":95,"context_line":"            if cleanednh:"},{"line_number":96,"context_line":"                flattened[\u0027nexthops\u0027] \u003d \u0027+\u0027.join(cleanednh)"},{"line_number":97,"context_line":"            else:"}],"source_content_type":"text/x-python","patch_set":16,"id":"AAAASn%2F%2FYrU%3D","line":94,"updated":"2013-09-05 11:44:48.000000000","message":"I replied in patch set 15.","commit_id":"2a9e0f2c07cb34c2d43d0c04051ff2bce2f6b39d"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"a53ead5be745e7ba5d86499fa176caa3a85d1c10","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# vim: tabstop\u003d4 shiftwidth\u003d4 softtabstop\u003d4"},{"line_number":2,"context_line":""},{"line_number":3,"context_line":"# Copyright 2013,  Big Switch Networks"},{"line_number":4,"context_line":"#"}],"source_content_type":"text/x-python","patch_set":18,"id":"AAAAS3%2F%2FJ5s%3D","line":1,"updated":"2013-10-03 11:46:01.000000000","message":"[Just a question] This module looks a kind of API layer. What do you think?","commit_id":"2ba68987a66a3152f2f70f90e0f00b1a3aed57f8"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"096181ce2e86214f527a6ef407f479066860f989","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# vim: tabstop\u003d4 shiftwidth\u003d4 softtabstop\u003d4"},{"line_number":2,"context_line":""},{"line_number":3,"context_line":"# Copyright 2013,  Big Switch Networks"},{"line_number":4,"context_line":"#"}],"source_content_type":"text/x-python","patch_set":18,"id":"AAAAS3%2F%2FHEk%3D","line":1,"in_reply_to":"AAAAS3%2F%2FJ5s%3D","updated":"2013-10-04 09:45:35.000000000","message":"Yes. Is there a more appropriate location for it? The advantage of being here is that it\u0027s contained in the \u0027extensions\u0027 folder.","commit_id":"2ba68987a66a3152f2f70f90e0f00b1a3aed57f8"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"ecb4febce00cf0bf5158dfda3bad2a2134df9520","unresolved":false,"context_lines":[{"line_number":28,"context_line":"        # database ID from neutron changes on every update, making a list of"},{"line_number":29,"context_line":"        # sequential operations based on the DB ID invalid after the first one"},{"line_number":30,"context_line":"        # occurs (e.g. deleting multiple from the table"},{"line_number":31,"context_line":"        self.id \u003d rule[\u0027source\u0027] + rule[\u0027destination\u0027]"},{"line_number":32,"context_line":"        self.nexthops \u003d \u0027,\u0027.join(rule[\u0027nexthops\u0027])"},{"line_number":33,"context_line":""},{"line_number":34,"context_line":""}],"source_content_type":"text/x-python","patch_set":20,"id":"AAAATH%2F%2Fwlg%3D","line":31,"updated":"2013-10-10 08:29:20.000000000","message":"This still leaves the old ID in the resulting dict, which causes the grid to reference the wrong ID since it references the dict value rather than the object attribute.","commit_id":"92ad861b4e0900719a046b12465b8db1e2262b59"}],"openstack_dashboard/dashboards/project/routers/extensions/routerrules/tables.py":[{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"925cba22a3b30fd4f85a7642e2dfcca601093fc3","unresolved":false,"context_lines":[{"line_number":43,"context_line":""},{"line_number":44,"context_line":"class RouterRulesTable(tables.DataTable):"},{"line_number":45,"context_line":"    source \u003d tables.Column(\"source\", verbose_name\u003d_(\"Source\"))"},{"line_number":46,"context_line":"    destination \u003d tables.Column(\"destination\", verbose_name\u003d_(\"Destination\"))"},{"line_number":47,"context_line":"    action \u003d tables.Column(\"action\", verbose_name\u003d_(\"Action\"))"},{"line_number":48,"context_line":"    nexthops \u003d tables.Column(\"nexthops\", verbose_name\u003d_(\"Next Hops\"))"},{"line_number":49,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAQn%2F%2FIx4%3D","line":46,"updated":"2013-08-06 16:39:56.000000000","message":"Source CIDR and Destination CIDR look better.","commit_id":"0290ee0b52151ea8d730f7bcc427b1bccb3016ef"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"f4bdd07070cfe1f604c70fd5e79cb1a0b565028e","unresolved":false,"context_lines":[{"line_number":43,"context_line":""},{"line_number":44,"context_line":"class RouterRulesTable(tables.DataTable):"},{"line_number":45,"context_line":"    source \u003d tables.Column(\"source\", verbose_name\u003d_(\"Source\"))"},{"line_number":46,"context_line":"    destination \u003d tables.Column(\"destination\", verbose_name\u003d_(\"Destination\"))"},{"line_number":47,"context_line":"    action \u003d tables.Column(\"action\", verbose_name\u003d_(\"Action\"))"},{"line_number":48,"context_line":"    nexthops \u003d tables.Column(\"nexthops\", verbose_name\u003d_(\"Next Hops\"))"},{"line_number":49,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAQn%2F%2FIgI%3D","line":46,"in_reply_to":"AAAAQn%2F%2FIx4%3D","updated":"2013-08-06 21:01:08.000000000","message":"Done","commit_id":"0290ee0b52151ea8d730f7bcc427b1bccb3016ef"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"c0302124f8c2fe2f26472ede41d69ee434c7ad39","unresolved":false,"context_lines":[{"line_number":57,"context_line":"    nexthops \u003d tables.Column(\"nexthops\", verbose_name\u003d_(\"Next Hops\"))"},{"line_number":58,"context_line":""},{"line_number":59,"context_line":"    def get_object_display(self, rule):"},{"line_number":60,"context_line":"        return \"(%s) %s -\u003e %s\" % (rule[\u0027action\u0027], rule[\u0027source\u0027],"},{"line_number":61,"context_line":"                                  rule[\u0027destination\u0027])"},{"line_number":62,"context_line":""},{"line_number":63,"context_line":"    class Meta:"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAASn%2F%2FZuI%3D","line":60,"updated":"2013-09-05 08:20:34.000000000","message":"(nit) Please keyword substitution","commit_id":"2f8636e98417b662152189520296dd7a304dbaf2"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"e55328ed66c1cf05edfa6bb81d31e8e248d0023d","unresolved":false,"context_lines":[{"line_number":57,"context_line":"    nexthops \u003d tables.Column(\"nexthops\", verbose_name\u003d_(\"Next Hops\"))"},{"line_number":58,"context_line":""},{"line_number":59,"context_line":"    def get_object_display(self, rule):"},{"line_number":60,"context_line":"        return \"(%s) %s -\u003e %s\" % (rule[\u0027action\u0027], rule[\u0027source\u0027],"},{"line_number":61,"context_line":"                                  rule[\u0027destination\u0027])"},{"line_number":62,"context_line":""},{"line_number":63,"context_line":"    class Meta:"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAASn%2F%2FZOc%3D","line":60,"in_reply_to":"AAAASn%2F%2FZuI%3D","updated":"2013-09-05 09:40:21.000000000","message":"Done","commit_id":"2f8636e98417b662152189520296dd7a304dbaf2"}],"openstack_dashboard/dashboards/project/routers/extensions/routerrules/tabs.py":[{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"925cba22a3b30fd4f85a7642e2dfcca601093fc3","unresolved":false,"context_lines":[{"line_number":45,"context_line":"    def get_routerrules_data(self):"},{"line_number":46,"context_line":"        try:"},{"line_number":47,"context_line":"            routerrules \u003d getattr(self.tab_group.router, \u0027router_rules\u0027)"},{"line_number":48,"context_line":"            self._allowed \u003d True"},{"line_number":49,"context_line":"        except:"},{"line_number":50,"context_line":"            routerrules \u003d []"},{"line_number":51,"context_line":"            self._allowed \u003d False"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAQn%2F%2FIxw%3D","line":48,"updated":"2013-08-06 16:39:56.000000000","message":"Can\u0027t we use allowed() method? it is the usual way to control whether the object is displayed or not. TableTab supports allowed() method.","commit_id":"0290ee0b52151ea8d730f7bcc427b1bccb3016ef"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"f4bdd07070cfe1f604c70fd5e79cb1a0b565028e","unresolved":false,"context_lines":[{"line_number":45,"context_line":"    def get_routerrules_data(self):"},{"line_number":46,"context_line":"        try:"},{"line_number":47,"context_line":"            routerrules \u003d getattr(self.tab_group.router, \u0027router_rules\u0027)"},{"line_number":48,"context_line":"            self._allowed \u003d True"},{"line_number":49,"context_line":"        except:"},{"line_number":50,"context_line":"            routerrules \u003d []"},{"line_number":51,"context_line":"            self._allowed \u003d False"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAQn%2F%2FIPA%3D","line":48,"in_reply_to":"AAAAQn%2F%2FIxw%3D","updated":"2013-08-06 21:01:08.000000000","message":"Done","commit_id":"0290ee0b52151ea8d730f7bcc427b1bccb3016ef"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"925cba22a3b30fd4f85a7642e2dfcca601093fc3","unresolved":false,"context_lines":[{"line_number":82,"context_line":"                           self.tab_group.kwargs[\u0027router_id\u0027]}}"},{"line_number":83,"context_line":"        self.request \u003d request"},{"line_number":84,"context_line":"        rules, supported \u003d self.get_routerrules_data(checksupport\u003dTrue)"},{"line_number":85,"context_line":"        self._allowed \u003d supported"},{"line_number":86,"context_line":"        data[\u0027rulessupported\u0027] \u003d supported"},{"line_number":87,"context_line":"        if supported:"},{"line_number":88,"context_line":"            data[\"rulesmatrix\"] \u003d self.get_routerrulesgrid_data(rules)"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAQn%2F%2FIxk%3D","line":85,"updated":"2013-08-06 16:39:56.000000000","message":"Same comment as the above.","commit_id":"0290ee0b52151ea8d730f7bcc427b1bccb3016ef"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"f4bdd07070cfe1f604c70fd5e79cb1a0b565028e","unresolved":false,"context_lines":[{"line_number":82,"context_line":"                           self.tab_group.kwargs[\u0027router_id\u0027]}}"},{"line_number":83,"context_line":"        self.request \u003d request"},{"line_number":84,"context_line":"        rules, supported \u003d self.get_routerrules_data(checksupport\u003dTrue)"},{"line_number":85,"context_line":"        self._allowed \u003d supported"},{"line_number":86,"context_line":"        data[\u0027rulessupported\u0027] \u003d supported"},{"line_number":87,"context_line":"        if supported:"},{"line_number":88,"context_line":"            data[\"rulesmatrix\"] \u003d self.get_routerrulesgrid_data(rules)"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAQn%2F%2FIcE%3D","line":85,"in_reply_to":"AAAAQn%2F%2FIxk%3D","updated":"2013-08-06 21:01:08.000000000","message":"Done","commit_id":"0290ee0b52151ea8d730f7bcc427b1bccb3016ef"},{"author":{"_account_id":6914,"name":"Tatiana Ovchinnikova","email":"t.v.ovtchinnikova@gmail.com","username":"tmazur"},"change_message_id":"343206ad277c288e7a9170ccb3af7b1aca5ae94f","unresolved":false,"context_lines":[{"line_number":26,"context_line":"    import rulemanager"},{"line_number":27,"context_line":"from openstack_dashboard.dashboards.project.routers.\\"},{"line_number":28,"context_line":"    extensions.routerrules.tables import RouterRulesTable"},{"line_number":29,"context_line":""},{"line_number":30,"context_line":""},{"line_number":31,"context_line":"class RuleObject(dict):"},{"line_number":32,"context_line":"    def __init__(self, rule):"}],"source_content_type":"text/x-python","patch_set":13,"id":"AAAASn%2F%2FkXs%3D","line":29,"updated":"2013-09-03 12:06:36.000000000","message":"Same here.","commit_id":"73c19032467255c432e67e929447d736d9179dcf"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"5a8fe16a9ed65fc7e2790c7ceb4bf37a742acdc2","unresolved":false,"context_lines":[{"line_number":26,"context_line":"    import rulemanager"},{"line_number":27,"context_line":"from openstack_dashboard.dashboards.project.routers.\\"},{"line_number":28,"context_line":"    extensions.routerrules.tables import RouterRulesTable"},{"line_number":29,"context_line":""},{"line_number":30,"context_line":""},{"line_number":31,"context_line":"class RuleObject(dict):"},{"line_number":32,"context_line":"    def __init__(self, rule):"}],"source_content_type":"text/x-python","patch_set":13,"id":"AAAASn%2F%2FgpE%3D","line":29,"in_reply_to":"AAAASn%2F%2FkXs%3D","updated":"2013-09-04 05:07:08.000000000","message":"Done","commit_id":"73c19032467255c432e67e929447d736d9179dcf"},{"author":{"_account_id":7585,"name":"Ladislav Smola","email":"lsmola@redhat.com","username":"lsmola"},"change_message_id":"98a8465140ea28d7de69044ac2600d5d68d6bf3f","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# vim: tabstop\u003d4 shiftwidth\u003d4 softtabstop\u003d4"},{"line_number":2,"context_line":""},{"line_number":3,"context_line":"# Copyright 2013,  Big Switch Networks, Inc."},{"line_number":4,"context_line":"#"},{"line_number":5,"context_line":"#    Licensed under the Apache License, Version 2.0 (the \"License\"); you may"},{"line_number":6,"context_line":"#    not use this file except in compliance with the License. You may obtain"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAASn%2F%2FZYg%3D","line":3,"updated":"2013-09-05 08:09:25.000000000","message":"just noticed that, copyright shouldn\u0027t be there any more (just copyright line)\n\nhttp://lists.openstack.org/pipermail/openstack-dev/2013-May/009190.html","commit_id":"2f8636e98417b662152189520296dd7a304dbaf2"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"33182c8d34304a58dd08e6f307feaf16db810528","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# vim: tabstop\u003d4 shiftwidth\u003d4 softtabstop\u003d4"},{"line_number":2,"context_line":""},{"line_number":3,"context_line":"# Copyright 2013,  Big Switch Networks, Inc."},{"line_number":4,"context_line":"#"},{"line_number":5,"context_line":"#    Licensed under the Apache License, Version 2.0 (the \"License\"); you may"},{"line_number":6,"context_line":"#    not use this file except in compliance with the License. You may obtain"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAASn%2F%2FYq4%3D","line":3,"in_reply_to":"AAAASn%2F%2FZPM%3D","updated":"2013-09-05 11:45:23.000000000","message":"I see this in all other files you adde in this patch.","commit_id":"2f8636e98417b662152189520296dd7a304dbaf2"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"e55328ed66c1cf05edfa6bb81d31e8e248d0023d","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# vim: tabstop\u003d4 shiftwidth\u003d4 softtabstop\u003d4"},{"line_number":2,"context_line":""},{"line_number":3,"context_line":"# Copyright 2013,  Big Switch Networks, Inc."},{"line_number":4,"context_line":"#"},{"line_number":5,"context_line":"#    Licensed under the Apache License, Version 2.0 (the \"License\"); you may"},{"line_number":6,"context_line":"#    not use this file except in compliance with the License. You may obtain"}],"source_content_type":"text/x-python","patch_set":15,"id":"AAAASn%2F%2FZPM%3D","line":3,"in_reply_to":"AAAASn%2F%2FZYg%3D","updated":"2013-09-05 09:40:21.000000000","message":"Done","commit_id":"2f8636e98417b662152189520296dd7a304dbaf2"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"a53ead5be745e7ba5d86499fa176caa3a85d1c10","unresolved":false,"context_lines":[{"line_number":20,"context_line":"from django.template.loader import render_to_string  # noqa"},{"line_number":21,"context_line":"from django.utils.translation import ugettext_lazy as _  # noqa"},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"from horizon import tabs"},{"line_number":24,"context_line":"from openstack_dashboard import api"},{"line_number":25,"context_line":"from openstack_dashboard.dashboards.project.routers.extensions.routerrules\\"},{"line_number":26,"context_line":"    import rulemanager"}],"source_content_type":"text/x-python","patch_set":18,"id":"AAAAS3%2F%2FJ5g%3D","line":23,"updated":"2013-10-03 11:46:01.000000000","message":"It is better to have a blank line here.","commit_id":"2ba68987a66a3152f2f70f90e0f00b1a3aed57f8"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"096181ce2e86214f527a6ef407f479066860f989","unresolved":false,"context_lines":[{"line_number":20,"context_line":"from django.template.loader import render_to_string  # noqa"},{"line_number":21,"context_line":"from django.utils.translation import ugettext_lazy as _  # noqa"},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"from horizon import tabs"},{"line_number":24,"context_line":"from openstack_dashboard import api"},{"line_number":25,"context_line":"from openstack_dashboard.dashboards.project.routers.extensions.routerrules\\"},{"line_number":26,"context_line":"    import rulemanager"}],"source_content_type":"text/x-python","patch_set":18,"id":"AAAAS3%2F%2FHEg%3D","line":23,"in_reply_to":"AAAAS3%2F%2FJ5g%3D","updated":"2013-10-04 09:45:35.000000000","message":"Done","commit_id":"2ba68987a66a3152f2f70f90e0f00b1a3aed57f8"}],"openstack_dashboard/dashboards/project/routers/extensions/routerrules/views.py":[{"author":{"_account_id":6914,"name":"Tatiana Ovchinnikova","email":"t.v.ovtchinnikova@gmail.com","username":"tmazur"},"change_message_id":"343206ad277c288e7a9170ccb3af7b1aca5ae94f","unresolved":false,"context_lines":[{"line_number":24,"context_line":"from openstack_dashboard import api"},{"line_number":25,"context_line":"from openstack_dashboard.dashboards.project.routers.\\"},{"line_number":26,"context_line":"    extensions.routerrules.forms import AddRouterRule"},{"line_number":27,"context_line":""},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":30,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"AAAASn%2F%2FkXo%3D","line":27,"updated":"2013-09-03 12:06:36.000000000","message":"And here","commit_id":"73c19032467255c432e67e929447d736d9179dcf"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"5a8fe16a9ed65fc7e2790c7ceb4bf37a742acdc2","unresolved":false,"context_lines":[{"line_number":24,"context_line":"from openstack_dashboard import api"},{"line_number":25,"context_line":"from openstack_dashboard.dashboards.project.routers.\\"},{"line_number":26,"context_line":"    extensions.routerrules.forms import AddRouterRule"},{"line_number":27,"context_line":""},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":30,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"AAAASn%2F%2Fgo8%3D","line":27,"in_reply_to":"AAAASn%2F%2FkXo%3D","updated":"2013-09-04 05:07:08.000000000","message":"Done","commit_id":"73c19032467255c432e67e929447d736d9179dcf"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"a53ead5be745e7ba5d86499fa176caa3a85d1c10","unresolved":false,"context_lines":[{"line_number":20,"context_line":"from django.utils.translation import ugettext_lazy as _  # noqa"},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"from horizon import exceptions"},{"line_number":23,"context_line":"from horizon import forms"},{"line_number":24,"context_line":"from openstack_dashboard import api"},{"line_number":25,"context_line":"from openstack_dashboard.dashboards.project.routers.extensions.routerrules\\"},{"line_number":26,"context_line":"    import forms as rrforms"}],"source_content_type":"text/x-python","patch_set":18,"id":"AAAAS3%2F%2FJ5c%3D","line":23,"updated":"2013-10-03 11:46:01.000000000","message":"It is better to have a blank line here. Juts a horizon convention.","commit_id":"2ba68987a66a3152f2f70f90e0f00b1a3aed57f8"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"096181ce2e86214f527a6ef407f479066860f989","unresolved":false,"context_lines":[{"line_number":20,"context_line":"from django.utils.translation import ugettext_lazy as _  # noqa"},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"from horizon import exceptions"},{"line_number":23,"context_line":"from horizon import forms"},{"line_number":24,"context_line":"from openstack_dashboard import api"},{"line_number":25,"context_line":"from openstack_dashboard.dashboards.project.routers.extensions.routerrules\\"},{"line_number":26,"context_line":"    import forms as rrforms"}],"source_content_type":"text/x-python","patch_set":18,"id":"AAAAS3%2F%2FHEY%3D","line":23,"in_reply_to":"AAAAS3%2F%2FJ5c%3D","updated":"2013-10-04 09:45:35.000000000","message":"Done","commit_id":"2ba68987a66a3152f2f70f90e0f00b1a3aed57f8"}],"openstack_dashboard/dashboards/project/routers/tabs.py":[{"author":{"_account_id":8642,"name":"Lukasz Jernas","email":"deejay1@srem.org","username":"deejay1"},"change_message_id":"635b449b92da65bc4a8f26befe13aecb5e8febed","unresolved":false,"context_lines":[{"line_number":54,"context_line":"            self.ports \u003d api.neutron.port_list(request, device_id\u003drid)"},{"line_number":55,"context_line":"        except Exception:"},{"line_number":56,"context_line":"            self.ports \u003d []"},{"line_number":57,"context_line":"            msg \u003d _(\u0027Router information can not be retrieved.\u0027)"},{"line_number":58,"context_line":"            exceptions.handle(request, msg)"},{"line_number":59,"context_line":"        super(RouterDetailTabs, self).__init__(request, **kwargs)"}],"source_content_type":"text/x-python","patch_set":13,"id":"AAAASn%2F%2Fh8c%3D","line":57,"updated":"2013-09-03 19:16:03.000000000","message":"Maybe to keep it in line with other messages, keep the original \"Unable to retrieve router details.\" string.","commit_id":"73c19032467255c432e67e929447d736d9179dcf"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"5a8fe16a9ed65fc7e2790c7ceb4bf37a742acdc2","unresolved":false,"context_lines":[{"line_number":54,"context_line":"            self.ports \u003d api.neutron.port_list(request, device_id\u003drid)"},{"line_number":55,"context_line":"        except Exception:"},{"line_number":56,"context_line":"            self.ports \u003d []"},{"line_number":57,"context_line":"            msg \u003d _(\u0027Router information can not be retrieved.\u0027)"},{"line_number":58,"context_line":"            exceptions.handle(request, msg)"},{"line_number":59,"context_line":"        super(RouterDetailTabs, self).__init__(request, **kwargs)"}],"source_content_type":"text/x-python","patch_set":13,"id":"AAAASn%2F%2Fgos%3D","line":57,"in_reply_to":"AAAASn%2F%2Fh8c%3D","updated":"2013-09-04 05:07:08.000000000","message":"Done","commit_id":"73c19032467255c432e67e929447d736d9179dcf"}],"openstack_dashboard/dashboards/project/routers/templates/routers/extensions/routerrules/_create.html":[{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"0bed8660fd259c101e0f2b48323ac3388c24da30","unresolved":false,"context_lines":[{"line_number":17,"context_line":"    \u003ch3\u003e{% trans \"Description\" %}:\u003c/h3\u003e"},{"line_number":18,"context_line":"    \u003cp\u003e"},{"line_number":19,"context_line":"    {% trans \"Routing rules to apply to router. Rules are matched by most specific source first and then by most specific destination.\" %}\u003cbr/\u003e"},{"line_number":20,"context_line":"    {% trans \"The next hop addresses can be used to override the router used by the client.\" %}   "},{"line_number":21,"context_line":"    \u003c/p\u003e"},{"line_number":22,"context_line":"\u003c/div\u003e"},{"line_number":23,"context_line":"{% endblock %}"}],"source_content_type":"text/html","patch_set":8,"id":"AAAAQn%2F%2FbKo%3D","line":20,"updated":"2013-07-31 12:38:32.000000000","message":"trailing whitespace(s)","commit_id":"a672d052332a9d4b9914a815228c9a1677df93aa"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"ce3bfb815309711f3888b6d8210a27a4f8c9f2a7","unresolved":false,"context_lines":[{"line_number":17,"context_line":"    \u003ch3\u003e{% trans \"Description\" %}:\u003c/h3\u003e"},{"line_number":18,"context_line":"    \u003cp\u003e"},{"line_number":19,"context_line":"    {% trans \"Routing rules to apply to router. Rules are matched by most specific source first and then by most specific destination.\" %}\u003cbr/\u003e"},{"line_number":20,"context_line":"    {% trans \"The next hop addresses can be used to override the router used by the client.\" %}   "},{"line_number":21,"context_line":"    \u003c/p\u003e"},{"line_number":22,"context_line":"\u003c/div\u003e"},{"line_number":23,"context_line":"{% endblock %}"}],"source_content_type":"text/html","patch_set":8,"id":"AAAAQn%2F%2FZmU%3D","line":20,"in_reply_to":"AAAAQn%2F%2FbKo%3D","updated":"2013-07-31 22:11:01.000000000","message":"Done","commit_id":"a672d052332a9d4b9914a815228c9a1677df93aa"}],"openstack_dashboard/dashboards/project/routers/templates/routers/extensions/routerrules/grid.html":[{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"0bed8660fd259c101e0f2b48323ac3388c24da30","unresolved":false,"context_lines":[{"line_number":67,"context_line":"           \u003cinput type\u003d\"hidden\" name\u003d\"source\" value\u003d\"{{ dest.inverse_rule.source }}\"\u003e"},{"line_number":68,"context_line":"           \u003cinput type\u003d\"hidden\" name\u003d\"destination\" value\u003d\"{{ dest.inverse_rule.destination }}\"\u003e"},{"line_number":69,"context_line":"           \u003cinput type\u003d\"hidden\" name\u003d\"action\" value\u003d\"{{ dest.inverse_rule.action }}\"\u003e"},{"line_number":70,"context_line":"           "},{"line_number":71,"context_line":"           {% if dest.rule_to_delete %}"},{"line_number":72,"context_line":"               \u003ccenter\u003e\u003cinput type\u003d\"hidden\" name\u003d\"rule_to_delete\" value\u003d\"{{ dest.rule_to_delete.id }}\"/\u003e\u003c/center\u003e"},{"line_number":73,"context_line":"           {% endif %}"}],"source_content_type":"text/html","patch_set":8,"id":"AAAAQn%2F%2FbKc%3D","line":70,"updated":"2013-07-31 12:38:32.000000000","message":"Whitespace","commit_id":"a672d052332a9d4b9914a815228c9a1677df93aa"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"ce3bfb815309711f3888b6d8210a27a4f8c9f2a7","unresolved":false,"context_lines":[{"line_number":67,"context_line":"           \u003cinput type\u003d\"hidden\" name\u003d\"source\" value\u003d\"{{ dest.inverse_rule.source }}\"\u003e"},{"line_number":68,"context_line":"           \u003cinput type\u003d\"hidden\" name\u003d\"destination\" value\u003d\"{{ dest.inverse_rule.destination }}\"\u003e"},{"line_number":69,"context_line":"           \u003cinput type\u003d\"hidden\" name\u003d\"action\" value\u003d\"{{ dest.inverse_rule.action }}\"\u003e"},{"line_number":70,"context_line":"           "},{"line_number":71,"context_line":"           {% if dest.rule_to_delete %}"},{"line_number":72,"context_line":"               \u003ccenter\u003e\u003cinput type\u003d\"hidden\" name\u003d\"rule_to_delete\" value\u003d\"{{ dest.rule_to_delete.id }}\"/\u003e\u003c/center\u003e"},{"line_number":73,"context_line":"           {% endif %}"}],"source_content_type":"text/html","patch_set":8,"id":"AAAAQn%2F%2FZl8%3D","line":70,"in_reply_to":"AAAAQn%2F%2FbKc%3D","updated":"2013-07-31 22:11:01.000000000","message":"Done","commit_id":"a672d052332a9d4b9914a815228c9a1677df93aa"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"925cba22a3b30fd4f85a7642e2dfcca601093fc3","unresolved":false,"context_lines":[{"line_number":14,"context_line":"          style\u003d\u0027display: inline; background-color: transparent; float: none; margin-left: 0;\u0027\u003e"},{"line_number":15,"context_line":"          {% csrf_token %}"},{"line_number":16,"context_line":"          \u003cinput type\u003d\"hidden\" name\u003d\"router_id\" value\u003d\"{{ router.id }}\"/\u003e"},{"line_number":17,"context_line":"          \u003cbutton class\u003d\"btn btn-small btn-danger btn-delete\" "},{"line_number":18,"context_line":"                  type\u003d\"submit\" href\u003d\"#\" name\u003d\"action\" value\u003d\"routerrules__resetrules\"\u003e{% trans \"Reset to Default\" %}\u003c/button\u003e"},{"line_number":19,"context_line":"          \u003c/form\u003e"},{"line_number":20,"context_line":"       \u003c/div\u003e"}],"source_content_type":"text/html","patch_set":10,"id":"AAAAQn%2F%2FIw8%3D","line":17,"updated":"2013-08-06 16:39:56.000000000","message":"trailing whitespace","commit_id":"0290ee0b52151ea8d730f7bcc427b1bccb3016ef"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"f4bdd07070cfe1f604c70fd5e79cb1a0b565028e","unresolved":false,"context_lines":[{"line_number":14,"context_line":"          style\u003d\u0027display: inline; background-color: transparent; float: none; margin-left: 0;\u0027\u003e"},{"line_number":15,"context_line":"          {% csrf_token %}"},{"line_number":16,"context_line":"          \u003cinput type\u003d\"hidden\" name\u003d\"router_id\" value\u003d\"{{ router.id }}\"/\u003e"},{"line_number":17,"context_line":"          \u003cbutton class\u003d\"btn btn-small btn-danger btn-delete\" "},{"line_number":18,"context_line":"                  type\u003d\"submit\" href\u003d\"#\" name\u003d\"action\" value\u003d\"routerrules__resetrules\"\u003e{% trans \"Reset to Default\" %}\u003c/button\u003e"},{"line_number":19,"context_line":"          \u003c/form\u003e"},{"line_number":20,"context_line":"       \u003c/div\u003e"}],"source_content_type":"text/html","patch_set":10,"id":"AAAAQn%2F%2FIOg%3D","line":17,"in_reply_to":"AAAAQn%2F%2FIw8%3D","updated":"2013-08-06 21:01:08.000000000","message":"Done","commit_id":"0290ee0b52151ea8d730f7bcc427b1bccb3016ef"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"925cba22a3b30fd4f85a7642e2dfcca601093fc3","unresolved":false,"context_lines":[{"line_number":84,"context_line":"                   \u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;"},{"line_number":85,"context_line":"              {% endif %}"},{"line_number":86,"context_line":"           \u003c/center\u003e"},{"line_number":87,"context_line":"           {% else %} "},{"line_number":88,"context_line":"                \u003ccenter\u003e\u003ca type\u003d\"button\" class\u003d\"btn btn-mini\" href\u003d\"#modal_{{ dest.subnetid|add:row.source.subnetid }}\" data-toggle\u003d\"modal\"\u003e\u003ci class\u003d\"icon-exclamation-sign\"\u003e\u003c/i\u003e Conflict\u003c/a\u003e\u003c/center\u003e"},{"line_number":89,"context_line":"               \u003cdiv class\u003d\"modal hide\" id\u003d\"modal_{{ dest.subnetid|add:row.source.subnetid }}\"\u003e"},{"line_number":90,"context_line":"                 \u003cdiv class\u003d\"modal-header\"\u003e"}],"source_content_type":"text/html","patch_set":10,"id":"AAAAQn%2F%2FIw4%3D","line":87,"updated":"2013-08-06 16:39:56.000000000","message":"Ditto","commit_id":"0290ee0b52151ea8d730f7bcc427b1bccb3016ef"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"f4bdd07070cfe1f604c70fd5e79cb1a0b565028e","unresolved":false,"context_lines":[{"line_number":84,"context_line":"                   \u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;"},{"line_number":85,"context_line":"              {% endif %}"},{"line_number":86,"context_line":"           \u003c/center\u003e"},{"line_number":87,"context_line":"           {% else %} "},{"line_number":88,"context_line":"                \u003ccenter\u003e\u003ca type\u003d\"button\" class\u003d\"btn btn-mini\" href\u003d\"#modal_{{ dest.subnetid|add:row.source.subnetid }}\" data-toggle\u003d\"modal\"\u003e\u003ci class\u003d\"icon-exclamation-sign\"\u003e\u003c/i\u003e Conflict\u003c/a\u003e\u003c/center\u003e"},{"line_number":89,"context_line":"               \u003cdiv class\u003d\"modal hide\" id\u003d\"modal_{{ dest.subnetid|add:row.source.subnetid }}\"\u003e"},{"line_number":90,"context_line":"                 \u003cdiv class\u003d\"modal-header\"\u003e"}],"source_content_type":"text/html","patch_set":10,"id":"AAAAQn%2F%2FIOc%3D","line":87,"in_reply_to":"AAAAQn%2F%2FIw4%3D","updated":"2013-08-06 21:01:08.000000000","message":"Done","commit_id":"0290ee0b52151ea8d730f7bcc427b1bccb3016ef"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"925cba22a3b30fd4f85a7642e2dfcca601093fc3","unresolved":false,"context_lines":[{"line_number":94,"context_line":"                 \u003cdiv class\u003d\"modal-body\"\u003e"},{"line_number":95,"context_line":"                   \u003cp\u003eA more specific rule affects a portion of this traffic so a rule cannot be automatically generated to control the behavior of the entire source/destination combination.\u003c/p\u003e"},{"line_number":96,"context_line":"                   \u003chr\u003e"},{"line_number":97,"context_line":"                   \u003ch4\u003eConflicting Rule:\u003c/h4\u003e "},{"line_number":98,"context_line":"                   \u003cb\u003eSource:\u003c/b\u003e {{ dest.conflicting_rule.source }}\u003cbr\u003e"},{"line_number":99,"context_line":"                   \u003cb\u003eDestination:\u003c/b\u003e {{ dest.conflicting_rule.destination }}\u003cbr\u003e"},{"line_number":100,"context_line":"                   \u003cb\u003eAction:\u003c/b\u003e {{ dest.conflicting_rule.action }}\u003cbr\u003e"}],"source_content_type":"text/html","patch_set":10,"id":"AAAAQn%2F%2FIw0%3D","line":97,"updated":"2013-08-06 16:39:56.000000000","message":"Ditto","commit_id":"0290ee0b52151ea8d730f7bcc427b1bccb3016ef"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"f4bdd07070cfe1f604c70fd5e79cb1a0b565028e","unresolved":false,"context_lines":[{"line_number":94,"context_line":"                 \u003cdiv class\u003d\"modal-body\"\u003e"},{"line_number":95,"context_line":"                   \u003cp\u003eA more specific rule affects a portion of this traffic so a rule cannot be automatically generated to control the behavior of the entire source/destination combination.\u003c/p\u003e"},{"line_number":96,"context_line":"                   \u003chr\u003e"},{"line_number":97,"context_line":"                   \u003ch4\u003eConflicting Rule:\u003c/h4\u003e "},{"line_number":98,"context_line":"                   \u003cb\u003eSource:\u003c/b\u003e {{ dest.conflicting_rule.source }}\u003cbr\u003e"},{"line_number":99,"context_line":"                   \u003cb\u003eDestination:\u003c/b\u003e {{ dest.conflicting_rule.destination }}\u003cbr\u003e"},{"line_number":100,"context_line":"                   \u003cb\u003eAction:\u003c/b\u003e {{ dest.conflicting_rule.action }}\u003cbr\u003e"}],"source_content_type":"text/html","patch_set":10,"id":"AAAAQn%2F%2FIOY%3D","line":97,"in_reply_to":"AAAAQn%2F%2FIw0%3D","updated":"2013-08-06 21:01:08.000000000","message":"Done","commit_id":"0290ee0b52151ea8d730f7bcc427b1bccb3016ef"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"925cba22a3b30fd4f85a7642e2dfcca601093fc3","unresolved":false,"context_lines":[{"line_number":111,"context_line":"\u003c/tr\u003e"},{"line_number":112,"context_line":"\u003c/tbody\u003e"},{"line_number":113,"context_line":"  \u003ctfoot\u003e"},{"line_number":114,"context_line":"      "},{"line_number":115,"context_line":"      \u003ctr\u003e"},{"line_number":116,"context_line":"        \u003ctd colspan\u003d\"{{ rulesmatrix|length|add:1}}\"\u003e"},{"line_number":117,"context_line":"          \u003cspan class\u003d\"table_count\"\u003e\u003c/span\u003e"}],"source_content_type":"text/html","patch_set":10,"id":"AAAAQn%2F%2FIww%3D","line":114,"updated":"2013-08-06 16:39:56.000000000","message":"This line is unnecessary.","commit_id":"0290ee0b52151ea8d730f7bcc427b1bccb3016ef"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"f4bdd07070cfe1f604c70fd5e79cb1a0b565028e","unresolved":false,"context_lines":[{"line_number":111,"context_line":"\u003c/tr\u003e"},{"line_number":112,"context_line":"\u003c/tbody\u003e"},{"line_number":113,"context_line":"  \u003ctfoot\u003e"},{"line_number":114,"context_line":"      "},{"line_number":115,"context_line":"      \u003ctr\u003e"},{"line_number":116,"context_line":"        \u003ctd colspan\u003d\"{{ rulesmatrix|length|add:1}}\"\u003e"},{"line_number":117,"context_line":"          \u003cspan class\u003d\"table_count\"\u003e\u003c/span\u003e"}],"source_content_type":"text/html","patch_set":10,"id":"AAAAQn%2F%2FIOU%3D","line":114,"in_reply_to":"AAAAQn%2F%2FIww%3D","updated":"2013-08-06 21:01:08.000000000","message":"Done","commit_id":"0290ee0b52151ea8d730f7bcc427b1bccb3016ef"},{"author":{"_account_id":8642,"name":"Lukasz Jernas","email":"deejay1@srem.org","username":"deejay1"},"change_message_id":"635b449b92da65bc4a8f26befe13aecb5e8febed","unresolved":false,"context_lines":[{"line_number":92,"context_line":"                   \u003ch3\u003eRule Conflict\u003c/h3\u003e"},{"line_number":93,"context_line":"                 \u003c/div\u003e"},{"line_number":94,"context_line":"                 \u003cdiv class\u003d\"modal-body\"\u003e"},{"line_number":95,"context_line":"                   \u003cp\u003eA more specific rule affects a portion of this traffic so a rule cannot be automatically generated to control the behavior of the entire source/destination combination.\u003c/p\u003e"},{"line_number":96,"context_line":"                   \u003chr\u003e"},{"line_number":97,"context_line":"                   \u003ch4\u003eConflicting Rule:\u003c/h4\u003e"},{"line_number":98,"context_line":"                   \u003cb\u003eSource:\u003c/b\u003e {{ dest.conflicting_rule.source }}\u003cbr\u003e"}],"source_content_type":"text/html","patch_set":13,"id":"AAAASn%2F%2Fh70%3D","line":95,"updated":"2013-09-03 19:16:03.000000000","message":"shouldn\u0027t the strings here be marked with trans/blocktrans?","commit_id":"73c19032467255c432e67e929447d736d9179dcf"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"5a8fe16a9ed65fc7e2790c7ceb4bf37a742acdc2","unresolved":false,"context_lines":[{"line_number":92,"context_line":"                   \u003ch3\u003eRule Conflict\u003c/h3\u003e"},{"line_number":93,"context_line":"                 \u003c/div\u003e"},{"line_number":94,"context_line":"                 \u003cdiv class\u003d\"modal-body\"\u003e"},{"line_number":95,"context_line":"                   \u003cp\u003eA more specific rule affects a portion of this traffic so a rule cannot be automatically generated to control the behavior of the entire source/destination combination.\u003c/p\u003e"},{"line_number":96,"context_line":"                   \u003chr\u003e"},{"line_number":97,"context_line":"                   \u003ch4\u003eConflicting Rule:\u003c/h4\u003e"},{"line_number":98,"context_line":"                   \u003cb\u003eSource:\u003c/b\u003e {{ dest.conflicting_rule.source }}\u003cbr\u003e"}],"source_content_type":"text/html","patch_set":13,"id":"AAAASn%2F%2FgnI%3D","line":95,"in_reply_to":"AAAASn%2F%2Fh70%3D","updated":"2013-09-04 05:07:08.000000000","message":"Done","commit_id":"73c19032467255c432e67e929447d736d9179dcf"},{"author":{"_account_id":8642,"name":"Lukasz Jernas","email":"deejay1@srem.org","username":"deejay1"},"change_message_id":"fd8a2aa5b067bad5c072dea45b032201705bed22","unresolved":false,"context_lines":[{"line_number":8,"context_line":""},{"line_number":9,"context_line":"   \u003ctr class\u003d\u0027table_caption\u0027\u003e"},{"line_number":10,"context_line":"     \u003cth class\u003d\u0027table_header\u0027 colspan\u003d\u0027{{ rulesmatrix|length|add:1 }}\u0027\u003e"},{"line_number":11,"context_line":"       \u003ch3 class\u003d\u0027table_title\u0027\u003eRouter Rule Grid \u003c/h3\u003e"},{"line_number":12,"context_line":"       \u003cdiv class\u003d\"table_actions clearfix\"\u003e"},{"line_number":13,"context_line":"         \u003cform action\u003d\"./\" method\u003d\"POST\""},{"line_number":14,"context_line":"          style\u003d\u0027display: inline; background-color: transparent; float: none; margin-left: 0;\u0027\u003e"}],"source_content_type":"text/html","patch_set":14,"id":"AAAASn%2F%2Ffdo%3D","line":11,"updated":"2013-09-04 06:08:37.000000000","message":"{% trans %}, also the space after that isn\u0027t needed","commit_id":"b00753b79f3f74c708a7c0a4d38aadd411a45357"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"fde4549eb1ff7c70d6e85c27aff029670dc6983f","unresolved":false,"context_lines":[{"line_number":8,"context_line":""},{"line_number":9,"context_line":"   \u003ctr class\u003d\u0027table_caption\u0027\u003e"},{"line_number":10,"context_line":"     \u003cth class\u003d\u0027table_header\u0027 colspan\u003d\u0027{{ rulesmatrix|length|add:1 }}\u0027\u003e"},{"line_number":11,"context_line":"       \u003ch3 class\u003d\u0027table_title\u0027\u003eRouter Rule Grid \u003c/h3\u003e"},{"line_number":12,"context_line":"       \u003cdiv class\u003d\"table_actions clearfix\"\u003e"},{"line_number":13,"context_line":"         \u003cform action\u003d\"./\" method\u003d\"POST\""},{"line_number":14,"context_line":"          style\u003d\u0027display: inline; background-color: transparent; float: none; margin-left: 0;\u0027\u003e"}],"source_content_type":"text/html","patch_set":14,"id":"AAAASn%2F%2FfYU%3D","line":11,"in_reply_to":"AAAASn%2F%2Ffdo%3D","updated":"2013-09-04 06:11:57.000000000","message":"Done","commit_id":"b00753b79f3f74c708a7c0a4d38aadd411a45357"}],"openstack_dashboard/dashboards/project/routers/tests.py":[{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"925cba22a3b30fd4f85a7642e2dfcca601093fc3","unresolved":false,"context_lines":[{"line_number":87,"context_line":""},{"line_number":88,"context_line":"        self.assertTemplateUsed(res, \u0027%s/routers/detail.html\u0027 % self.DASHBOARD)"},{"line_number":89,"context_line":"        ports \u003d res.context[\u0027interfaces_table\u0027].data"},{"line_number":90,"context_line":"        self.assertItemsEqual(ports, [self.ports.first()])"},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"    @test.create_stubs({api.neutron: (\u0027router_get\u0027, \u0027port_list\u0027,"},{"line_number":93,"context_line":"                                      \u0027network_get\u0027)})"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAQn%2F%2FIvw%3D","line":90,"updated":"2013-08-06 16:39:56.000000000","message":"Can we check rule table is not rendered?","commit_id":"0290ee0b52151ea8d730f7bcc427b1bccb3016ef"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"f4bdd07070cfe1f604c70fd5e79cb1a0b565028e","unresolved":false,"context_lines":[{"line_number":87,"context_line":""},{"line_number":88,"context_line":"        self.assertTemplateUsed(res, \u0027%s/routers/detail.html\u0027 % self.DASHBOARD)"},{"line_number":89,"context_line":"        ports \u003d res.context[\u0027interfaces_table\u0027].data"},{"line_number":90,"context_line":"        self.assertItemsEqual(ports, [self.ports.first()])"},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"    @test.create_stubs({api.neutron: (\u0027router_get\u0027, \u0027port_list\u0027,"},{"line_number":93,"context_line":"                                      \u0027network_get\u0027)})"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAQn%2F%2FILk%3D","line":90,"in_reply_to":"AAAAQn%2F%2FIvw%3D","updated":"2013-08-06 21:01:08.000000000","message":"Done","commit_id":"0290ee0b52151ea8d730f7bcc427b1bccb3016ef"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"925cba22a3b30fd4f85a7642e2dfcca601093fc3","unresolved":false,"context_lines":[{"line_number":107,"context_line":""},{"line_number":108,"context_line":"        self.assertTemplateUsed(res, \u0027%s/routers/detail.html\u0027 % self.DASHBOARD)"},{"line_number":109,"context_line":"        ports \u003d res.context[\u0027interfaces_table\u0027].data"},{"line_number":110,"context_line":"        self.assertItemsEqual(ports, [self.ports.first()])"},{"line_number":111,"context_line":""},{"line_number":112,"context_line":"    @test.create_stubs({api.neutron: (\u0027router_get\u0027,)})"},{"line_number":113,"context_line":"    def test_router_detail_exception(self):"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAQn%2F%2FIwA%3D","line":110,"updated":"2013-08-06 16:39:56.000000000","message":"Can we test rule table is also displayed? Though I am not sure whether it can, I think the same approach here can be used to check it. The reason of this is because this is an extension and many developers cannot test this feature.","commit_id":"0290ee0b52151ea8d730f7bcc427b1bccb3016ef"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"f4bdd07070cfe1f604c70fd5e79cb1a0b565028e","unresolved":false,"context_lines":[{"line_number":107,"context_line":""},{"line_number":108,"context_line":"        self.assertTemplateUsed(res, \u0027%s/routers/detail.html\u0027 % self.DASHBOARD)"},{"line_number":109,"context_line":"        ports \u003d res.context[\u0027interfaces_table\u0027].data"},{"line_number":110,"context_line":"        self.assertItemsEqual(ports, [self.ports.first()])"},{"line_number":111,"context_line":""},{"line_number":112,"context_line":"    @test.create_stubs({api.neutron: (\u0027router_get\u0027,)})"},{"line_number":113,"context_line":"    def test_router_detail_exception(self):"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAQn%2F%2FILU%3D","line":110,"in_reply_to":"AAAAQn%2F%2FIwA%3D","updated":"2013-08-06 21:01:08.000000000","message":"Done","commit_id":"0290ee0b52151ea8d730f7bcc427b1bccb3016ef"}],"openstack_dashboard/dashboards/project/routers/urls.py":[{"author":{"_account_id":6914,"name":"Tatiana Ovchinnikova","email":"t.v.ovtchinnikova@gmail.com","username":"tmazur"},"change_message_id":"343206ad277c288e7a9170ccb3af7b1aca5ae94f","unresolved":false,"context_lines":[{"line_number":18,"context_line":"from django.conf.urls.defaults import url  # noqa"},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"from openstack_dashboard.dashboards.project.routers.\\"},{"line_number":21,"context_line":"    extensions.routerrules.views import AddRouterRuleView"},{"line_number":22,"context_line":"from openstack_dashboard.dashboards.project.routers.ports \\"},{"line_number":23,"context_line":"    import views as port_views"},{"line_number":24,"context_line":"from openstack_dashboard.dashboards.project.routers import views"}],"source_content_type":"text/x-python","patch_set":13,"id":"AAAASn%2F%2FkYA%3D","line":21,"updated":"2013-09-03 12:06:36.000000000","message":"Please don\u0027t import methods. We have H302 import standard here.","commit_id":"73c19032467255c432e67e929447d736d9179dcf"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"5a8fe16a9ed65fc7e2790c7ceb4bf37a742acdc2","unresolved":false,"context_lines":[{"line_number":18,"context_line":"from django.conf.urls.defaults import url  # noqa"},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"from openstack_dashboard.dashboards.project.routers.\\"},{"line_number":21,"context_line":"    extensions.routerrules.views import AddRouterRuleView"},{"line_number":22,"context_line":"from openstack_dashboard.dashboards.project.routers.ports \\"},{"line_number":23,"context_line":"    import views as port_views"},{"line_number":24,"context_line":"from openstack_dashboard.dashboards.project.routers import views"}],"source_content_type":"text/x-python","patch_set":13,"id":"AAAASn%2F%2Fgms%3D","line":21,"in_reply_to":"AAAASn%2F%2FkYA%3D","updated":"2013-09-04 05:07:08.000000000","message":"Sorry about that. I noticed that changed since when I first proposed the patch so I corrected it where the pep8 checks were catching it, but it missed a few.","commit_id":"73c19032467255c432e67e929447d736d9179dcf"}],"openstack_dashboard/dashboards/project/routers/views.py":[{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"0bed8660fd259c101e0f2b48323ac3388c24da30","unresolved":false,"context_lines":[{"line_number":96,"context_line":"    template_name \u003d \u0027project/routers/detail.html\u0027"},{"line_number":97,"context_line":"    failure_url \u003d reverse_lazy(\u0027horizon:project:routers:index\u0027)"},{"line_number":98,"context_line":""},{"line_number":99,"context_line":"    def post(self, request, *args, **kwargs):"},{"line_number":100,"context_line":"        if request.POST[\u0027action\u0027] \u003d\u003d \u0027routerrules__resetrules\u0027:"},{"line_number":101,"context_line":"            kwargs[\u0027reset_rules\u0027] \u003d True"},{"line_number":102,"context_line":"            rulemanager.remove_rules(request, [], **kwargs)"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAQn%2F%2FbE4%3D","line":99,"updated":"2013-07-31 12:38:32.000000000","message":"The logic of this method is very implementation specific and such logic should be hidden in horizon and should not be exposed to openstack_dashboard. The similar logic can be found in loadbalancers/view.\n\nCan\u0027t we enhance Horizon module? This is one of the goals of \"horizon\". (\"horizon\" and \"openstack_dashboard\" have different meanings)","commit_id":"a672d052332a9d4b9914a815228c9a1677df93aa"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"ce3bfb815309711f3888b6d8210a27a4f8c9f2a7","unresolved":false,"context_lines":[{"line_number":96,"context_line":"    template_name \u003d \u0027project/routers/detail.html\u0027"},{"line_number":97,"context_line":"    failure_url \u003d reverse_lazy(\u0027horizon:project:routers:index\u0027)"},{"line_number":98,"context_line":""},{"line_number":99,"context_line":"    def post(self, request, *args, **kwargs):"},{"line_number":100,"context_line":"        if request.POST[\u0027action\u0027] \u003d\u003d \u0027routerrules__resetrules\u0027:"},{"line_number":101,"context_line":"            kwargs[\u0027reset_rules\u0027] \u003d True"},{"line_number":102,"context_line":"            rulemanager.remove_rules(request, [], **kwargs)"}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAQn%2F%2FZFs%3D","line":99,"in_reply_to":"AAAAQn%2F%2FbE4%3D","updated":"2013-07-31 22:11:01.000000000","message":"What I did to address this was to have the TabbedTableView catch the post request. It then determines which tab it belongs to based on the slug and invokes the post method defined inside the tab. \n\nThis method allows the view to stay clean of individual tab actions and moves the post handing into the individual tab that needs to handle the logic. \n\nThis could then allow the load balancer to be cleaned up by moving each post handler into its corresponding tab.\n\nLet me know if that\u0027s what you had in mind.","commit_id":"a672d052332a9d4b9914a815228c9a1677df93aa"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"a53ead5be745e7ba5d86499fa176caa3a85d1c10","unresolved":false,"context_lines":[{"line_number":127,"context_line":""},{"line_number":128,"context_line":"    def get(self, request, *args, **kwargs):"},{"line_number":129,"context_line":"        router \u003d self._get_data()"},{"line_number":130,"context_line":"        self.kwargs[\u0027router\u0027] \u003d router"},{"line_number":131,"context_line":"        return super(DetailView, self).get(request, *args, **kwargs)"},{"line_number":132,"context_line":""},{"line_number":133,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"AAAAS3%2F%2FJ6s%3D","line":130,"updated":"2013-10-03 11:46:01.000000000","message":"I am not sure why L.129-130 are required. In TabbedTableView.get, kwargs is just passed to get_context_data. get_context_data @ L.123 extends \u0027router\u0027 already, so I wonder why these are required.","commit_id":"2ba68987a66a3152f2f70f90e0f00b1a3aed57f8"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"e4654c4a59cf0746d84054691846584c05cbdd22","unresolved":false,"context_lines":[{"line_number":127,"context_line":""},{"line_number":128,"context_line":"    def get(self, request, *args, **kwargs):"},{"line_number":129,"context_line":"        router \u003d self._get_data()"},{"line_number":130,"context_line":"        self.kwargs[\u0027router\u0027] \u003d router"},{"line_number":131,"context_line":"        return super(DetailView, self).get(request, *args, **kwargs)"},{"line_number":132,"context_line":""},{"line_number":133,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"AAAAS3%2F%2FD8o%3D","line":130,"in_reply_to":"AAAAS3%2F%2FG6k%3D","updated":"2013-10-05 07:26:29.000000000","message":"I got it. Sounds reasonable.","commit_id":"2ba68987a66a3152f2f70f90e0f00b1a3aed57f8"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"096181ce2e86214f527a6ef407f479066860f989","unresolved":false,"context_lines":[{"line_number":127,"context_line":""},{"line_number":128,"context_line":"    def get(self, request, *args, **kwargs):"},{"line_number":129,"context_line":"        router \u003d self._get_data()"},{"line_number":130,"context_line":"        self.kwargs[\u0027router\u0027] \u003d router"},{"line_number":131,"context_line":"        return super(DetailView, self).get(request, *args, **kwargs)"},{"line_number":132,"context_line":""},{"line_number":133,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"AAAAS3%2F%2FG6k%3D","line":130,"in_reply_to":"AAAAS3%2F%2FJ6s%3D","updated":"2013-10-04 09:45:35.000000000","message":"The issue is that TabbedTableView.get will call load_tabs() before it calls get_context_data. When that happens, the tab group needs the router object to give to the info to the router rules tabs. However, the tab group is scoped in a way that it can\u0027t make the router object available to the view, which requires it to populate the router info at the top of the page (name, ID, etc). L125 handles this, but it results in another get_router call to the backend since it doesn\u0027t have the router object retrieved by the tab group. \n\nBy setting it in kwargs here, it\u0027s passed to the tab group initialization so a redundant call is not necessary. You can see where it\u0027s referenced in openstack_dashboard/dashboards/project/routers/tabs.py L49.","commit_id":"2ba68987a66a3152f2f70f90e0f00b1a3aed57f8"}]}
