···11+{% extends "base.html.j2" %}
22+{% import "try-it-macros.html.j2" as try_it %}
33+44+{% block title %}Many to Many counts{% endblock %}
55+{% block description %}Counts of many-to-many {{ query.source }} join records with links to {{ query.subject }} and a secondary target at {{ query.path_to_other }}{% endblock %}
66+77+{% block content %}
88+99+ {% call try_it::get_many_to_many_counts(
1010+ query.subject,
1111+ query.source,
1212+ query.path_to_other,
1313+ query.did,
1414+ query.other_subject,
1515+ query.limit,
1616+ ) %}
1717+1818+ <h2>
1919+ Many-to-many links to <code>{{ query.subject }}</code> joining through <code>{{ query.path_to_other }}</code>
2020+ {% if let Some(browseable_uri) = query.subject|to_browseable %}
2121+ <small style="font-weight: normal; font-size: 1rem"><a href="{{ browseable_uri }}">browse record</a></small>
2222+ {% endif %}
2323+ </h2>
2424+2525+ <p><strong>{% if cursor.is_some() || query.cursor.is_some() %}more than {% endif %}{{ counts_by_other_subject.len()|to_u64|human_number }} joins</strong> <code>{{ query.source }}→{{ query.path_to_other }}</code></p>
2626+2727+ <ul>
2828+ <li>See direct backlinks at <code>/xrpc/blue.microcosm.links.getBacklinks</code>: <a href="/xrpc/blue.microcosm.links.getBacklinks?subject={{ query.subject|urlencode }}&source={{ query.source|urlencode }}">/xrpc/blue.microcosm.links.getBacklinks?subject={{ query.subject }}&source={{ query.source }}</a></li>
2929+ <li>See all links to this target at <code>/links/all</code>: <a href="/links/all?target={{ query.subject|urlencode }}">/links/all?target={{ query.subject }}</a></li>
3030+ </ul>
3131+3232+ <h3>Counts by other subject:</h3>
3333+3434+ {% for counts in counts_by_other_subject %}
3535+ <pre style="display: block; margin: 1em 2em" class="code"><strong>Joined subject</strong>: {{ counts.subject }}
3636+<strong>Joining records</strong>: {{ counts.total }}
3737+<strong>Unique joiner ids</strong>: {{ counts.distinct }}
3838+-> {% if let Some(browseable_uri) = counts.subject|to_browseable -%}
3939+ <a href="{{ browseable_uri }}">browse record</a>
4040+ {%- endif %}</pre>
4141+ {% endfor %}
4242+4343+ {% if let Some(c) = cursor %}
4444+ <form method="get" action="/xrpc/blue.microcosm.links.getManyToManyCounts">
4545+ <input type="hidden" name="subject" value="{{ query.subject }}" />
4646+ <input type="hidden" name="source" value="{{ query.source }}" />
4747+ <input type="hidden" name="pathToOther" value="{{ query.path_to_other }}" />
4848+ {% for did in query.did %}
4949+ <input type="hidden" name="did" value="{{ did }}" />
5050+ {% endfor %}
5151+ {% for otherSubject in query.other_subject %}
5252+ <input type="hidden" name="otherSubject" value="{{ otherSubject }}" />
5353+ {% endfor %}
5454+ <input type="hidden" name="limit" value="{{ query.limit }}" />
5555+ <input type="hidden" name="cursor" value={{ c|json|safe }} />
5656+ <button type="submit">next page…</button>
5757+ </form>
5858+ {% else %}
5959+ <button disabled><em>end of results</em></button>
6060+ {% endif %}
6161+6262+ <details>
6363+ <summary>Raw JSON response</summary>
6464+ <pre class="code">{{ self|tojson }}</pre>
6565+ </details>
6666+6767+{% endblock %}
+38-2
constellation/templates/hello.html.j2
···1919 <p>It works by recursively walking <em>all</em> records coming through the firehose, searching for anything that looks like a link. Links are indexed by the target they point at, the collection the record came from, and the JSON path to the link in that record.</p>
20202121 <p>
2222- This server has indexed <span class="stat">{{ stats.linking_records|human_number }}</span> links between <span class="stat">{{ stats.targetables|human_number }}</span> targets and sources from <span class="stat">{{ stats.dids|human_number }}</span> identities over <span class="stat">{{ days_indexed|human_number }}</span> days.<br/>
2222+ This server has indexed <span class="stat">{{ stats.linking_records|human_number }}</span> links between <span class="stat">{{ stats.targetables|human_number }}</span> targets and sources from <span class="stat">{{ stats.dids|human_number }}</span> identities over <span class="stat">
2323+ {%- if let Some(days) = days_indexed %}
2424+ {{ days|human_number }}
2525+ {% else %}
2626+ ???
2727+ {% endif -%}
2828+ </span> days.<br/>
2329 <small>(indexing new records in real time, backfill coming soon!)</small>
2430 </p>
25312626- <p>But feel free to use it! If you want to be nice, put your project name and bsky username (or email) in your user-agent header for api requests.</p>
3232+ {# {% for k, v in stats.other_data.iter() %}
3333+ <p><strong>{{ k }}</strong>: {{ v }}</p>
3434+ {% endfor %} #}
3535+3636+ <p>You're welcome to use this public instance! Please do not build the torment nexus. If you want to be nice, put your project name and bsky username (or email) in your user-agent header for api requests.</p>
273728382939 <h2>API Endpoints</h2>
···43534454 <p style="margin-bottom: 0"><strong>Try it:</strong></p>
4555 {% call try_it::get_backlinks("at://did:plc:a4pqq234yw7fqbddawjo7y35/app.bsky.feed.post/3m237ilwc372e", "app.bsky.feed.like:subject.uri", [""], 16) %}
5656+5757+5858+ <h3 class="route"><code>GET /xrpc/blue.microcosm.links.getManyToManyCounts</code></h3>
5959+6060+ <p>TODO: description</p>
6161+6262+ <h4>Query parameters:</h4>
6363+6464+ <ul>
6565+ <li><p><code>subject</code>: required, must url-encode. Example: <code>at://did:plc:vc7f4oafdgxsihk4cry2xpze/app.bsky.feed.post/3lgwdn7vd722r</code></p></li>
6666+ <li><p><code>source</code>: required. Example: <code>app.bsky.feed.like:subject.uri</code></p></li>
6767+ <li><p><code>pathToOther</code>: required. Path to the secondary link in the many-to-many record. Example: <code>otherThing.uri</code></p></li>
6868+ <li><p><code>did</code>: optional, filter links to those from specific users. Include multiple times to filter by multiple users. Example: <code>did=did:plc:vc7f4oafdgxsihk4cry2xpze&did=did:plc:vc7f4oafdgxsihk4cry2xpze</code></p></li>
6969+ <li><p><code>otherSubject</code>: optional, filter secondary links to specific subjects. Include multiple times to filter by multiple users. Example: <code>at://did:plc:vc7f4oafdgxsihk4cry2xpze/app.bsky.feed.post/3lgwdn7vd722r</code></p></li>
7070+ <li><p><code>limit</code>: optional. Default: <code>16</code>. Maximum: <code>100</code></p></li>
7171+ </ul>
7272+7373+ <p style="margin-bottom: 0"><strong>Try it:</strong></p>
7474+ {% call try_it::get_many_to_many_counts(
7575+ "at://did:plc:wshs7t2adsemcrrd4snkeqli/sh.tangled.label.definition/good-first-issue",
7676+ "sh.tangled.label.op:add[].key",
7777+ "subject",
7878+ [""],
7979+ [""],
8080+ 25,
8181+ ) %}
468247834884 <h3 class="route"><code>GET /links</code></h3>