aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mastodon/Mastodon.py35
-rw-r--r--tests/cassettes/test_server_time.yaml63
-rw-r--r--tests/test_instance.py7
-rw-r--r--tests/test_notifications.py1
-rw-r--r--tests/test_status.py1
5 files changed, 96 insertions, 11 deletions
diff --git a/mastodon/Mastodon.py b/mastodon/Mastodon.py
index 05ebaaa..44e3b52 100644
--- a/mastodon/Mastodon.py
+++ b/mastodon/Mastodon.py
@@ -481,8 +481,7 @@ class Mastodon:
481 # instance() was added in 1.1.0, so our best guess is 1.0.0. 481 # instance() was added in 1.1.0, so our best guess is 1.0.0.
482 version_str = "1.0.0" 482 version_str = "1.0.0"
483 483
484 self.mastodon_major, self.mastodon_minor, self.mastodon_patch = parse_version_string( 484 self.mastodon_major, self.mastodon_minor, self.mastodon_patch = parse_version_string(version_str)
485 version_str)
486 return version_str 485 return version_str
487 486
488 def verify_minimum_version(self, version_str, cached=False): 487 def verify_minimum_version(self, version_str, cached=False):
@@ -503,7 +502,24 @@ class Mastodon:
503 elif major == self.mastodon_major and minor == self.mastodon_minor and patch > self.mastodon_patch: 502 elif major == self.mastodon_major and minor == self.mastodon_minor and patch > self.mastodon_patch:
504 return False 503 return False
505 return True 504 return True
505
506 def get_approx_server_time(self):
507 """
508 Retrieve the approximate server time
509
510 We parse this from the hopefully present "Date" header, but make no effort to compensate for latency.
511 """
512 response = self.__api_request("HEAD", "/", return_response_object=True)
513 print(response.headers)
514 if 'Date' in response.headers:
515 server_time_datetime = dateutil.parser.parse(response.headers['Date'])
506 516
517 # Make sure we're in local time
518 epoch_time = self.__datetime_to_epoch(server_time_datetime)
519 return datetime.datetime.fromtimestamp(epoch_time)
520 else:
521 raise MastodonAPIError("No server time in response.")
522
507 @staticmethod 523 @staticmethod
508 def get_supported_version(): 524 def get_supported_version():
509 """ 525 """
@@ -937,7 +953,7 @@ class Mastodon:
937 953
938 Returns a `card dict`_. 954 Returns a `card dict`_.
939 """ 955 """
940 if self.verify_minimum_version("3.0.0"): 956 if self.verify_minimum_version("3.0.0", cached=True):
941 return self.status(id).card 957 return self.status(id).card
942 else: 958 else:
943 id = self.__unpack_id(id) 959 id = self.__unpack_id(id)
@@ -2139,7 +2155,7 @@ class Mastodon:
2139 """ 2155 """
2140 id = self.__unpack_id(id) 2156 id = self.__unpack_id(id)
2141 2157
2142 if self.verify_minimum_version("2.9.2"): 2158 if self.verify_minimum_version("2.9.2", cached=True):
2143 url = '/api/v1/notifications/{0}/dismiss'.format(str(id)) 2159 url = '/api/v1/notifications/{0}/dismiss'.format(str(id))
2144 self.__api_request('POST', url) 2160 self.__api_request('POST', url)
2145 else: 2161 else:
@@ -2590,14 +2606,14 @@ class Mastodon:
2590 focus = str(focus[0]) + "," + str(focus[1]) 2606 focus = str(focus[0]) + "," + str(focus[1])
2591 2607
2592 if not thumbnail is None: 2608 if not thumbnail is None:
2593 if not self.verify_minimum_version("3.2.0"): 2609 if not self.verify_minimum_version("3.2.0", cached=True):
2594 raise MastodonVersionError( 2610 raise MastodonVersionError(
2595 'Thumbnail requires version > 3.2.0') 2611 'Thumbnail requires version > 3.2.0')
2596 files["thumbnail"] = self.__load_media_file( 2612 files["thumbnail"] = self.__load_media_file(
2597 thumbnail, thumbnail_mime_type) 2613 thumbnail, thumbnail_mime_type)
2598 2614
2599 # Disambiguate URL by version 2615 # Disambiguate URL by version
2600 if self.verify_minimum_version("3.1.4"): 2616 if self.verify_minimum_version("3.1.4", cached=True):
2601 ret_dict = self.__api_request( 2617 ret_dict = self.__api_request(
2602 'POST', '/api/v2/media', files=files, params={'description': description, 'focus': focus}) 2618 'POST', '/api/v2/media', files=files, params={'description': description, 'focus': focus})
2603 else: 2619 else:
@@ -2637,7 +2653,7 @@ class Mastodon:
2637 locals(), ['id', 'thumbnail', 'thumbnail_mime_type']) 2653 locals(), ['id', 'thumbnail', 'thumbnail_mime_type'])
2638 2654
2639 if not thumbnail is None: 2655 if not thumbnail is None:
2640 if not self.verify_minimum_version("3.2.0"): 2656 if not self.verify_minimum_version("3.2.0", cached=True):
2641 raise MastodonVersionError( 2657 raise MastodonVersionError(
2642 'Thumbnail requires version > 3.2.0') 2658 'Thumbnail requires version > 3.2.0')
2643 files = {"thumbnail": self.__load_media_file( 2659 files = {"thumbnail": self.__load_media_file(
@@ -3359,8 +3375,7 @@ class Mastodon:
3359 else: 3375 else:
3360 date_time_utc = date_time.astimezone(pytz.utc) 3376 date_time_utc = date_time.astimezone(pytz.utc)
3361 3377
3362 epoch_utc = datetime.datetime.utcfromtimestamp( 3378 epoch_utc = datetime.datetime.utcfromtimestamp(0).replace(tzinfo=pytz.utc)
3363 0).replace(tzinfo=pytz.utc)
3364 3379
3365 return (date_time_utc - epoch_utc).total_seconds() 3380 return (date_time_utc - epoch_utc).total_seconds()
3366 3381
@@ -3632,7 +3647,7 @@ class Mastodon:
3632 response_object.status_code, 3647 response_object.status_code,
3633 response_object.reason, 3648 response_object.reason,
3634 error_msg) 3649 error_msg)
3635 3650
3636 if return_response_object: 3651 if return_response_object:
3637 return response_object 3652 return response_object
3638 3653
diff --git a/tests/cassettes/test_server_time.yaml b/tests/cassettes/test_server_time.yaml
new file mode 100644
index 0000000..a94b3aa
--- /dev/null
+++ b/tests/cassettes/test_server_time.yaml
@@ -0,0 +1,63 @@
1interactions:
2- request:
3 body: null
4 headers:
5 Accept:
6 - '*/*'
7 Accept-Encoding:
8 - gzip, deflate
9 Authorization:
10 - Bearer __MASTODON_PY_TEST_ACCESS_TOKEN
11 Connection:
12 - keep-alive
13 User-Agent:
14 - tests/v311
15 method: HEAD
16 uri: http://localhost:3000/
17 response:
18 body:
19 string: ''
20 headers:
21 Cache-Control:
22 - max-age=0, public
23 Content-Security-Policy:
24 - 'base-uri ''none''; default-src ''none''; frame-ancestors ''none''; font-src
25 ''self'' http://localhost:3000; img-src ''self'' https: data: blob: http://localhost:3000;
26 style-src ''self'' http://localhost:3000 ''nonce-2+ENJYUdR8BJrDBHHtp0Iw=='';
27 media-src ''self'' https: data: http://localhost:3000; frame-src ''self''
28 https:; manifest-src ''self'' http://localhost:3000; connect-src ''self''
29 data: blob: http://localhost:3000 http://localhost:3000 ws://localhost:4000
30 ws://localhost:3035 http://localhost:3035; script-src ''self'' ''unsafe-inline''
31 ''unsafe-eval'' http://localhost:3000; child-src ''self'' blob: http://localhost:3000;
32 worker-src ''self'' blob: http://localhost:3000'
33 Content-Type:
34 - text/html; charset=utf-8
35 Date:
36 - Thu, 17 Nov 2022 20:42:32 GMT
37 ETag:
38 - W/"9bb3b62cb5fb0388ee3b972a95ee0633"
39 Referrer-Policy:
40 - origin
41 Set-Cookie:
42 - _mastodon_session=S%2F25BrjlEMmL38vg%2FCMcsvHcd8%2BW45HbUkMBwTiqvTgNnzQ%2FhKVYvwORXtqZ5IgNVXl7gMcJ7SxG9y1ks1LN%2Bw3rvgb%2FxECYIlBWY7C3m%2B0aWsWG%2F8iNJsZfHvXlEY3xQxDzenmA2Mw35wRyPiT%2FSUJvwM9I5RtY1iUDsaCPzUbhGFcw3aoGUTdeag37%2FfGsJuG%2F9JsR0jj%2FCgWAlokV8%2Freu8XPUBFFDmjV9SdyFfzsIvP8%2Bd7cAebpCpaqp2DPngNSm8k6xgqXCuMCqpNc09slWQHzfDVqtWPTCMc95SmGpO0DOethwA44F8WbsfX1x5HGml8%3D--x1Ipi2xI5V5ct712--m3eM1Vf8f4oi87fjm0LEvw%3D%3D;
43 path=/; HttpOnly; SameSite=Lax
44 Vary:
45 - Accept
46 X-Content-Type-Options:
47 - nosniff
48 X-Download-Options:
49 - noopen
50 X-Frame-Options:
51 - SAMEORIGIN
52 X-Permitted-Cross-Domain-Policies:
53 - none
54 X-Request-Id:
55 - 9d6b0c84-dff7-481a-a975-c669b8469976
56 X-Runtime:
57 - '0.691929'
58 X-XSS-Protection:
59 - 1; mode=block
60 status:
61 code: 200
62 message: OK
63version: 1
diff --git a/tests/test_instance.py b/tests/test_instance.py
index 2762ecb..5de61f6 100644
--- a/tests/test_instance.py
+++ b/tests/test_instance.py
@@ -1,6 +1,7 @@
1import pytest 1import pytest
2 2
3from mastodon.Mastodon import MastodonVersionError 3from mastodon.Mastodon import MastodonVersionError
4import datetime
4 5
5@pytest.mark.vcr() 6@pytest.mark.vcr()
6def test_instance(api): 7def test_instance(api):
@@ -36,7 +37,11 @@ def test_emoji(api):
36@pytest.mark.vcr() 37@pytest.mark.vcr()
37def test_health(api): 38def test_health(api):
38 assert api.instance_health() == True 39 assert api.instance_health() == True
39 40
41@pytest.mark.vcr()
42def test_server_time(api):
43 assert isinstance(api.get_approx_server_time(), datetime.datetime)
44
40@pytest.mark.vcr() 45@pytest.mark.vcr()
41def test_nodeinfo(api): 46def test_nodeinfo(api):
42 nodeinfo = api.instance_nodeinfo() 47 nodeinfo = api.instance_nodeinfo()
diff --git a/tests/test_notifications.py b/tests/test_notifications.py
index 0be81c6..6e761ce 100644
--- a/tests/test_notifications.py
+++ b/tests/test_notifications.py
@@ -26,6 +26,7 @@ def test_notifications_dismiss_pre_2_9_2(api, api2):
26 try: 26 try:
27 status = api2.status_post('@mastodonpy_test hello!') 27 status = api2.status_post('@mastodonpy_test hello!')
28 notifications = api.notifications() 28 notifications = api.notifications()
29 api.verify_minimum_version("2.9.2", cached=False)
29 api.notifications_dismiss(notifications[0]) 30 api.notifications_dismiss(notifications[0])
30 finally: 31 finally:
31 if not status is None: 32 if not status is None:
diff --git a/tests/test_status.py b/tests/test_status.py
index 7e30362..f45634f 100644
--- a/tests/test_status.py
+++ b/tests/test_status.py
@@ -53,6 +53,7 @@ def test_status_card_pre_2_9_2(api):
53 import time 53 import time
54 status = api.status_post("http://example.org/") 54 status = api.status_post("http://example.org/")
55 time.sleep(5) # Card generation may take time 55 time.sleep(5) # Card generation may take time
56 api.verify_minimum_version("2.9.2", cached=False)
56 card = api.status_card(status['id']) 57 card = api.status_card(status['id'])
57 try: 58 try:
58 assert card 59 assert card
Powered by cgit v1.2.3 (git 2.41.0)