granary package
Reference documentation.
as1
Utilities for ActivityStreams 1 objects.
- object_type(obj)[source]
Returns the object type, or the verb if it’s an activity object.
Details: http://activitystrea.ms/specs/json/1.0/#activity-object
- get_object(obj, field='object')[source]
Extracts and returns a field value as an object.
If the field value is a string, returns an object with it as the id, eg
{'id': val}. If the field value is a list, returns the first element.
- get_objects(obj, field='object')[source]
Extracts and returns a field’s values as objects.
If a field value is a string, generates an object with it as the id, eg
{'id': val}.
- get_owner(obj)[source]
Returns an object’s author or actor.
Prefers author, then actor. If that’s an object, returns its id, if available. If neither field exists, but
obj.objectTypeis inACTOR_TYPES, returns its own id, if available.For posts, updates, and deletes, falls back to the inner object’s owner if the outer activity has no actor.
- get_url(obj)[source]
Returns the url field’s first text value, or
''.Somewhat duplicates
microformats2.get_text().
- get_ids(obj, field)[source]
Extracts and returns a given field’s values as ids.
Returns string values as is. For dict values, returns their inner
idorurlfield value, in that order of precedence.
- get_id(obj, field)[source]
Extracts and returns a given field’s id value.
Returns a string value as is. For dict values, returns its inner
id.
- merge_by_id(obj, field, new)[source]
Merges new items by id into a field in an existing AS1 object, in place.
Merges new items by id into the given field. If it exists, it must be a list. Requires all existing and new items in the field to have ids.
- is_public(obj, unlisted=True)[source]
Returns True if the object is public, False if private, None if unknown.
…according to the Audience Targeting extension: http://activitystrea.ms/specs/json/targeting/1.0/
Expects values generated by this library:
objectTypegroup,alias@public,@unlisted, or@private.Also, important point: this defaults to True, ie public. Bridgy depends on that and prunes the to field from stored activities in Response objects (in
bridgy/util.prune_activity). If the default here ever changes, be sure to update Bridgy’s code.
- recipient_if_dm(obj, actor=None)[source]
If
objis a DM, returns the recipient actor’s id.DMs are
note``s addressed to a single recipient, ie ``tohas one value andcc,bcc, andbtohave none.If
objisn’t a DM, returns None.Those fields are based on the Audience Targeting extension: http://activitystrea.ms/specs/json/targeting/1.0/
- is_dm(obj, actor=None)[source]
Returns True if the object is a DM, ie addressed to a single recipient.
See
recipient_if_dm()for details.
- is_audience(val)[source]
Returns True if val is a “special” AS1 or AS2 audience, eg “public.”
See the AS1 Audience Targeting extension and AS2 spec: * http://activitystrea.ms/specs/json/targeting/1.0/ * https://www.w3.org/TR/activitystreams-vocabulary/#dfn-audience
- add_rsvps_to_event(event, rsvps)[source]
Adds RSVP objects to an event’s attending fields, in place.
- activity_changed(before, after, inReplyTo=True, log=False)[source]
Returns whether two activities or objects differ meaningfully.
Only compares a few fields:
objectType,verb,displayName`, ``content,summary,location, andimage. Notably does not compareauthor,published, orupdated.
- original_post_discovery(activity, domains=None, include_redirect_sources=True, include_reserved_hosts=True, max_redirect_fetches=None, **kwargs)[source]
Discovers original post links.
This is a variation on http://indiewebcamp.com/original-post-discovery . It differs in that it finds multiple candidate links instead of one, and it doesn’t bother looking for MF2 (etc) markup because the silos don’t let you input it. More background: https://github.com/snarfed/bridgy/issues/51#issuecomment-136018857
Original post candidates come from the
upstreamDuplicates,attachments, andtagsfields, as well as links and permashortlinks/permashortcitations in the text content.- Parameters:
activity (dict) – activity
domains (sequence of str) – these domains will be considered original and stored in
upstreamDuplicates. (Permashortcitations are exempt.)include_redirect_sources (bool) – whether to include URLs that redirect as well as their final destination URLs
include_reserved_hosts (bool) – whether to include domains on reserved TLDs (eg foo.example) and local hosts (eg http://foo.local/, http://my-server/)
max_redirect_fetches (int) – if specified, only make up to this many HTTP fetches to resolve redirects.
kwargs – passed to
requests.head()when following redirects
- Returns:
(original post URLs, mentions)
- Return type:
- prefix_urls(activity, field, prefix)[source]
Adds a prefix to all matching URL fields, eg to inject a caching proxy.
Generally used with the
imageorstreamfields. For example:>>> prefix_urls({'actor': {'image': 'http://image'}}, 'image', 'https://proxy/') {'actor': {'image': 'https://proxy/http://image'}}
Skips any URL fields that already start with the prefix. URLs are not URL-encoded before adding the prefix. (This is currently used with our caching-proxy Cloudflare worker and https://cloudimage.io/ , neither of which URL-decodes.)
- targets(obj)[source]
Collects an AS1 activity or object’s targets.
This is all ids/URLs that are direct “targets” of the activity, eg:
the post it’s replying to
the post it’s sharing
the post it’s reacting to
the post it’s quoting
the actor or other object it’s tagging
the event it’s inviting someone to
the event it’s RSVPing to
the link or object it’s bookmarking
etc…
as2
Convert between ActivityStreams 1 and 2, including ActivityPub.
- set_content(obj, new_content)[source]
Sets
contentand also all matching values incontentMap.…to try to keep them in sync.
- from_as1(obj, type=None, context=('https://www.w3.org/ns/activitystreams', 'https://purl.archive.org/miscellany'), top_level=True)[source]
Converts an ActivityStreams 1 activity or object to ActivityStreams 2.
- to_as1(obj, use_type=True, get_fn=None)[source]
Converts an ActivityStreams 2 activity or object to ActivityStreams 1.
May make external HTTP requests if
get_fnis provided, eg to fetch thefeaturedcollection. https://docs.joinmastodon.org/spec/activitypub/#featured- Parameters:
obj (dict) – AS2 activity or object
use_type (bool) – whether to include
objectTypeandverbget_fn (callable, str URL =>
requests.Response) – requests to fetch AS2 objects when necessary, eg thefeaturedcollection. HTTP requests should usually be signed to satisfy many fediverse servers’ authorized fetch requirement.
- Returns:
AS1 activity or object
- Return type:
- is_public(activity, unlisted=True)[source]
Returns True if the given AS2 object or activity is public or unlisted.
https://docs.joinmastodon.org/spec/activitypub/#properties-used
- address(actor)[source]
Returns an actor’s fediverse handle aka WebFinger address aka @-@.
There’s no standard for this, it’s just a heuristic that uses
preferredUsernameandidorurlif available, otherwise detects and transforms common user profile URLs.
- link_tags(obj)[source]
Adds HTML links to
contentfor tags withstartIndexandlength.contentis modified in place. Ifcontent_is_htmlistrue, does nothing. Otherwise, sets it totrueif at least one link is added. Tags withoutstartIndex/lengthare ignored.TODO: duplicated in
microformats2.render_content(). unify?- Parameters:
obj (dict) – AS2 JSON object
- is_server_actor(actor)[source]
Returns True if this is the instance’s server actor, False otherwise.
Server actors are non-user actors used for fetching remote objects, sending
Flagactivities, etc. Background: * https://seb.jambor.dev/posts/understanding-activitypub-part-4-threads/#the-instance-actor * https://codeberg.org/fediverse/fep/src/branch/main/fep/d556/fep-d556.mdRight now, this just uses a well-known set of paths as a heuristic.
TODO: actually do a WebFinger lookup of the root path, eg
webfinger?resource=https://example.com/, and use FEP-d556 to determine the server actor.
atom
Convert between ActivityStreams 1 and Atom.
Atom spec: https://tools.ietf.org/html/rfc4287 (RIP atomenabled.org)
- class Defaulter(init={})[source]
Bases:
defaultdictEmulates Django template behavior that returns a special default value that can continue to be referenced when an attribute or item lookup fails. Helps avoid conditionals in the template itself.
https://docs.djangoproject.com/en/1.8/ref/templates/language/#variables
- from_as1(input, actor=None, title=None, request_url=None, host_url=None, xml_base=None, rels=None, reader=True)[source]
Converts an ActivityStreams 1 activity or activities to an Atom feed.
- Parameters:
input (dict or list of dict) – ActivityStreams activity or activities
actor (dict) – ActivityStreams actor, the author of the feed.
title (str) – the feed <title> element. Defaults to
User feed for [NAME]request_url (str) – URL of this Atom feed, if any. Used in a link rel=”self”.
host_url (str) – home URL for this Atom feed, if any. Used in the top-level feed
<id>element.xml_base (str) – base URL, if any. Used in the top-level
xml:baseattribute.rels (dict) – rel links to include. Keys are string
rel, values are string URLs.reader (bool) – whether the output will be rendered in a feed reader. Currently just includes location if True, not otherwise.
- Returns:
Atom XML
- Return type:
- activities_to_atom(input, actor=None, title=None, request_url=None, host_url=None, xml_base=None, rels=None, reader=True)
Deprecated! Use
from_as1()instead.
- activity_to_atom(input, actor=None, title=None, request_url=None, host_url=None, xml_base=None, rels=None, reader=True)
Deprecated! Use
from_as1()instead.
- atom_to_activity(atom)[source]
Converts an Atom entry to an ActivityStreams 1 activity.
Deprecated! Use
to_as1()instead.
- from_html(html, url=None, fetch_author=False, reader=True)[source]
Converts microformats2 HTML to an Atom feed.
- Parameters:
- Returns:
Atom XML
- Return type:
- html_to_atom(html, url=None, fetch_author=False, reader=True)
Deprecated! Use
from_html()instead.
bluesky
Bluesky source class.
- url_to_did_web(url)[source]
Converts a URL to a
did:web.In AT Proto, only hostname-based web DIDs are supported. Paths are not supported, and will be discarded.
Examples:
https://foo.com=>did:web:foo.comhttps://foo.com:3000=>did:web:foo.comhttps://foo.bar.com/baz/baj=>did:web:foo.bar.com
- did_web_to_url(did)[source]
Converts a did:web to a URL.
In AT Proto, only hostname-based web DIDs are supported. Paths are not supported, and will throw an invalid error.
Examples:
did:web:foo.com=>https://foo.comdid:web:foo.com%3A3000=> INVALIDdid:web:bar.com:baz:baj=> INVALID
- at_uri_to_web_url(uri, handle=None)[source]
Converts an
at://URI to ahttps://bsky.appURL.https://atproto.com/specs/at-uri-scheme
- Parameters:
uri (str) –
at://URIhandle – (str): optional user handle. If not provided, defaults to the DID in uri.
- Returns:
https://bsky.appURL, or None- Return type:
- Raises:
ValueError – if uri is not a string or doesn’t start with
at://
- web_url_to_at_uri(url, handle=None, did=None)[source]
Converts a
https://bsky.appURL to anat://URI.https://atproto.com/specs/at-uri-scheme
Currently supports profile, post, and feed URLs with DIDs and handles, eg:
https://bsky.app/profile/did:plc:123abchttps://bsky.app/profile/vito.fyi/post/3jt7sst7vok2uhttps://bsky.app/profile/bsky.app/feed/mutuals
If both
handleanddidare provided, andhandlematches the URL, the handle in the resulting URI will be replaced withdid.- Parameters:
- Returns:
at://URI, or None- Return type:
- Raises:
ValueError – if
urlcan’t be parsed as absky.appprofile or post URL
- from_as1_to_strong_ref(obj, client=None, value=False, raise_=False)[source]
Converts an AS1 object to an ATProto
com.atproto.repo.strongRef.Uses AS1
idorurl`, which should be an ``at://URI.- Parameters:
obj (dict) – AS1 object or activity
client (lexrpc.Client) – optional; if provided, this will be used to make API calls to PDSes to fetch and populate the
cidfield and resolve handle to DID.value (bool) – whether to include the record’s
valuefield in the returned objectraise (bool) – whether to raise
ValueErrorifclientis provided and we can’t fetch the object’s record and populatecid
- Returns:
ATProto
com.atproto.repo.strongRefrecord- Return type:
- from_as1_datetime(val)[source]
Converts an AS1 RFC 3339 datetime string to ATProto ISO 8601.
Bluesky requires full date and time with time zone, recommends UTC with Z suffix, fractional seconds.
https://atproto.com/specs/lexicon#datetime
Returns now (ie the current time) if the input datetime can’t be parsed.
- base_object(obj)[source]
Returns the “base” Bluesky object that an object operates on.
If the object is a reply, repost, or like of a Bluesky post, this returns that post object. The id in the returned object is the AT protocol URI, while the URL is the bsky.app web URL.
If the object is a follow or block, this returns the followed or blocked id, eg a DID.
- from_as1(obj, out_type=None, blobs=None, aspects=None, client=None, original_fields_prefix=None, as_embed=False, raise_=False)[source]
Converts an AS1 object to a Bluesky object.
Converts to
recordtypes by default, egapp.bsky.actor.profileorapp.bsky.feed.post. Useout_typeto convert to a different type, egapp.bsky.actor.defs#profileViewBasicorapp.bsky.feed.defs#feedViewPost.The
objectTypefield is required.If a string value in an output Bluesky object is longer than its
maxGraphemesormaxLengthin its lexicon, it’s truncated with an…ellipsis character at the end in order to fit.- Parameters:
obj (dict) – AS1 object or activity
out_type (str) – desired output lexicon
$typeblobs (dict) – optional mapping from str URL to
$type: blobdict (withref,mimeType, andsize) to use in the returned object. If not provided, or if this doesn’t have animageor similar URL in the input object, its output blob will be omitted.aspects (dict) – optional mapping from str URL to int (width,height) tuple. Used to provide aspect ratio in image/video embeds.
client (Bluesky or lexrpc.Client) – optional; if provided, this will be used to make API calls to PDSes to fetch and populate CIDs for records referenced by replies, likes, reposts, etc.
original_fields_prefix (str) – optional; if provided, stores original object URLs, post text, and actor profiles (ie before truncation) in custom fields with this prefix in output records. For example, if this is foo, an actor’s complete summary field will be stored in the custom fooOriginalDescription field, and their (first) url will be stored in the custom fooOriginalUrl field.
as_embed (bool) – whether to render the post as an external embed (ie link preview) instead of a native post. This happens automatically if
objectTypeisarticleraise (bool) – whether to raise
ValueErrorifclientis provided and we can’t fetch an object’s record
- Returns:
app.bsky.*object- Return type:
- Raises:
ValueError – if the object can’t be converted, eg if the
objectTypeorverbfields are missing or unsupported
- to_external_embed(obj, description=None, blobs=None)[source]
Converts an AS1 object to a Bluesky
app.bsky.embed.external#external.
- to_as1(obj, type=None, uri=None, repo_did=None, repo_handle=None, pds='https://bsky.social/', client=None)[source]
Converts a Bluesky object to an AS1 object.
- Parameters:
obj (dict) –
app.bsky.*objecttype (str) – optional
$typeto parse with, only used ifobj['$type']is unseturi (str) – optional
at://URI of this object. Used to populate theidandurlfields for some object types, eg posts.repo_did (str) – optional DID of the repo this object is from. Required to generate image URLs.
repo_handle (str) – optional handle of the user whose repo this object is from
pds (str) – base URL of the PDS that currently serves this object’s repo. Required to generate image URLs. Defaults to
https://bsky.social/.client (Bluesky or lexrpc.Client) – optional; if provided, this will be used to make API calls to PDSes to fetch secondary records needed for conversion, eg
community.lexicon.payments.webMonetizationfor profiles
- Returns:
- AS1 object, or None if the record doesn’t correspond to an AS1 object,
eg “not found” records
- Return type:
- Raises:
ValueError – if the
$typefield is missing or unsupported
- blob_to_url(*, blob, repo_did, pds='https://bsky.social/')[source]
Generates a URL for a blob.
Supports both new and old style blobs: https://atproto.com/specs/data-model#blob-type
Supports
refvalues as raw bytes, base-32 encoded strings, and DAG-JSON mappings with inner$linkvalues.The resulting URL is a
com.atproto.sync.getBlobXRPC call to the PDS.For blobs on the official
bsky.socialPDS, we could consider using their CDN instead:https://av-cdn.bsky.app/img/avatar/plain/[DID]/[CID]@jpegThey also run a resizing image proxy on
cdn.bsky.socialwith URLs likehttps://cdn.bsky.social/imgproxy/[SIG]/rs:fit:2000:2000:1:0/plain/[CID]@jpeg, not sure how to generate signatures for it yet.- Parameters:
blob (dict) – https://atproto.com/specs/data-model#blob-type
repo_did (str) – DID of the repo that owns this blob
pds (str) – base URL of the PDS that serves this repo. Defaults to
DEFAULT_PDS
- Returns:
URL for this blob, or None if
blobis empty or has no CID- Return type:
- blob_cid(blob)[source]
Returns a blob’s base32-encoded CID.
Supports both new and old style blobs: https://atproto.com/specs/data-model#blob-type
Supports
refvalues as raw bytes, base-32 encoded strings, and DAG-JSON mappings with inner$linkvalues.- Parameters:
blob (dict) – https://atproto.com/specs/data-model#blob-type
- Returns:
this blob’s CID, base32-encoded
- Return type:
- class Bluesky(handle, pds_url=None, did=None, access_token=None, refresh_token=None, app_password=None, auth=None, session_callback=None, **requests_kwargs)[source]
Bases:
SourceBluesky source class. See file docstring and
Sourceclass for details.- client
- Type:
lexrpc.Client
- classmethod user_to_actor(user, **kwargs)
Deprecated! Use
to_as1_actor()instead.
- classmethod post_id(url)[source]
Returns the at:// URI for the given URL if it’s for a post.
Also see
arroba.util.parse_at_uri.- Returns:
str or None
- get_activities_response(user_id=None, group_id=None, app_id=None, activity_id=None, fetch_replies=False, fetch_likes=False, fetch_shares=False, include_shares=True, fetch_mentions=False, search_query=None, start_index=None, count=None, cache=None, **kwargs)[source]
Fetches posts and converts them to AS1 activities.
See
Source.get_activities_response()for more information.Bluesky-specific details:
- Parameters:
activity_id (str) – an
at://URI
- get_comment(comment_id, **kwargs)[source]
Fetches and returns a comment.
- Parameters:
comment_id – string status id
**kwargs – unused
Returns: dict, ActivityStreams object
- Raises:
ValueError – if comment_id is invalid
- get_followers(user_id=None)[source]
Returns the current user’s followers.
Limited to the first 10k followers.
- get_follows(user_id=None)[source]
Returns the current user’s follows.
Limited to the first 10k follows.
- create(obj, include_link='omit', ignore_formatting=False)[source]
Creates a post, reply, repost, or like.
- Parameters:
- Returns:
whose content will be a dict with
id,url, andtypekeys (all optional) for the newly created object (or None)- Return type:
- preview_create(obj, include_link='omit', ignore_formatting=False)[source]
Preview creating a post, reply, repost, or like.
- Parameters:
- Returns:
content will be a str HTML snippet or None
- Return type:
- delete(at_uri)[source]
Deletes a record.
- Parameters:
at_uri (str) – at:// URI of record delete
- Returns:
content is dict with
urlandidfields- Return type:
- preview_delete(at_uri)[source]
Previews deleting a record.
- Parameters:
at_uri (str) – at:// URI of record delete
- Return type:
facebook
Facebook source class. Supports both Graph API and scraping HTML.
https://developers.facebook.com/docs/graph-api/using-graph-api/
- class Facebook(access_token=None, user_id=None, scrape=False, cookie_c_user=None, cookie_xs=None)[source]
Bases:
SourceFacebook source class. See file docstring and
Sourcefor details.- get_actor(user_id=None)[source]
Returns a user as a JSON ActivityStreams actor dict.
- Parameters:
user_id (str) – id or username. Defaults to
me, ie the current user.
- get_activities_response(user_id=None, group_id=None, app_id=None, activity_id=None, start_index=0, count=0, etag=None, min_id=None, cache=None, fetch_replies=False, fetch_likes=False, fetch_shares=False, fetch_events=False, fetch_mentions=False, search_query=None, fetch_news=False, event_owner_id=None, **kwargs)[source]
Fetches posts and converts them to ActivityStreams activities.
See
Source.get_activities_response()for details.Likes, top-level replies (ie comments), and reactions are always included. They come from the
comments,likes, andreactionsfields in the Graph API’s Post object: https://developers.facebook.com/docs/reference/api/post/Threaded comments, ie comments in reply to other top-level comments, require an additional API call, so they’re only included if fetch_replies is True.
Mentions are never fetched or included because the API doesn’t support searching for them. https://github.com/snarfed/bridgy/issues/523#issuecomment-155523875
Most parameters are documented in
Source.get_activities_response(). Additional parameters are documented here.- Parameters:
fetch_news (bool) – whether to also fetch and include Open Graph news stories (
/USER/news.publishes). Requires theuser_actions.newspermission. Background in https://github.com/snarfed/bridgy/issues/479event_owner_id (str) – if provided, only events owned by this user id will be returned. Avoids (but doesn’t entirely prevent) processing big non-indieweb events with tons of attendees that put us over App Engine’s instance memory limit. https://github.com/snarfed/bridgy/issues/77
- get_comment(comment_id, activity_id=None, activity_author_id=None, activity=None)[source]
Returns an ActivityStreams comment object.
Returns an ActivityStreams share activity object.
- get_reaction(activity_user_id, activity_id, reaction_user_id, reaction_id, activity=None)[source]
Fetches and returns a reaction.
- Parameters:
activity_user_id (str) – id of the user who posted the original activity
activity_id (str) – activity id
reaction_user_id (str) – id of the user who reacted
reaction_id (str) – id of the reaction. one of:
love,wow,haha,sad,angry,thankful,pride,careactivity (dict) – activity object (optional)
- Return type:
- create(obj, include_link='omit', ignore_formatting=False)[source]
Creates a new post, comment, like, or RSVP.
- Parameters:
- Returns:
contents will be a dict with
idandurlkeys for the newly created Facebook object- Return type:
CreationResult or None
- preview_create(obj, include_link='omit', ignore_formatting=False)[source]
Previews creating a new post, comment, like, or RSVP.
- Parameters:
- Returns:
contents will be an HTML snippet
- Return type:
CreationResult or None
- create_notification(user_id, text, link)[source]
Sends the authenticated user a notification.
Uses the Notifications API (beta): https://developers.facebook.com/docs/games/notifications/#impl
- Parameters:
user_id (str) – username or user ID
text (str) – shown to the user in the notification
link (str) – relative URL, the user is redirected here when they click on the notification. Note that only the path and query parameters are used! they’re combined with the domain in your Facebook app’s Game App URL: https://developers.facebook.com/docs/games/services/appnotifications#parameters
- Raises:
urllib3.HTPPError –
- post_url(post)[source]
Returns a short Facebook URL for a post.
- Parameters:
post (dict) – Facebook post
- comment_url(post_id, comment_id, post_author_id=None)[source]
Returns a short Facebook URL for a comment.
- classmethod base_id(url)[source]
Guesses the id of the object in the given URL.
- Return type:
str or None
- base_object(obj, verb=None, resolve_numeric_id=False)[source]
Returns the ‘base’ silo object that an object operates on.
This is mostly a big bag of heuristics for reverse engineering and parsing Facebook URLs. Whee.
- Parameters:
- Returns:
minimal ActivityStreams object. Usually has at least
id,numeric_id, andurlfields; may also haveauthor.- Return type:
- post_to_activity(post)
Deprecated! Use
post_to_as1_activity()instead.
- post_to_as1(post, type=None)[source]
Converts a post to an AS1 object.
TODO: handle the
sharedpostsfield
- post_to_object(post, type=None)
Deprecated! Use
post_to_as1()instead.
- comment_to_as1(comment, post_id=None, post_author_id=None)[source]
Converts a comment to an AS1 object.
- Parameters:
- Returns:
ActivityStreams object
- Return type:
- comment_to_object(comment, post_id=None, post_author_id=None)
Deprecated! Use
comment_to_as1()instead.
Converts a share (from
/OBJECT/sharedposts) to an AS1 object.
Deprecated! Use
share_to_as1()instead.
- user_to_actor(user)
Deprecated! Use
to_as1_actor()instead.
- event_to_object(event, rsvps=None)
Deprecated! Use
event_to_as1_object()instead.
- event_to_activity(event, rsvps=None)
Deprecated! Use
event_to_as1_activity()instead.
- rsvp_to_as1(rsvp, type=None, event=None)[source]
Converts an RSVP to an AS1 object.
The
idfield will ony be filled in ifevent['id']is provided.
- rsvp_to_object(rsvp, type=None, event=None)
Deprecated! Use
rsvp_to_as1()instead.
- album_to_object(album)
Deprecated! Use
album_to_as1()instead.
- privacy_to_to(obj, type=None)[source]
Converts a Facebook
privacyfield to an ActivityStreamstofield.privacyis sometimes an object: https://developers.facebook.com/docs/graph-api/reference/post#fields…and other times a string: https://developers.facebook.com/docs/graph-api/reference/album/#readfields
- email_to_as1(html)[source]
Converts a Facebook HTML notification email to an AS1 object.
- Parameters:
html – str
- Returns:
ActivityStreams object, or None if
htmlcouldn’t be parsed- Return type:
- email_to_object(html)
Deprecated! Use
email_to_as1()instead.
- scraped_to_as1_activities(scraped, log_html=False, **kwargs)[source]
Converts HTML from an
mbasic.facebook.comtimeline to AS1 activities.
- scraped_to_activities(scraped, log_html=False, **kwargs)
Deprecated! Use
scraped_to_as1_activities()instead.
- scraped_to_as1_activity(scraped, log_html=False, **kwargs)[source]
Converts HTML from an
mbasic.facebook.compost page to an AS1 activity.
- scraped_to_activity(scraped, log_html=False, **kwargs)
Deprecated! Use
scraped_to_as1_activity()instead.
- merge_scraped_reactions(scraped, activity)[source]
Converts and merges scraped likes and reactions into an activity.
New likes and emoji reactions are added to the activity in
tags. Existing likes and emoji reactions intagsare ignored.
- scraped_to_actor(scraped)
Deprecated! Use
scraped_to_as1_actor()instead.
- static parse_id(id, is_comment=False)[source]
Parses a Facebook post or comment id.
Facebook ids come in different formats:
Simple number, usually a user or post:
12Two numbers with underscore, usually
POST_COMMENTorUSER_POST:12_34Three numbers with underscores,
USER_POST_COMMENT:12_34_56Three numbers with colons,
USER:POST:SHARD:12:34:63(We’re guessing that the third part is a shard in some FB internal system. In our experience so far, it’s always either 63 or the app-scoped user id for 63.)Two numbers with colon,
POST:SHARD:12:34(We’ve seen 0 as shard in this format.)Four numbers with colons/underscore,
USER:POST:SHARD_COMMENT:12:34:63_56Five numbers with colons/underscore,
USER:EVENT:UNKNOWN:UNKNOWN_UNKNOWN. Not currently supported! Examples: *111599105530674:998145346924699:10102446236688861:10207188792305341_998153510257216*111599105530674:195181727490727:10102446236688861:10205257726909910_195198790822354
Background:
- Parameters:
- Returns:
Some or all fields may be None.
- Return type:
- resolve_object_id(user_id, post_id, activity=None)[source]
Resolve a post id to its Facebook object id, if any.
Used for photo posts, since Facebook has (at least) two different objects (and ids) for them, one for the post and one for each photo.
This is the same logic that we do for canonicalizing photo objects in
get_activities()above.If activity is not provided, fetches the post from Facebook.
- urlopen(url, _as=<class 'dict'>, **kwargs)[source]
Wraps
urllib2.urlopen()and passes through the access token.
- urlopen_batch(urls)[source]
Sends a batch of multiple API calls using Facebook’s batch API.
Raises the appropriate
urllib2.HTTPErrorif any individual call returns HTTP status code 4xx or 5xx.https://developers.facebook.com/docs/graph-api/making-multiple-requests
- urlopen_batch_full(requests)[source]
Sends a batch of multiple API calls using Facebook’s batch API.
Similar to
urlopen_batch(), but the requests arg and return value are dicts with headers, HTTP status code, etc. Raisesurllib2.HTTPErrorif the outer batch request itself returns an HTTP error.https://developers.facebook.com/docs/graph-api/making-multiple-requests
- Parameters:
requests (sequence of dict) –
requests in Facebook’s batch format, except that headers is a single dict, not a list of dicts, e.g.:
[{'relative_url': 'me/feed', 'headers': {'ETag': 'xyz', ...}, }, ... ]
- Returns:
responses in Facebook’s batch format, except that body is JSON-decoded if possible, and headers is a single dict, not a list of dicts, e.g.:
[{'code': 200, 'headers': {'ETag': 'xyz', ...}, 'body': {...}, }, ... ]
- Return type:
sequence of dict
flickr
Flickr source class.
Uses Flickr’s REST API https://www.flickr.com/services/api/
TODO: Fetching feeds with comments and/or favorites is very request
intensive right now. It would be ideal to find a way to batch
requests, make requests asynchronously, or make better calls to the
API itself. Maybe use flickr.activity.userPhotos
(https://www.flickr.com/services/api/flickr.activity.userPhotos.html)
when group_id=SELF`.
- class Flickr(access_token_key, access_token_secret, user_id=None, path_alias=None)[source]
Bases:
SourceFlickr source class. See file docstring and Source class for details.
- create(obj, include_link='omit', ignore_formatting=False)[source]
Creates a photo, comment, or favorite.
- Parameters:
- Returns:
contentwill be a dict withid,url, andtypekeys (all optional) for the newly created Flickr object- Return type:
CreationResult or None
- preview_create(obj, include_link='omit', ignore_formatting=False)[source]
Preview creation of a photo, comment, or favorite.
- Parameters:
- Returns:
whose description will be an HTML summary of what publishing will do, and whose content will be an HTML preview of the result
- Return type:
CreationResult or None
- delete(id)[source]
Deletes a photo. The authenticated user must have created it.
- Parameters:
- Returns:
contentis Flickr API response dict- Return type:
- get_activities_response(user_id=None, group_id=None, app_id=None, activity_id=None, start_index=0, count=0, etag=None, min_id=None, cache=None, fetch_replies=False, fetch_likes=False, fetch_shares=False, fetch_events=False, fetch_mentions=False, search_query=None, **kwargs)[source]
Fetches Flickr photos and converts them to ActivityStreams activities.
See
Source.get_activities_response()for details.Mentions are not fetched or included because they don’t exist in Flickr. https://github.com/snarfed/bridgy/issues/523#issuecomment-155523875
- get_actor(user_id=None)[source]
Get an ActivityStreams object of type
persongiven a user’s nsid. If nouser_idis provided, this method will make another API request to find out the currently logged in user’s id.
- user_to_actor(resp)
Deprecated! Use
to_as1_actor()instead.
- get_comment(comment_id, activity_id=None, activity_author_id=None, activity=None)[source]
Returns an ActivityStreams comment object.
- photo_to_activity(photo)[source]
Convert a Flickr photo to an ActivityStreams object.
Takes either data in the expanded form returned by
flickr.photos.getInfoor the abbreviated form returned byflickr.people.getPhotos.
- like_to_as1(person, photo_activity)[source]
Convert a Flickr favorite into an ActivityStreams
liketag.
- like_to_object(person, photo_activity)
Deprecated! Use
like_to_as1()instead.
- comment_to_as1(comment, photo_id)[source]
Convert a Flickr comment JSON object to an ActivityStreams comment.
- comment_to_object(comment, photo_id)
Deprecated! Use
comment_to_as1()instead.
- get_user_image(farm, server, author)[source]
Convert fields from a typical Flickr response into the buddy icon URL.
- user_id()[source]
Get the nsid of the currently authorized user.
The first time this is called, it will invoke the
flickr.people.getLimitsAPI method.https://www.flickr.com/services/api/flickr.people.getLimits.html
- Return type:
- path_alias()[source]
Get the path_alias of the currently authorized user.
The first time this is called, it will invoke the
flickr.people.getInfoAPI method.https://www.flickr.com/services/api/flickr.people.getInfo.html
- Return type:
github
GitHub source class. Uses the v4 GraphQL API and the v3 REST API.
API docs:
- class GitHub(access_token=None)[source]
Bases:
SourceGitHub source class. See file docstring and
Sourcefor details.- rest(url, data=None, parse_json=True, **kwargs)[source]
Makes a v3 REST API call.
Uses HTTP POST if data is provided, otherwise GET.
- Parameters:
data (dict) – JSON payload for POST requests
json (bool) – whether to parse the response body as JSON and return it as a dict. If False, returns a
requests.Responseinstead.
- Returns:
- decoded from JSON response if
json=True, otherwise
- decoded from JSON response if
- Return type:
- get_activities_response(user_id=None, group_id=None, app_id=None, activity_id=None, start_index=0, count=0, etag=None, min_id=None, cache=None, fetch_replies=False, fetch_likes=False, fetch_shares=False, fetch_events=False, fetch_mentions=False, search_query=None, public_only=True, **kwargs)[source]
Fetches issues and comments and converts them to ActivityStreams activities.
See
Source.get_activities_response()for details.Not comprehensive! Uses the notifications API (v3 REST).
Also note that start_index is not currently supported.
fetch_likesdetermines whether emoji reactions are fetched: https://help.github.com/articles/about-conversations-on-github#reacting-to-ideas-in-commentsThe notifications API call supports
Last-Modified/If-Modified-Sinceheaders and304 Not Changedresponses. If provided,etagshould be an RFC2822 timestamp, usually the exact value returned in aLast-Modifiedheader. It will also be passed to the comments API endpoint as thesince=value (converted to ISO8601).
- render_markdown(markdown, owner, repo)[source]
Uses the GitHub API to render GitHub-flavored Markdown to HTML.
- create(obj, include_link='omit', ignore_formatting=False)[source]
Creates a new issue or comment.
- Parameters:
- Returns:
contents will be a dict with
idandurlkeys for the newly created GitHub object- Return type:
CreationResult or None
- preview_create(obj, include_link='omit', ignore_formatting=False)[source]
Previews creating an issue or comment.
- Parameters:
- Returns:
contentswill be a str HTML snippet- Return type:
CreationResult or None
- issue_to_as1(issue)[source]
Converts a GitHub issue or pull request to ActivityStreams.
Handles both v4 GraphQL and v3 REST API issue and PR objects.
- issue_to_object(issue)
Deprecated! Use
issue_to_as1()instead.
- pr_to_as1(issue)
Converts a GitHub issue or pull request to ActivityStreams.
Handles both v4 GraphQL and v3 REST API issue and PR objects.
- pr_to_object(issue)
Deprecated! Use
pr_to_as1()instead.
- comment_to_as1(comment)[source]
Converts a GitHub comment to ActivityStreams.
Handles both v4 GraphQL and v3 REST API issue objects.
- comment_to_object(comment)
Deprecated! Use
comment_to_as1()instead.
- reaction_to_as1(reaction, target)[source]
Converts a GitHub emoji reaction to ActivityStreams.
Handles v3 REST API reaction objects.
- reaction_to_object(reaction, target)
Deprecated! Use
reaction_to_as1()instead.
- to_as1_actor(user)[source]
Converts a GitHub user to an ActivityStreams actor.
Handles both v4 GraphQL and v3 REST API user objects.
- user_to_actor(user)
Deprecated! Use
to_as1_actor()instead.
instagram
Instagram source class.
Instagram’s API doesn’t tell you if a user has marked their account private or
not, so the Audience Targeting to field is currently always set to
@public.
https://groups.google.com/forum/m/#!topic/instagram-api-developers/DAO7OriVFsw
https://groups.google.com/forum/#!searchin/instagram-api-developers/private
- class Instagram(access_token=None, allow_comment_creation=False, scrape=False, cookie=None)[source]
Bases:
SourceInstagram source class. See file docstring and Source class for details.
- get_actor(user_id=None, **kwargs)[source]
Returns a user as a JSON ActivityStreams actor dict.
- Parameters:
user_id (str) – id or username. Defaults to
self, ie the current user.kwargs – if scraping, passed through to :meth:get_activities_response``.
- Raises:
AssertionError – if kwargs is provided but we’re not scraping
- get_activities_response(user_id=None, group_id=None, app_id=None, activity_id=None, start_index=0, count=0, etag=None, min_id=None, cache=None, fetch_replies=False, fetch_likes=False, fetch_shares=False, fetch_events=False, fetch_mentions=False, search_query=None, scrape=False, cookie=None, ignore_rate_limit=False, **kwargs)[source]
Fetches posts and converts them to ActivityStreams activities.
See
Source.get_activities_response()for details.app_idis ignored. Supportsmin_id, but notETag, since Instagram doesn’t support it.http://instagram.com/developer/endpoints/users/#get_users_feed
http://instagram.com/developer/endpoints/users/#get_users_media_recent
Likes are always included, regardless of the
fetch_likeskwarg. They come bundled in thelikesfield of the API Media object: http://instagram.com/developer/endpoints/media/#Mentions are never fetched or included because the API doesn’t support searching for them. https://github.com/snarfed/bridgy/issues/523#issuecomment-155523875
Shares are never fetched or included since there is no share feature.
Instagram only supports search over hashtags, so if search_query is set, it must begin with
#.May populate a custom
ig_like_countproperty in media objects. (Currently only when scraping.)- Parameters:
scrape (bool) – if True, scrapes HTML from instagram.com instead of using the API. Populates the user’s actor object in the
actorresponse field. Useful for apps that haven’t yet been approved in the new permissions approval process. Currently only supportsgroup_id=SELF. Also supports passing a shortcode as activity_id as well as the internal API id. http://developers.instagram.com/post/133424514006/instagram-platform-updatecookie (str) – only used if
scrape=Trueignore_rate_limit (bool) – for scraping, always make an HTTP request, even if we’ve been rate limited recently
- get_comment(comment_id, activity_id=None, activity_author_id=None, activity=None)[source]
Returns an ActivityStreams comment object.
Not implemented. Returns None. Resharing isn’t a feature of Instagram.
- create(obj, include_link='omit', ignore_formatting=False)[source]
Creates a new comment or like.
- Parameters:
- Returns:
- if successful, content will have and
idandurl keys for the newly created Instagram object
- if successful, content will have and
- Return type:
- preview_create(obj, include_link='omit', ignore_formatting=False)[source]
Preview a new comment or like.
- Parameters:
- Returns:
- if successful, content and description will describe the
new Instagram object.
- Return type:
- media_to_activity(media)
Deprecated! Use
media_to_as1()instead.
- media_to_object(media)[source]
Converts a media to an object.
Deprecated! Use
media_to_as1()instead.
- comment_to_object(comment, media_id, media_url)
Deprecated! Use
comment_to_as1()instead.
- like_to_object(liker, media_id, media_url)
Deprecated! Use
like_to_as1()instead.
- user_to_actor(user)
Deprecated! Use
to_as1_actor()instead.
- base_object(obj)[source]
Extends the default base_object() to avoid using shortcodes as object ids.
- static id_to_shortcode(id)[source]
Converts a media id to the shortcode used in its instagram.com URL.
Based on http://carrot.is/coding/instagram-ids , which determined that shortcodes are just URL-safe base64 encoded ids.
- scraped_to_as1(input, cookie=None, count=None, fetch_extras=False)[source]
Converts scraped Instagram HTML to ActivityStreams activities.
The input HTML may be from:
a user’s feed, eg https://www.instagram.com/ while logged in
a user’s profile, eg https://www.instagram.com/snarfed/
a photo or video, eg https://www.instagram.com/p/BBWCSrfFZAk/
serialized JSON from the API for a feed, profile, or post, eg https://i.instagram.com/api/v1/feed/timeline/
- Parameters:
- Returns:
([ActivityStreams activities], ActivityStreams viewer actor)
- Return type:
- html_to_activities(input, cookie=None, count=None, fetch_extras=False)
Deprecated! Use
scraped_to_as1()instead.
- scraped_to_activities(input, cookie=None, count=None, fetch_extras=False)
Deprecated! Use
scraped_to_as1()instead.
- scraped_json_to_as1(input, cookie=None, count=None, fetch_extras=False)[source]
Converts scraped Instagram JSON to ActivityStreams activities.
- The input JSON may be from a user’s profile, eg
https://i.instagram.com/api/v1/users/web_profile_info/?username=…
- Parameters:
- Returns:
([ActivityStreams activities], ActivityStreams viewer actor)
- Return type:
- scraped_json_to_activities(input, cookie=None, count=None, fetch_extras=False)
Deprecated! Use
scraped_json_to_as1()instead.
- scraped_to_activity(html, **kwargs)[source]
Converts HTML from photo/video permalink page to an AS1 activity.
Deprecated! Use
scraped_to_as1()instead.
- scraped_to_as1_actor(html, **kwargs)[source]
Extracts and returns the logged in actor from any Instagram HTML.
- scraped_to_actor(html, **kwargs)
Deprecated! Use
scraped_to_as1_actor()instead.
- merge_scraped_comments(scraped, activity)[source]
Converts and merges scraped comments (replies) into an activity.
- Parameters:
- Returns:
AS comment objects converted from scraped
- Return type:
- Raises:
ValueError – if scraped is not valid JSON
jsonfeed
Convert between ActivityStreams and JSON Feed.
JSON Feed spec: https://jsonfeed.org/version/1.1
- from_as1(activities, actor=None, title=None, feed_url=None, home_page_url=None)[source]
Converts ActivityStreams activities to a JSON feed.
- Parameters:
- Returns:
JSON Feed data
- Return type:
- activities_to_jsonfeed(activities, actor=None, title=None, feed_url=None, home_page_url=None)
Deprecated! Use
from_as1()instead.
- to_as1(jsonfeed)[source]
Converts a JSON feed to ActivityStreams activities and actor.
- Parameters:
jsonfeed (dict) – JSON Feed data
- Returns:
(activities, actor), where activities and actor are both ActivityStreams object dicts- Return type:
- Raises:
ValueError – if jsonfeed isn’t a valid JSON Feed dict
mastodon
Mastodon source class.
Mastodon is an ActivityPub implementation, but it also has a REST + OAuth 2 API independent of AP. This class handles that API. API docs: https://docs.joinmastodon.org/api/
May also be used for services with Mastodon-compatible APIs, eg Pleroma: https://docs-develop.pleroma.social/backend/API/differences_in_mastoapi_responses/
- class Mastodon(instance, access_token, user_id=None, truncate_text_length=None, **requests_kwargs)[source]
Bases:
SourceMastodon source class. See file docstring and Source class for details.
- requests_kwargs
passed to
requests.get()/requests.post()- Type:
- get_activities_response(user_id=None, group_id=None, app_id=None, activity_id=None, fetch_replies=False, fetch_likes=False, fetch_shares=False, include_shares=True, fetch_events=False, fetch_mentions=False, search_query=None, start_index=0, count=0, cache=None, **kwargs)[source]
Fetches toots and converts them to ActivityStreams activities.
See
Source.get_activities_response()for details.
- get_comment(comment_id, **kwargs)[source]
Fetches and returns a comment.
- Parameters:
comment_id (str) – status id
kwargs – unused
- Returns:
ActivityStreams object
- Return type:
- Raises:
ValueError – if comment_id is invalid
- status_to_activity(status)
Deprecated! Use
status_to_as1_activity()instead.
- status_to_object(status)
Deprecated! Use
status_to_as1_object()instead.
- user_to_actor(account)
Deprecated! Use
to_as1_actor()instead.
- actor_id(user)[source]
Returns the ActivityPub actor id for an API user object.
In Mastodon, the AP actor id is in the
urifield.Unfortunately, it’s much more complicated in some other Mastodon API implementations, eg Pixelfed: https://github.com/pixelfed/pixelfed/discussions/6182
- Parameters:
user (dict) – user API object: https://docs.joinmastodon.org/methods/accounts/#get
- Returns:
str or None
- create(obj, include_link='omit', ignore_formatting=False)[source]
Creates a status (aka toot), reply, boost (aka reblog), or favorite.
https://docs.joinmastodon.org/methods/statuses/
- Parameters:
- Returns:
whose content will be a dict with
id,url, andtypekeys (all optional) for the newly created object (or None)- Return type:
- preview_create(obj, include_link='omit', ignore_formatting=False)[source]
Preview creating a status (aka toot), reply, boost (aka reblog), or favorite.
https://docs.joinmastodon.org/methods/statuses/
- Parameters:
- Returns:
content will be a str HTML snippet or None
- Return type:
- base_object(obj)[source]
Returns the “base” Mastodon object that an object operates on.
If the object is a reply, boost, or favorite of a Mastodon post - on any instance - this returns that post object. The id in the returned object is the id of that remote post on the local instance. (As a Mastodon style id, ie an int in a string, not a tag URI.)
Uses Mastodon’s search API on the local instance to determine whether a URL is a Mastodon post, and if it is, to find or generate an id for it on the local instance.
Discovered via https://mastodon.social/@jkreeftmeijer/101245063526942536
- delete(id)[source]
Deletes a toot. The authenticated user must have authored it.
- Parameters:
- Returns:
content is dict with
urlandidfields- Return type:
- get_followers(user_id=None)[source]
Returns the current user’s followers.
Limited to the first 10k followers.
- get_follows(user_id=None)[source]
Returns the current user’s follows.
This will often be limited, eg to the first 10k follows, depending on the silo.
- get_blocklist_ids()[source]
Returns the current user’s block list as a list of int account ids.
May make multiple API calls to fully fetch large block lists. https://docs.joinmastodon.org/methods/accounts/blocks/
- Returns:
Mastodon account ids on the current instance
- Return type:
sequence of int
meetup
Meetup.com source class.
microformats2
Convert ActivityStreams to microformats2 HTML and JSON.
Microformats2 specs: http://microformats.org/wiki/microformats2
ActivityStreams 1 specs: http://activitystrea.ms/specs/
- get_string_urls(objs)[source]
Extracts string URLs from a list of either string URLs or mf2 dicts.
Many mf2 properties can contain either string URLs or full mf2 objects, eg
h-cite.in-reply-tois the most commonly used example: http://indiewebcamp.com/in-reply-to#How_to_consume_in-reply-to
- get_text(val)[source]
Returns a plain text string value. See
get_html().
- from_as1(obj, trim_nulls=True, entry_class='h-entry', default_object_type=None, synthesize_content=True)[source]
Converts an ActivityStreams object to microformats2 JSON.
- Parameters:
obj (dict) – a decoded JSON ActivityStreams object or activity
trim_nulls (bool) – whether to remove elements with null or empty values
entry_class (str or sequence of str), the mf2 class(es) – given, eg
h-citewhen parsing a reference to a foreign entry. defaults to h-entry`default_object_type (str) – the ActivityStreams
objectTypeto use if one is not present. defaults to Nonesynthesize_content (bool) – whether to generate synthetic content if the object doesn’t have its own, eg
likes thisorshared this
- Returns:
decoded microformats2 JSON
- Return type:
- object_to_json(obj, trim_nulls=True, entry_class='h-entry', default_object_type=None, synthesize_content=True)
Deprecated! Use
from_as1()instead.
- activity_to_json(activity, **kwargs)[source]
Converts an ActivityStreams activity to microformats2 JSON.
Deprecated! Use
from_as1()instead.- Parameters:
activity (dict) – a decoded JSON ActivityStreams activity
kwargs – passed to
object_to_json()
- Returns:
decoded microformats2 JSON
- Return type:
- to_as1(mf2, actor=None, fetch_mf2=False, rel_urls=None)[source]
Converts a single microformats2 JSON item to an ActivityStreams object.
Supports
h-entry,h-event,h-card, and other single item times. Does not yet supporth-feed.If
rel_urlsis provided, the returnedurlandurlsfields will be objects that may includedisplayNamefields with the text ortitlefrom the original HTML links.- Parameters:
mf2 (dict) – decoded JSON microformats2 object
actor (dict) – optional author AS actor object. usually comes from a
rel="author"link. ifmf2has its own author, that overrides thisfetch_mf2 (bool) – whether to fetch additional pages via HTTP if necessary, eg to determine authorship: https://indieweb.org/authorship
rel_urls (dict) – optional rel-urls field from parsed mf2
- Returns:
ActivityStreams object
- Return type:
- html_hfeed_to_as1(html, url=None, actor=None, id=None)[source]
Converts a microformats2 HTML
h-feedto ActivityStreams activities.- Parameters:
html (str) – HTML or
requests.Responseurl (str) – optional URL that HTML came from
actor (dict) – optional author AS actor object for all activities. usually comes from a
rel="author"link.id (str) – optional id of specific element to extract and parse. defaults to the whole page.
- Returns:
ActivityStreams activities
- Return type:
- html_to_activities(html, url=None, actor=None, id=None)
Deprecated! Use
html_hfeed_to_as1()instead.
- hfeed_to_as1(parsed, actor=None)[source]
Converts a parsed microformats2 JSON
h-feedto ActivityStreams activities.
- json_to_activities(parsed, actor=None)
Deprecated! Use
hfeed_to_as1()instead.
- activities_to_html(activities, extra='', body_class='')[source]
Converts ActivityStreams activities to a microformats2 HTML
h-feed.- Parameters:
- Returns:
the content field in
objwith the tags in thetagsfield converted to links if they havestartIndexandlength, otherwise added to the end.- Return type:
- object_to_html(obj, parent_props=None, synthesize_content=True)[source]
Converts an ActivityStreams object to microformats2 HTML.
Features:
linkifies embedded tags and adds links for other tags
linkifies embedded URLs
adds links, summaries, and thumbnails for attachments and checkins
adds a “via SOURCE” postscript
- Parameters:
- Returns:
the content field in
objwith tags in thetagsfield converted to links if they havestartIndexandlength, otherwise added to the end.- Return type:
- json_to_html(obj, parent_props=None)[source]
Converts a microformats2 JSON object to microformats2 HTML.
See
object_to_html()for details.
- render_content(obj, include_location=True, synthesize_content=True, render_attachments=False, render_image=False, white_space_pre=True)[source]
Renders the content of an ActivityStreams object as HTML.
Includes tags, mentions, and non-note/article attachments. (Note/article attachments are converted to mf2 children in object_to_json and then rendered in
json_to_html().)- Parameters:
obj (dict) – decoded JSON ActivityStreams object
include_location (bool) – whether to render location, if provided
synthesize_content (bool) – whether to generate synthetic content if the object doesn’t have its own, eg
likes thisorshared thisrender_attachments (bool) – whether to render attachments, eg links, images, audio, and video
render_image (bool) – whether to render the object’s image(s)
white_space_pre (bool) – whether to wrap in CSS
white-space: pre. If False, newlines will be converted to<br>tags instead. Background: https://indiewebcamp.com/note#Indieweb_whitespace_thinking
- Returns:
rendered HTML
- Return type:
- tags_to_html(tags, classname, visible=True)[source]
Returns an HTML string with links to the given tag objects.
- author_display_name(hcard)[source]
Returns a human-readable string display name for an
h-cardobject.
- maybe_linked(text, url=None, linked_classname=None, unlinked_classname=None)[source]
Wraps text in an
<a href=...>iff a non-empty url is provided.
nostr
Nostr.
NIPS implemented:
01: base protocol, events, profile metadata
02: contacts/followings
05: domain identifiers
09: deletes
10: replies, mentions
12: hashtags, locations
14: subject tag in notes
18: reposts, including 10 for e/p tags
19: bech32-encoded ids
21: nostr: URI scheme
23: articles
24: extra fields
25: likes, emoji reactions
27: text notes
39: external identities
48: proxy tags
50: search
92/94: image, video, audio attachments
TODO:
11: relay info (like nodeinfo)
12: tag queries
16, 33: ephemeral/replaceable events
17: DMs
27: user mentions, note/event mentions
the difficulty is that the Nostr tags don’t include human-readable
text. clients are supposed to get that from their local database.
32: tag activities
46: “Nostr Connect,” signing proxy that holds user’s keys
65: user relays. what would this be in AS1? anything?
73: external content ids
- bech32_prefix_for(event)[source]
Returns the bech32 prefix for a given event, based on its kind.
Defined by NIP-19: https://nips.nostr.com/19
- uri_to_id(uri)[source]
Converts a nostr: URI with bech32-encoded id to a hex sha256 hash id.
Based on NIP-21.
- id_to_uri(prefix, id)[source]
Converts a hex sha256 hash id to a nostr: URI with bech32-encoded id.
Based on NIP-21.
- bech32_decode(val)[source]
Converts a bech32-encoded string to its corresponding hex string.
Based on NIP-19.
- bech32_encode(prefix, hex)[source]
Converts a hex string to a bech32-encoded string.
Based on NIP-19.
- nip05_to_npub(nip05)[source]
Resolves a NIP-05 identifier or domain to a bech32-encoded npub public key.
- Parameters:
nip05 (str) – NIP-05 identifier, e.g. “alice@example.com” or “_@example.com”
- Returns:
bech32-encoded npub public key
- Return type:
- Raises:
ValueError – if nip05 is invalid format or user not found
HTTPError – if HTTP request fails
- pubkey_from_privkey(privkey)[source]
Returns the hex-encoded public key for a hex-encoded private key.
Removes the leading 0x02 or 0x03 byte prefix that secp256k1-py includes. Background: https://github.com/snarfed/bridgy-fed/issues/446#issuecomment-2925960330
Note that
verify()does the inverse; it adds a 0x02 prefix internally, which secp256k1-py needs to load the public key.
- from_as1(obj, privkey=None, remote_relay='', from_protocol=None)[source]
Converts an ActivityStreams 1 activity or object to a Nostr event.
- Parameters:
obj (dict) – AS1 activity or object
privkey (str) – optional bech32-encoded private key to sign the event with. Also used to set the output event’s
pubkeyfield ifobjdoesn’t have annsecidremote_relays (sequence of str) – optional sequence of remote relays where the “target” of this object - followee, in-reply-to, repost-of, etc - can be fetched.
from_protocol (str) – optional source protocol for NIP-48 proxy tag. Supported values: ‘activitypub’, ‘atproto’, ‘web’
- Returns:
Nostr event
- Return type:
- to_as1(event, id_format='hex', nostr_uri_ids=True)[source]
Converts a Nostr event to an ActivityStreams 2 activity or object.
- Parameters:
- Returns:
AS1 activity or object
- Return type:
- class Nostr(relays=(), privkey=None)[source]
Bases:
SourceNostr source class. See file docstring and
Sourcefor details.- get_activities_response(user_id=None, group_id=None, app_id=None, activity_id=None, fetch_replies=False, fetch_likes=False, fetch_shares=False, include_shares=True, fetch_events=False, fetch_mentions=False, search_query=None, start_index=None, count=None, cache=None, **kwargs)[source]
Fetches events and converts them to AS1 activities.
See
Source.get_activities_response()for more information.
- query(websocket, filter)[source]
Runs a Nostr
REQquery on an open websocket.Sends the query, collects the responses, and closes the
REQsubscription. Iflimitis not set on the filter, it defaults to 20.- Parameters:
websocket (ClientConnection)
filter (dict) – NIP-01
REQfilterlimit (int)
- Returns:
Nostr events
- Return type:
pixelfed
Pixelfed source class, heavily based on Mastodon.
Pixelfed’s API is a clone of Mastodon’s. https://docs.pixelfed.org/technical-documentation/api-v1.html
- class Pixelfed(instance, access_token, user_id=None, truncate_text_length=None, **requests_kwargs)[source]
Bases:
MastodonPixelfed source class.
- actor_id(user)[source]
Returns the ActivityPub actor id for an API user object.
This is complicated in Pixelfed: https://github.com/pixelfed/pixelfed/discussions/6182
- Parameters:
user (dict) – user API object
- Returns:
str or None
reddit
Reddit source class.
Not thread safe!
Reddit API docs:
PRAW API docs: https://praw.readthedocs.io/
- class Reddit(refresh_token)[source]
Bases:
SourceReddit source class. See file docstring and
source.Sourcefor details.- praw_to_as1_actor(praw_user)[source]
Converts a PRAW Redditor to an actor.
Makes external calls to fetch data from the Reddit API.
https://praw.readthedocs.io/en/latest/code_overview/models/redditor.html
Caches fetched user data for 5m to avoid repeating user profile API requests when fetching multiple comments or posts from the same author. Background: https://github.com/snarfed/bridgy/issues/1021
Ideally this would be part of PRAW, but they seem uninterested:
- praw_to_actor(praw_user)
Deprecated! Use
praw_to_as1_actor()instead.
- user_to_actor(user)
Deprecated! Use
to_as1_actor()instead.
- to_as1_object(thing, type)[source]
Converts a PRAW object to an AS1 object.
Currently only returns public content.
Note that this will make external API calls to lazily load some attributes.
- Parameters:
thing (Submission or Comment)
type (str) – either
submissionorcomment, which content to get
- Returns:
ActivityStreams object
- Return type:
- praw_to_object(thing, type)
Deprecated! Use
to_as1_object()instead.
- to_as1_activity(thing, type)[source]
Converts a PRAW submission or comment to an activity.
Note that this will make external API calls to lazily load some attributes.
https://praw.readthedocs.io/en/latest/code_overview/models/submission.html
https://praw.readthedocs.io/en/latest/code_overview/models/comment.html
- Parameters:
thing (Submission or Comment)
type (str) – whether to get submission or comment content
- Returns:
ActivityStreams activity
- Return type:
- praw_to_activity(thing, type)
Deprecated! Use
to_as1_activity()instead.
- get_activities_response(user_id=None, group_id=None, app_id=None, activity_id=None, start_index=0, count=None, etag=None, min_id=None, cache=None, fetch_replies=False, fetch_likes=False, fetch_shares=False, fetch_events=False, fetch_mentions=False, search_query=None, **kwargs)[source]
Fetches submissions and ActivityStreams activities.
Currently only implements
activity_id,search_queryandfetch_replies.
- get_actor(user_id=None)[source]
Fetches a Reddit user and converts them to an AS1 actor.
- Parameters:
user_id (str)
- Returns
dict: AS1 actor, or
{}if the user isn’t found
rss
Convert between ActivityStreams and RSS 2.0.
RSS 2.0 spec: http://www.rssboard.org/rss-specification
Feedgen docs: https://feedgen.kiesow.be/
Apple iTunes Podcasts feed requirements: https://help.apple.com/itc/podcasts_connect/#/itc1723472cb
Notably:
Valid RSS 2.0.
Each podcast item requires
<guid>.Images should be JPEG or PNG, 1400x1400 to 3000x3000.
HTTP server that hosts assets and files should support range requests.
- from_as1(activities, actor=None, title=None, feed_url=None, home_page_url=None, hfeed=None)[source]
Converts ActivityStreams activities to an RSS 2.0 feed.
- Parameters:
- Returns:
RSS 2.0 XML
- Return type:
- from_activities(activities, actor=None, title=None, feed_url=None, home_page_url=None, hfeed=None)
Deprecated! Use
from_as1()instead.
source
Source base class.
Based on the OpenSocial ActivityStreams REST API: http://opensocial-resources.googlecode.com/svn/spec/2.0.1/Social-API-Server.xml#ActivityStreams-Service
Uses the to field of the Audience Targeting extension to indicate an
activity’s privacy settings. It’s set to a group with alias @public or
@private, or unset if unknown.
http://activitystrea.ms/specs/json/targeting/1.0/#anchor3
- class CreationResult(content, description, abort, error_plain, error_html)
Bases:
tupleResult of creating a new object in a silo.
create()andpreview_create()use this to provide a detailed description of publishing failures. Ifabortis False, we should continue looking for an entry to publish; if True, we should immediately inform the user.error_plaintext is sent in response to failed publish webmentions;error_htmlwill be displayed to the user when publishing interactively.- description
HTML snippet describing the publish action, e.g.
@-replyorRSVP yes to this event. The verb itself is surrounded by a<span class="verb">to allow styling. May also include<a>link(s) and embedded silo post(s).- Type:
- exception RateLimited(*args, **kwargs)[source]
Bases:
BaseExceptionRaised when an API rate limits us, and we may have a partial result.
- partial
the partial result, if any. Usually a list.
- html_to_text(html, baseurl='', **kwargs)[source]
Converts HTML to plain text with html2text.
- Parameters:
html (str) – input HTML content
baseurl (str) – base URL to use when resolving relative URLs. Passed through to
HTML2Text.kwargs – html2text options: https://github.com/Alir3z4/html2text/blob/master/docs/usage.md#available-options
- Returns:
converted plain text
- Return type:
- load_json(body, url)[source]
Utility method to parse a JSON string. Raises HTTPError 502 on failure.
- creation_result(content=None, description=None, abort=False, error_plain=None, error_html=None)[source]
Creates a new
CreationResult.
- class SourceMeta(name, bases, class_dict)[source]
Bases:
typeSource metaclass. Registers all source classes in the sources global.
- class Source[source]
Bases:
objectAbstract base class for a source (e.g. Facebook, Twitter).
Concrete subclasses must override the class constants below and implement
get_activities().- EMBED_POST
the HTML for embedding a post. Should have a
%(url)splaceholder for the post URL and optionally a%(content)splaceholder for the post content.- Type:
- HTML2TEXT_OPTIONS
maps str html2text option names to values. https://github.com/Alir3z4/html2text/blob/master/docs/usage.md#available-options
- Type:
- TRUNCATE_TEXT_LENGTH
optional character limit to truncate to. Defaults to Twitter’s limit, 280 characters as of 2019-10-12.
- Type:
- TRUNCATE_URL_LENGTH
optional number of characters that URLs count for. Defaults to Twitter’s, 23 as of 2019-10-12.
- Type:
- OPTIMIZED_COMMENTS
whether
get_comment()is optimized and only fetches the requested comment. If False,get_comment()fetches many or all of the post’s comments to find the requested one.- Type:
- get_activities(*args, **kwargs)[source]
Fetches and returns a list of activities.
See
get_activities_response()for args and kwargs.
- get_activities_response(user_id=None, group_id=None, app_id=None, activity_id=None, start_index=0, count=0, etag=None, min_id=None, cache=None, fetch_replies=False, fetch_likes=False, fetch_shares=False, include_shares=True, fetch_events=False, fetch_mentions=False, search_query=None, scrape=False, **kwargs)[source]
Fetches and returns ActivityStreams activities and response details.
Subclasses should override this. See
get_activities()for an alternative that just returns the list of activities.If user_id is provided, only that user’s activity(s) are included. start_index and count determine paging, as described in the spec: http://activitystrea.ms/draft-spec.html#anchor14
app id is just object id: http://opensocial-resources.googlecode.com/svn/spec/2.0/Social-Data.xml#appId
group id is string id of group or @self, @friends, @all, @search: http://opensocial-resources.googlecode.com/svn/spec/2.0/Social-Data.xml#Group-ID
The
fetch_*kwargs all default to False because they often require extra API round trips. Some sources return replies, likes, and shares in the same initial call, so they may be included even if you don’t set their kwarg to True.- Parameters:
user_id (str) – defaults to the currently authenticated user
group_id (str) – one of
@self,@all,@friends,@search. defaults to@friendsapp_id (str)
activity_id (str)
start_index (int) – >= 0
count (int) – >= 0
etag (str) – optional ETag to send with the API request. Results will only be returned if the ETag has changed. Should include enclosing double quotes, e.g.
"ABC123"min_id (only) – return activities with ids greater than this
cache (dict) – optional, used to cache metadata like comment and like counts per activity across calls. Used to skip expensive API calls that haven’t changed.
fetch_replies (bool) – whether to fetch each activity’s replies also
fetch_likes (bool) – whether to fetch each activity’s likes also
include_shares (bool) – whether to include share activities
fetch_shares (bool) – whether to fetch each activity’s shares also
fetch_events (bool) – whether to fetch the user’s events also
fetch_mentions (bool) – whether to fetch posts that mention the user
search_query (str) – an optional search query, only for use with @search group_id
scrape (bool) – whether to scrape activities from HTML (etc) instead of using an API. Not supported by all sources.
kwargs – some subclasses accept extra kwargs. See their docs for details.
- Returns:
Response values based on OpenSocial ActivityStreams REST API.
The returned dict has at least these keys:
items(list of dict): activitiesstartIndex(int or None)itemsPerPage(int)totalResults(int or None, eg if it can’t be calculated efficiently)filtered: Falsesorted: FalseupdatedSince: Falseetag(str): ETag returned by the API’s initial call to get activities
- Return type:
- Raises:
ValueError – if any argument is invalid for this source
NotImplementedError – if the source doesn’t support the requested operation, eg Facebook doesn’t support search.
- classmethod make_activities_base_response(activities, *args, **kwargs)[source]
Generates a base response dict for
get_activities_response().See
get_activities()for args and kwargs.
- scraped_to_activities(scraped, count=None, fetch_extras=False, cookie=None)[source]
Converts scraped HTML (or JSON, etc) to AS activities.
Used for scraping data from the web instead of using an API. Useful for sources with APIs that are restricted or have difficult approval processes.
- Parameters:
- Returns:
([AS activities], AS logged in actor (ie viewer))
- Return type:
- scraped_to_activity(scraped)[source]
Converts scraped HTML (or JSON, etc) to a single AS activity.
Used for scraping data from the web instead of using an API. Useful for sources with APIs that are restricted or have difficult approval processes.
- scraped_to_actor(scraped)[source]
Converts HTML from a profile page to an AS1 actor.
- Args
html (str): HTML from a profile page
- Returns:
AS1 actor
- Return type:
- merge_scraped_reactions(scraped, activity)[source]
Converts and merges scraped likes and reactions into an activity.
New likes and emoji reactions are added to the activity in
tags. Existing likes and emoji reactions intagsare ignored.
- create(obj, include_link='omit', ignore_formatting=False)[source]
Creates a new object: a post, comment, like, share, or RSVP.
Subclasses should override this. Different sites will support different functionality; check each subclass for details. The actor will usually be the authenticated user.
- Parameters:
obj (dict) – ActivityStreams object. At minimum, must have the content field. objectType is strongly recommended.
include_link (str) –
INCLUDE_LINK,OMIT_LINK, orINCLUDE_IF_TRUNCATED; whether to include a link to the object (if it has one) in the content.ignore_formatting (bool) – whether to use content text as is, instead of converting its HTML to plain text styling (newlines, etc.)
- Returns:
The result.
contentwill be a dict or None. If the newly created object has an id or permalink, they’ll be provided in the values foridandurl.- Return type:
- preview_create(obj, include_link='omit', ignore_formatting=False)[source]
Previews creating a new object: a post, comment, like, share, or RSVP.
Returns HTML that previews what
create()with the same object will do.Subclasses should override this. Different sites will support different functionality; check each subclass for details. The actor will usually be the authenticated user.
- Parameters:
obj (dict) – ActivityStreams object. At minimum, must have the
contentfield.objectTypeis strongly recommended.include_link (str) –
INCLUDE_LINK,OMIT_LINK, orINCLUDE_IF_TRUNCATED; whether to include a link to the object (if it has one) in the content.ignore_formatting (bool) – whether to use content text as is, instead of converting its HTML to plain text styling (newlines, etc.)
- Returns:
The result. content will be a dict or
None.- Return type:
- delete(id)[source]
Deletes a post.
Generally only supports posts that were authored by the authenticating user.
- Parameters:
id (str) – silo object id
- Return type:
- preview_delete(id)[source]
Previews deleting a post.
- Parameters:
id (str) – silo object id
- Return type:
- get_comment(comment_id, activity_id=None, activity_author_id=None, activity=None)[source]
Fetches and returns a comment.
Subclasses should override this.
- Parameters:
- Returns:
ActivityStreams comment object
- Return type:
- Raises:
ValueError – if any argument is invalid for this source
- get_like(activity_user_id, activity_id, like_user_id, activity=None)[source]
Fetches and returns a ‘like’.
Default implementation that fetches the activity and its likes, then searches for a like by the given user. Subclasses should override this if they can optimize the process.
- Parameters:
- Returns:
ActivityStreams like activity
- Return type:
- get_reaction(activity_user_id, activity_id, reaction_user_id, reaction_id, activity=None)[source]
Fetches and returns a reaction.
Default implementation that fetches the activity and its reactions, then searches for this specific reaction. Subclasses should override this if they can optimize the process.
- Parameters:
- Returns:
ActivityStreams reaction activity
- Return type:
Fetches and returns a share.
- Parameters:
- Returns:
an ActivityStreams share activity
- Return type:
- get_rsvp(activity_user_id, event_id, user_id, event=None)[source]
Fetches and returns an RSVP.
- Parameters:
Returns: dict, an ActivityStreams RSVP activity object
- get_followers(user_id)[source]
Returns the current user’s followers.
This will often be limited, eg to the first 10k followers, depending on the silo.
- get_follows(user_id)[source]
Returns the current user’s follows.
This will often be limited, eg to the first 10k follows, depending on the silo.
- get_blocklist()[source]
Fetches and returns the current user’s block list.
…ie the users that the current user is blocking. The exact semantics of blocking vary from silo to silo.
- Returns:
actor objects
- Return type:
sequence of dict
- get_blocklist_ids()[source]
Returns the current user’s block list as a list of silo-specific user ids.
- to_as1_actor(user)[source]
Converts a user to an actor.
The returned object will have at least a
urlfield. If the user has multiple URLs, there will also be aurlslist field whose elements are dicts withvalueURL.
- user_to_actor(user)
Deprecated! Use
to_as1_actor()instead.
- static postprocess_activity(activity, **kwargs)[source]
Does source-independent post-processing of an AS1 activity, in place.
populates
titlecalls
postprocess_object`()
- Parameters:
activity (dict) – AS1 activity
**kwargs – passed through to
postprocess_object`()
- static postprocess_object(obj, mentions=False, first_link_to_attachment=False)[source]
Does source-independent post-processing of an AS1 object, in place.
Populates
location.positionbased on latitude and longitude.Optionally interprets HTML links in content with text starting with
@, eg@useror@user.comor@user@instance.com, as @-mentions and addsmentiontags for them.Optionally fetches the first HTML link in content and generates an
attachmentfor it
- Parameters:
obj (dict) – AS1 object
mentions (boolean) – whether to detect @-mention links and convert them to mention tags
first_link_to_attachment (boolean) – whether to generate an
attachmentfor the first HTML link incontent, if any. Will make external HTTP requests!
- Returns:
obj, modified in place- Return type:
- base_object(obj)[source]
Returns the
basesilo object that an object operates on.For example, if the object is a comment, this returns the post that it’s a comment on. If it’s an RSVP, this returns the event. The id in the returned object is silo-specific, ie not a tag URI.
Subclasses may override this.
- classmethod base_id(url)[source]
Guesses the id of the object in the given URL.
- Returns:
str or None
- truncate(content, url, include_link, type=None, quote_url=None, **kwargs)[source]
Shorten text content to fit within a character limit.
Character limit and URL character length are taken from
TRUNCATE_TEXT_LENGTHandTRUNCATE_URL_LENGTH.- Parameters:
content (str)
url (str)
include_link (str) –
OMIT_LINK,INCLUDE_LINK, orINCLUDE_IF_TRUNCATEDtype (str) – optional:
article,note, etc. Also accepts custom typedm.quote_url (str) – URL, optional. If provided, it will be appended to the content, after truncating.
**kwargs – passed through to brevity.shorten
- Returns:
the possibly shortened and ellipsized text
- Return type:
twitter
Twitter source class.
Uses the v1.1 REST API: https://developer.twitter.com/en/docs/api-reference-index
The Audience Targeting to field is set to @public or @private based
on whether the tweet author’s protected field is true or false.
https://dev.twitter.com/docs/platform-objects/users
- class OffsetTzinfo(utc_offset=0)[source]
Bases:
tzinfoA simple, DST-unaware tzinfo from given utc offset in seconds.
- class Twitter(access_token_key, access_token_secret, username=None, scrape_headers=None)[source]
Bases:
SourceTwitter source class. See file docstring and
Sourcefor details.- get_actor(screen_name=None)[source]
Returns a user as a JSON ActivityStreams actor dict.
- Parameters:
screen_name (str) – username. Defaults to the current user.
- get_activities_response(user_id=None, group_id=None, app_id=None, activity_id=None, start_index=0, count=0, etag=None, min_id=None, cache=None, fetch_replies=False, fetch_likes=False, fetch_shares=False, include_shares=True, fetch_events=False, fetch_mentions=False, search_query=None, scrape=False, **kwargs)[source]
Fetches posts and converts them to ActivityStreams activities.
See
source.Source.get_activities_response()for details.app_idis ignored.min_idis translated to Twitter’ssince_id.The code for handling ETags (and 304 Not Changed responses and setting
If-None-Match) is here, but unused right now since Twitter evidently doesn’t support ETags. From https://dev.twitter.com/discussions/5800 : “I’ve confirmed with our team that we’re not explicitly supporting this family of features.”Likes (nee favorites) are scraped from twitter.com, since Twitter’s REST API doesn’t offer a way to fetch them. You can also get them from the Streaming API, though, and convert them with
streaming_event_to_object(). https://dev.twitter.com/docs/streaming-apis/messages#Events_eventShares (ie retweets) are fetched with a separate API call per tweet: https://dev.twitter.com/docs/api/1.1/get/statuses/retweets/%3Aid
However, retweets are only fetched for the first 15 tweets that have them, since that’s Twitter’s rate limit per 15 minute window. :( https://dev.twitter.com/docs/rate-limiting/1.1/limits
Quote tweets are fetched by searching for the possibly quoted tweet’s ID, using the OR operator to search up to 5 IDs at a time, and then checking the
quoted_status_id_strfield: https://dev.twitter.com/overview/api/tweets#quoted_status_id_strUse the group_id @self to retrieve a user_id’s timeline. If
user_idis None or@me, it will return tweets for the current API user.group_id can be used to specify the slug of a list for which to return tweets. By default the current API user’s lists will be used, but lists owned by other users can be fetched by explicitly passing a username to
user_id, e.g. to fetch tweets from the list@exampleuser/example-listyou would callget_activities(user_id='exampleuser', group_id='example-list').Twitter replies default to including a mention of the user they’re replying to, which overloads mentions a bit. When fetch_mentions is True, we determine that a tweet mentions the current user if it @-mentions their username and:
it’s not a reply, OR
it’s a reply, but not to the current user, AND
the tweet it’s replying to doesn’t @-mention the current user
- Raises:
NotImplementedError – if
fetch_likesis True butscrape_headerswas not provided to the constructor.
XXX HACK: this is currently hacked for Bridgy to NOT pass
min_idto the request for fetching activity tweets themselves, but to pass it to all of the requests for filling in replies, retweets, etc. That’s because we want to find new replies and retweets of older initial tweets. TODO: find a better way.
- fetch_replies(activities, min_id=None)[source]
Fetches and injects Twitter replies into a list of activities, in place.
Includes indirect replies ie reply chains, not just direct replies. Searches for @-mentions, matches them to the original tweets with
in_reply_to_status_id_str, and recurses until it’s walked the entire tree.
- fetch_mentions(username, tweets, min_id=None)[source]
Fetches a user’s @-mentions and returns them as ActivityStreams.
Tries to only include explicit mentions, not mentions automatically created by @-replying. See
get_activities_response()for details.
- get_comment(comment_id, activity_id=None, activity_author_id=None, activity=None)[source]
Returns an ActivityStreams comment object.
Returns an ActivityStreams ‘share’ activity object.
- get_blocklist()[source]
Returns the current user’s block list.
May make multiple API calls, using cursors, to fully fetch large blocklists. https://dev.twitter.com/overview/api/cursoring
Block lists may have up to 10k users, but each API call only returns 100 at most, and the API endpoint is rate limited to 15 calls per user per 15m. So if a user has >1500 users on their block list, we can’t get the whole thing at once. :(
- Returns:
actors
- Return type:
- Raises:
RateLimited – if we hit the rate limit. The partial attribute will
have the list of user ids we fetched before hitting the limit. –
- get_blocklist_ids()[source]
Returns the current user’s block list as a list of Twitter user ids.
May make multiple API calls, using cursors, to fully fetch large blocklists. https://dev.twitter.com/overview/api/cursoring
Subject to the same rate limiting as
get_blocklist(), but each API call returns ~4k ids, so realistically this can actually fetch blocklists of up to 75k users at once. Beware though, many Twitter users have even more!- Returns:
Twitter user ids
- Return type:
sequence of str
- Raises:
RateLimited – if we hit the rate limit. The partial attribute will
have the list of user ids we fetched before hitting the limit. –
- create(obj, include_link='omit', ignore_formatting=False)[source]
Creates a tweet, reply tweet, retweet, or favorite.
- Parameters:
- Returns:
content will be a dict with
id,url, andtypekeys (all optional) for the newly created Twitter object (or None)- Return type:
- preview_create(obj, include_link='omit', ignore_formatting=False)[source]
Previews creating a tweet, reply tweet, retweet, or favorite.
- Parameters:
- Returns:
content will be an HTML snippet
- Return type:
CreationResult or None
- upload_images(images)[source]
Uploads one or more images from web URLs.
https://dev.twitter.com/rest/reference/post/media/upload
Note that files and JSON bodies in media POST API requests are not included in OAuth signatures. https://developer.twitter.com/en/docs/media/upload-media/uploading-media/media-best-practices
- upload_video(url)[source]
Uploads a video from a web URL using the chunked upload process.
Chunked upload consists of multiple API calls:
command=INIT, which allocates the media idcommand=APPENDfor each 5MB block, up to 15MB totalcommand=FINALIZEcommand=STATUSto wait until Twitter finishes processing the video
https://developer.twitter.com/en/docs/media/upload-media/uploading-media/chunked-media-upload
- delete(id)[source]
Deletes a tweet. The authenticated user must have authored it.
- Parameters:
- Returns:
content is Twitter API response dict
- Return type:
- urlopen(url, parse_response=True, **kwargs)[source]
Wraps
urllib.request.urlopen()and adds an OAuth signature.
- base_object(obj)[source]
Returns the “base” silo object that an object operates on.
Includes special handling for Twitter photo and video URLs, eg:
https://twitter.com/nelson/status/447465082327298048/photo/1https://twitter.com/nelson/status/447465082327298048/video/1
- tweet_to_activity(tweet)
Deprecated! Use
tweet_to_as1_activity()instead.
- tweet_to_as1_object(tweet)[source]
Converts a tweet to an AS1 object.
- Parameters:
tweet (dict) – a decoded JSON tweet
- Returns:
an ActivityStreams object dict, ready to be JSON-encoded
- tweet_to_object(tweet)
Deprecated! Use
tweet_to_as1_object()instead.
- user_to_actor(user)
Deprecated! Use
to_as1_actor()instead.
- retweet_to_object(retweet)
Deprecated! Use
retweet_to_as1()instead.
- streaming_event_to_object(event)[source]
Converts a Streaming API event to an object.
https://dev.twitter.com/docs/streaming-apis/messages#Events_event
Right now, only converts favorite events to like objects.
- static rfc2822_to_iso8601(time_str)[source]
Converts a timestamp string from RFC 2822 format to ISO 8601.
- Example RFC 2822 timestamp string generated by Twitter:
Wed May 23 06:01:13 +0000 2007- Resulting ISO 8610 timestamp string:
2007-05-23T06:01:13