)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":8392,"name":"Aleksey Kasatkin","email":"akasatkin@mirantis.com","username":"aleksey"},"change_message_id":"ff9f2460e1352b0b33cc568c9a76c6fb58c67c47","unresolved":false,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Handler for counting notifications statuses added"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"For calculation notifications statuses we made requests in the UI"},{"line_number":10,"context_line":"and fetch all notifications data and process them on the UI side."},{"line_number":11,"context_line":"With new handler UI fetchs only statuses with counts."},{"line_number":12,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"3a461143_2de12dff","line":9,"range":{"start_line":9,"start_character":56,"end_line":9,"end_character":58},"updated":"2017-01-26 16:32:53.000000000","message":"from","commit_id":"4355eeb8290971e0db05682c926a028728e26f1e"},{"author":{"_account_id":10959,"name":"Alexander Kislitsky","email":"akislitsky@mirantis.com","username":"akislitsky"},"change_message_id":"b7ac4fc602360c3a2568c2c867896d7fc209edf4","unresolved":false,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Handler for counting notifications statuses added"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"For calculation notifications statuses we made requests in the UI"},{"line_number":10,"context_line":"and fetch all notifications data and process them on the UI side."},{"line_number":11,"context_line":"With new handler UI fetchs only statuses with counts."},{"line_number":12,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"3a461143_6dc6d54a","line":9,"range":{"start_line":9,"start_character":56,"end_line":9,"end_character":58},"in_reply_to":"3a461143_2de12dff","updated":"2017-01-26 16:34:28.000000000","message":"Done","commit_id":"4355eeb8290971e0db05682c926a028728e26f1e"},{"author":{"_account_id":8392,"name":"Aleksey Kasatkin","email":"akasatkin@mirantis.com","username":"aleksey"},"change_message_id":"ff9f2460e1352b0b33cc568c9a76c6fb58c67c47","unresolved":false,"context_lines":[{"line_number":8,"context_line":""},{"line_number":9,"context_line":"For calculation notifications statuses we made requests in the UI"},{"line_number":10,"context_line":"and fetch all notifications data and process them on the UI side."},{"line_number":11,"context_line":"With new handler UI fetchs only statuses with counts."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"Change-Id: I8f83d4e2d7f58beaf06c489b2264ccb69f9927ce"},{"line_number":14,"context_line":"Partial-Bug: #1657348"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"3a461143_0dac719f","line":11,"range":{"start_line":11,"start_character":20,"end_line":11,"end_character":26},"updated":"2017-01-26 16:32:53.000000000","message":"typo","commit_id":"4355eeb8290971e0db05682c926a028728e26f1e"},{"author":{"_account_id":10959,"name":"Alexander Kislitsky","email":"akislitsky@mirantis.com","username":"akislitsky"},"change_message_id":"b7ac4fc602360c3a2568c2c867896d7fc209edf4","unresolved":false,"context_lines":[{"line_number":8,"context_line":""},{"line_number":9,"context_line":"For calculation notifications statuses we made requests in the UI"},{"line_number":10,"context_line":"and fetch all notifications data and process them on the UI side."},{"line_number":11,"context_line":"With new handler UI fetchs only statuses with counts."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"Change-Id: I8f83d4e2d7f58beaf06c489b2264ccb69f9927ce"},{"line_number":14,"context_line":"Partial-Bug: #1657348"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"3a461143_8dc5c13d","line":11,"range":{"start_line":11,"start_character":20,"end_line":11,"end_character":26},"in_reply_to":"3a461143_0dac719f","updated":"2017-01-26 16:34:28.000000000","message":"Done","commit_id":"4355eeb8290971e0db05682c926a028728e26f1e"},{"author":{"_account_id":8392,"name":"Aleksey Kasatkin","email":"akasatkin@mirantis.com","username":"aleksey"},"change_message_id":"8999903b265e0fbf92d7a8004850d65d319c4605","unresolved":false,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Handler for counting notifications statuses added"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"For calculation notifications statuses we made requests in the UI"},{"line_number":10,"context_line":"and fetch all notifications data and process them on the UI side."},{"line_number":11,"context_line":"With new handler UI fetchs only statuses with counts."},{"line_number":12,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":3,"id":"3a461143_1ca00190","line":9,"range":{"start_line":9,"start_character":15,"end_line":9,"end_character":16},"updated":"2017-01-27 10:00:04.000000000","message":"of","commit_id":"afbcf92966731ce204712e4a590bff58967e084f"},{"author":{"_account_id":8392,"name":"Aleksey Kasatkin","email":"akasatkin@mirantis.com","username":"aleksey"},"change_message_id":"8999903b265e0fbf92d7a8004850d65d319c4605","unresolved":false,"context_lines":[{"line_number":8,"context_line":""},{"line_number":9,"context_line":"For calculation notifications statuses we made requests in the UI"},{"line_number":10,"context_line":"and fetch all notifications data and process them on the UI side."},{"line_number":11,"context_line":"With new handler UI fetchs only statuses with counts."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"Change-Id: I8f83d4e2d7f58beaf06c489b2264ccb69f9927ce"},{"line_number":14,"context_line":"Partial-Bug: #1657348"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":3,"id":"3a461143_7cbd8567","line":11,"range":{"start_line":11,"start_character":52,"end_line":11,"end_character":53},"updated":"2017-01-27 10:00:04.000000000","message":"BTW, could we live w/o counts? I didn\u0027t find description of proposed solution(workflow) for the issue.","commit_id":"afbcf92966731ce204712e4a590bff58967e084f"},{"author":{"_account_id":8766,"name":"Julia Aranovich","email":"jkirnosova@mirantis.com","username":"CesarSar"},"change_message_id":"de9eab7f8d99c39646b73f0790f0d7832e7791d1","unresolved":false,"context_lines":[{"line_number":8,"context_line":""},{"line_number":9,"context_line":"For calculation notifications statuses we made requests in the UI"},{"line_number":10,"context_line":"and fetch all notifications data and process them on the UI side."},{"line_number":11,"context_line":"With new handler UI fetchs only statuses with counts."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"Change-Id: I8f83d4e2d7f58beaf06c489b2264ccb69f9927ce"},{"line_number":14,"context_line":"Partial-Bug: #1657348"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":3,"id":"3a461143_1e4d4e6c","line":11,"range":{"start_line":11,"start_character":52,"end_line":11,"end_character":53},"in_reply_to":"3a461143_7cbd8567","updated":"2017-01-27 13:05:20.000000000","message":"We want to replace a polling of the whole notification collection by a polling of unread notifications number.\nTo be consistent with existing node statistics handler: GET /api/nodes/allocation/stats (returns {total: N, unallocated: M}) - I suggest to provide a new GET /api/notifications/stats handler which should return {total: N, unread: M}. This will dramatically decrease Fuel UI load in case of a big amount of notifications.","commit_id":"afbcf92966731ce204712e4a590bff58967e084f"},{"author":{"_account_id":8392,"name":"Aleksey Kasatkin","email":"akasatkin@mirantis.com","username":"aleksey"},"change_message_id":"8999903b265e0fbf92d7a8004850d65d319c4605","unresolved":false,"context_lines":[{"line_number":9,"context_line":"For calculation notifications statuses we made requests in the UI"},{"line_number":10,"context_line":"and fetch all notifications data and process them on the UI side."},{"line_number":11,"context_line":"With new handler UI fetchs only statuses with counts."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"Change-Id: I8f83d4e2d7f58beaf06c489b2264ccb69f9927ce"},{"line_number":14,"context_line":"Partial-Bug: #1657348"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":3,"id":"3a461143_3cc69d48","line":12,"updated":"2017-01-27 10:00:04.000000000","message":"also, pls see comments in #2","commit_id":"afbcf92966731ce204712e4a590bff58967e084f"},{"author":{"_account_id":8392,"name":"Aleksey Kasatkin","email":"akasatkin@mirantis.com","username":"aleksey"},"change_message_id":"10578868bca47487fceee2fb5a03c8d658f96e67","unresolved":false,"context_lines":[{"line_number":9,"context_line":"For calculation of notifications statuses we made requests in the UI"},{"line_number":10,"context_line":"and fetch all notifications data and process them on the UI side."},{"line_number":11,"context_line":"We want to replace a polling of the whole notification collection by"},{"line_number":12,"context_line":"a polling of unread notifications number. This dramatically decrease"},{"line_number":13,"context_line":"Fuel UI load in case of a big amount of notifications."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"Change-Id: I8f83d4e2d7f58beaf06c489b2264ccb69f9927ce"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":4,"id":"3a461143_b480d947","line":12,"range":{"start_line":12,"start_character":13,"end_line":12,"end_character":40},"updated":"2017-01-27 13:57:48.000000000","message":"how UI deals with this number? why isn\u0027t it said about getting unread notifications data, just about their number?","commit_id":"d0ed46eaf660f2f3cc16c9078deff7233f3de710"},{"author":{"_account_id":8392,"name":"Aleksey Kasatkin","email":"akasatkin@mirantis.com","username":"aleksey"},"change_message_id":"9819adb619897f56317d64c50028a266913290a7","unresolved":false,"context_lines":[{"line_number":9,"context_line":"For calculation of notifications statuses we made requests in the UI"},{"line_number":10,"context_line":"and fetch all notifications data and process them on the UI side."},{"line_number":11,"context_line":"We want to replace a polling of the whole notification collection by"},{"line_number":12,"context_line":"a polling of unread notifications number. This dramatically decrease"},{"line_number":13,"context_line":"Fuel UI load in case of a big amount of notifications."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"Change-Id: I8f83d4e2d7f58beaf06c489b2264ccb69f9927ce"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":4,"id":"3a461143_d422be00","line":12,"range":{"start_line":12,"start_character":13,"end_line":12,"end_character":40},"in_reply_to":"3a461143_54897525","updated":"2017-01-27 16:48:36.000000000","message":"Okay, it\u0027s probably better to talk about this in https://review.openstack.org/#/c/425483","commit_id":"d0ed46eaf660f2f3cc16c9078deff7233f3de710"},{"author":{"_account_id":10959,"name":"Alexander Kislitsky","email":"akislitsky@mirantis.com","username":"akislitsky"},"change_message_id":"5652c2a52e1aa88c0eb86419b97268f9c69deab3","unresolved":false,"context_lines":[{"line_number":9,"context_line":"For calculation of notifications statuses we made requests in the UI"},{"line_number":10,"context_line":"and fetch all notifications data and process them on the UI side."},{"line_number":11,"context_line":"We want to replace a polling of the whole notification collection by"},{"line_number":12,"context_line":"a polling of unread notifications number. This dramatically decrease"},{"line_number":13,"context_line":"Fuel UI load in case of a big amount of notifications."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"Change-Id: I8f83d4e2d7f58beaf06c489b2264ccb69f9927ce"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":4,"id":"3a461143_54897525","line":12,"range":{"start_line":12,"start_character":13,"end_line":12,"end_character":40},"in_reply_to":"3a461143_b480d947","updated":"2017-01-27 14:06:04.000000000","message":"This hanler will be used only for periodical checking of notifications statuses. Fetching and showing of notifications data doesn\u0027t changed.","commit_id":"d0ed46eaf660f2f3cc16c9078deff7233f3de710"},{"author":{"_account_id":8766,"name":"Julia Aranovich","email":"jkirnosova@mirantis.com","username":"CesarSar"},"change_message_id":"a5e63f26880b151fbb534d34d9949a41cf687445","unresolved":false,"context_lines":[{"line_number":9,"context_line":"For calculation of notifications statuses we made requests in the UI"},{"line_number":10,"context_line":"and fetch all notifications data and process them on the UI side."},{"line_number":11,"context_line":"We want to replace a polling of the whole notification collection by"},{"line_number":12,"context_line":"a polling of unread notifications number. This dramatically decrease"},{"line_number":13,"context_line":"Fuel UI load in case of a big amount of notifications."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"Change-Id: I8f83d4e2d7f58beaf06c489b2264ccb69f9927ce"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":4,"id":"3a461143_e4b9a57a","line":12,"range":{"start_line":12,"start_character":13,"end_line":12,"end_character":40},"in_reply_to":"3a461143_d422be00","updated":"2017-01-30 07:50:20.000000000","message":"Alexey, we need to poll unread notifications number every 20 sec just to show an orange badge in the top right corner in Fuel UI. Now we fetch te whole notification collection for this purpose (to show a number of unread items), and it loads Fuel UI significantly.\nSo, we want to organize notifications counter in the similar way as we work with node statistics: GET /api/nodes/allocation/stats that returns {total: N, unallocated: M}.","commit_id":"d0ed46eaf660f2f3cc16c9078deff7233f3de710"}],"nailgun/nailgun/api/v1/handlers/notifications.py":[{"author":{"_account_id":8392,"name":"Aleksey Kasatkin","email":"akasatkin@mirantis.com","username":"aleksey"},"change_message_id":"3753dc086cc6123fa04e89dd230edfc434a3d29a","unresolved":false,"context_lines":[{"line_number":61,"context_line":"        return self.collection.to_list(notifications_updated)"},{"line_number":62,"context_line":""},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"class NotificationStatusesHandler(CollectionHandler):"},{"line_number":65,"context_line":""},{"line_number":66,"context_line":"    collection \u003d objects.NotificationCollection"},{"line_number":67,"context_line":"    validator \u003d NotificationValidator"}],"source_content_type":"text/x-python","patch_set":2,"id":"3a461143_e4a4a2ba","line":64,"range":{"start_line":64,"start_character":6,"end_line":64,"end_character":33},"updated":"2017-01-26 15:48:09.000000000","message":"why not \"NotificationStatusCollectionHandler\"?","commit_id":"4355eeb8290971e0db05682c926a028728e26f1e"},{"author":{"_account_id":10959,"name":"Alexander Kislitsky","email":"akislitsky@mirantis.com","username":"akislitsky"},"change_message_id":"b7ac4fc602360c3a2568c2c867896d7fc209edf4","unresolved":false,"context_lines":[{"line_number":61,"context_line":"        return self.collection.to_list(notifications_updated)"},{"line_number":62,"context_line":""},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"class NotificationStatusesHandler(CollectionHandler):"},{"line_number":65,"context_line":""},{"line_number":66,"context_line":"    collection \u003d objects.NotificationCollection"},{"line_number":67,"context_line":"    validator \u003d NotificationValidator"}],"source_content_type":"text/x-python","patch_set":2,"id":"3a461143_0aa0d742","line":64,"range":{"start_line":64,"start_character":6,"end_line":64,"end_character":33},"in_reply_to":"3a461143_e4a4a2ba","updated":"2017-01-26 16:34:28.000000000","message":"Done","commit_id":"4355eeb8290971e0db05682c926a028728e26f1e"},{"author":{"_account_id":8392,"name":"Aleksey Kasatkin","email":"akasatkin@mirantis.com","username":"aleksey"},"change_message_id":"ff9f2460e1352b0b33cc568c9a76c6fb58c67c47","unresolved":false,"context_lines":[{"line_number":70,"context_line":"    @validate"},{"line_number":71,"context_line":"    @serialize"},{"line_number":72,"context_line":"    def GET(self):"},{"line_number":73,"context_line":"        \"\"\":returns: Notifications statuses count"},{"line_number":74,"context_line":""},{"line_number":75,"context_line":"        :http: * 200 (OK)"},{"line_number":76,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":2,"id":"3a461143_6d6415e5","line":73,"updated":"2017-01-26 16:32:53.000000000","message":"imo, description does not address real output well enough.","commit_id":"4355eeb8290971e0db05682c926a028728e26f1e"},{"author":{"_account_id":8392,"name":"Aleksey Kasatkin","email":"akasatkin@mirantis.com","username":"aleksey"},"change_message_id":"8999903b265e0fbf92d7a8004850d65d319c4605","unresolved":false,"context_lines":[{"line_number":70,"context_line":"    @validate"},{"line_number":71,"context_line":"    @serialize"},{"line_number":72,"context_line":"    def GET(self):"},{"line_number":73,"context_line":"        \"\"\":returns: Notifications statuses count"},{"line_number":74,"context_line":""},{"line_number":75,"context_line":"        :http: * 200 (OK)"},{"line_number":76,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":3,"id":"3a461143_dc867912","line":73,"updated":"2017-01-27 10:00:04.000000000","message":"pls see comment in #2","commit_id":"afbcf92966731ce204712e4a590bff58967e084f"}],"nailgun/nailgun/api/v1/urls.py":[{"author":{"_account_id":8392,"name":"Aleksey Kasatkin","email":"akasatkin@mirantis.com","username":"aleksey"},"change_message_id":"3753dc086cc6123fa04e89dd230edfc434a3d29a","unresolved":false,"context_lines":[{"line_number":337,"context_line":"    NotificationCollectionHandler,"},{"line_number":338,"context_line":"    r\u0027/notifications/(?P\u003cobj_id\u003e\\d+)/?$\u0027,"},{"line_number":339,"context_line":"    NotificationHandler,"},{"line_number":340,"context_line":"    r\u0027/notifications/statuses?$\u0027,"},{"line_number":341,"context_line":"    NotificationStatusesHandler,"},{"line_number":342,"context_line":""},{"line_number":343,"context_line":"    r\u0027/dump/(?P\u003csnapshot_name\u003e[A-Za-z0-9-_.]+)$\u0027,"}],"source_content_type":"text/x-python","patch_set":2,"id":"3a461143_64fef239","line":340,"range":{"start_line":340,"start_character":29,"end_line":340,"end_character":30},"updated":"2017-01-26 15:48:09.000000000","message":"add \"/\" ?","commit_id":"4355eeb8290971e0db05682c926a028728e26f1e"},{"author":{"_account_id":10959,"name":"Alexander Kislitsky","email":"akislitsky@mirantis.com","username":"akislitsky"},"change_message_id":"b7ac4fc602360c3a2568c2c867896d7fc209edf4","unresolved":false,"context_lines":[{"line_number":337,"context_line":"    NotificationCollectionHandler,"},{"line_number":338,"context_line":"    r\u0027/notifications/(?P\u003cobj_id\u003e\\d+)/?$\u0027,"},{"line_number":339,"context_line":"    NotificationHandler,"},{"line_number":340,"context_line":"    r\u0027/notifications/statuses?$\u0027,"},{"line_number":341,"context_line":"    NotificationStatusesHandler,"},{"line_number":342,"context_line":""},{"line_number":343,"context_line":"    r\u0027/dump/(?P\u003csnapshot_name\u003e[A-Za-z0-9-_.]+)$\u0027,"}],"source_content_type":"text/x-python","patch_set":2,"id":"3a461143_6a215bb4","line":340,"range":{"start_line":340,"start_character":29,"end_line":340,"end_character":30},"in_reply_to":"3a461143_64fef239","updated":"2017-01-26 16:34:28.000000000","message":"Done","commit_id":"4355eeb8290971e0db05682c926a028728e26f1e"},{"author":{"_account_id":21013,"name":"Georgy Kibardin","email":"gkibardin@mirantis.com","username":"gkibardin"},"change_message_id":"a462bcf88c32161a933b865a45d2a171c7dc4b08","unresolved":false,"context_lines":[{"line_number":334,"context_line":"    r\u0027(?P\u003cgraph_type\u003e[a-zA-Z0-9-_]+)/?$\u0027,"},{"line_number":335,"context_line":"    PluginDeploymentGraphHandler,"},{"line_number":336,"context_line":""},{"line_number":337,"context_line":"    r\u0027/notifications/?$\u0027,"},{"line_number":338,"context_line":"    NotificationCollectionHandler,"},{"line_number":339,"context_line":"    r\u0027/notifications/(?P\u003cobj_id\u003e\\d+)/?$\u0027,"},{"line_number":340,"context_line":"    NotificationHandler,"}],"source_content_type":"text/x-python","patch_set":4,"id":"3a461143_a9a8588e","line":337,"updated":"2017-01-30 06:22:31.000000000","message":"Guys, why cannot we just add a parameter here?\nI mean to add a \"from\" parameter which is id of last read notification so that the handler would return only unread notifications.","commit_id":"d0ed46eaf660f2f3cc16c9078deff7233f3de710"},{"author":{"_account_id":8766,"name":"Julia Aranovich","email":"jkirnosova@mirantis.com","username":"CesarSar"},"change_message_id":"a5e63f26880b151fbb534d34d9949a41cf687445","unresolved":false,"context_lines":[{"line_number":334,"context_line":"    r\u0027(?P\u003cgraph_type\u003e[a-zA-Z0-9-_]+)/?$\u0027,"},{"line_number":335,"context_line":"    PluginDeploymentGraphHandler,"},{"line_number":336,"context_line":""},{"line_number":337,"context_line":"    r\u0027/notifications/?$\u0027,"},{"line_number":338,"context_line":"    NotificationCollectionHandler,"},{"line_number":339,"context_line":"    r\u0027/notifications/(?P\u003cobj_id\u003e\\d+)/?$\u0027,"},{"line_number":340,"context_line":"    NotificationHandler,"}],"source_content_type":"text/x-python","patch_set":4,"id":"3a461143_ff15ae3f","line":337,"in_reply_to":"3a461143_a9a8588e","updated":"2017-01-30 07:50:20.000000000","message":"UI won\u0027t have a notification collection in a common case, but only if user is on Notifications page.\nSo, UI won\u0027t know about last read notification ID.","commit_id":"d0ed46eaf660f2f3cc16c9078deff7233f3de710"}],"nailgun/nailgun/objects/notification.py":[{"author":{"_account_id":8392,"name":"Aleksey Kasatkin","email":"akasatkin@mirantis.com","username":"aleksey"},"change_message_id":"3753dc086cc6123fa04e89dd230edfc434a3d29a","unresolved":false,"context_lines":[{"line_number":87,"context_line":"        return notif_dict"},{"line_number":88,"context_line":""},{"line_number":89,"context_line":"    @classmethod"},{"line_number":90,"context_line":"    def get_statuses_count(cls):"},{"line_number":91,"context_line":"        result \u003d {}"},{"line_number":92,"context_line":"        query \u003d db().query(cls.model.status, func.count(cls.model.status)).\\"},{"line_number":93,"context_line":"            group_by(cls.model.status)"}],"source_content_type":"text/x-python","patch_set":2,"id":"3a461143_245eaa76","line":90,"range":{"start_line":90,"start_character":8,"end_line":90,"end_character":26},"updated":"2017-01-26 15:48:09.000000000","message":"get_statuses_with_counts?\n\nimo, docstring/comment would be helpful on what is returned here.","commit_id":"4355eeb8290971e0db05682c926a028728e26f1e"},{"author":{"_account_id":10959,"name":"Alexander Kislitsky","email":"akislitsky@mirantis.com","username":"akislitsky"},"change_message_id":"b7ac4fc602360c3a2568c2c867896d7fc209edf4","unresolved":false,"context_lines":[{"line_number":87,"context_line":"        return notif_dict"},{"line_number":88,"context_line":""},{"line_number":89,"context_line":"    @classmethod"},{"line_number":90,"context_line":"    def get_statuses_count(cls):"},{"line_number":91,"context_line":"        result \u003d {}"},{"line_number":92,"context_line":"        query \u003d db().query(cls.model.status, func.count(cls.model.status)).\\"},{"line_number":93,"context_line":"            group_by(cls.model.status)"}],"source_content_type":"text/x-python","patch_set":2,"id":"3a461143_ca188f87","line":90,"range":{"start_line":90,"start_character":8,"end_line":90,"end_character":26},"in_reply_to":"3a461143_245eaa76","updated":"2017-01-26 16:34:28.000000000","message":"Done","commit_id":"4355eeb8290971e0db05682c926a028728e26f1e"},{"author":{"_account_id":8392,"name":"Aleksey Kasatkin","email":"akasatkin@mirantis.com","username":"aleksey"},"change_message_id":"10578868bca47487fceee2fb5a03c8d658f96e67","unresolved":false,"context_lines":[{"line_number":96,"context_line":""},{"line_number":97,"context_line":"        :return: dict of {\u0027total\u0027: count, \u0027unread\u0027: count, ...}"},{"line_number":98,"context_line":"        \"\"\""},{"line_number":99,"context_line":"        result \u003d {\u0027unread\u0027: 0}"},{"line_number":100,"context_line":"        query \u003d db().query(cls.model.status, func.count(cls.model.status)).\\"},{"line_number":101,"context_line":"            group_by(cls.model.status)"},{"line_number":102,"context_line":"        for status, num in query.all():"}],"source_content_type":"text/x-python","patch_set":4,"id":"3a461143_14360de6","line":99,"range":{"start_line":99,"start_character":19,"end_line":99,"end_character":25},"updated":"2017-01-27 13:57:48.000000000","message":"why just \u0027unread\u0027 is initialized?","commit_id":"d0ed46eaf660f2f3cc16c9078deff7233f3de710"},{"author":{"_account_id":10959,"name":"Alexander Kislitsky","email":"akislitsky@mirantis.com","username":"akislitsky"},"change_message_id":"5652c2a52e1aa88c0eb86419b97268f9c69deab3","unresolved":false,"context_lines":[{"line_number":96,"context_line":""},{"line_number":97,"context_line":"        :return: dict of {\u0027total\u0027: count, \u0027unread\u0027: count, ...}"},{"line_number":98,"context_line":"        \"\"\""},{"line_number":99,"context_line":"        result \u003d {\u0027unread\u0027: 0}"},{"line_number":100,"context_line":"        query \u003d db().query(cls.model.status, func.count(cls.model.status)).\\"},{"line_number":101,"context_line":"            group_by(cls.model.status)"},{"line_number":102,"context_line":"        for status, num in query.all():"}],"source_content_type":"text/x-python","patch_set":4,"id":"3a461143_94275d63","line":99,"range":{"start_line":99,"start_character":19,"end_line":99,"end_character":25},"in_reply_to":"3a461143_14360de6","updated":"2017-01-27 14:06:04.000000000","message":"I don\u0027t want hardcode any statuses at all, but for UI it would be convinient to have total and unread in the response. Thats why it is done in this way.","commit_id":"d0ed46eaf660f2f3cc16c9078deff7233f3de710"},{"author":{"_account_id":8766,"name":"Julia Aranovich","email":"jkirnosova@mirantis.com","username":"CesarSar"},"change_message_id":"a5e63f26880b151fbb534d34d9949a41cf687445","unresolved":false,"context_lines":[{"line_number":96,"context_line":""},{"line_number":97,"context_line":"        :return: dict of {\u0027total\u0027: count, \u0027unread\u0027: count, ...}"},{"line_number":98,"context_line":"        \"\"\""},{"line_number":99,"context_line":"        result \u003d {\u0027unread\u0027: 0}"},{"line_number":100,"context_line":"        query \u003d db().query(cls.model.status, func.count(cls.model.status)).\\"},{"line_number":101,"context_line":"            group_by(cls.model.status)"},{"line_number":102,"context_line":"        for status, num in query.all():"}],"source_content_type":"text/x-python","patch_set":4,"id":"3a461143_24256dc0","line":99,"range":{"start_line":99,"start_character":19,"end_line":99,"end_character":25},"in_reply_to":"3a461143_14d8c61c","updated":"2017-01-30 07:50:20.000000000","message":"We want to be consistent with existing node statisics handler /api/nodes/allocation/stats that returns {total: N, unallocated: M}.\nWe consider this new endpoint as collecting of statistics data. I think we can set up statistics in more less free format.\nAt the same time, I have no strict concerns against returning of {unread: N, read: M} that represents 2 different notification statuses. But again, {total: N, unread: M} looks preferred.","commit_id":"d0ed46eaf660f2f3cc16c9078deff7233f3de710"},{"author":{"_account_id":8392,"name":"Aleksey Kasatkin","email":"akasatkin@mirantis.com","username":"aleksey"},"change_message_id":"ca400bfe2afa16e313f307543a68fa968513309f","unresolved":false,"context_lines":[{"line_number":96,"context_line":""},{"line_number":97,"context_line":"        :return: dict of {\u0027total\u0027: count, \u0027unread\u0027: count, ...}"},{"line_number":98,"context_line":"        \"\"\""},{"line_number":99,"context_line":"        result \u003d {\u0027unread\u0027: 0}"},{"line_number":100,"context_line":"        query \u003d db().query(cls.model.status, func.count(cls.model.status)).\\"},{"line_number":101,"context_line":"            group_by(cls.model.status)"},{"line_number":102,"context_line":"        for status, num in query.all():"}],"source_content_type":"text/x-python","patch_set":4,"id":"3a461143_9abd98b9","line":99,"range":{"start_line":99,"start_character":19,"end_line":99,"end_character":25},"in_reply_to":"3a461143_24256dc0","updated":"2017-01-30 09:02:56.000000000","message":"I\u0027m not against \u0027total\u0027 here. Just it does not look consistent that \u0027unread\u0027 has some different behaviour than \u0027read\u0027 (or some another possible status). Also, we rely on name \u0027unread\u0027 here but it actually is defined in consts.\n\nIt would be better just to add \u0027total\u0027 and not to hardcode \u0027unread\u0027 (e.g., init all possible statuses with zeros). \n\n\"/api/nodes/allocation/stats\" is somewhat different (it does not differentiate by status or by some another enum). Though, it could be improved: return more verbose info and make one query instead of two.","commit_id":"d0ed46eaf660f2f3cc16c9078deff7233f3de710"},{"author":{"_account_id":8392,"name":"Aleksey Kasatkin","email":"akasatkin@mirantis.com","username":"aleksey"},"change_message_id":"9819adb619897f56317d64c50028a266913290a7","unresolved":false,"context_lines":[{"line_number":96,"context_line":""},{"line_number":97,"context_line":"        :return: dict of {\u0027total\u0027: count, \u0027unread\u0027: count, ...}"},{"line_number":98,"context_line":"        \"\"\""},{"line_number":99,"context_line":"        result \u003d {\u0027unread\u0027: 0}"},{"line_number":100,"context_line":"        query \u003d db().query(cls.model.status, func.count(cls.model.status)).\\"},{"line_number":101,"context_line":"            group_by(cls.model.status)"},{"line_number":102,"context_line":"        for status, num in query.all():"}],"source_content_type":"text/x-python","patch_set":4,"id":"3a461143_14d8c61c","line":99,"range":{"start_line":99,"start_character":19,"end_line":99,"end_character":25},"in_reply_to":"3a461143_94275d63","updated":"2017-01-27 16:48:36.000000000","message":"I don\u0027t think it\u0027s a good idea to make API relying on implementation of particular client.\n\nAs an option, maybe initialize values for all statuses then?","commit_id":"d0ed46eaf660f2f3cc16c9078deff7233f3de710"},{"author":{"_account_id":8766,"name":"Julia Aranovich","email":"jkirnosova@mirantis.com","username":"CesarSar"},"change_message_id":"7602890fea7903734ec9301cbf8faa6758cf022e","unresolved":false,"context_lines":[{"line_number":96,"context_line":""},{"line_number":97,"context_line":"        :return: dict of {\u0027total\u0027: count, \u0027unread\u0027: count, ...}"},{"line_number":98,"context_line":"        \"\"\""},{"line_number":99,"context_line":"        result \u003d {\u0027unread\u0027: 0}"},{"line_number":100,"context_line":"        query \u003d db().query(cls.model.status, func.count(cls.model.status)).\\"},{"line_number":101,"context_line":"            group_by(cls.model.status)"},{"line_number":102,"context_line":"        for status, num in query.all():"}],"source_content_type":"text/x-python","patch_set":4,"id":"3a461143_e0a7ceba","line":99,"range":{"start_line":99,"start_character":19,"end_line":99,"end_character":25},"in_reply_to":"3a461143_9abd98b9","updated":"2017-01-30 09:29:19.000000000","message":"Now /api/notifications/stats returns {total: N, unread: M, read: P}. So, this is a dict with keys which are notification statuses, and with an additional key \u0027total\u0027.\nI\u0027m totally Ok with this approach. Support the idea not to hardcode \u0027unread\u0027.","commit_id":"d0ed46eaf660f2f3cc16c9078deff7233f3de710"},{"author":{"_account_id":10959,"name":"Alexander Kislitsky","email":"akislitsky@mirantis.com","username":"akislitsky"},"change_message_id":"30a81e9af48a02beabcc271a63e2645555854ef3","unresolved":false,"context_lines":[{"line_number":96,"context_line":""},{"line_number":97,"context_line":"        :return: dict of {\u0027total\u0027: count, \u0027unread\u0027: count, ...}"},{"line_number":98,"context_line":"        \"\"\""},{"line_number":99,"context_line":"        result \u003d {\u0027unread\u0027: 0}"},{"line_number":100,"context_line":"        query \u003d db().query(cls.model.status, func.count(cls.model.status)).\\"},{"line_number":101,"context_line":"            group_by(cls.model.status)"},{"line_number":102,"context_line":"        for status, num in query.all():"}],"source_content_type":"text/x-python","patch_set":4,"id":"3a461143_c3381ca3","line":99,"range":{"start_line":99,"start_character":19,"end_line":99,"end_character":25},"in_reply_to":"3a461143_e0a7ceba","updated":"2017-01-30 09:59:27.000000000","message":"Done. All statuses defined in the NOTIFICATION_STATUSES will be present in the result.","commit_id":"d0ed46eaf660f2f3cc16c9078deff7233f3de710"},{"author":{"_account_id":8392,"name":"Aleksey Kasatkin","email":"akasatkin@mirantis.com","username":"aleksey"},"change_message_id":"d2352d406d695a4a8b2134f708ed028ed38d29b8","unresolved":false,"context_lines":[{"line_number":92,"context_line":"        \"\"\"Counts notifications statuses in DB"},{"line_number":93,"context_line":""},{"line_number":94,"context_line":"        Calculates total number of notifications and adds it to the"},{"line_number":95,"context_line":"        result. Count of unread notifications and total are mandatory"},{"line_number":96,"context_line":"        fields"},{"line_number":97,"context_line":""},{"line_number":98,"context_line":"        :return: dict of {\u0027total\u0027: count, \u0027unread\u0027: count, ...}"},{"line_number":99,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":5,"id":"3a461143_fddf6c37","line":96,"range":{"start_line":95,"start_character":16,"end_line":96,"end_character":14},"updated":"2017-01-30 14:26:46.000000000","message":"this could be re-phrased now","commit_id":"7af634dda3cec3787875ed1655ae28b2d12e736c"},{"author":{"_account_id":10959,"name":"Alexander Kislitsky","email":"akislitsky@mirantis.com","username":"akislitsky"},"change_message_id":"03ef0713a06d0d13e4e9750fc18d777139123b38","unresolved":false,"context_lines":[{"line_number":92,"context_line":"        \"\"\"Counts notifications statuses in DB"},{"line_number":93,"context_line":""},{"line_number":94,"context_line":"        Calculates total number of notifications and adds it to the"},{"line_number":95,"context_line":"        result. Count of unread notifications and total are mandatory"},{"line_number":96,"context_line":"        fields"},{"line_number":97,"context_line":""},{"line_number":98,"context_line":"        :return: dict of {\u0027total\u0027: count, \u0027unread\u0027: count, ...}"},{"line_number":99,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":5,"id":"3a461143_5b408834","line":96,"range":{"start_line":95,"start_character":16,"end_line":96,"end_character":14},"in_reply_to":"3a461143_fddf6c37","updated":"2017-01-30 15:04:29.000000000","message":"Thanks. Done","commit_id":"7af634dda3cec3787875ed1655ae28b2d12e736c"}],"nailgun/nailgun/test/unit/test_notification_handler.py":[{"author":{"_account_id":8392,"name":"Aleksey Kasatkin","email":"akasatkin@mirantis.com","username":"aleksey"},"change_message_id":"3753dc086cc6123fa04e89dd230edfc434a3d29a","unresolved":false,"context_lines":[{"line_number":102,"context_line":"        )"},{"line_number":103,"context_line":"        self.assertEqual(404, resp.status_code)"},{"line_number":104,"context_line":""},{"line_number":105,"context_line":"    def test_notification_statuses(self):"},{"line_number":106,"context_line":"        resp \u003d self.app.get("},{"line_number":107,"context_line":"            reverse("},{"line_number":108,"context_line":"                \u0027NotificationStatusesHandler\u0027,"}],"source_content_type":"text/x-python","patch_set":2,"id":"3a461143_c4bc066f","line":105,"range":{"start_line":105,"start_character":8,"end_line":105,"end_character":34},"updated":"2017-01-26 15:48:09.000000000","message":"this tests \"GET\" only. maybe reflect this in the name?","commit_id":"4355eeb8290971e0db05682c926a028728e26f1e"},{"author":{"_account_id":10959,"name":"Alexander Kislitsky","email":"akislitsky@mirantis.com","username":"akislitsky"},"change_message_id":"b7ac4fc602360c3a2568c2c867896d7fc209edf4","unresolved":false,"context_lines":[{"line_number":102,"context_line":"        )"},{"line_number":103,"context_line":"        self.assertEqual(404, resp.status_code)"},{"line_number":104,"context_line":""},{"line_number":105,"context_line":"    def test_notification_statuses(self):"},{"line_number":106,"context_line":"        resp \u003d self.app.get("},{"line_number":107,"context_line":"            reverse("},{"line_number":108,"context_line":"                \u0027NotificationStatusesHandler\u0027,"}],"source_content_type":"text/x-python","patch_set":2,"id":"3a461143_0d7d516e","line":105,"range":{"start_line":105,"start_character":8,"end_line":105,"end_character":34},"in_reply_to":"3a461143_c4bc066f","updated":"2017-01-26 16:34:28.000000000","message":"Done","commit_id":"4355eeb8290971e0db05682c926a028728e26f1e"},{"author":{"_account_id":8392,"name":"Aleksey Kasatkin","email":"akasatkin@mirantis.com","username":"aleksey"},"change_message_id":"3753dc086cc6123fa04e89dd230edfc434a3d29a","unresolved":false,"context_lines":[{"line_number":109,"context_line":"            ),"},{"line_number":110,"context_line":"            headers\u003dself.default_headers"},{"line_number":111,"context_line":"        )"},{"line_number":112,"context_line":"        self.assertEqual({}, resp.json_body)"},{"line_number":113,"context_line":""},{"line_number":114,"context_line":"        self.env.create_notification()"},{"line_number":115,"context_line":"        resp \u003d self.app.get("}],"source_content_type":"text/x-python","patch_set":2,"id":"3a461143_871e8061","line":112,"updated":"2017-01-26 15:48:09.000000000","message":"it would be nice to check status code somewhere.","commit_id":"4355eeb8290971e0db05682c926a028728e26f1e"},{"author":{"_account_id":10959,"name":"Alexander Kislitsky","email":"akislitsky@mirantis.com","username":"akislitsky"},"change_message_id":"b7ac4fc602360c3a2568c2c867896d7fc209edf4","unresolved":false,"context_lines":[{"line_number":109,"context_line":"            ),"},{"line_number":110,"context_line":"            headers\u003dself.default_headers"},{"line_number":111,"context_line":"        )"},{"line_number":112,"context_line":"        self.assertEqual({}, resp.json_body)"},{"line_number":113,"context_line":""},{"line_number":114,"context_line":"        self.env.create_notification()"},{"line_number":115,"context_line":"        resp \u003d self.app.get("}],"source_content_type":"text/x-python","patch_set":2,"id":"3a461143_edb9e5cc","line":112,"in_reply_to":"3a461143_871e8061","updated":"2017-01-26 16:34:28.000000000","message":"In case of failed request get will rise an exception without parameter expect_errors\u003dTrue.","commit_id":"4355eeb8290971e0db05682c926a028728e26f1e"},{"author":{"_account_id":8392,"name":"Aleksey Kasatkin","email":"akasatkin@mirantis.com","username":"aleksey"},"change_message_id":"da6fab01be2ace3b63d27b517d5ad98e79c67c4c","unresolved":false,"context_lines":[{"line_number":109,"context_line":"            ),"},{"line_number":110,"context_line":"            headers\u003dself.default_headers"},{"line_number":111,"context_line":"        )"},{"line_number":112,"context_line":"        self.assertEqual({}, resp.json_body)"},{"line_number":113,"context_line":""},{"line_number":114,"context_line":"        self.env.create_notification()"},{"line_number":115,"context_line":"        resp \u003d self.app.get("}],"source_content_type":"text/x-python","patch_set":2,"id":"3a461143_4d275912","line":112,"in_reply_to":"3a461143_edb9e5cc","updated":"2017-01-26 16:36:48.000000000","message":"Done","commit_id":"4355eeb8290971e0db05682c926a028728e26f1e"}]}
