-
Notifications
You must be signed in to change notification settings - Fork 26
/
Copy pathrentry.py
166 lines (131 loc) · 5.43 KB
/
rentry.py
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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#!/usr/bin/env python3
import getopt
import http.cookiejar
import sys
import urllib.parse
import urllib.request
from http.cookies import SimpleCookie
from json import loads as json_loads
from os import environ
from dotenv import load_dotenv, dotenv_values
load_dotenv()
env = dotenv_values()
_headers = {"Referer": f"{env['BASE_PROTOCOL']}{env['BASE_URL']}"}
class UrllibClient:
"""Simple HTTP Session Client, keeps cookies."""
def __init__(self):
self.cookie_jar = http.cookiejar.CookieJar()
self.opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(self.cookie_jar))
urllib.request.install_opener(self.opener)
def get(self, url, headers={}):
request = urllib.request.Request(url, headers=headers)
return self._request(request)
def post(self, url, data=None, headers={}):
postdata = urllib.parse.urlencode(data).encode()
request = urllib.request.Request(url, postdata, headers)
return self._request(request)
def _request(self, request):
response = self.opener.open(request)
response.status_code = response.getcode()
response.data = response.read().decode('utf-8')
return response
def raw(url):
client = UrllibClient()
endpoint = f"{env['BASE_PROTOCOL']}{env['BASE_URL']}" + '/api/raw/{}'.format(url)
print(endpoint)
return json_loads(client.get(endpoint).data)
def new(url, edit_code, text):
client, cookie = UrllibClient(), SimpleCookie()
cookie.load(vars(client.get(f"{env['BASE_PROTOCOL']}{env['BASE_URL']}"))['headers']['Set-Cookie'])
csrftoken = cookie['csrftoken'].value
payload = {
'csrfmiddlewaretoken': csrftoken,
'url': url,
'edit_code': edit_code,
'text': text
}
return json_loads(client.post(f"{env['BASE_PROTOCOL']}{env['BASE_URL']}" + '/api/new', payload, headers=_headers).data)
def edit(url, edit_code, text):
client, cookie = UrllibClient(), SimpleCookie()
cookie.load(vars(client.get(f"{env['BASE_PROTOCOL']}{env['BASE_URL']}"))['headers']['Set-Cookie'])
csrftoken = cookie['csrftoken'].value
payload = {
'csrfmiddlewaretoken': csrftoken,
'edit_code': edit_code,
'text': text
}
return json_loads(client.post(f"{env['BASE_PROTOCOL']}{env['BASE_URL']}" + '/api/edit/{}'.format(url), payload, headers=_headers).data)
def usage():
print('''
Usage: rentry {new | edit | raw} {-h | --help} {-u | --url} {-p | --edit-code} text
Commands:
new create a new entry
edit edit an existing entry
raw get raw markdown text of an existing entry
Options:
-h, --help show this help message and exit
-u, --url URL url for the entry, random if not specified
-p, --edit-code EDIT-CODE edit code for the entry, random if not specified
Examples:
rentry new 'markdown text' # new entry with random url and edit code
rentry new -p pw -u example 'text' # with custom edit code and url
rentry edit -p pw -u example 'text' # edit the example entry
cat FILE | rentry new # read from FILE and paste it to rentry
cat FILE | rentry edit -p pw -u example # read from FILE and edit the example entry
rentry raw -u example # get raw markdown text
rentry raw -u https://rentry.co/example # -u accepts absolute and relative urls
''')
if __name__ == '__main__':
try:
environ.pop('POSIXLY_CORRECT', None)
opts, args = getopt.gnu_getopt(sys.argv[1:], "hu:p:", ["help", "url=", "edit-code="])
except getopt.GetoptError as e:
sys.exit("error: {}".format(e))
command, url, edit_code, text = None, '', '', None
for o, a in opts:
if o in ("-h", "--help"):
usage()
sys.exit()
elif o in ("-u", "--url"):
url = urllib.parse.urlparse(a).path.strip('/')
elif o in ("-p", "--edit-code"):
edit_code = a
command = (args[0:1] or [None])[0]
command or sys.exit(usage())
command in ['new', 'edit', 'raw'] or sys.exit('error: command must be new, edit or raw')
text = (args[1:2] or [None])[0]
if not text and command != 'raw':
text = sys.stdin.read().strip()
text or sys.exit('error: text is required')
if command == 'new':
response = new(url, edit_code, text)
if response['status'] != '200':
print('error: {}'.format(response['content']))
try:
for i in response['errors'].split('.'):
i and print(i)
sys.exit(1)
except:
sys.exit(1)
else:
print('Url: {}\nEdit code: {}'.format(response['url'], response['edit_code']))
elif command == 'edit':
url or sys.exit('error: url is required')
edit_code or sys.exit('error: edit code is required')
response = edit(url, edit_code, text)
if response['status'] != '200':
print('error: {}'.format(response['content']))
try:
for i in response['errors'].split('.'):
i and print(i)
sys.exit(1)
except:
sys.exit(1)
else:
print('Ok')
elif command == 'raw':
url or sys.exit('error: url is required')
response = raw(url)
if response['status'] != '200':
sys.exit('error: {}'.format(response['content']))
print(response['content'])