From 20a640eb7ee4628979252743c567d31cab4dbb91 Mon Sep 17 00:00:00 2001 From: Lorenz Diener Date: Sun, 28 Apr 2019 20:38:49 +0200 Subject: [PATCH] Fix the isoformat formatter --- mastodon/Mastodon.py | 19 +++++++- tests/cassettes/test_scheduled_status.yaml | 52 +++++++++++----------- 2 files changed, 43 insertions(+), 28 deletions(-) diff --git a/mastodon/Mastodon.py b/mastodon/Mastodon.py index c037ceb..679aac8 100644 --- a/mastodon/Mastodon.py +++ b/mastodon/Mastodon.py @@ -1381,7 +1381,7 @@ class Mastodon: in_reply_to_id = self.__unpack_id(in_reply_to_id) if scheduled_at != None: - scheduled_at = scheduled_at.astimezone(pytz.utc).isoformat() + scheduled_at = self.__consistent_isoformat_utc(scheduled_at) params_initial = locals() @@ -1585,7 +1585,7 @@ class Mastodon: Returns a `scheduled toot dict`_ """ - scheduled_at = scheduled_at.astimezone(pytz.utc).isoformat() + scheduled_at = self.__consistent_isoformat_utc(scheduled_at) id = self.__unpack_id(id) params = self.__generate_params(locals(), ['id']) url = '/api/v1/scheduled_statuses/{0}'.format(str(id)) @@ -2406,12 +2406,27 @@ class Mastodon: @staticmethod def __json_hooks(json_object): + """ + All the json hooks. Used in request parsing. + """ json_object = Mastodon.__json_strnum_to_bignum(json_object) json_object = Mastodon.__json_date_parse(json_object) json_object = Mastodon.__json_truefalse_parse(json_object) json_object = Mastodon.__json_allow_dict_attrs(json_object) return json_object + @staticmethod + def __consistent_isoformat_utc(datetime_val): + """ + Function that does what isoformat does but it actually does the same + every time instead of randomly doing different things on some systems + and also it represents that time as the equivalent UTC time. + """ + isotime = datetime_val.astimezone(pytz.utc).strftime("%Y-%m-%dT%H:%M:%S%z") + if isotime[-2] != ":": + isotime = isotime[:-2] + ":" + isotime[-2:] + return isotime + def __api_request(self, method, endpoint, params={}, files={}, headers={}, access_token_override=None, do_ratelimiting=True): """ Internal API request helper. diff --git a/tests/cassettes/test_scheduled_status.yaml b/tests/cassettes/test_scheduled_status.yaml index 04fec5a..c0843ea 100644 --- a/tests/cassettes/test_scheduled_status.yaml +++ b/tests/cassettes/test_scheduled_status.yaml @@ -12,12 +12,12 @@ interactions: method: POST uri: http://localhost:3000/api/v1/statuses response: - body: {string: '{"id":"18","scheduled_at":"4000-01-01T11:33:14.000Z","params":{"text":"please + body: {string: '{"id":"19","scheduled_at":"4000-01-01T11:33:14.000Z","params":{"text":"please ensure adequate headroom","media_ids":null,"sensitive":null,"spoiler_text":null,"visibility":null,"scheduled_at":null,"poll":null,"idempotency":null,"in_reply_to_id":null,"application_id":1234567890123456},"media_attachments":[]}'} headers: Cache-Control: ['max-age=0, private, must-revalidate'] Content-Type: [application/json; charset=utf-8] - ETag: [W/"55a21b75b918b4af7fdb4b8d90f7d6e7"] + ETag: [W/"869b974553c558251472c898ce2b4b30"] Referrer-Policy: [strict-origin-when-cross-origin] Transfer-Encoding: [chunked] Vary: ['Accept-Encoding, Origin'] @@ -25,8 +25,8 @@ interactions: X-Download-Options: [noopen] X-Frame-Options: [SAMEORIGIN] X-Permitted-Cross-Domain-Policies: [none] - X-Request-Id: [0a550963-ff3c-46a1-b8b5-5e40dd64c746] - X-Runtime: ['0.042131'] + X-Request-Id: [268bf716-1ca5-4e0a-a1bf-9c06b23b0c6f] + X-Runtime: ['0.064617'] X-XSS-Protection: [1; mode=block] content-length: ['307'] status: {code: 200, message: OK} @@ -41,14 +41,14 @@ interactions: Content-Type: [application/x-www-form-urlencoded] User-Agent: [python-requests/2.18.4] method: PUT - uri: http://localhost:3000/api/v1/scheduled_statuses/18 + uri: http://localhost:3000/api/v1/scheduled_statuses/19 response: - body: {string: '{"id":"18","scheduled_at":"4000-01-01T11:23:14.000Z","params":{"poll":null,"text":"please + body: {string: '{"id":"19","scheduled_at":"4000-01-01T11:23:14.000Z","params":{"poll":null,"text":"please ensure adequate headroom","media_ids":null,"sensitive":null,"visibility":null,"idempotency":null,"scheduled_at":null,"spoiler_text":null,"application_id":1234567890123456,"in_reply_to_id":null},"media_attachments":[]}'} headers: Cache-Control: ['max-age=0, private, must-revalidate'] Content-Type: [application/json; charset=utf-8] - ETag: [W/"4211b1c063163578d72e0d9fee015aac"] + ETag: [W/"d0254474867b88e60e2a7d1754ab928c"] Referrer-Policy: [strict-origin-when-cross-origin] Transfer-Encoding: [chunked] Vary: ['Accept-Encoding, Origin'] @@ -56,8 +56,8 @@ interactions: X-Download-Options: [noopen] X-Frame-Options: [SAMEORIGIN] X-Permitted-Cross-Domain-Policies: [none] - X-Request-Id: [00ce2af1-000d-40fc-9765-9661b4fda8a5] - X-Runtime: ['0.023685'] + X-Request-Id: [dcd95b0e-7116-454a-9ba4-122de3a6913e] + X-Runtime: ['0.047892'] X-XSS-Protection: [1; mode=block] content-length: ['307'] status: {code: 200, message: OK} @@ -72,13 +72,13 @@ interactions: method: GET uri: http://localhost:3000/api/v1/scheduled_statuses response: - body: {string: '[{"id":"18","scheduled_at":"4000-01-01T11:23:14.000Z","params":{"poll":null,"text":"please + body: {string: '[{"id":"19","scheduled_at":"4000-01-01T11:23:14.000Z","params":{"poll":null,"text":"please ensure adequate headroom","media_ids":null,"sensitive":null,"visibility":null,"idempotency":null,"scheduled_at":null,"spoiler_text":null,"application_id":1234567890123456,"in_reply_to_id":null},"media_attachments":[]}]'} headers: Cache-Control: ['max-age=0, private, must-revalidate'] Content-Type: [application/json; charset=utf-8] - ETag: [W/"214cbc9aaa46dbb18c2d5a1437d145d5"] - Link: ['; rel="prev"'] + ETag: [W/"f942fa659c7f711edf601fd02eb28f2f"] + Link: ['; rel="prev"'] Referrer-Policy: [strict-origin-when-cross-origin] Transfer-Encoding: [chunked] Vary: ['Accept-Encoding, Origin'] @@ -86,8 +86,8 @@ interactions: X-Download-Options: [noopen] X-Frame-Options: [SAMEORIGIN] X-Permitted-Cross-Domain-Policies: [none] - X-Request-Id: [9790aeb5-05f9-4d77-87bb-05e7add83909] - X-Runtime: ['0.017555'] + X-Request-Id: [97962c99-e4a1-4bd2-849d-51f48544c67c] + X-Runtime: ['0.022832'] X-XSS-Protection: [1; mode=block] content-length: ['309'] status: {code: 200, message: OK} @@ -100,14 +100,14 @@ interactions: Connection: [keep-alive] User-Agent: [python-requests/2.18.4] method: GET - uri: http://localhost:3000/api/v1/scheduled_statuses/18 + uri: http://localhost:3000/api/v1/scheduled_statuses/19 response: - body: {string: '{"id":"18","scheduled_at":"4000-01-01T11:23:14.000Z","params":{"poll":null,"text":"please + body: {string: '{"id":"19","scheduled_at":"4000-01-01T11:23:14.000Z","params":{"poll":null,"text":"please ensure adequate headroom","media_ids":null,"sensitive":null,"visibility":null,"idempotency":null,"scheduled_at":null,"spoiler_text":null,"application_id":1234567890123456,"in_reply_to_id":null},"media_attachments":[]}'} headers: Cache-Control: ['max-age=0, private, must-revalidate'] Content-Type: [application/json; charset=utf-8] - ETag: [W/"4211b1c063163578d72e0d9fee015aac"] + ETag: [W/"d0254474867b88e60e2a7d1754ab928c"] Referrer-Policy: [strict-origin-when-cross-origin] Transfer-Encoding: [chunked] Vary: ['Accept-Encoding, Origin'] @@ -115,8 +115,8 @@ interactions: X-Download-Options: [noopen] X-Frame-Options: [SAMEORIGIN] X-Permitted-Cross-Domain-Policies: [none] - X-Request-Id: [720a388c-96a2-4159-951b-5e24012646be] - X-Runtime: ['0.015976'] + X-Request-Id: [f95378c9-b0c8-4c93-bf1e-f993db396b98] + X-Runtime: ['0.030762'] X-XSS-Protection: [1; mode=block] content-length: ['307'] status: {code: 200, message: OK} @@ -130,13 +130,13 @@ interactions: Content-Length: ['0'] User-Agent: [python-requests/2.18.4] method: DELETE - uri: http://localhost:3000/api/v1/scheduled_statuses/18 + uri: http://localhost:3000/api/v1/scheduled_statuses/19 response: body: {string: '{}'} headers: Cache-Control: ['max-age=0, private, must-revalidate'] Content-Type: [application/json; charset=utf-8] - ETag: [W/"a97c68bcd1ca704122f54447e96fcb7a"] + ETag: [W/"0990eb85ee6e415913216239571d30e5"] Referrer-Policy: [strict-origin-when-cross-origin] Transfer-Encoding: [chunked] Vary: ['Accept-Encoding, Origin'] @@ -144,8 +144,8 @@ interactions: X-Download-Options: [noopen] X-Frame-Options: [SAMEORIGIN] X-Permitted-Cross-Domain-Policies: [none] - X-Request-Id: [b57c0e70-97bf-4777-8272-e0d06799291d] - X-Runtime: ['0.025188'] + X-Request-Id: [ed7c8df2-5a65-474e-81ec-9f4ef3f50b3d] + X-Runtime: ['0.028344'] X-XSS-Protection: [1; mode=block] content-length: ['2'] status: {code: 200, message: OK} @@ -164,7 +164,7 @@ interactions: headers: Cache-Control: ['max-age=0, private, must-revalidate'] Content-Type: [application/json; charset=utf-8] - ETag: [W/"a3f1c7eff68af7234bcf2a8d4233d0c1"] + ETag: [W/"cc6e706f1723e565ab0b83aab7be53aa"] Referrer-Policy: [strict-origin-when-cross-origin] Transfer-Encoding: [chunked] Vary: ['Accept-Encoding, Origin'] @@ -172,8 +172,8 @@ interactions: X-Download-Options: [noopen] X-Frame-Options: [SAMEORIGIN] X-Permitted-Cross-Domain-Policies: [none] - X-Request-Id: [e1152c40-5d88-410a-bd73-cb0c7dbc3f92] - X-Runtime: ['0.014370'] + X-Request-Id: [6d71010e-5cc0-4029-a19b-67cac6b8f5bc] + X-Runtime: ['0.017476'] X-XSS-Protection: [1; mode=block] content-length: ['2'] status: {code: 200, message: OK}