-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsender.py
53 lines (43 loc) · 1.97 KB
/
sender.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
from rdflib import Graph
import requests
import ipaddress
import json
import socket
from urllib.parse import urlparse
from .base import BaseLDN
class Sender(BaseLDN):
def __init__(self, **kwargs):
super(self.__class__, self).__init__(**kwargs)
self.allow_localhost = kwargs.get('allow_localhost', False)
def __accept_post_options(self, inbox, **kwargs):
r = requests.options(inbox, **kwargs)
if r.status_code == requests.codes.ok and 'accept-post' in r.headers:
if self.JSON_LD in r.headers['accept-post']:
return self.JSON_LD
for content_type in r.headers['accept-post'].split(','):
return self.content_type_to_mime_type(content_type)
def __is_localhost(self, inbox):
return ipaddress.ip_address(socket.gethostbyname(
urlparse(inbox).hostname)).is_loopback
def __post_message(self, inbox, data, content_type, **kwargs):
if self.allow_localhost or not self.__is_localhost(inbox):
headers = kwargs.pop("headers", dict())
headers['content-type'] = content_type
r = requests.post(inbox, data=data, headers=headers, **kwargs)
r.raise_for_status()
else:
raise ValueError("Invalid local inbox.")
def send(self, inbox, data, **kwargs):
"""Send the provided data to an inbox."""
if isinstance(data, dict) or isinstance(data, list):
self.__post_message(inbox, json.dumps(data), self.JSON_LD,
**kwargs)
elif isinstance(data, str):
self.__post_message(inbox, data, self.JSON_LD, **kwargs)
elif isinstance(data, Graph):
ct = self.__accept_post_options(inbox, **kwargs) or self.JSON_LD
self.__post_message(inbox, data.serialize(format=ct), ct,
**kwargs)
else:
raise TypeError(
"You cannot send data of type {}.".format(type(data)))