)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":21013,"name":"Georgy Kibardin","email":"gkibardin@mirantis.com","username":"gkibardin"},"change_message_id":"0ccca0a0d10676595b577e8afea948473a5e8672","unresolved":false,"context_lines":[{"line_number":5,"context_line":"CommitDate: 2016-07-28 18:08:29 +0300"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"[WIP] Add ability to export deployment history in CSV format"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Change-Id: I196e878c0e0c951d4a0021b3ede22c1a3c97cc72"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"bacf61ea_d33637e6","line":8,"updated":"2016-07-29 07:08:03.000000000","message":"Please drop a line about who needs this. Otherwise we have a chance to forget and to never know this :)","commit_id":"d9536e19598bc9635cae746ad3f6844efbc5cf2b"}],"nailgun/nailgun/api/v1/handlers/base.py":[{"author":{"_account_id":21013,"name":"Georgy Kibardin","email":"gkibardin@mirantis.com","username":"gkibardin"},"change_message_id":"0ccca0a0d10676595b577e8afea948473a5e8672","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"bacf61ea_3364f3e2","updated":"2016-07-29 07:08:03.000000000","message":"Why don\u0027t you base your work on https://review.openstack.org/#/c/346957/ ?","commit_id":"d9536e19598bc9635cae746ad3f6844efbc5cf2b"},{"author":{"_account_id":19158,"name":"Ilya Kutukov","email":"post.ilya@gmail.com","username":"ikutukov"},"change_message_id":"3504cf4d0e18c152229c67ab7f8fe644d3b29bdb","unresolved":false,"context_lines":[{"line_number":303,"context_line":"    keys \u003d list(keys)"},{"line_number":304,"context_line":""},{"line_number":305,"context_line":"    res \u003d StringIO()"},{"line_number":306,"context_line":"    csv_writer \u003d csv.writer(res)"},{"line_number":307,"context_line":"    csv_writer.writerow(keys)"},{"line_number":308,"context_line":"    for obj in data:"},{"line_number":309,"context_line":"        values \u003d []"}],"source_content_type":"text/x-python","patch_set":1,"id":"bacf61ea_5f5a6f51","line":306,"updated":"2016-07-28 15:46:09.000000000","message":"excel dialect?\nhow about unicode support?","commit_id":"d9536e19598bc9635cae746ad3f6844efbc5cf2b"}],"nailgun/nailgun/api/v1/handlers/decorators.py":[{"author":{"_account_id":21013,"name":"Georgy Kibardin","email":"gkibardin@mirantis.com","username":"gkibardin"},"change_message_id":"1f180eef0a36c060dc0cd292ce40409b4deb21f1","unresolved":false,"context_lines":[{"line_number":127,"context_line":"def _serialize_to_csv(data):"},{"line_number":128,"context_line":"    from nailgun.api.v1.handlers.base import BaseHandler"},{"line_number":129,"context_line":"    if not (isinstance(data, list) and"},{"line_number":130,"context_line":"            all(map(lambda x: isinstance(x, dict), data))):"},{"line_number":131,"context_line":"        raise BaseHandler.http(415, repr(data))"},{"line_number":132,"context_line":""},{"line_number":133,"context_line":"    keys \u003d set()"}],"source_content_type":"text/x-python","patch_set":7,"id":"9ad45d7e_fd193489","line":130,"updated":"2016-08-11 09:34:27.000000000","message":"I think list of lists or tuples could also be very well (and even better than dicts) exported to CSV.","commit_id":"0dba5a692f7469ec6dd5a3af7cb6e3c179bf24bd"}],"nailgun/nailgun/api/v1/handlers/deployment_history.py":[{"author":{"_account_id":10959,"name":"Alexander Kislitsky","email":"akislitsky@mirantis.com","username":"akislitsky"},"change_message_id":"43fa4268b5f0cd7e82d153d06c4b5c773d92c341","unresolved":false,"context_lines":[{"line_number":36,"context_line":"    validator \u003d DeploymentHistoryValidator"},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"    def _to_csv(self, data):"},{"line_number":39,"context_line":"        keys \u003d list(data[0].keys())"},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"        res \u003d StringIO()"},{"line_number":42,"context_line":"        csv_writer \u003d csv.writer(res)"}],"source_content_type":"text/x-python","patch_set":3,"id":"bacf61ea_b09a476c","line":39,"updated":"2016-08-01 08:59:49.000000000","message":"I\u0027d prefer to have sorted keys. It is much better for end user to have predictable columns order in the result CSV.","commit_id":"5ba490f167ef3813ff4be792eec2376bfcc7f4b6"},{"author":{"_account_id":12661,"name":"Dmitry Guryanov","email":"dmitry.guryanov@gmail.com","username":"dguryanov"},"change_message_id":"492cfc94ee84b96049f439fa5fbd25d8356dec71","unresolved":false,"context_lines":[{"line_number":36,"context_line":"    validator \u003d DeploymentHistoryValidator"},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"    def _to_csv(self, data):"},{"line_number":39,"context_line":"        keys \u003d list(data[0].keys())"},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"        res \u003d StringIO()"},{"line_number":42,"context_line":"        csv_writer \u003d csv.writer(res)"}],"source_content_type":"text/x-python","patch_set":3,"id":"3ac371cc_b9166356","line":39,"in_reply_to":"bacf61ea_b09a476c","updated":"2016-08-18 19:05:29.000000000","message":"Done","commit_id":"5ba490f167ef3813ff4be792eec2376bfcc7f4b6"},{"author":{"_account_id":10959,"name":"Alexander Kislitsky","email":"akislitsky@mirantis.com","username":"akislitsky"},"change_message_id":"43fa4268b5f0cd7e82d153d06c4b5c773d92c341","unresolved":false,"context_lines":[{"line_number":87,"context_line":"        if \u0027text/csv\u0027 in web.ctx.env.get(\u0027HTTP_ACCEPT\u0027, \u0027\u0027):"},{"line_number":88,"context_line":"            web.header(\u0027Content-Type\u0027, \u0027text/csv\u0027, unique\u003dTrue)"},{"line_number":89,"context_line":"            web.header(\u0027Content-Disposition\u0027,"},{"line_number":90,"context_line":"                       \u0027attachment; filename\u003d\"output.csv\"\u0027)"},{"line_number":91,"context_line":"            ret \u003d self._to_csv(data)"},{"line_number":92,"context_line":"            web.header(\u0027Content-Length\u0027, len(ret))"},{"line_number":93,"context_line":"            return ret"}],"source_content_type":"text/x-python","patch_set":3,"id":"bacf61ea_d0e37ba2","line":90,"updated":"2016-08-01 08:59:49.000000000","message":"I guess it much better to have transaction_id in the result file name. It would be mess of \u0027output(N).csv\u0027 files if we have made several downloads.","commit_id":"5ba490f167ef3813ff4be792eec2376bfcc7f4b6"},{"author":{"_account_id":12661,"name":"Dmitry Guryanov","email":"dmitry.guryanov@gmail.com","username":"dguryanov"},"change_message_id":"492cfc94ee84b96049f439fa5fbd25d8356dec71","unresolved":false,"context_lines":[{"line_number":87,"context_line":"        if \u0027text/csv\u0027 in web.ctx.env.get(\u0027HTTP_ACCEPT\u0027, \u0027\u0027):"},{"line_number":88,"context_line":"            web.header(\u0027Content-Type\u0027, \u0027text/csv\u0027, unique\u003dTrue)"},{"line_number":89,"context_line":"            web.header(\u0027Content-Disposition\u0027,"},{"line_number":90,"context_line":"                       \u0027attachment; filename\u003d\"output.csv\"\u0027)"},{"line_number":91,"context_line":"            ret \u003d self._to_csv(data)"},{"line_number":92,"context_line":"            web.header(\u0027Content-Length\u0027, len(ret))"},{"line_number":93,"context_line":"            return ret"}],"source_content_type":"text/x-python","patch_set":3,"id":"3ac371cc_6b47f24b","line":90,"in_reply_to":"bacf61ea_d0e37ba2","updated":"2016-08-18 19:05:29.000000000","message":"We decided to don\u0027t return as attachment, so no problem with filename anymore.","commit_id":"5ba490f167ef3813ff4be792eec2376bfcc7f4b6"},{"author":{"_account_id":20384,"name":"Nikita Zubkov","email":"zubchick@yandex.ru","username":"zubchick"},"change_message_id":"b1a0b9f51ecf5e188cd0907f13ed41294a5c6893","unresolved":false,"context_lines":[{"line_number":35,"context_line":"    @handle_errors"},{"line_number":36,"context_line":"    @validate"},{"line_number":37,"context_line":"    def GET(self, transaction_id):"},{"line_number":38,"context_line":"        \"\"\":returns: Collection of JSONized DeploymentHistory records."},{"line_number":39,"context_line":""},{"line_number":40,"context_line":"        :http: * 200 (OK)"},{"line_number":41,"context_line":"               * 400 (Bad tasks in given transaction)"}],"source_content_type":"text/x-python","patch_set":15,"id":"1ac06dbe_76d5a8b7","line":38,"range":{"start_line":38,"start_character":35,"end_line":38,"end_character":44},"updated":"2016-08-22 15:51:39.000000000","message":"outdated","commit_id":"bac55ff47039058e42b55324f6521e9f4e520103"},{"author":{"_account_id":18205,"name":"Bulat Gaifullin","email":"gaifullinbf@gmail.com","username":"bgaifullin"},"change_message_id":"59e46bfa929c71ddb52c19c8c69ffd00afdcca93","unresolved":false,"context_lines":[{"line_number":72,"context_line":"        return data"},{"line_number":73,"context_line":""},{"line_number":74,"context_line":"    def get_csv(self, data):"},{"line_number":75,"context_line":"        keys \u003d [\u0027task_name\u0027, \u0027node_id\u0027, \u0027status\u0027, \u0027time_start\u0027, \u0027time_end\u0027]"},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"        res \u003d StringIO()"},{"line_number":78,"context_line":"        csv_writer \u003d csv.writer(res)"}],"source_content_type":"text/x-python","patch_set":19,"id":"1ac06dbe_3d12b109","line":75,"range":{"start_line":75,"start_character":8,"end_line":75,"end_character":12},"updated":"2016-08-23 12:54:37.000000000","message":"It is not good idea to hard-code keys here.","commit_id":"09274625b07e113ef92268276c41a4026ff9ce13"},{"author":{"_account_id":18205,"name":"Bulat Gaifullin","email":"gaifullinbf@gmail.com","username":"bgaifullin"},"change_message_id":"59e46bfa929c71ddb52c19c8c69ffd00afdcca93","unresolved":false,"context_lines":[{"line_number":78,"context_line":"        csv_writer \u003d csv.writer(res)"},{"line_number":79,"context_line":"        csv_writer.writerow(keys)"},{"line_number":80,"context_line":"        for obj in data:"},{"line_number":81,"context_line":"            values \u003d []"},{"line_number":82,"context_line":"            for k in keys:"},{"line_number":83,"context_line":"                values.append(obj.get(k))"},{"line_number":84,"context_line":"            csv_writer.writerow(values)"}],"source_content_type":"text/x-python","patch_set":19,"id":"1ac06dbe_dd60bdd1","line":81,"range":{"start_line":81,"start_character":12,"end_line":81,"end_character":18},"updated":"2016-08-23 12:54:37.000000000","message":"cvs_writer.writerow([obj.get(k) for k in keys])","commit_id":"09274625b07e113ef92268276c41a4026ff9ce13"}]}
