UI edits: enter web site page, /docs, flashed messages, copy Bridgy's CSS

pull/297/head
Ryan Barrett 2022-11-18 22:30:07 -08:00
rodzic f384bf5529
commit b854981497
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 6BE31FDF4776E9D4
10 zmienionych plików z 661 dodań i 68 usunięć

Wyświetl plik

@ -82,7 +82,8 @@ def requests_post(url, **kwargs):
def _requests_fn(fn, url, parse_json=False, **kwargs):
"""Wraps requests.* and adds raise_for_status()."""
resp = fn(url, gateway=True, **kwargs)
kwargs.setdefault('gateway', True)
resp = fn(url, **kwargs)
logger.info(f'Got {resp.status_code} headers: {resp.headers}')
type = content_type(resp)
@ -449,13 +450,14 @@ def redirect_unwrap(val):
return val
def actor(domain):
def actor(domain, user=None):
"""Fetches a home page, converts its representative h-card to AS2 actor.
Creates a User for the given domain if one doesn't already exist.
Args:
domain: str
user: :class:`User`, optional
Returns: dict, AS2 actor
"""
@ -469,7 +471,9 @@ def actor(domain):
if not hcard:
error(f"Couldn't find a representative h-card (http://microformats.org/wiki/representative-hcard-parsing) on {mf2['url']}")
user = User.get_or_create(domain)
if not user:
user = User.get_or_create(domain)
actor = postprocess_as2(
as2.from_as1(microformats2.json_to_object(hcard)), user=user)
actor.update({

Wyświetl plik

@ -2,6 +2,7 @@
import logging
import urllib.parse
import requests
from werkzeug.exceptions import BadRequest, NotFound
from Crypto.PublicKey import RSA
@ -79,18 +80,21 @@ class User(StringIdModel):
# check webfinger redirect
path = f'/.well-known/webfinger?resource=acct:{domain}@{domain}'
resp = common.requests_get(urllib.parse.urljoin(site, path),
allow_redirects=False)
expected = urllib.parse.urljoin(request.host_url, path)
if resp.is_redirect and resp.headers.get('Location') == expected:
self.has_redirects = True
try:
resp = common.requests_get(urllib.parse.urljoin(site, path),
allow_redirects=False, gateway=False)
expected = urllib.parse.urljoin(request.host_url, path)
self.has_redirects = (resp.is_redirect and
resp.headers.get('Location') == expected)
except requests.RequestException:
self.has_redirects = False
# check home page
try:
common.actor(self.key.id())
common.actor(self.key.id(), user=self)
self.has_hcard = True
except (BadRequest, NotFound):
pass
self.has_hcard = False
class Activity(StringIdModel):

Wyświetl plik

@ -9,7 +9,7 @@ from flask import redirect, render_template, request
from google.cloud.ndb.stats import KindStat
from granary import as2, atom, microformats2, rss
from oauth_dropins.webutil import flask_util, logs, util
from oauth_dropins.webutil.flask_util import error
from oauth_dropins.webutil.flask_util import error, flash, redirect
from oauth_dropins.webutil.util import json_dumps, json_loads
from app import app, cache
@ -23,8 +23,40 @@ FOLLOWERS_UI_LIMIT = 999
@app.route('/')
@flask_util.cached(cache, datetime.timedelta(days=1))
def front_page():
"""View for the front page."""
return render_template('index.html')
"""View for the front page."""
return render_template('index.html')
@app.route('/docs')
@flask_util.cached(cache, datetime.timedelta(days=1))
def docs():
"""View for the docs page."""
return render_template('docs.html')
@app.get('/web-site')
@flask_util.cached(cache, datetime.timedelta(days=1))
def enter_web_site():
return render_template('enter_web_site.html')
@app.post('/web-site')
def check_web_site():
url = request.values['url']
domain = util.domain_from_link(url)
if not domain:
error(f'No domain found in {url}')
user = User.get_or_create(domain)
try:
user.verify()
except BaseException as e:
if util.is_connection_failure(e):
flash(f"Couldn't connect to {url}")
return render_template('enter_web_site.html')
user.put()
return redirect(f'/user/{domain}')
@app.get(f'/responses/<regex("{common.DOMAIN_RE}"):domain>') # deprecated
@ -34,13 +66,14 @@ def user_deprecated(domain):
@app.get(f'/user/<regex("{common.DOMAIN_RE}"):domain>')
def user(domain):
if not User.get_by_id(domain):
return render_template('user_not_found.html', domain=domain), 404
user = User.get_by_id(domain)
if not user:
return render_template('user_not_found.html', domain=domain), 404
query = Activity.query(
Activity.status.IN(('new', 'complete', 'error')),
Activity.domain == domain,
)
)
activities, before, after = fetch_page(query, Activity)
followers = Follower.query(Follower.dest == domain)\

Wyświetl plik

@ -18,6 +18,48 @@
min-width: 30px;
}
#messages {
position: fixed;
width: 100%;
font-size: 1.5em;
top: .2em;
text-align: center;
z-index: 999;
}
.message {
display: block;
opacity: 1;
background-color: gold;
color: #444;
padding: .5em;
transition: opacity 5s linear 20s;
}
#logins {
margin-top: .3em;
text-align: right;
}
@media (max-width: 600px) {
#logo {
float: left;
}
#header {
float: none;
width: 100%;
}
}
#signups {
margin-top: 2em;
}
#signups hr {
width: 50%;
border-color: lightgray;
}
.big {
font-size: 1.5em;
}
@ -40,22 +82,157 @@
font-weight: normal;
}
#more-link {
font-size: .7em;
}
body.about #more-link {
display: none;
}
pre .keyword, code .keyword, code.keyword {
color: green;
}
pre .value, code .value, code.value {
color: chocolate;
}
.row {
text-align: center;
}
#top {
#blogposts, #publishes, #webmentions, #user {
margin-top: 1em;
}
#top, #listen-ui, #listening-label, #publish-ui, #publishing-label {
margin-bottom: 1em;
}
/* tentatively removed since it didn't look great with webmention signups */
/* @media (min-width: 768px) { */
/* #listen-signup, #listen-ui { */
/* border-left: 1px solid lightgray; */
/* border-right: 1px solid lightgray; */
/* } */
/* } */
#listen-signups input, #webmention-signups input {
margin: .5em;
}
.header, #user, .promo, #listen-signups, #webmention-signups {
margin-bottom: 1em;
}
#edit-profile em {
font-style: normal;
}
form {
display: inline;
}
form input {
vertical-align: middle;
}
.delete-website {
padding: 0;
font-size: .7em;
border: none;
background-color: transparent;
}
.delete-website:hover {
color: red;
background-color: transparent;
}
#users-label {
margin-top: 1em;
}
#users {
list-style: none;
}
#users-paging {
clear: both;
}
.source {
text-align: left;
margin-top: .5em;
}
#choose-blog > ul {
list-style: none;
text-align: left;
}
@media (min-width: 768px) {
.user-items > .row {
display: table;
table-layout: fixed !important;
width: 100%;
text-align: left;
}
.user-items > .row > .col-sm-1,
.user-items > .row > .col-sm-2,
.user-items > .row > .col-sm-3,
.user-items > .row > .col-sm-4 {
display: table-cell;
float: none;
text-align: left;
border-spacing: 0;
}
}
@media (max-width: 767px) {
.user-items > .row {
margin-bottom: 1em;
}
}
.source-buttons, .original-post {
white-space: nowrap;
}
.delete {
border: none;
background: none;
font-weight: bold;
color: red;
}
.delete:hover, .delete:focus {
color: darkred;
}
/* .glyphicon-warning-sign { color: gold; } */
.glyphicon-ok-sign { color: green; }
.glyphicon-exclamation-sign { color: gold; }
.glyphicon-pause { color: gold`; }
.glyphicon-refresh { color: blue; }
.glyphicon-remove { color: red !important; }
.glyphicon-transfer { color: blue; }
.user-items {
font-size: .8em;
list-style: none;
}
code {
color: black;
background-color: white !important;
font-size: .8em;
}
a code {
color: inherit;
.original-post-links {
list-style: none;
padding-left: 0;
}
label {
@ -63,16 +240,11 @@ label {
font-weight: 300;
}
#sites li {
display: inline;
}
#sites li::before {
content: "\2022 \00A0";
}
#sites li:first-child::before {
content: none;
/* Seems like this shouldn't be necessary, but cursor was ending up as auto on the
* a > img for the disabled Facebook signup button for some reason, not sure why.
*/
a > img {
cursor: pointer;
}
button {
@ -86,7 +258,26 @@ button {
border-radius: 2px;
}
button[disabled] {
border-color: gray !important;
color: gray !important;
pointer-events: auto !important;
}
button[disabled]:hover {
background-color: lightgray !important;
}
#preview-ui {
margin-top: 1em;
}
#preview-ui > * {
vertical-align: middle;
}
.btn-default {
background-color: #CEF;
border-color: #337AB7;
color: #337AB7;
}
@ -97,15 +288,76 @@ button {
color: #337AB7;
}
#get-started {
border-color: green;
color: white;
background-color: #6A6;
font-size: 1.5em;
.disable-button, #bad-button {
border-color: red;
color: red;
}
#get-started:hover {
background-color: #8C8;
.disable-button:hover, #bad-button:hover {
background-color: #FCC;
}
#good-button {
border-color: green;
color: green;
}
#good-button:hover {
background-color: #DED;
}
#micropub-token-button, #disable-publish-button {
margin-top: -6px;
}
.mastodon-button {
height: 50px;
padding: 6px;
background-color: #323946;
}
#preview .verb {
font-weight: bold;
}
#preview-text {
display: inline-block;
margin-top: 1em;
text-align: left;
white-space: pre-wrap;
font-family: inherit;
font-size: inherit;
max-width: 98%;
}
#preview-text hr {
border-color: #cccccc;
}
#preview-text img, #preview-text video {
max-height: 200px;
max-width: 100%;
margin-top: 1em;
}
.mastodon-embed {
margin: 1em;
}
input[type="text"], input[type="url"] {
padding-left: .3em;
padding-right: .3em;
border: 1px solid black;
font-size: 1em;
}
#sent pre {
display: inline-block;
}
/* Override the inline display:block which makes it align left instead of center. */
iframe#twitter-widget-0 {
display: inline !important;
}
#footer {
@ -114,7 +366,7 @@ button {
text-align: right;
}
.shadow {
.shadow, .profile, #screenshot {
-moz-box-shadow: 2px 2px 4px rgba(0,0,0,0.4);
-webkit-box-shadow: 2px 2px 4px rgba(0,0,0,0.4);
/* CSS3 */
@ -125,7 +377,7 @@ button {
filter: progid:DXImageTransform.Microsoft.Shadow(Strength=2,Direction=135,Color='#666666');
}
.shadow:hover {
.shadow:hover, .profile:hover, #screenshot:hover {
-moz-box-shadow: 2px 2px 4px rgba(0,0,0,0.8);
-webkit-box-shadow: 2px 2px 4px rgba(0,0,0,0.8);
/* CSS3 */
@ -136,7 +388,30 @@ button {
filter: progid:DXImageTransform.Microsoft.Shadow(Strength=2,Direction=135,Color='#222222');
}
#docs > ul {
.error, .warning {
margin: 10px;
padding: .2em;
font-style: italic;
}
.error {
background-color: lightcoral !important;
}
.warning {
background-color: gold !important;
}
.error p, .warning p {
margin: 10px;
}
.error code, .warning code {
font-style: normal;
background-color: inherit !important;
}
#docs {
list-style: none;
}
@ -146,34 +421,18 @@ button {
font-weight: bold;
}
.answer ul {
.answer ul li, .answer ol {
margin-bottom: .5em;
}
pre .keyword, code.keyword {
color: green;
}
pre .value, code.value {
color: chocolate;
}
td, th {
padding-left: .4em;
padding-right: .4em;
padding-top: .2em;
padding-bottom: .2em;
/* confirm_instagram.html */
iframe {
width: 50%;
border: 1px solid gray;
height: 300px;
}
.follower {
text-align: left;
margin-top: .5em;
}
/* .glyphicon-warning-sign { color: gold; } */
.glyphicon-ok-sign { color: green; }
.glyphicon-exclamation-sign { color: gold; }
.glyphicon-pause { color: gold; }
.glyphicon-refresh { color: blue; }
.glyphicon-remove { color: red !important; }
.glyphicon-transfer { color: blue; }

Wyświetl plik

@ -17,7 +17,7 @@
</div>
</div>
{% else %}
<div class="row">None</div>
<div class="row">Nothing yet!</div>
{% endfor %}
{% include "paging.html" %}

Wyświetl plik

@ -13,10 +13,23 @@
<link rel="stylesheet" href="/oauth_dropins_static/bootstrap.min.css" />
<link rel="stylesheet" href="/static/style.css" type="text/css" />
<link rel="webmention" href="/webmention" />
<!-- Not async because it adds a DOMContentLoaded event listener, which may
-- happen before an async script loads. -->
<script src="/oauth_dropins_static/util.js"></script>
</head>
<body>
{% with messages = get_flashed_messages() %}
{% if messages %}
<div id="messages">
{% for message in messages %}
<p class="message shadow">{{ message|safe }}</p>
{% endfor %}
</div>
{% endif %}
{% endwith %}
<main class="tp-main lead container">
<br />
@ -33,10 +46,9 @@
<div id="header" class="col-xs-7">
<p class="big">
Got an <a href="https://indieweb.org/">IndieWeb</a> site?
Want to interact with <a href="https://joinmastodon.org/">Mastodon</a>
and the rest of the <a href="https://en.wikipedia.org/wiki/Fediverse">fediverse</a>?
<a id="title" href="/" style="white-space: nowrap">Bridgy Fed</a> is for you.
<a id="title" href="/" style="white-space: nowrap">Bridgy Fed</a>
connects your web site to <a href="https://joinmastodon.org/">Mastodon</a>
and the <a href="https://en.wikipedia.org/wiki/Fediverse">fediverse</a>.
</p></div>
</div>
@ -48,7 +60,8 @@ and the rest of the <a href="https://en.wikipedia.org/wiki/Fediverse">fediverse<
{% endblock %}
<div id="footer">
<a href="https://github.com/snarfed/bridgy-fed/issues">Bugs</a>
<a href="/docs">Docs</a>
| <a href="https://github.com/snarfed/bridgy-fed/issues">Bug?</a>
| <a href="https://github.com/snarfed/bridgy-fed">Source</a>
| <a href="https://indieweb.org/">#IndieWeb</a>
| <a href="https://brid.gy/">Bridgy</a>

241
templates/docs.html 100644
Wyświetl plik

@ -0,0 +1,241 @@
{% extends "base.html" %}
{% block content %}
<div id="docs">
<ul>
<li><a href="#work">How does it work?</a></li>
<li><a href="#sites">Which sites are supported?</a></li>
<li><a href="#use">How do I use it?</a></li>
<li><a href="#setup">How do I set it up?</a></li>
<li><a href="#image">How do I include an image in a post?</a></li>
<li><a href="#fragment">Can I publish just one part of a page?</a></li>
<li><a href="#discovery">How can people on the fediverse find me?</a></li>
<li><a href="#troubleshooting">I tried it, and it didn't work!</a></li>
<li><a href="#cost">How much does it cost?</a></li>
<li><a href="#who">Who are you? Why did you make this?</a></li>
<li><a href="#privacy">What do you do with my data?</a></li>
<li><a href="#history">How long has this been around?</a></li>
<li><a href="#bug">I found a bug! I have a feature request!</a></li>
</ul>
<ul>
<li id="work" class="question">How does it work?</li>
<li class="answer">
<p>
Bridgy Fed lets you interact with federated social networks like <a href="https://joinmastodon.org/">Mastodon</a> and <a href="https://project.hubzilla.org/">Hubzilla</a> from your <a href="https://indieweb.org/">IndieWeb</a> site. It translates posts, replies, likes, reposts, and follows from <a href="http://www.webmention.org/">webmentions</a> to federated social networking protocols like <a href="https://activitypub.rocks/">ActivityPub</a> and <a href="https://en.wikipedia.org/wiki/OStatus">OStatus</a>, and vice versa.
</p>
<p>
This isn't <a href="https://indieweb.org/syndication">syndication</a> or <a href="https://indieweb.org/POSSE">POSSE</a>! You don't need an account on Mastodon, Hubzilla, or anywhere else. Bridgy Fed lets your site act like a first class member of the <a href="https://en.wikipedia.org/wiki/Fediverse">fediverse</a>. People on federated social networks (aka fedsocnets) will see your posts directly from your own site, and vice versa.
</p>
<p>
Here's <a href="https://mastodon.technology/@snarfed/3194674">an example on Mastodon</a>, and <a href="https://hubzilla.com.br/channel/snarfed/?f=&mid=459a0b809f2d5395efd5d581dad70043c5ea9e1dbd156bc5e1b2f771c98eb970@hubzilla.com.br&zid=snarfed%40hubzilla.com.br">another example on Hubzilla</a>.
</p>
<p>
(If you just want people in the fediverse to see posts from your web site, <a href="https://www.google.com/search?q=rss+atom+mastodon+bot">consider an RSS or Atom feed bot instead</a>. Bridgy Fed is more powerful, but also more work to set up and use.)
</p>
<li id="sites" class="question">Which sites are supported?</li>
<li class="answer">
<p>
These sites are currently supported:
</p>
<ul>
<li><em><a href="https://joinmastodon.org/">Mastodon</a></em>: posts, replies, likes, reposts aka boosts, @-mentions, and follows, both directions, via ActivityPub.<br />
The instance must be running at least <a href="https://hackernoon.com/mastodon-and-the-w3c-f75f376f422">Mastodon 1.6</a>, and more reliably with 2.0 and up. You can find its version on the bottom or right of its <code>/about/more</code> page, e.g. <a href="https://mastodon.social/about/more">mastodon.social/about/more</a>.
</li>
<li><em><a href="https://project.hubzilla.org/">Hubzilla</a></em>: replies, likes, and reposts aka shares, both directions, via OStatus.<br />
The instance must be running <a href="https://hub.somaton.com/channel/mario/?f=&mid=6db16e0e253c3c376cb921e7b31f94c24522933d7e54c6cf9febaa05359ab2fe@hub.somaton.com">Hubzilla 2.6</a> or higher. You can find its version on its <code>/siteinfo</code> page, e.g. <a href="https://hub.somaton.com/siteinfo">hub.somaton.com/siteinfo</a>. It also needs the GNU Social addon installed and enabled, and you also need to enable it in your account settings on the <em>Feature/Addon settings</em> page (<code>/settings/featured</code>).
</li>
</ul>
<p>
We're aware of the sites below, and we've made progress on some, but they're not yet supported. Click through and vote for their feature requests if you're interested in any of them!
</p>
<ul>
<li><em><a href="https://github.com/snarfed/bridgy-fed/issues/7">Diaspora</a></em>, via OStatus.</li>
<li><em><a href="https://github.com/snarfed/bridgy-fed/issues/9">Friendica</a></em>, via OStatus.</li>
<li><em><a href="https://github.com/snarfed/bridgy-fed/issues/8">GNU Social</a></em> (née StatusNet), via OStatus.</li>
<li><em><a href="https://github.com/snarfed/bridgy-fed/issues/11">MediaGoblin</a></em>, via ActivityPub?</li>
<li><em><a href="https://github.com/snarfed/bridgy-fed/issues/12">Pleroma</a></em>, via ActivityPub.</li>
<li><em><a href="https://github.com/snarfed/bridgy-fed/issues/10">postActiv</a></em>, via ActivityPub or OStatus.</li>
</ul>
</li>
<li id="use" class="question">How do I use it?</li>
<li class="answer">
<p>
Federated social network identities take the form <code>@username@example.com</code>, like an email address with a leading <code>@</code>. Your site's identity via Bridgy Fed will be <code>@yourdomain.com@yourdomain.com</code>. Once you've <a href="#setup">set up Atom on your site</a>, people can follow you at that address.
</p>
<p>
Most fedsocnets also publish Atom themselves, so you can add profile URLs like <a href="https://mastodon.technology/@snarfed">mastodon.technology/@snarfed</a> to your <a href="https://indieweb.org/reader">reader</a> and see their posts there too.
</p>
<p>
To use it, first <a href="#setup">set up your site</a>, then create an IndieWeb <a href="https://indieweb.org/post">post</a>, <a href="https://indieweb.org/like">like</a>, <a href="https://indieweb.org/repost">repost</a>, <a href="https://indieweb.org/reply">reply</a>, or <a href="https://indieweb.org/follow">follow</a> as usual, and include a link to <code><a href="https://fed.brid.gy/">https://fed.brid.gy/</a></code> in that post. Your web server should then <a href="#setup">send Bridgy Fed a webmention</a>, which it will translate to a Salmon slap or ActivityPub activity and forward to the destination. For example:
</p>
<pre>&lt;div class="<span class='keyword'>h-entry</span>"&gt;
Regarding &lt;a class="<span class='keyword'>u-in-reply-to</span>" href="<a href='https://mastodon.technology/@snarfed/3194674'>https://mastodon.technology/@snarfed/3194674</a>"&gt;this post&lt;/a&gt;:
&lt;p class="<span class='keyword'>e-content</span>"&gt;<span class='value'>Highly entertaining. Please subscribe me to your newsletter.</span>&lt;/p&gt;
&lt;a href="<a href='https://fed.brid.gy/'>https://fed.brid.gy/</a>"&gt;&lt;/a&gt;
&lt;/div&gt;
</pre>
<p>
To receive likes, reposts, replies, and follows from fedsocnets, just make sure your site accepts webmentions! Bridgy translates incoming Salmon slaps and ActivityPub activities to webmentions and sends them to your site.</p>
<p>
The webmention source URL will usually be a proxy page on <code>fed.brid.gy</code>. For best results, <a href="https://brid.gy/about#appspot">make sure your webmention handler detects and handles <code>u-url</code> links</a>!
</p>
<p>
You can see your recent interactions at <a href="https://fed.brid.gy/user/[your-domain.com]">fed.brid.gy/user/[your-domain.com]</a>.
</p>
</li>
<li id="setup" class="question">How do I set it up?</li>
<li class="answer">
<p>
First, your site needs to support <a href="http://www.webmention.org/">webmentions</a>. <a href="https://indieweb.org/webmention#Publishing_Software">Check out the IndieWeb wiki</a> for instructions for your web server.
</p>
<p>
Next, configure your web site to redirect these URL paths to the same paths on <code>https://fed.brid.gy/</code>, including query parameters:
</p>
<pre>
/.well-known/host-meta
/.well-known/webfinger
</pre>
<p>Here are instructions for a few common web servers:</p>
<ul>
<li>
<p><em><a href="http://wordpress.org/">WordPress</a> (self-hosted)</em>: install the <a href="https://wordpress.org/plugins/safe-redirect-manager/">Safe Redirect Manager</a> plugin, then add these entries:</p>
<code>
/.well-known/host-meta* => https://fed.brid.gy/.well-known/host-meta*<br/>
/.well-known/webfinger* => https://fed.brid.gy/.well-known/webfinger*
</code>
</li>
<li><em><a href="http://withknown.com/">Known</a></em> or <em><a href="https://drupal.org/project/indieweb">Drupal</a></em>: follow the <a href="#apache">Apache</a> or <a href="#nginx">nginx</a> instructions below.
</li>
<li id="apache"><em><a href="http://httpd.apache.org/">Apache</a></em>: add this to your <code>.htaccess</code> file:<br />
<pre>RewriteEngine on
RewriteBase /
RewriteRule ^.well-known/(host-meta|webfinger).* https://fed.brid.gy/$0 [redirect=302,last]</pre>
(<code>RewriteEngine on</code> is optional if you already have it earlier in your <code>.htaccess</code>. <code>RewriteBase /</code> is optional if you don't have any other <code>RewriteBase</code> directives, or if you put this <code>RewriteRule</code> inside an existing <code>RewriteBase /</code> section.)
</li>
<li id="nginx"><em><a href="https://nginx.org/">nginx</a></em>: add this to your <code>nginx.conf</code> file, in the <code>server</code> section:<br />
<pre>rewrite ^/.well-known/(host-meta|webfinger).* https://fed.brid.gy$request_uri redirect;</pre>
</li>
<!--
<em><a href="https://www.blogger.com/">Blogger</a></em>:
Not to other domains
https://helplogger.blogspot.com/2014/07/how-to-set-custom-redirects-for-blogger-post.html
<em><a href="https://medium.com/">Medium</a>: TODO</em>
Redirects but not custom
https://help.medium.com/hc/en-us/articles/213475208-301-Redirects
<em><a href="http://www.tumblr.com/">Tumblr</a></em>:
Looks doable!
https://tumblr.zendesk.com/hc/en-us/articles/231449328-Redirect-pages
<em><a href="http://wordpress.com/">WordPress.com</a></em>:
Site Redirect, but not per URL
https://en.support.wordpress.com/site-redirect/
-->
</ul>
<p>
If you want people on OStatus sites like Hubzilla to see your posts, your web site will also need to support <a href="https://indieweb.org/WebSub">WebSub</a> (née PubSubHubbub). Specifically, <a href="https://blog.superfeedr.com/howto-pubsubhubbub/#discovery">your Atom feed needs to advertise it</a>. <a href="https://github.com/tootsuite/mastodon/issues/1441#issuecomment-302969948">Example details for Mastodon.</a> If you're on a CMS, it may already have a plugin! <a href="https://wordpress.org/">WordPress</a> has <a href="https://indieweb.org/WebSub#WordPress_Plugins_for_PuSH">a couple</a>, and <a href="http://withknown.com/">Known</a> has it <a href="https://indieweb.org/WebSub#1000s_of_Known_Sites">built in</a>. Or you can use <a href="https://superfeedr.com/publisher">Superfeedr</a> or <a href="https://switchboard.p3k.io/">Switchboard</a>.
</p>
</ol>
</li>
<li id="image" class="question">How do I include an image in a post?</li>
<li class="answer">
<p>
Use <code>&lt;img class="u-photo"&gt;</code> for the image in your post. For example:
<pre>
&lt;img class="<span class='keyword'>u-photo</span>" src="<span class='value'>/full_glass.jpg</span>" /&gt;
I love scotch. Scotchy scotchy scotch.
</pre>
</p>
</li>
<li id="fragment" class="question">Can I publish just one part of a page?</li>
<li class="answer">
<p>If that HTML element has its own id, then sure! Just put the id in the fragment of the URL that you publish. For example, to publish the <code>bar</code> post here:</p>
<pre>&lt;div id="<span class='value'>a</span>" class="<span class='keyword'>h-entry</span>"&gt;<span class='value'>foo</span>&lt;/div&gt;
&lt;div id="<span class='value'>b</span>" class="<span class='keyword'>h-entry</span>"&gt;<span class='value'>bar</span>&lt;/div&gt;
&lt;div id="<span class='value'>c</span>" class="<span class='keyword'>h-entry</span>"&gt;<span class='value'>baz</span>&lt;/div&gt;
</pre>
<p>...just add the id to your page's URL in a fragment, e.g. <code>http://site/post#b</code> here.</p>
</li>
<li id="discovery" class="question">How can people on the fediverse find me?</li>
<li class="answer">
<p>In general, all you have to do is use Bridgy Fed to interact with the fediverse once. Send an original post from your site, like or repost something, follow someone, etc. Then, when other users search for <code>@yourdomain.com@yourdomain.com</code>, they should find your profile!
</p>
<p>In practice, this can be a bit finicky, and takes time to propagate to other instances besides the one you first interacted with, but it generally does work.
</p>
</li>
<li id="troubleshooting" class="question">I tried it, and it didn't work!</li>
<li class="answer">
<p>If you sent a webmention, check the HTTP response code and body. It will usually describe the error.</p>
<p>If you got an HTTP 204 from an attempt to federate a response to Mastodon, that means Mastodon accepted the response. If it doesn't show up, that's a known inconsistency right now. We're actively working with them to debug these cases.</p>
<p>You can also <a href="/recent">see all recent Bridgy Fed requests here</a>, including raw logs. Warning: not for the faint of heart!</p>
</li>
<li id="cost" class="question">How much does it cost?</li>
<li class="answer">
<p>Nothing! Bridgy Fed is small, and it doesn't cost much to run. We don't need donations, promise.
</p>
<p>If you <em>really</em> want to contribute, <a href="https://github.com/snarfed/bridgy-fed/issues">file an issue</a> or <a href="https://github.com/snarfed/bridgy-fed">send a pull request</a>, or <a href="https://opencollective.com/indieweb">donate to the IndieWeb</a>!
</p></li>
<li id="who" class="question">Who are you? Why did you make this?</li>
<li class="answer">
<p>
I'm <a href="https://snarfed.org/">Ryan Barrett</a>. I'm just a guy who
<a href="https://snarfed.org/2012-07-25_why_i_have_my_own_web_site">likes the web</a> and <a href="https://indieweb.org/why">owning my data</a>.
</p>
</li>
<li id="privacy" class="question">What do you do with my data?</li>
<li class="answer">
<p>Nothing! Bridgy Fed isn't a business, and never will be, so we don't have the same motivations to abuse your data that other services might. More concretely, Bridgy Fed won't ever send you email, it stores as little of your <a href="http://en.wikipedia.org/wiki/Personally_identifiable_information">PII</a> (personally identifiable information) as possible, and it <em>never</em> has access to any of your passwords.
</p>
</li>
<li id="history" class="question">How long has this been around?</li>
<li class="answer">
<p>I started thinking about bridging federated social networks and peer to peer networks when I discovered them in the early 2000s. I started talking about bridging them to the IndieWeb in 2016, <a href="http://indieweb.org/2017/ostatusbridge">led a session on it at IndieWeb Summit</a> in July 2017, wrote up <a href="https://snarfed.org/indieweb-activitypub-bridge">concrete</a> <a href="https://snarfed.org/indieweb-ostatus-bridge"> designs</a> soon after, and started working on Bridgy Fed in August 2017.
</li>
<li id="bug" class="question">I found a bug! I have a feature request!</li>
<li class="answer">
<p>Great! Please <a href="https://github.com/snarfed/bridgy-fed/issues">file it in GitHub</a>. Thank you!
</p>
</li>
</ul>
</div>
{% endblock %}

Wyświetl plik

@ -0,0 +1,16 @@
{% extends "base.html" %}
{% block content %}
<br>
<p class="row big">What's your web site?</p>
<br>
<div class="row">
<form method="post" action=""> <!-- empty action means post to same URL -->
<input required class="big" type="url" name="url" id="url" placeholder="snarfed.org" />
<input type="submit" class="btn btn-default" value="OK" />
</form>
</div>
{% endblock %}

Wyświetl plik

@ -4,6 +4,25 @@
{% block content %}
{% if user.has_redirects == False %}
<div class="row promo warning">
<p>Your site isn't serving the <code>.well-known</code> redirects.
<a href="/docs#redirect+these+URL+paths">Please set those up!</a>
</p>
</div>
{% endif %}
{% if user.has_hcard == False %}
<div class="row promo warning">
<p>Your site doesn't have a
<a href="https://indieweb.org/representative_h-card">representative h-card</a>.
<a href="https://indieweb.org/h-card#How">Please add one!</a>
</p>
</div>
{% endif %}
<br>
<div class="row">
<h2 style="display: inline">
<a href="https://{{ domain }}/">🌐 {{ domain }}</a>

Wyświetl plik

@ -82,6 +82,10 @@ class UserTest(testutil.TestCase):
mock_get.side_effect = [full_redir, hcard]
check(True, True)
# reset
mock_get.side_effect = [empty, empty]
check(False, False)
class ActivityTest(testutil.TestCase):