kopia lustrzana https://github.com/dsblank/activitypub
Refactor expand/parse; WIP fetch
rodzic
7a140e26c5
commit
88e1881cda
|
@ -33,7 +33,7 @@ class ActivityPubBase():
|
|||
if attr_name.startswith("ap_"):
|
||||
attr = getattr(self, attr_name)
|
||||
if isinstance(attr, str) and "$" in attr:
|
||||
dependencies[attr_name[3:]] = {x[1:] for x in self.parse(attr)
|
||||
dependencies[attr_name[3:]] = {x[1:] for x in self.manager.parse(attr)
|
||||
if x.startswith("$") and x[1:] != attr_name[3:]}
|
||||
## Now, replace them in order:
|
||||
for attr_name in self.topological_sort(dependencies):
|
||||
|
@ -46,7 +46,7 @@ class ActivityPubBase():
|
|||
if attr is None:
|
||||
raise Exception("variable depends on field that is empty: %s" % attr_name)
|
||||
if isinstance(attr, str) and "$" in attr:
|
||||
setattr(self, attr_name, self.expand_defaults(attr))
|
||||
setattr(self, attr_name, self.manager.expand_defaults(attr))
|
||||
|
||||
def topological_sort(self, data):
|
||||
"""
|
||||
|
@ -71,49 +71,6 @@ class ActivityPubBase():
|
|||
for item, dep in data.items()
|
||||
if item not in ordered}
|
||||
|
||||
def parse(self, string):
|
||||
"""
|
||||
Parse a string delimited by non-alpha, non-$ symbols.
|
||||
|
||||
>>> from activitypub import Manager
|
||||
>>> m = Manager()
|
||||
>>> p = m.Person()
|
||||
>>> p.parse("apple/banana/$variable")
|
||||
['apple', 'banana', '$variable']
|
||||
"""
|
||||
retval = []
|
||||
current = []
|
||||
for s in string:
|
||||
if s.isalpha() or (s in ["$"] and len(current) == 0):
|
||||
current.append(s)
|
||||
else:
|
||||
if current:
|
||||
retval.append("".join(current))
|
||||
if s == "$":
|
||||
current = ["$"]
|
||||
else:
|
||||
current = []
|
||||
if current:
|
||||
retval.append("".join(current))
|
||||
return retval
|
||||
|
||||
def expand_defaults(self, string):
|
||||
"""
|
||||
Expand a string with defaults.
|
||||
"""
|
||||
for key in self.manager.defaults:
|
||||
if key.startswith("$"):
|
||||
if callable(self.manager.defaults[key]):
|
||||
string = string.replace(key, self.manager.defaults[key]())
|
||||
else:
|
||||
string = string.replace(key, self.manager.defaults[key])
|
||||
for key in self.parse(string):
|
||||
if key.startswith("$"):
|
||||
if getattr(self, "ap_" + key[1:]) is None:
|
||||
raise Exception("expansion requires %s" % key[1:])
|
||||
string = string.replace(key, getattr(self, "ap_" + key[1:]))
|
||||
return string
|
||||
|
||||
def to_dict(self):
|
||||
"""
|
||||
Convert object to JSON format.
|
||||
|
|
|
@ -194,9 +194,10 @@ class DummyTable(Table):
|
|||
>>> table.find({"c": 1, "d": 2}).count()
|
||||
2
|
||||
"""
|
||||
row = copy.deepcopy(row) # expensive, but prevents errors
|
||||
if row.get("_id", None) is None:
|
||||
row["_id"] = ObjectId()
|
||||
self.data.append(copy.deepcopy(row))
|
||||
self.data.append(row)
|
||||
|
||||
def find(self, query=None, limit=None):
|
||||
"""
|
||||
|
|
|
@ -11,6 +11,8 @@ class Manager():
|
|||
>>> manager = Manager(database=db)
|
||||
>>>
|
||||
"""
|
||||
app_name = "activitypub"
|
||||
version = "1.0.0"
|
||||
def __init__(self, context=None, defaults=None, database=None):
|
||||
from .classes import ActivityPubBase
|
||||
self.callback = lambda box, activity_id: None
|
||||
|
@ -53,6 +55,54 @@ class Manager():
|
|||
"Note.id": "$attributedTo/note/$id",
|
||||
}
|
||||
|
||||
def user_agent(self):
|
||||
return "%s (%s/%s; +%s)" % (requests.utils.default_user_agent(),
|
||||
self.app_name,
|
||||
self.version,
|
||||
self.expand_defaults("$SCHEME/$HOST"))
|
||||
|
||||
def expand_defaults(self, obj, string):
|
||||
"""
|
||||
Expand a string with defaults.
|
||||
"""
|
||||
for key in self.defaults:
|
||||
if key.startswith("$"):
|
||||
if callable(self.defaults[key]):
|
||||
string = string.replace(key, self.defaults[key]())
|
||||
else:
|
||||
string = string.replace(key, self.defaults[key])
|
||||
for key in self.parse(string):
|
||||
if key.startswith("$"):
|
||||
if getattr(obj, "ap_" + key[1:]) is None:
|
||||
raise Exception("expansion requires %s" % key[1:])
|
||||
string = string.replace(key, getattr(obj, "ap_" + key[1:]))
|
||||
return string
|
||||
|
||||
def parse(self, string):
|
||||
"""
|
||||
Parse a string delimited by non-alpha, non-$ symbols.
|
||||
|
||||
>>> from activitypub import Manager
|
||||
>>> m = Manager()
|
||||
>>> m.parse("apple/banana/$variable")
|
||||
['apple', 'banana', '$variable']
|
||||
"""
|
||||
retval = []
|
||||
current = []
|
||||
for s in string:
|
||||
if s.isalpha() or (s in ["$"] and len(current) == 0):
|
||||
current.append(s)
|
||||
else:
|
||||
if current:
|
||||
retval.append("".join(current))
|
||||
if s == "$":
|
||||
current = ["$"]
|
||||
else:
|
||||
current = []
|
||||
if current:
|
||||
retval.append("".join(current))
|
||||
return retval
|
||||
|
||||
def from_dict(self, data):
|
||||
from .classes import ActivityPubBase
|
||||
return ActivityPubBase.from_dict(data)
|
||||
|
@ -65,6 +115,8 @@ class Manager():
|
|||
def on_post_to_box(self, box, activity):
|
||||
"""
|
||||
manager.on_post_to_box("inbox", activity)
|
||||
manager.on_post_to_box("outbox", activity)
|
||||
manager.on_post_to_box("replies", reply)
|
||||
"""
|
||||
self.database.activities.insert_one(
|
||||
{
|
||||
|
@ -110,3 +162,34 @@ class Manager():
|
|||
return [doc["activity"]["object"]
|
||||
for doc in self.database.activities.find(q)]
|
||||
|
||||
def get_iri(self, iri):
|
||||
if iri.startswith(self.expand_defaults("$SCHEME/$HOST")):
|
||||
## get from table
|
||||
## self.database.activity.find()
|
||||
## TODO: WIP
|
||||
pass
|
||||
else:
|
||||
try:
|
||||
response = requests.get(
|
||||
iri,
|
||||
headers={
|
||||
"User-Agent": self.user_agent(),
|
||||
"Accept": "application/activity+json",
|
||||
},
|
||||
timeout=10,
|
||||
allow_redirects=False,
|
||||
**kwargs)
|
||||
except:
|
||||
raise Exception("unable to fetch uri")
|
||||
return self.handle(response)
|
||||
|
||||
def handle_response(self, response):
|
||||
if response.status_code == 404:
|
||||
raise Exception("iri is not found")
|
||||
elif response.status_code == 410:
|
||||
raise Exception("iri is gone")
|
||||
elif response.status_code in [500, 502, 503]:
|
||||
raise Exception("unable to fetch; server error")
|
||||
response.raise_for_status()
|
||||
return response.json()
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue