-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpastebin.py
More file actions
140 lines (117 loc) · 4.26 KB
/
Copy pathpastebin.py
File metadata and controls
140 lines (117 loc) · 4.26 KB
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
"""
Pastebin manipulation module.
Based on [this code](https://pastebin.com/asRbutde).
"""
from typing import Union
import requests
class PastebinNetworkError(Exception):
"""
Exception raised when a network request fails.
"""
message_format = "{r.status_code}"
def __init__(self, r):
super().__init__(self.message_format.format(r=r))
self.r = r
class PastebinLogInError(PastebinNetworkError):
"""
Exception raised when log in fails.
"""
message_format = "error logging in: {r.status_code}"
class PastebinPasteError(PastebinNetworkError):
"""
Exception raised when sending a paste fails.
"""
message_format = "error sending a paste: {r.status_code}"
class Pastebin:
"""
Pastebin manipulation class.
"""
privacy_arguments = {
"public": 0, "unlisted": 1, "private": 2, # Originals
"pub": 0, "u": 1, "unl": 1, "priv": 2, # Abbreviated
}
def __init__(self, dev_key, username, password, debug=False):
self.dev_key = dev_key
self.username = username
self.password = password
self.debug = debug
self._api_user_key = None
@property
def api_user_key(self) -> str:
"""
Return API user key, newly created or cached from a previous call.
:return: API user key, required by other API calls.
"""
if self._api_user_key is None:
data = {
"api_dev_key": self.dev_key,
"api_user_name": self.username,
"api_user_password": self.password,
}
r = requests.post(
"https://pastebin.com/api/api_login.php", data=data,
)
if 200 <= r.status_code <= 299:
self._api_user_key = r.text
if self.debug:
print(f"Login status: OK/{r.status_code}")
print(f"User token: {self._api_user_key}")
else:
if self.debug:
print(f"Login status: {r.status_code}")
raise PastebinLogInError(r)
return self._api_user_key
def paste(
self,
title: str,
text: str,
*,
text_format: str = "text",
expire_date: str = "N",
privacy: Union[int, str] = "private",
) -> str:
"""
Send a paste to Pastebin.
:param title: The title of the paste.
:param text: The text to be pasted.
:param text_format: The format of the pasted text. A list of valid
values can be found [here](https://pastebin.com/doc_api#5).
:param expire_date: The time when the paste should expire, as
explained [here](https://pastebin.com/doc_api#6).
:param privacy: If `int` (the meanings of these values are described
[here](https://pastebin.com/doc_api#7)), this is used as given.
There are no restrictions imposed, allowing the use of any privacy
values that Pastebin might add in the future. If `str`, it is
mapped via `self.privacy_arguments` dictionary.
:return: The URL of the new paste.
"""
try:
if not isinstance(privacy, int):
privacy = self.privacy_arguments[privacy.lower()]
except (AttributeError, KeyError):
allowed = ", ".join(
repr(key) for key in sorted(self.privacy_arguments)
)
raise ValueError(
f"invalid privacy value {repr(privacy)} [allowed: {allowed}]",
)
data = {
"api_option": "paste",
"api_dev_key": self.dev_key,
"api_paste_name": title,
"api_paste_code": text,
"api_paste_expire_date": expire_date,
"api_user_key": self.api_user_key,
"api_paste_format": text_format,
"api_paste_private": privacy,
}
r = requests.post("https://pastebin.com/api/api_post.php", data=data)
if 200 <= r.status_code < 299:
if self.debug:
print("Paste send: OK/200")
print("Paste URL: ", r.text)
return r.text
else:
if self.debug:
print(f"Paste send: {r.status_code}")
raise PastebinPasteError(r)