Here's a short Rust program using the microformats
crate that checks the presence of a webmention on a certain page, properly resolving all URLs and even scanning HTML content in entry["properties"]["content"]
.
use std::cell::{RefCell, Ref};
use std::rc::Rc;
use clap::Parser;
use microformats::types::PropertyValue;
use microformats::html5ever;
use microformats::html5ever::tendril::TendrilSink;
#[derive(thiserror::Error, Debug)]
enum Error {
#[error("http request error: {0}")]
Http(#[from] reqwest::Error),
#[error("microformats error: {0}")]
Microformats(#[from] microformats::Error),
#[error("json error: {0}")]
Json(#[from] serde_json::Error),
#[error("url parse error: {0}")]
UrlParse(#[from] url::ParseError),
}
#[derive(Debug)]
enum MentionType {
Reply,
Like,
Repost,
Bookmark,
Mention
}
fn check_mention(document: impl AsRef<str>, base_url: &url::Url, link: &url::Url) -> Result<Option<MentionType>, Error> {
// First, check the document for MF2 markup
let document = microformats::from_html(document.as_ref(), base_url.clone())?;
// Get an iterator of all items
let items_iter = document.items.iter()
.map(AsRef::as_ref)
.map(RefCell::borrow);
for item in items_iter {
let props = item.properties.borrow();
for (prop, interaction_type) in [
("in-reply-to", MentionType::Reply), ("like-of", MentionType::Like),
("bookmark-of", MentionType::Bookmark), ("repost-of", MentionType::Repost)
] {
if let Some(propvals) = props.get(prop) {
for val in propvals {
if let PropertyValue::Url(url) = val {
if url == link {
return Ok(Some(interaction_type))
}
}
}
}
}
// Process `content`
if let Some(PropertyValue::Fragment(content)) = props.get("content")
.map(Vec::as_slice)
.unwrap_or_default()
.first()
{
let root = html5ever::parse_document(html5ever::rcdom::RcDom::default(), Default::default())
.from_utf8()
.one(content.html.to_owned().as_bytes())
.document;
// This is a trick to unwrap recursion into a loop
//
// A list of unprocessed node is made. Then, in each
// iteration, the list is "taken" and replaced with an
// empty list, which is populated with nodes for the next
// iteration of the loop.
//
// Empty list means all nodes were processed.
let mut unprocessed_nodes: Vec<Rc<html5ever::rcdom::Node>> = root.children.borrow().iter().cloned().collect();
while unprocessed_nodes.len() > 0 {
// "Take" the list out of its memory slot, replace it with an empty list
let nodes = std::mem::take(&mut unprocessed_nodes);
for node in nodes.into_iter() {
// Add children nodes to the list for the next iteration
unprocessed_nodes.extend(node.children.borrow().iter().cloned());
if let html5ever::rcdom::NodeData::Element { ref name, ref attrs, .. } = node.data {
// If it's not `<a>`, skip it
if name.local != *"a" { continue; }
for attr in attrs.borrow().iter() {
// if it's not `<a href="...">`, skip it
if attr.name.local != *"href" { continue; }
// Be forgiving in parsing URLs, and resolve them against the base URL
if let Ok(url) = base_url.join(attr.value.as_ref()) {
if &url == link {
return Ok(Some(MentionType::Mention));
}
}
}
}
}
}
}
}
Ok(None)
}
#[derive(Parser, Debug)]
#[clap(
name = "kittybox-check-webmention",
author = "Vika <vika@fireburn.ru>",
version = env!("CARGO_PKG_VERSION"),
about = "Verify an incoming webmention"
)]
struct Args {
#[clap(value_parser)]
url: url::Url,
#[clap(value_parser)]
link: url::Url
}
#[tokio::main]
async fn main() -> Result<(), self::Error> {
let args = Args::parse();
let http: reqwest::Client = {
#[allow(unused_mut)]
let mut builder = reqwest::Client::builder()
.user_agent(concat!(
env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION")
));
builder.build().unwrap()
};
let response = http.get(args.url.clone()).send().await?;
let text = response.text().await?;
if let Some(mention_type) = check_mention(text, &args.url, &args.link)? {
println!("{:?}", mention_type);
Ok(())
} else {
std::process::exit(1)
}
}
{
"type": "entry",
"published": "2023-07-01T18:46:11.162062149+03:00",
"url": "https://fireburn.ru/posts/rust-check-webmention",
"category": [
"Kittybox",
"Rust",
"microformats2",
"IndieWeb"
],
"content": {
"text": "Here's a short Rust program using the microformats crate that checks the presence of a webmention on a certain page, properly resolving all URLs and even scanning HTML content in entry[\"properties\"][\"content\"].\nuse std::cell::{RefCell, Ref};\nuse std::rc::Rc;\n\nuse clap::Parser;\nuse microformats::types::PropertyValue;\nuse microformats::html5ever;\nuse microformats::html5ever::tendril::TendrilSink;\n\n#[derive(thiserror::Error, Debug)]\nenum Error {\n #[error(\"http request error: {0}\")]\n Http(#[from] reqwest::Error),\n #[error(\"microformats error: {0}\")]\n Microformats(#[from] microformats::Error),\n #[error(\"json error: {0}\")]\n Json(#[from] serde_json::Error),\n #[error(\"url parse error: {0}\")]\n UrlParse(#[from] url::ParseError),\n}\n\n#[derive(Debug)]\nenum MentionType {\n Reply,\n Like,\n Repost,\n Bookmark,\n Mention\n}\n\nfn check_mention(document: impl AsRef<str>, base_url: &url::Url, link: &url::Url) -> Result<Option<MentionType>, Error> {\n // First, check the document for MF2 markup\n let document = microformats::from_html(document.as_ref(), base_url.clone())?;\n\n // Get an iterator of all items\n let items_iter = document.items.iter()\n .map(AsRef::as_ref)\n .map(RefCell::borrow);\n\n for item in items_iter {\n let props = item.properties.borrow();\n for (prop, interaction_type) in [\n (\"in-reply-to\", MentionType::Reply), (\"like-of\", MentionType::Like),\n (\"bookmark-of\", MentionType::Bookmark), (\"repost-of\", MentionType::Repost)\n ] {\n if let Some(propvals) = props.get(prop) {\n for val in propvals {\n if let PropertyValue::Url(url) = val {\n if url == link {\n return Ok(Some(interaction_type))\n }\n }\n }\n }\n }\n // Process `content`\n if let Some(PropertyValue::Fragment(content)) = props.get(\"content\")\n .map(Vec::as_slice)\n .unwrap_or_default()\n .first()\n {\n let root = html5ever::parse_document(html5ever::rcdom::RcDom::default(), Default::default())\n .from_utf8()\n .one(content.html.to_owned().as_bytes())\n .document;\n\n // This is a trick to unwrap recursion into a loop\n //\n // A list of unprocessed node is made. Then, in each\n // iteration, the list is \"taken\" and replaced with an\n // empty list, which is populated with nodes for the next\n // iteration of the loop.\n //\n // Empty list means all nodes were processed.\n let mut unprocessed_nodes: Vec<Rc<html5ever::rcdom::Node>> = root.children.borrow().iter().cloned().collect();\n while unprocessed_nodes.len() > 0 {\n // \"Take\" the list out of its memory slot, replace it with an empty list\n let nodes = std::mem::take(&mut unprocessed_nodes);\n for node in nodes.into_iter() {\n // Add children nodes to the list for the next iteration\n unprocessed_nodes.extend(node.children.borrow().iter().cloned());\n\n if let html5ever::rcdom::NodeData::Element { ref name, ref attrs, .. } = node.data {\n // If it's not `<a>`, skip it\n if name.local != *\"a\" { continue; }\n for attr in attrs.borrow().iter() {\n // if it's not `<a href=\"...\">`, skip it \n if attr.name.local != *\"href\" { continue; }\n // Be forgiving in parsing URLs, and resolve them against the base URL\n if let Ok(url) = base_url.join(attr.value.as_ref()) {\n if &url == link {\n return Ok(Some(MentionType::Mention));\n }\n }\n }\n }\n }\n }\n \n }\n }\n\n Ok(None)\n}\n\n#[derive(Parser, Debug)]\n#[clap(\n name = \"kittybox-check-webmention\",\n author = \"Vika <vika@fireburn.ru>\",\n version = env!(\"CARGO_PKG_VERSION\"),\n about = \"Verify an incoming webmention\"\n)]\nstruct Args {\n #[clap(value_parser)]\n url: url::Url,\n #[clap(value_parser)]\n link: url::Url\n}\n\n#[tokio::main]\nasync fn main() -> Result<(), self::Error> {\n let args = Args::parse();\n \n let http: reqwest::Client = {\n #[allow(unused_mut)]\n let mut builder = reqwest::Client::builder()\n .user_agent(concat!(\n env!(\"CARGO_PKG_NAME\"), \"/\", env!(\"CARGO_PKG_VERSION\")\n ));\n\n builder.build().unwrap()\n };\n\n let response = http.get(args.url.clone()).send().await?;\n let text = response.text().await?;\n \n if let Some(mention_type) = check_mention(text, &args.url, &args.link)? {\n println!(\"{:?}\", mention_type);\n\n Ok(())\n } else {\n std::process::exit(1)\n }\n}",
"html": "<p>Here's a short Rust program using the <code>microformats</code> crate that checks the presence of a webmention on a certain page, properly resolving all URLs and even scanning HTML content in <code>entry[\"properties\"][\"content\"]</code>.</p>\n<pre><code>use std::cell::{RefCell, Ref};\nuse std::rc::Rc;\n\nuse clap::Parser;\nuse microformats::types::PropertyValue;\nuse microformats::html5ever;\nuse microformats::html5ever::tendril::TendrilSink;\n\n#[derive(thiserror::Error, Debug)]\nenum Error {\n #[error(\"http request error: {0}\")]\n Http(#[from] reqwest::Error),\n #[error(\"microformats error: {0}\")]\n Microformats(#[from] microformats::Error),\n #[error(\"json error: {0}\")]\n Json(#[from] serde_json::Error),\n #[error(\"url parse error: {0}\")]\n UrlParse(#[from] url::ParseError),\n}\n\n#[derive(Debug)]\nenum MentionType {\n Reply,\n Like,\n Repost,\n Bookmark,\n Mention\n}\n\nfn check_mention(document: impl AsRef<str>, base_url: &url::Url, link: &url::Url) -> Result<Option<MentionType>, Error> {\n // First, check the document for MF2 markup\n let document = microformats::from_html(document.as_ref(), base_url.clone())?;\n\n // Get an iterator of all items\n let items_iter = document.items.iter()\n .map(AsRef::as_ref)\n .map(RefCell::borrow);\n\n for item in items_iter {\n let props = item.properties.borrow();\n for (prop, interaction_type) in [\n (\"in-reply-to\", MentionType::Reply), (\"like-of\", MentionType::Like),\n (\"bookmark-of\", MentionType::Bookmark), (\"repost-of\", MentionType::Repost)\n ] {\n if let Some(propvals) = props.get(prop) {\n for val in propvals {\n if let PropertyValue::Url(url) = val {\n if url == link {\n return Ok(Some(interaction_type))\n }\n }\n }\n }\n }\n // Process `content`\n if let Some(PropertyValue::Fragment(content)) = props.get(\"content\")\n .map(Vec::as_slice)\n .unwrap_or_default()\n .first()\n {\n let root = html5ever::parse_document(html5ever::rcdom::RcDom::default(), Default::default())\n .from_utf8()\n .one(content.html.to_owned().as_bytes())\n .document;\n\n // This is a trick to unwrap recursion into a loop\n //\n // A list of unprocessed node is made. Then, in each\n // iteration, the list is \"taken\" and replaced with an\n // empty list, which is populated with nodes for the next\n // iteration of the loop.\n //\n // Empty list means all nodes were processed.\n let mut unprocessed_nodes: Vec<Rc<html5ever::rcdom::Node>> = root.children.borrow().iter().cloned().collect();\n while unprocessed_nodes.len() > 0 {\n // \"Take\" the list out of its memory slot, replace it with an empty list\n let nodes = std::mem::take(&mut unprocessed_nodes);\n for node in nodes.into_iter() {\n // Add children nodes to the list for the next iteration\n unprocessed_nodes.extend(node.children.borrow().iter().cloned());\n\n if let html5ever::rcdom::NodeData::Element { ref name, ref attrs, .. } = node.data {\n // If it's not `<a>`, skip it\n if name.local != *\"a\" { continue; }\n for attr in attrs.borrow().iter() {\n // if it's not `<a href=\"...\">`, skip it \n if attr.name.local != *\"href\" { continue; }\n // Be forgiving in parsing URLs, and resolve them against the base URL\n if let Ok(url) = base_url.join(attr.value.as_ref()) {\n if &url == link {\n return Ok(Some(MentionType::Mention));\n }\n }\n }\n }\n }\n }\n \n }\n }\n\n Ok(None)\n}\n\n#[derive(Parser, Debug)]\n#[clap(\n name = \"kittybox-check-webmention\",\n author = \"Vika <vika@fireburn.ru>\",\n version = env!(\"CARGO_PKG_VERSION\"),\n about = \"Verify an incoming webmention\"\n)]\nstruct Args {\n #[clap(value_parser)]\n url: url::Url,\n #[clap(value_parser)]\n link: url::Url\n}\n\n#[tokio::main]\nasync fn main() -> Result<(), self::Error> {\n let args = Args::parse();\n \n let http: reqwest::Client = {\n #[allow(unused_mut)]\n let mut builder = reqwest::Client::builder()\n .user_agent(concat!(\n env!(\"CARGO_PKG_NAME\"), \"/\", env!(\"CARGO_PKG_VERSION\")\n ));\n\n builder.build().unwrap()\n };\n\n let response = http.get(args.url.clone()).send().await?;\n let text = response.text().await?;\n \n if let Some(mention_type) = check_mention(text, &args.url, &args.link)? {\n println!(\"{:?}\", mention_type);\n\n Ok(())\n } else {\n std::process::exit(1)\n }\n}\n</code></pre>"
},
"author": {
"type": "card",
"name": "Vika",
"url": "https://fireburn.ru/",
"photo": "https://fireburn.ru/.kittybox/media/uploads/f1/5a/fb/9b/081efafb97b4ad59f5025cf2fd0678b8f3e20e4c292489107d52be09"
},
"post-type": "note",
"_id": "38161429",
"_source": "1371",
"_is_read": false
}
This seems extremely cool. I am 100% here for nntp in all its glory and warts.
https://dialup.cafe/@vga256/110637361651638656 #Indieweb #retro #technology
{
"type": "entry",
"author": {
"name": "@gilmae",
"url": "https://aus.social/@gilmae",
"photo": null
},
"url": "https://aus.social/@gilmae/110637980449939540",
"content": {
"html": "<p>This seems extremely cool. I am 100% here for nntp in all its glory and warts.</p><p><a href=\"https://dialup.cafe/@vga256/110637361651638656\"><span>https://</span><span>dialup.cafe/@vga256/1106373616</span><span>51638656</span></a> <a href=\"https://aus.social/tags/Indieweb\">#<span>Indieweb</span></a> <a href=\"https://aus.social/tags/retro\">#<span>retro</span></a> <a href=\"https://aus.social/tags/technology\">#<span>technology</span></a></p>",
"text": "This seems extremely cool. I am 100% here for nntp in all its glory and warts.https://dialup.cafe/@vga256/110637361651638656 #Indieweb #retro #technology"
},
"published": "2023-07-01T08:53:25+00:00",
"post-type": "note",
"_id": "38156183",
"_source": "7235",
"_is_read": false
}
searching for a recipe
on the limits of searching for a recipe online, the problem with search engines, the problem with subscriptions, and the futility of trying to clean up this mess.
https://alexsirac.com/searching-for-a-recipe/
#cooking #en #indieWeb #recipe #SearchEngines
{
"type": "entry",
"author": {
"name": "@alexture",
"url": "https://todon.eu/@alexture",
"photo": null
},
"url": "https://todon.eu/@alexture/110637743808047345",
"content": {
"html": "<p>searching for a recipe</p><p>on the limits of searching for a recipe online, the problem with search engines, the problem with subscriptions, and the futility of trying to clean up this mess.</p><p><a href=\"https://alexsirac.com/searching-for-a-recipe/\"><span>https://</span><span>alexsirac.com/searching-for-a-</span><span>recipe/</span></a></p><p><a href=\"https://todon.eu/tags/cooking\">#<span>cooking</span></a> <a href=\"https://todon.eu/tags/en\">#<span>en</span></a> <a href=\"https://todon.eu/tags/indieWeb\">#<span>indieWeb</span></a> <a href=\"https://todon.eu/tags/recipe\">#<span>recipe</span></a> <a href=\"https://todon.eu/tags/SearchEngines\">#<span>SearchEngines</span></a></p>",
"text": "searching for a recipeon the limits of searching for a recipe online, the problem with search engines, the problem with subscriptions, and the futility of trying to clean up this mess.https://alexsirac.com/searching-for-a-recipe/#cooking #en #indieWeb #recipe #SearchEngines"
},
"published": "2023-07-01T07:53:15+00:00",
"post-type": "note",
"_id": "38155748",
"_source": "7235",
"_is_read": false
}
indieweb carnival
Just found out about the first edition of the IndieWeb Carnival, which is for June 2023. Of course, today is July 1st and I had to find about it today.
I'll try to keep an eye on the July one and see if it inspires me!
https://alexsirac.com/indieweb-carnival/
#en #indieWeb #WritingPrompts
{
"type": "entry",
"author": {
"name": "@alexture",
"url": "https://todon.eu/@alexture",
"photo": null
},
"url": "https://todon.eu/@alexture/110637713443735382",
"content": {
"html": "<p>indieweb carnival</p><p>Just found out about the first edition of the IndieWeb Carnival, which is for June 2023. Of course, today is July 1st and I had to find about it today.</p><p>I'll try to keep an eye on the July one and see if it inspires me!</p><p><a href=\"https://alexsirac.com/indieweb-carnival/\"><span>https://</span><span>alexsirac.com/indieweb-carniva</span><span>l/</span></a></p><p><a href=\"https://todon.eu/tags/en\">#<span>en</span></a> <a href=\"https://todon.eu/tags/indieWeb\">#<span>indieWeb</span></a> <a href=\"https://todon.eu/tags/WritingPrompts\">#<span>WritingPrompts</span></a></p>",
"text": "indieweb carnivalJust found out about the first edition of the IndieWeb Carnival, which is for June 2023. Of course, today is July 1st and I had to find about it today.I'll try to keep an eye on the July one and see if it inspires me!https://alexsirac.com/indieweb-carnival/#en #indieWeb #WritingPrompts"
},
"published": "2023-07-01T07:45:31+00:00",
"post-type": "note",
"_id": "38155749",
"_source": "7235",
"_is_read": false
}
That Man: The Outerworlds formed the Federation because they had to. At least, that's the "official" story. A Distant Stars tale.
This story is exclusive for blog subscribers, so do subscribe to the blog to read the story* :)
* I am mirroring my #Substack content on my website as you should. #IndieWeb, baby!
#Fiction #Writing #WritingCommunity
https://firediarist.wordpress.com/2023/07/01/that-man/
{
"type": "entry",
"author": {
"name": "@liztai",
"url": "https://hachyderm.io/@liztai",
"photo": null
},
"url": "https://hachyderm.io/@liztai/110636765952595960",
"content": {
"html": "<p>That Man: The Outerworlds formed the Federation because they had to. At least, that's the \"official\" story. A Distant Stars tale.</p><p>This story is exclusive for blog subscribers, so do subscribe to the blog to read the story* :)</p><p>* I am mirroring my <a href=\"https://hachyderm.io/tags/Substack\">#<span>Substack</span></a> content on my website as you should. <a href=\"https://hachyderm.io/tags/IndieWeb\">#<span>IndieWeb</span></a>, baby!</p><p><a href=\"https://hachyderm.io/tags/Fiction\">#<span>Fiction</span></a> <a href=\"https://hachyderm.io/tags/Writing\">#<span>Writing</span></a> <a href=\"https://hachyderm.io/tags/WritingCommunity\">#<span>WritingCommunity</span></a> <br /><a href=\"https://firediarist.wordpress.com/2023/07/01/that-man/\"><span>https://</span><span>firediarist.wordpress.com/2023</span><span>/07/01/that-man/</span></a></p>",
"text": "That Man: The Outerworlds formed the Federation because they had to. At least, that's the \"official\" story. A Distant Stars tale.This story is exclusive for blog subscribers, so do subscribe to the blog to read the story* :)* I am mirroring my #Substack content on my website as you should. #IndieWeb, baby!#Fiction #Writing #WritingCommunity \nhttps://firediarist.wordpress.com/2023/07/01/that-man/"
},
"published": "2023-07-01T03:44:34+00:00",
"post-type": "note",
"_id": "38154552",
"_source": "7235",
"_is_read": false
}
To continue my thoughts on why I left the #Apple ecosystem. It's the same reason why I left #Twitter #Facebook for #Mastodon. Why I embraced #IndieWeb and now blog the POSSE/PESOS way.
I realised that Apple products, shiny and high quality as they are, was trapping me in their ecosystem. I hated having to upgrade just because they deemed my device "too old". I hate having to buy a new thingamajic when my old dongle worked just fine - just because Apple removed a port. 1/3
{
"type": "entry",
"author": {
"name": "@liztai",
"url": "https://hachyderm.io/@liztai",
"photo": null
},
"url": "https://hachyderm.io/@liztai/110636096296416024",
"content": {
"html": "<p>To continue my thoughts on why I left the <a href=\"https://hachyderm.io/tags/Apple\">#<span>Apple</span></a> ecosystem. It's the same reason why I left <a href=\"https://hachyderm.io/tags/Twitter\">#<span>Twitter</span></a> <a href=\"https://hachyderm.io/tags/Facebook\">#<span>Facebook</span></a> for <a href=\"https://hachyderm.io/tags/Mastodon\">#<span>Mastodon</span></a>. Why I embraced <a href=\"https://hachyderm.io/tags/IndieWeb\">#<span>IndieWeb</span></a> and now blog the POSSE/PESOS way. <br />I realised that Apple products, shiny and high quality as they are, was trapping me in their ecosystem. I hated having to upgrade just because they deemed my device \"too old\". I hate having to buy a new thingamajic when my old dongle worked just fine - just because Apple removed a port. 1/3</p>",
"text": "To continue my thoughts on why I left the #Apple ecosystem. It's the same reason why I left #Twitter #Facebook for #Mastodon. Why I embraced #IndieWeb and now blog the POSSE/PESOS way. \nI realised that Apple products, shiny and high quality as they are, was trapping me in their ecosystem. I hated having to upgrade just because they deemed my device \"too old\". I hate having to buy a new thingamajic when my old dongle worked just fine - just because Apple removed a port. 1/3"
},
"published": "2023-07-01T00:54:16+00:00",
"post-type": "note",
"_id": "38153675",
"_source": "7235",
"_is_read": false
}
There are real downsides to running my website on VPS I sysadmin myself & a homegrown pile of code in JavaScript, Python, Swift, and Zsh. The code is all over the place in every sense of the phrase.
But I can personally guarantee that it'll keep working and remain available so long as I can afford the DNS and VPS fees. I can't say that about any other place I post on the internet.
Own your own space on the web. Post there. Write there. Link to it from your various accounts elsewhere. #indieweb
{
"type": "entry",
"author": {
"name": "@hober",
"url": "https://mastodon.social/@hober",
"photo": null
},
"url": "https://mastodon.social/@hober/110635199526581601",
"content": {
"html": "<p>There are real downsides to running my website on VPS I sysadmin myself & a homegrown pile of code in JavaScript, Python, Swift, and Zsh. The code is all over the place in every sense of the phrase.</p><p>But I can personally guarantee that it'll keep working and remain available so long as I can afford the DNS and VPS fees. I can't say that about any other place I post on the internet.</p><p>Own your own space on the web. Post there. Write there. Link to it from your various accounts elsewhere. <a href=\"https://mastodon.social/tags/indieweb\">#<span>indieweb</span></a></p>",
"text": "There are real downsides to running my website on VPS I sysadmin myself & a homegrown pile of code in JavaScript, Python, Swift, and Zsh. The code is all over the place in every sense of the phrase.But I can personally guarantee that it'll keep working and remain available so long as I can afford the DNS and VPS fees. I can't say that about any other place I post on the internet.Own your own space on the web. Post there. Write there. Link to it from your various accounts elsewhere. #indieweb"
},
"published": "2023-06-30T21:06:12+00:00",
"post-type": "note",
"_id": "38151610",
"_source": "7235",
"_is_read": false
}
DECEMBER 1994 AND HOW ARNIE KATZ CHANGED MY LIFE
Remembering a long lost friend who made things seem possible for a nerdy teenage fanboy.
#Retrocomputing #retrogaming #fanzines #magazines #diy #VideoGames #industrialmusic #Developers #indiedev #indieweb
(Reposting with tags for communities who might dig it)
https://ndd.funkatron.com/december-1994-and-how-arnie-katz-changed-my-life/
{
"type": "entry",
"author": {
"name": "@funkatron",
"url": "https://indieweb.social/@funkatron",
"photo": null
},
"url": "https://indieweb.social/@funkatron/110635039468812168",
"content": {
"html": "<p>DECEMBER 1994 AND HOW ARNIE KATZ CHANGED MY LIFE</p><p>Remembering a long lost friend who made things seem possible for a nerdy teenage fanboy.</p><p><a href=\"https://indieweb.social/tags/Retrocomputing\">#<span>Retrocomputing</span></a> <a href=\"https://indieweb.social/tags/retrogaming\">#<span>retrogaming</span></a> <a href=\"https://indieweb.social/tags/fanzines\">#<span>fanzines</span></a> <a href=\"https://indieweb.social/tags/magazines\">#<span>magazines</span></a> <a href=\"https://indieweb.social/tags/diy\">#<span>diy</span></a> <a href=\"https://indieweb.social/tags/VideoGames\">#<span>VideoGames</span></a> <a href=\"https://indieweb.social/tags/industrialmusic\">#<span>industrialmusic</span></a> <a href=\"https://indieweb.social/tags/Developers\">#<span>Developers</span></a> <a href=\"https://indieweb.social/tags/indiedev\">#<span>indiedev</span></a> <a href=\"https://indieweb.social/tags/indieweb\">#<span>indieweb</span></a></p><p>(Reposting with tags for communities who might dig it)</p><p><a href=\"https://ndd.funkatron.com/december-1994-and-how-arnie-katz-changed-my-life/\"><span>https://</span><span>ndd.funkatron.com/december-199</span><span>4-and-how-arnie-katz-changed-my-life/</span></a></p>",
"text": "DECEMBER 1994 AND HOW ARNIE KATZ CHANGED MY LIFERemembering a long lost friend who made things seem possible for a nerdy teenage fanboy.#Retrocomputing #retrogaming #fanzines #magazines #diy #VideoGames #industrialmusic #Developers #indiedev #indieweb(Reposting with tags for communities who might dig it)https://ndd.funkatron.com/december-1994-and-how-arnie-katz-changed-my-life/"
},
"published": "2023-06-30T20:25:30+00:00",
"post-type": "note",
"_id": "38151105",
"_source": "7235",
"_is_read": false
}
Today’s #FollowFriday:
- @decius for his work on https://news.feedseer.com/, an excellent personal aggregation of one’s feed
- @pfefferle for his great and persistent work on #Fediverse / #DiSo / #IndieWeb plug-ins for #WordPress over the last decade(?) which recently landed him a job at Automattic
{
"type": "entry",
"author": {
"name": "@voxpelli",
"url": "https://mastodon.social/@voxpelli",
"photo": null
},
"url": "https://mastodon.social/@voxpelli/110634915696549602",
"content": {
"html": "<p>Today\u2019s <a href=\"https://mastodon.social/tags/FollowFriday\">#<span>FollowFriday</span></a>:</p><p>- <span class=\"h-card\"><a class=\"u-url\" href=\"https://ioc.exchange/@decius\">@<span>decius</span></a></span> for his work on <a href=\"https://news.feedseer.com/\"><span>https://</span><span>news.feedseer.com/</span><span></span></a>, an excellent personal aggregation of one\u2019s feed<br />- <span class=\"h-card\"><a class=\"u-url\" href=\"https://mastodon.social/@pfefferle\">@<span>pfefferle</span></a></span> for his great and persistent work on <a href=\"https://mastodon.social/tags/Fediverse\">#<span>Fediverse</span></a> / <a href=\"https://mastodon.social/tags/DiSo\">#<span>DiSo</span></a> / <a href=\"https://mastodon.social/tags/IndieWeb\">#<span>IndieWeb</span></a> plug-ins for <a href=\"https://mastodon.social/tags/WordPress\">#<span>WordPress</span></a> over the last decade(?) which recently landed him a job at Automattic</p>",
"text": "Today\u2019s #FollowFriday:- @decius for his work on https://news.feedseer.com/, an excellent personal aggregation of one\u2019s feed\n- @pfefferle for his great and persistent work on #Fediverse / #DiSo / #IndieWeb plug-ins for #WordPress over the last decade(?) which recently landed him a job at Automattic"
},
"published": "2023-06-30T19:54:01+00:00",
"post-type": "note",
"_id": "38150776",
"_source": "7235",
"_is_read": false
}
The potential is there, but it doesn’t do that right now. I doubt Emissary would implement (for example) the Twitter or Facebook APIs like traditional #IndieWeb POSSE — but I am aiming at additional open PROTOCOLS, with BlueSky as a potential in the future. So, yes? Kinda? If you blur the definition of “Syndicate Elsewhere” @rmdes @shoq
{
"type": "entry",
"author": {
"name": "@benpate",
"url": "https://mastodon.social/@benpate",
"photo": null
},
"url": "https://mastodon.social/@benpate/110634818495783022",
"content": {
"html": "<p>The potential is there, but it doesn\u2019t do that right now. I doubt Emissary would implement (for example) the Twitter or Facebook APIs like traditional <a href=\"https://mastodon.social/tags/IndieWeb\">#<span>IndieWeb</span></a> POSSE \u2014 but I am aiming at additional open PROTOCOLS, with BlueSky as a potential in the future. So, yes? Kinda? If you blur the definition of \u201cSyndicate Elsewhere\u201d <span class=\"h-card\"><a class=\"u-url\" href=\"https://mstdn.social/@rmdes\">@<span>rmdes</span></a></span> <span class=\"h-card\"><a class=\"u-url\" href=\"https://mastodon.social/@shoq\">@<span>shoq</span></a></span></p>",
"text": "The potential is there, but it doesn\u2019t do that right now. I doubt Emissary would implement (for example) the Twitter or Facebook APIs like traditional #IndieWeb POSSE \u2014 but I am aiming at additional open PROTOCOLS, with BlueSky as a potential in the future. So, yes? Kinda? If you blur the definition of \u201cSyndicate Elsewhere\u201d @rmdes @shoq"
},
"published": "2023-06-30T19:29:18+00:00",
"post-type": "note",
"_id": "38150542",
"_source": "7235",
"_is_read": false
}
@benpate @scottjenson Oh, but there is no need to _host_ your reply within your reader, you simply have to be able to _write_ your response within your reader.
Eg: I use @ivory as a client for my Mastodon account and it both reads and writes to that Mastodon account (using the Mastodon-specific API?)
With #indieweb it instead could do:
- Read the content using a standard protocol like #MicroSub: https://indieweb.org/Microsub
- Write any actions / replies using #MicroPub: https://indieweb.org/Micropub
{
"type": "entry",
"author": {
"name": "@voxpelli",
"url": "https://mastodon.social/@voxpelli",
"photo": null
},
"url": "https://mastodon.social/@voxpelli/110634768176895788",
"content": {
"html": "<p><span class=\"h-card\"><a class=\"u-url\" href=\"https://mastodon.social/@benpate\">@<span>benpate</span></a></span> <span class=\"h-card\"><a class=\"u-url\" href=\"https://social.coop/@scottjenson\">@<span>scottjenson</span></a></span> Oh, but there is no need to _host_ your reply within your reader, you simply have to be able to _write_ your response within your reader.</p><p>Eg: I use <span class=\"h-card\"><a class=\"u-url\" href=\"https://tapbots.social/@ivory\">@<span>ivory</span></a></span> as a client for my Mastodon account and it both reads and writes to that Mastodon account (using the Mastodon-specific API?)</p><p>With <a href=\"https://mastodon.social/tags/indieweb\">#<span>indieweb</span></a> it instead could do:</p><p>- Read the content using a standard protocol like <a href=\"https://mastodon.social/tags/MicroSub\">#<span>MicroSub</span></a>: <a href=\"https://indieweb.org/Microsub\"><span>https://</span><span>indieweb.org/Microsub</span><span></span></a><br />- Write any actions / replies using <a href=\"https://mastodon.social/tags/MicroPub\">#<span>MicroPub</span></a>: <a href=\"https://indieweb.org/Micropub\"><span>https://</span><span>indieweb.org/Micropub</span><span></span></a></p>",
"text": "@benpate @scottjenson Oh, but there is no need to _host_ your reply within your reader, you simply have to be able to _write_ your response within your reader.Eg: I use @ivory as a client for my Mastodon account and it both reads and writes to that Mastodon account (using the Mastodon-specific API?)With #indieweb it instead could do:- Read the content using a standard protocol like #MicroSub: https://indieweb.org/Microsub\n- Write any actions / replies using #MicroPub: https://indieweb.org/Micropub"
},
"published": "2023-06-30T19:16:30+00:00",
"post-type": "note",
"_id": "38150416",
"_source": "7235",
"_is_read": false
}
@scottjenson The worst part of most current #Fediverse implementations:
They bundle the reader part and the publishing part.
It’s like bundling Google Reader within WordPress.
Totally needless. (And something I think the #IndieWeb is getting more right with eg #MicroPub, ensuring reading, aggregation, publishing etc doesn’t have to all be in a single application / server)
{
"type": "entry",
"author": {
"name": "@voxpelli",
"url": "https://mastodon.social/@voxpelli",
"photo": null
},
"url": "https://mastodon.social/@voxpelli/110634700809339558",
"content": {
"html": "<p><span class=\"h-card\"><a class=\"u-url\" href=\"https://social.coop/@scottjenson\">@<span>scottjenson</span></a></span> The worst part of most current <a href=\"https://mastodon.social/tags/Fediverse\">#<span>Fediverse</span></a> implementations:</p><p>They bundle the reader part and the publishing part.</p><p>It\u2019s like bundling Google Reader within WordPress.</p><p>Totally needless. (And something I think the <a href=\"https://mastodon.social/tags/IndieWeb\">#<span>IndieWeb</span></a> is getting more right with eg <a href=\"https://mastodon.social/tags/MicroPub\">#<span>MicroPub</span></a>, ensuring reading, aggregation, publishing etc doesn\u2019t have to all be in a single application / server)</p>",
"text": "@scottjenson The worst part of most current #Fediverse implementations:They bundle the reader part and the publishing part.It\u2019s like bundling Google Reader within WordPress.Totally needless. (And something I think the #IndieWeb is getting more right with eg #MicroPub, ensuring reading, aggregation, publishing etc doesn\u2019t have to all be in a single application / server)"
},
"published": "2023-06-30T18:59:22+00:00",
"post-type": "note",
"_id": "38150072",
"_source": "7235",
"_is_read": false
}
I'm gonna have to do more #IndieWeb publishing my own content on my own site, aren't I. Mastodon isn't meant to be a long term stable host of content any more than Twitter is, as much as we might wish for it.
{
"type": "entry",
"author": {
"name": "@toba",
"url": "https://zeroes.ca/@toba",
"photo": null
},
"url": "https://zeroes.ca/@toba/110634539089101736",
"content": {
"html": "<p>I'm gonna have to do more <a href=\"https://zeroes.ca/tags/IndieWeb\">#<span>IndieWeb</span></a> publishing my own content on my own site, aren't I. Mastodon isn't meant to be a long term stable host of content any more than Twitter is, as much as we might wish for it.</p>",
"text": "I'm gonna have to do more #IndieWeb publishing my own content on my own site, aren't I. Mastodon isn't meant to be a long term stable host of content any more than Twitter is, as much as we might wish for it."
},
"published": "2023-06-30T18:18:14+00:00",
"post-type": "note",
"_id": "38149535",
"_source": "7235",
"_is_read": false
}
{
"type": "entry",
"author": {
"name": "@rmdes",
"url": "https://mstdn.social/@rmdes",
"photo": null
},
"url": "https://mstdn.social/@rmdes/110634231509434906",
"content": {
"html": "<p>Promising sweet goodies over here, star this repo and if you're a <a href=\"https://mstdn.social/tags/Go\">#<span>Go</span></a> developer, reach out to <span class=\"h-card\"><a class=\"u-url\" href=\"https://mastodon.social/@benpate\">@<span>benpate</span></a></span> </p><p><a href=\"https://github.com/EmissarySocial/emissary\"><span>https://</span><span>github.com/EmissarySocial/emis</span><span>sary</span></a></p><p><a href=\"https://mstdn.social/tags/indieweb\">#<span>indieweb</span></a> <a href=\"https://mstdn.social/tags/godev\">#<span>godev</span></a> <a href=\"https://mstdn.social/tags/golang\">#<span>golang</span></a> <a href=\"https://mstdn.social/tags/fediverse\">#<span>fediverse</span></a> <a href=\"https://mstdn.social/tags/activitypub\">#<span>activitypub</span></a></p>",
"text": "Promising sweet goodies over here, star this repo and if you're a #Go developer, reach out to @benpate https://github.com/EmissarySocial/emissary#indieweb #godev #golang #fediverse #activitypub"
},
"published": "2023-06-30T17:00:01+00:00",
"post-type": "note",
"_id": "38149097",
"_source": "7235",
"_is_read": false
}
#Emissary is a new kind of #social app that natively connects to the #Fediverse and the #IndieWeb. This site is a resource for #developers and #designers who are building Emissary #apps, or contributing to the core #server. Please visit https://emissary.social :
https://emissary.dev/
{
"type": "entry",
"author": {
"name": "@rmdes",
"url": "https://mstdn.social/@rmdes",
"photo": null
},
"url": "https://mstdn.social/@rmdes/110634126245812721",
"content": {
"html": "<p><a href=\"https://mstdn.social/tags/Emissary\">#<span>Emissary</span></a> is a new kind of <a href=\"https://mstdn.social/tags/social\">#<span>social</span></a> app that natively connects to the <a href=\"https://mstdn.social/tags/Fediverse\">#<span>Fediverse</span></a> and the <a href=\"https://mstdn.social/tags/IndieWeb\">#<span>IndieWeb</span></a>. This site is a resource for <a href=\"https://mstdn.social/tags/developers\">#<span>developers</span></a> and <a href=\"https://mstdn.social/tags/designers\">#<span>designers</span></a> who are building Emissary <a href=\"https://mstdn.social/tags/apps\">#<span>apps</span></a>, or contributing to the core <a href=\"https://mstdn.social/tags/server\">#<span>server</span></a>. Please visit <a href=\"https://emissary.social\"><span>https://</span><span>emissary.social</span><span></span></a> :<br /><a href=\"https://emissary.dev/\"><span>https://</span><span>emissary.dev/</span><span></span></a></p>",
"text": "#Emissary is a new kind of #social app that natively connects to the #Fediverse and the #IndieWeb. This site is a resource for #developers and #designers who are building Emissary #apps, or contributing to the core #server. Please visit https://emissary.social :\nhttps://emissary.dev/"
},
"published": "2023-06-30T16:33:15+00:00",
"post-type": "note",
"_id": "38149098",
"_source": "7235",
"_is_read": false
}
Anyone #indieweb inclined able to ping me a #webmention please? Thanks! Just need to see if this is working https://www.wyrd.systems/2023/06/30/77/
{
"type": "entry",
"author": {
"name": "@matt",
"url": "https://social.wyrd.systems/@matt",
"photo": null
},
"url": "https://social.wyrd.systems/@matt/110633714902632591",
"content": {
"html": "<p>Anyone <a href=\"https://social.wyrd.systems/tags/indieweb\">#<span>indieweb</span></a> inclined able to ping me a <a href=\"https://social.wyrd.systems/tags/webmention\">#<span>webmention</span></a> please? Thanks! Just need to see if this is working <a href=\"https://www.wyrd.systems/2023/06/30/77/\"><span>https://www.</span><span>wyrd.systems/2023/06/30/77/</span><span></span></a></p>",
"text": "Anyone #indieweb inclined able to ping me a #webmention please? Thanks! Just need to see if this is working https://www.wyrd.systems/2023/06/30/77/"
},
"published": "2023-06-30T14:48:38+00:00",
"post-type": "note",
"_id": "38147131",
"_source": "7235",
"_is_read": false
}
Djupa kommentarsfält.
"När jag byggde min nya blogg, sneglade jag förstås på förlagan: blogg. En typisk blogg innehåller inte bara textinnehåll som man kan läsa och dela vidare, utan även ett kommentarsfält, där man direkt efter man läst klart, eller även innan man läst alls, kan berätta för alla vad man tänker och tycker om det man läst/inte läst."
https://arvidmarklund.se/20230630.html
#data #skisser #gillamarkeringar #socialamedier #webmentions #indieweb #webmentions0
{
"type": "entry",
"author": {
"name": "@arvid",
"url": "https://fikaverse.club/@arvid",
"photo": null
},
"url": "https://fikaverse.club/@arvid/110632547368717250",
"content": {
"html": "<p>Djupa kommentarsf\u00e4lt.</p><p>\"N\u00e4r jag byggde min nya blogg, sneglade jag f\u00f6rst\u00e5s p\u00e5 f\u00f6rlagan: blogg. En typisk blogg inneh\u00e5ller inte bara textinneh\u00e5ll som man kan l\u00e4sa och dela vidare, utan \u00e4ven ett kommentarsf\u00e4lt, d\u00e4r man direkt efter man l\u00e4st klart, eller \u00e4ven innan man l\u00e4st alls, kan ber\u00e4tta f\u00f6r alla vad man t\u00e4nker och tycker om det man l\u00e4st/inte l\u00e4st.\"</p><p><a href=\"https://arvidmarklund.se/20230630.html\"><span>https://</span><span>arvidmarklund.se/20230630.html</span><span></span></a> </p><p><a href=\"https://fikaverse.club/tags/data\">#<span>data</span></a> <a href=\"https://fikaverse.club/tags/skisser\">#<span>skisser</span></a> <a href=\"https://fikaverse.club/tags/gillamarkeringar\">#<span>gillamarkeringar</span></a> <a href=\"https://fikaverse.club/tags/socialamedier\">#<span>socialamedier</span></a> <a href=\"https://fikaverse.club/tags/webmentions\">#<span>webmentions</span></a> <a href=\"https://fikaverse.club/tags/indieweb\">#<span>indieweb</span></a> <a href=\"https://fikaverse.club/tags/webmentions0\">#<span>webmentions0</span></a></p>",
"text": "Djupa kommentarsf\u00e4lt.\"N\u00e4r jag byggde min nya blogg, sneglade jag f\u00f6rst\u00e5s p\u00e5 f\u00f6rlagan: blogg. En typisk blogg inneh\u00e5ller inte bara textinneh\u00e5ll som man kan l\u00e4sa och dela vidare, utan \u00e4ven ett kommentarsf\u00e4lt, d\u00e4r man direkt efter man l\u00e4st klart, eller \u00e4ven innan man l\u00e4st alls, kan ber\u00e4tta f\u00f6r alla vad man t\u00e4nker och tycker om det man l\u00e4st/inte l\u00e4st.\"https://arvidmarklund.se/20230630.html #data #skisser #gillamarkeringar #socialamedier #webmentions #indieweb #webmentions0"
},
"published": "2023-06-30T09:51:43+00:00",
"post-type": "note",
"_id": "38143667",
"_source": "7235",
"_is_read": false
}
Glad to be back on #Mastodon specifically for post editing & posting from #WordPress.
#Fediverse #Indieweb
{
"type": "entry",
"author": {
"name": "@ArpComics",
"url": "https://sunny.garden/@ArpComics",
"photo": null
},
"url": "https://sunny.garden/@ArpComics/110630077900253623",
"content": {
"html": "<p>Glad to be back on <a href=\"https://sunny.garden/tags/Mastodon\">#<span>Mastodon</span></a> specifically for post editing & posting from <a href=\"https://sunny.garden/tags/WordPress\">#<span>WordPress</span></a>. </p><p><a href=\"https://sunny.garden/tags/Fediverse\">#<span>Fediverse</span></a> <a href=\"https://sunny.garden/tags/Indieweb\">#<span>Indieweb</span></a></p>",
"text": "Glad to be back on #Mastodon specifically for post editing & posting from #WordPress. #Fediverse #Indieweb"
},
"published": "2023-06-29T23:23:42+00:00",
"post-type": "note",
"_id": "38138094",
"_source": "7235",
"_is_read": false
}
TIL Postgres can be turned into a job queue: https://www.depesz.com/2014/10/10/waiting-for-9-5-implement-skip-locked-for-row-level-locks/
Might be nice for implementing webmentions in Kittybox.
{
"type": "entry",
"published": "2023-06-29T16:53:17.940975051+03:00",
"url": "https://fireburn.ru/posts/bAqXUK0",
"category": [
"Kittybox",
"Postgres"
],
"content": {
"text": "TIL Postgres can be turned into a job queue: https://www.depesz.com/2014/10/10/waiting-for-9-5-implement-skip-locked-for-row-level-locks/\nMight be nice for implementing webmentions in Kittybox.",
"html": "<p>TIL Postgres can be turned into a job queue: https://www.depesz.com/2014/10/10/waiting-for-9-5-implement-skip-locked-for-row-level-locks/</p>\n<p>Might be nice for implementing webmentions in Kittybox.</p>"
},
"author": {
"type": "card",
"name": "Vika",
"url": "https://fireburn.ru/",
"photo": "https://fireburn.ru/.kittybox/media/uploads/f1/5a/fb/9b/081efafb97b4ad59f5025cf2fd0678b8f3e20e4c292489107d52be09"
},
"post-type": "note",
"_id": "38134191",
"_source": "1371",
"_is_read": false
}
Are there any efforts for doing search on the #SmallWeb or #IndieWeb ?
#search
{
"type": "entry",
"author": {
"name": "@wmd",
"url": "https://chaos.social/@wmd",
"photo": null
},
"url": "https://chaos.social/@wmd/110621354958402243",
"content": {
"html": "<p>Are there any efforts for doing search on the <a href=\"https://chaos.social/tags/SmallWeb\">#<span>SmallWeb</span></a> or <a href=\"https://chaos.social/tags/IndieWeb\">#<span>IndieWeb</span></a> ?</p><p><a href=\"https://chaos.social/tags/search\">#<span>search</span></a></p>",
"text": "Are there any efforts for doing search on the #SmallWeb or #IndieWeb ?#search"
},
"published": "2023-06-28T10:25:21+00:00",
"post-type": "note",
"_id": "38113564",
"_source": "7235",
"_is_read": false
}