[-] wheresmysurplusvalue@hexbear.net 1 points 6 hours ago* (last edited 6 hours ago)

This sounds similar to my experience trying Dobry cola in Russia after 2022, it tastes identical but with a different label.

Awesome, glad to see more discussion about this channel. I concur with those comments. I had to signal boost this video when the intro section didn't focus on the cheapness to knock the Iranians, but to talk about how sanctions (a political choice) have affected the lives of normal people.

20

Oh interesting, dunno why they use a slightly different list of languages codes:

Language matrix

[-] wheresmysurplusvalue@hexbear.net 5 points 3 days ago* (last edited 2 days ago)

Alright I had nothing to do this evening so here's my API version. It was noticeably slower when using @run-at document-idle, but since this version doesn't need to reference anything on the page, I moved it up to document-start.

version 3 (code cleanup and using language code 'no' instead of 'nb')

// ==UserScript==
// @name         Wikipedia Language Redirector (Using Mediawiki API)
// @version      v3
// @match        https://en.wikipedia.org/wiki/*
// @description  Redirects wikipedia pages to alternate language pages in order of predefined preference
// @author       wheresmysurplusvalue
// @run-at       document-start
// @license      AGPL 3+
// ==/UserScript==

const LanguageList = ['no', 'nn', 'da', 'sv', 'eo', 'tok', 'ru', 'ja', 'zh'];

function main() {
    if (LanguageList.length == 0) {
        return;
    }

    const path = window.location.pathname;
    const title = parseTitle(path);

    if (title) {
        resolveTitle(title)
        .then(getLanguages)
        .then(chooseLanguage)
        .then(redirectLanguage)
        .catch(err => console.error(err));
    } else {
        console.log("Article title could not be parsed:", path);
    }
}

function redirectLanguage(pageLanguage) {
    window.location.href = `https://${pageLanguage.code}.wikipedia.org/wiki/${pageLanguage.key}`;
}

function chooseLanguage(availableLanguages) {
    const pageLanguage = filterLanguages(availableLanguages).next().value;
    if (!pageLanguage) {
        throw new Error(`Article not available in preferred languages: ${LanguageList}`);
    }
    return pageLanguage;
}

function* filterLanguages(availableLanguages) {
   for (const langCode of LanguageList) {
      for (const pageLanguage of availableLanguages) {
         if (pageLanguage.code == langCode) {
             yield pageLanguage;
         }
      }
   }
}

function parseTitle(path) {
    const regex = /^\/wiki\/(.*)/;
    const match = path.match(regex);

    if (!match) {
        console.error(`Could not parse title from path: ${path}`);
        return null;
    }

    const title = match[1];
    console.log("Extracted article title:", title);
    return title;
}

async function request(url) {
    const response = await fetch(url);
    if (!response.ok) {
        throw new Error(`HTTP error! url: ${url}, status: ${response.status}`);
    }
    return await response.json();
}

async function resolveTitle(title) {
    return getPage(title).then(data => data.key);
}

async function getPage(title) {
    const url = `/w/rest.php/v1/page/${title}/bare`;
    return requestPage(url, true);
}

async function requestPage(url, followRedirect) {
    return request(url).then(data => {
        console.log("data:", data);
        if (followRedirect && data.redirect_target) {
            return requestPage(data.redirect_target, followRedirect);
        }
        return data;
    });
}

async function getLanguages(title) {
    const url = `/w/rest.php/v1/page/${title}/links/language`;
    return request(url);
}

main();

version 2 (added a call to the page API to follow redirects)

// ==UserScript==
// @name         Wikipedia Language Redirector (Using Mediawiki API)
// @version      v2
// @match        https://en.wikipedia.org/wiki/*
// @description  Redirects wikipedia pages to alternate language pages in order of predefined preference
// @author       wheresmysurplusvalue
// @run-at       document-start
// @license      AGPL 3+
// ==/UserScript==

const LanguageList = ['nb', 'nn', 'da', 'sv', 'eo', 'tok', 'ru', 'ja', 'zh'];

function main() {
    const path = window.location.pathname;
    const title = getTitle(path);

    if (title) {
        getRealTitle(title)
        .then(title => getLanguages(title))
        .then(data => chooseLanguage(data));
    } else {
        console.log("Article title could not be parsed: ", path);
    }
}

function chooseLanguage(availableLanguages) {
   for (const langCode of LanguageList) {
      for (const pageLanguage of availableLanguages) {
         if (pageLanguage.code == langCode) {
             console.log("Found match: ", langCode);
             window.location.href = `https://${pageLanguage.code}.wikipedia.org/wiki/${pageLanguage.key}`;
             return;
         }
      }
   }
   console.log("Article not available in preferred languages.");
}

function getTitle(path) {
    const regex = /^\/wiki\/(.*)/;

    const match = path.match(regex);

    if (match) {
        const title = match[1];
        console.log("Extracted article title: ", title);

        return title;
    }

    return null;
}

async function request(url) {
    try {
        const response = await fetch(url);
        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }
        const data = await response.json();
        return data;
    } catch (error) {
        console.error('Error fetching data:', error);
    }
}

async function getLanguages(title) {
    const url = `/w/rest.php/v1/page/${title}/links/language`;
    return request(url);
}

async function getRealTitle(title) {
    const url = `/w/rest.php/v1/page/${title}/bare`;
    return getPage(url).then(data => {
        console.log("Resolved title: ", data.key);
        return data.key;
    });
}

async function getPage(url) {
    return request(url).then(data => {
        console.log("data: ", data);
        if (data.redirect_target) {
            return getPage(data.redirect_target);
        }
        return data;
    });

}

main();

version 1 (does not work if the page is redirected)

// ==UserScript==
// @name         Wikipedia Language Redirector (Using Mediawiki API)
// @version      v1
// @match        https://en.wikipedia.org/wiki/*
// @description  Redirects wikipedia pages to alternate language pages in order of predefined preference
// @author       wheresmysurplusvalue
// @run-at       document-start
// @license      AGPL 3+
// ==/UserScript==

const LanguageList = ['nb', 'nn', 'da', 'sv', 'eo', 'tok', 'ru', 'ja', 'zh'];

function handleResponse(json) {
   for (const langCode of LanguageList) {
      for (const pageLanguage of json) {
         if (pageLanguage.code == langCode) {
             console.log("Found match: ", langCode);
             window.location.href = `https://${pageLanguage.code}.wikipedia.org/wiki/${pageLanguage.key}`;
             return;
         }
      }
   }
   console.log("Article not available in preferred languages.");
}

const path = window.location.pathname;
const title = getTitle(path);

if (title) {
    getLanguages(title, handleResponse);
} else {
    console.log("Article title could not be parsed: ", path);
}

function getTitle(path) {
    const regex = /^\/wiki\/(.*)/;

    const match = path.match(regex);

    if (match) {
        const title = match[1];
        console.log("Extracted article title: ", title);

        return title;
    }

    return null;
}

function getLanguages(title, callback) {
    const request_url = `/w/rest.php/v1/page/${title}/links/language`;
    console.log("Request url: ", request_url);

    fetch(request_url)
        .then(response => {
            if (!response.ok) {
                throw new Error("HTTP status code in error: " + response.statusText);
            }
            return response.json();
        })
        .then(data => callback(data))
        .catch(error => {
            console.error("Error: ", error);
        });
}

[-] wheresmysurplusvalue@hexbear.net 6 points 3 days ago* (last edited 3 days ago)

Kudos to the authors for making it!

I was considering an alternate approach by calling Wikipedia's REST API Get languages GET /page/{title}/links/language to get all the available languages for a page. Then search the response for the first language in the list which is available, and redirect to that. It's an extra network request, but maybe more resilient to differences in how the HTML is rendered in the future.

See for example the languages list for the article on the Soviet Union: https://en.wikipedia.org/w/rest.php/v1/page/Soviet_Union/links/language

I started looking into this and this might be what the Accept-Language HTTP header^[https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Accept-Language] is used for? It seems to allow a list of languages in order of preference, and then websites can use this to decide which language to show content in.

There's probably a setting in about:config which will globally set Accept-Language for all pages you visit, or maybe you can try an extension like this to control it per site.

I tried using this addon to add a site setting for *.wikipedia.org to set Accept-Language to de, fr, but it's not working for me. It might be that my browser (IronFox on Android) has some settings to prevent browser fingerprinting which are interfering with this. (There's at least one setting "Request English versions of web pages - When enabled, strengthens fingerprinting protection")

Dunno if this helps, but maybe it gives a direction to look.

Sanction me once

second-plane

You can't sanction me again

118
10

The Shepherd is an init system and process manager initially built for GNU Hurd and now used by Guix. It can run with either root or user privileges to launch daemons, execute tasks, and manage processes. As we’ve discussed previously, Spritely has been working to port the Shepherd to Goblins. We’ve been a bit quiet since that announcement, so what’s the buzz?

First, as a quick refresher, the Shepherd is a great project to port to Goblins because it’s already built on the actor model. By switching to Goblins, we can bring the following benefits to the project:

  • Streamline the codebase by replacing the Shepherd’s ad-hoc actor model implementation.
  • Reduce the likelihood of concurrency bugs caused by the existing actor model implementation that exposes too much of its CSP foundation using Fibers.
  • Transform services (and other actors) into object capabilities for fine-grained management of privileges, which will (eventually) make it to possible to unify the currently separate worlds of “system” Shepherds that run as root under PID 1 and “user” Shepherds that run as an unprivileged user.
  • Enable Shepherd to use the Object Capability Network (OCapN) to open the door for distributed networks of “Communicating Shepherd Processes” in the future.

Since our last post, we’ve done the following:

  • Wrote Goblins versions of the core actors like the service controller, service registry, and process monitor.
  • Added unit tests for all of the core actors (there were none before).
  • Rewrote the public API as a compatibility layer on top of a new Goblins actor API. This new API is private for now.

What this means is that all of the extant Shepherd functionality will soon be available in the Goblins port. We’re currently working out the remaining sneaky, tricky, subtle bugs in order to have a full 1:1 port that passes the existing test suite. We’re getting very close, so we felt it was time to share this update!

20
[-] wheresmysurplusvalue@hexbear.net 78 points 10 months ago

So nice of the pope to die on a Monday so that the megathread topic writes itself

12
12
submitted 2 years ago* (last edited 2 years ago) by wheresmysurplusvalue@hexbear.net to c/hexbear@hexbear.net

I noticed while creating a new post that if I provide a Thumbnail URL with an external (not hexbear.net) URL, then the original image gets used when viewing the post. I first noticed it on this post where I added a youtube thumbnail icon (check it in the browser console).

I tried researching if there's a bug for this in upstream Lemmy:

This one seems like it would have fixed it: LemmyNet/lemmy-ui: Update post listing to prefer local image when available

And see also this: LemmyNet/lemmy: Add initial skeleton of image proxy improvements for feedback

Unfortunately I'm not that familiar with the Lemmy codebase, but how possible would it be to proxy+cache thumbnails? I don't quite mean store it permanently in the database, just proxy the source image and cache it for performance reasons. Otherwise, maybe we should disable the thumbnail URL for now until this support is added upstream?

[-] wheresmysurplusvalue@hexbear.net 85 points 2 years ago

squidward-chill

Did the Resistance retaliate yet?

squidward-nochill

Nah still cookin

squidward-chill

6
[-] wheresmysurplusvalue@hexbear.net 70 points 2 years ago* (last edited 2 years ago)

Has anyone here watched the show Derry Girls set in Ireland during the Troubles? It ended with

Tap for spoilera cameo by Chelsea fucking Clinton lmao, worst possible ending

4

I remembered this song I hadn't listened to in years. Checked out the musician's page and saw that she's actively posting pro Palestine activism hard. Give her a listen!

111

In Russian they don't say "I love you" they say "пожирать плоть капиталистов" which means "we are one and the same" and I think that's beautiful

[Screenshot of google translate]

Query: Пожирать плоть капиталистов
Result: Eat the flesh of the capitalists

[-] wheresmysurplusvalue@hexbear.net 79 points 2 years ago* (last edited 2 years ago)

Ursula von der Leyen getting harassed by anti-genocide protestors in Helsinki market square

https://streamable.com/ss72wo
https://streamable.com/i59yv6

No end to the genocide, no right to speak

[-] wheresmysurplusvalue@hexbear.net 71 points 2 years ago

Live stream and a news article for this one.

Protesters demanded Yle [Finnish state media] withdraw from the Eurovision Song Contest at Yle broadcasting in Helsinki

Demonstrators in the lobby of Ylen Mediatalo. Photo: Petteri Sopanen / Yle

On Saturday morning, a group of protesters arrived at Yle's Helsinki office to demand that Yle withdraw from Eurovision because Israel is participating in the competition.

Israel's participation has attracted strong criticism , as Israel is waging a war in the Palestinian territory of Gaza.

In the press release, the protesters say that Israel will get a platform to polish its own image in Eurovision.

16

No clue what they're saying but I'm enjoying the instrument selection and dance

21
submitted 2 years ago* (last edited 2 years ago) by wheresmysurplusvalue@hexbear.net to c/technology@hexbear.net

Recently I've been reading a lot about the topic of mesh VPNs (tinc, Nebula, Tailscale, ZeroTier, Netmaker, Netbird, etc) and find them pretty interesting. Is anyone here using these in some capacity at home or maybe at work?

My problem so far is that many of the options seem to be aimed at corporate use, understandably, so the developers can earn enough to keep doing it. This means the focus is on a centralized control plane, one server which knows everything about the entire network and manages firewall rules for all of it.

This is why I'm leaning towards Nebula, since I think the decentralized design just makes more sense. There is some centralization for issuing certs though. How do I go about setting up PKI? Is there some open source solution for managing certificates and automatically renewing them?

There's also the option of using vanilla WireGuard. This is my current setup, but I really like the idea of meshing, since it means I don't need to care if my devices are physically on the same network or not, the best connection will be used. Basically the layer of abstraction is a nice convenience that lets me think about hosts or services independently of the physical network topology.

I'm interested to hear your thoughts on this topic! What's your setup like and what do you use it for?

248
bib mag (hexbear.net)
view more: next ›

wheresmysurplusvalue

0 post score
0 comment score
joined 2 years ago