In Lists and folks on Mastodon I confirmed how I added a record column to the following tab of the Mastodon browser I’m constructing. That was a step within the path of simpler and extra highly effective record administration. It allows me to see whether or not the individuals I observe are assigned to lists, and to contemplate who ought to be on an inventory (or maybe on a distinct record).
At the moment, as I started to make use of that new affordance in earnest, I found a brand new problem. To be able to assign somebody to an inventory, or change an inventory project, I clicked the hyperlink within the account_url column to open that particular person’s profile within the Mastodon internet app. That was nice for accounts on my residence server, mastodon.social. An account URL like Shelley Powers’ https://mastodon.social/@burningbird brings me to Shelley’s profile on my residence server the place the record supervisor is accessible.
But when I’m following somebody elsewhere, like Ward Cunningham at https://mastodon.radio/@k9ox, the account URL brings me to Ward’s profile on that server the place the record supervisor isn’t accessible. To be able to assign Ward to an inventory I needed to seize his account URL, paste it into the search field in my residence server’s internet app, after which click on the ensuing hyperlink: https://mastodon.social/@k9ox@mastodon.radio.
That received outdated actual quick, so I adjusted the following tab to show the latter taste of URL which I’ll name an instance-qualified URL.
Steampipe supplies a number of methods to make that adjustment. As a consumer of the dashboard, you should utilize Postgres’ common expression capabilities to do the transformation within the SQL question that drives the view. However you’d somewhat not should. It’s a lot nicer if the plugin does that for you, so the SQL can simply consult with a column referred to as instance_qualified_url
.
I selected the latter method. Because the creator of a Steampipe plugin you wish to make life as straightforward as potential for customers of the plugin. Once you’re the creator of each the plugin and the dashboard, as I’m on this case, you’ll be able to take pleasure in a pleasant virtuous cycle. Because the dashboard evolves you uncover methods to enhance the plugin, which results in extra use of the dashboard, which suggests additional alternatives to enhance the plugin. I’ve been drastically having fun with the coevolution of those two parts!
Including a brand new column to a Steampipe desk
To make the change, I prolonged the construction that defines the columns of the tables mapped from Mastodon’s Account API. A Steampipe plugin defines columns utilizing an inventory of structs like this.
...,
{
Title: "url",
Sort: proto.ColumnType_STRING,
Description: "URL for the account.",
},
...,
That struct says: “When the title of a top-level area within the API response is URL, inform Steampipe to make a database column with that title and with the Postgres kind textual content
.”
You can too remodel values in API responses to synthesize new columns that don’t seem in API responses. Right here’s the struct I added for this case.
...,
{
Title: "instance_qualified_account_url",
Sort: proto.ColumnType_STRING,
Description: "Account URL prefixed with my occasion.",
Remodel: remodel.FromValue().Remodel(instanceQualifiedAccountUrl),
},
...
That one says: “Ship the API response to the remodel perform instanceQualifiedAccountUrl
, and use its outcome as the worth of the column.
Right here’s the perform.
func instanceQualifiedAccountUrl(ctx context.Context, enter *remodel.TransformData) (interface{}, error) {
url := enter.Worth.(*mastodon.Standing).Account.URL
qualifiedUrl := qualifiedUrl(ctx, url)
return qualifiedUrl, nil
}
It delegates the true work to a different perform.
func qualifiedUrl(ctx context.Context, url string) string {
plugin.Logger(ctx).Debug("instanceQualifiedUrl", "server", homeServer, "url", url)
re := regexp.MustCompile(`https://([^/]+)/@(.+)`)
matches := re.FindStringSubmatch(url)
if len(matches) == 0 {
return url
}
particular person := matches[1]
server := matches[2]
qualifiedUrl := fmt.Sprintf("%s/@%s@%s", homeServer, server, particular person)
plugin.Logger(ctx).Debug("instanceQualifiedUrl", "qualifiedUrl", qualifiedUrl)
schemelessHomeServer := strings.ReplaceAll(homeServer, "https://", "")
qualifiedUrl = strings.ReplaceAll(qualifiedUrl, "@"+schemelessHomeServer, "")
plugin.Logger(ctx).Debug("qualifiedUrl", "qualifiedUrl", qualifiedUrl)
return qualifiedUrl
}
Why? Two totally different units of column definitions want the identical transformation. instanceQualifiedAccountUrl
works with responses from the Account
API. However account URLs additionally seem within the Standing API that drives timeline views. These use a distinct remodel perform, instanceQualifiedStatusUrl
, to do the identical transformation for a distinct API response.
From account URLs to standing URLs
The instanceQualifiedAccountUrl
column solved the unique drawback. I used to be in a position to take away my plugin-author hat, placed on my dashboard-author hat, and consult with account URLs as instance-qualified URLs in all of the tabs that show them. Any such hyperlink now results in a profile that I view by means of the lens of mastodon.social and that permits me to make use of the online app’s record supervisor straight, with out the cumbersome copy/paste/search process.
My completely satisfied dance didn’t final lengthy, although. Newly sensitized to that replicate/paste/search friction, I spotted it was nonetheless taking place when I attempt to reply to objects that seem in a timeline view. Here’s a latest instance: https://techpolicy.social/@mnot/109610641523489182.
That’s the URL displayed within the dashboard. After I click on it I land on Mark’s server and might view the merchandise, but when I attempt to reply I’m confronted with the dreaded copy/paste/search operation.
No drawback! I’ll use an identical remodel! Not so quick. I can kind an URL like https://mastodon.social/@mnot@techpolicy.social/109610641523489182 but it surely doesn’t go wherever.
If I do the copy/paste/search operation, I land on a similar-but-different URL: https://mastodon.social/@mnot@techpolicy.social/109610641692667630. It has the identical construction however a distinct toot ID. This URL can also be the one which seems within the internet app’s residence timeline, which is why I can reply straight from that view.
I’m out of my depth right here so I’ll simply finish with an attraction for assist. It is smart {that a} residence server will assign its personal ID to an merchandise fetched from a international server, and that the online app will use that ID. However I’m not seeing a technique to aquire that id straight from the API. I believe it’s potential to accumulate it by the use of search, however doing that for each merchandise in a timeline will shortly exhaust the tight funds for API requests (simply 300 each 5 minutes).
So, Lazy Mastodon, am I simply caught right here or is there a technique to remodel international standing URLs into instance-relative standing URLs?
Replace: Solved!
After chatting with Jari Pennanen I took one other look and realized the wanted ID was accessible within the API response in spite of everything, I simply wasn’t utilizing it (facepalm). And in reality there are two flavors of the ID—one for authentic toots, one other for boosts. Columns for each circumstances are added right here and the tweak to make the dashboard use them right here.
Right here is the outcome.
Thanks for being my rubber duck, Jari! The instance-qualified toot and reblog URLs make this dashboard massively extra helpful.
See additionally:
Copyright © 2023 IDG Communications, Inc.