File: common.py

package info (click to toggle)
python-aioapns 4.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 160 kB
  • sloc: python: 835; makefile: 3
file content (115 lines) | stat: -rw-r--r-- 3,093 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import asyncio
from enum import Enum
from typing import Any, Dict, Optional
from uuid import uuid4

PRIORITY_NORMAL = "5"
PRIORITY_HIGH = "10"


class PushType(Enum):
    ALERT = "alert"
    BACKGROUND = "background"
    VOIP = "voip"
    COMPLICATION = "complication"
    FILEPROVIDER = "fileprovider"
    MDM = "mdm"
    LIVEACTIVITY = "liveactivity"


class NotificationRequest:
    __slots__ = (
        "device_token",
        "message",
        "notification_id",
        "time_to_live",
        "priority",
        "collapse_key",
        "push_type",
        "apns_topic",
    )

    def __init__(
        self,
        device_token: str,
        message: Dict[str, Any],
        notification_id: Optional[str] = None,
        time_to_live: Optional[int] = None,
        priority: Optional[int] = None,
        collapse_key: Optional[str] = None,
        push_type: Optional[PushType] = None,
        *,
        apns_topic: Optional[str] = None,
    ) -> None:
        self.device_token = device_token
        self.message = message
        self.notification_id = notification_id or str(uuid4())
        self.time_to_live = time_to_live
        self.priority = priority
        self.collapse_key = collapse_key
        self.push_type = push_type
        self.apns_topic = apns_topic


class NotificationResult:
    __slots__ = ("notification_id", "status", "description", "timestamp")

    def __init__(
        self,
        notification_id: str,
        status: str,
        description: Optional[str] = None,
        timestamp: Optional[int] = None,
    ):
        self.notification_id = notification_id
        self.status = status
        self.description = description
        self.timestamp = timestamp

    @property
    def is_successful(self) -> bool:
        return self.status == APNS_RESPONSE_CODE.SUCCESS


class DynamicBoundedSemaphore(asyncio.BoundedSemaphore):
    _bound_value: int

    @property
    def bound(self) -> int:
        return self._bound_value

    @bound.setter
    def bound(self, new_bound: int) -> None:
        if new_bound > self._bound_value:
            if self._value > 0:
                self._value += new_bound - self._bound_value
            if self._value <= 0:
                for _ in range(new_bound - self._bound_value):
                    self.release()
        elif new_bound < self._bound_value:
            self._value -= self._bound_value - new_bound
        self._bound_value = new_bound

    def release(self) -> None:
        self._value += 1
        if self._value > self._bound_value:
            self._value = self._bound_value
        self._wake_up_next()

    def destroy(self, exc: Exception) -> None:
        while self._waiters:
            waiter = self._waiters.popleft()
            if not waiter.done():
                waiter.set_exception(exc)


class APNS_RESPONSE_CODE:
    SUCCESS = "200"
    BAD_REQUEST = "400"
    FORBIDDEN = "403"
    METHOD_NOT_ALLOWED = "405"
    GONE = "410"
    PAYLOAD_TOO_LARGE = "413"
    TOO_MANY_REQUESTS = "429"
    INTERNAL_SERVER_ERROR = "500"
    SERVICE_UNAVAILABLE = "503"