Search

Items tagged with: poverty


Mutual Aid Request Roundup 21 Oct 2026


The media in this post is not displayed to visitors. To view it, please go to the original post.

1,929 words
8–12 minutes

How Many More Victims?


Hundreds of people broke through the barricades at the Central Kalimantan governor’s office in Palangka Raya on Monday afternoon, on the eve of the Prabowo-Gibran government’s second anniversary. The Aliansi Masyarakat Kalteng Melawan came with student councils, among them BEM UI, whose members flew in from Jakarta. Their central demand was that Jakarta declare the fires in Central Kalimantan a national disaster. Governor Agustiar Sabran came out and sat with them, then left to pray at the Asr call and did not return. The crowd took the courtyard. Organisers say a fourth and larger demonstration is coming. The haze has run for four months.

The Health Ministry counted 314,124 acute respiratory infection cases in fire-affected areas between 20 August and 20 October, across seven provinces and 65 districts and cities. Children aged 0 to 5 make up 70,890 of them. Tuesday alone added 3,269. As of Tuesday afternoon, Central Kalimantan had 295 “oxygen houses” running, South Kalimantan 127 and West Kalimantan 35. On 16 October, IQAir recorded air pollution in Palangka Raya in the hazardous range, with an air quality index above 300. Kompas reported on 17 October the death of a six-year-old, suspected to be from a respiratory infection, whose uncle asked: “Nunggu korban berapa lagi?” How many more victims are we waiting for? The smoke disrupted 390 flights across Kalimantan, with Central Kalimantan hit worst. The ministry’s advice is to stay home, work or study online where possible and wear an N95 or KN95 mask. It carves out field workers and public service staff. The people whose jobs cannot move online keep breathing it.

On 14 October anti-corruption investigators named five suspects over alleged corruption involving emergency funds at the national disaster agency, BNPB, following raids earlier that week. Among the suspects was the brother of BNPB head Suharyanto, who was replaced the next day. Two days before the suspects were named, Prabowo had expressed surprise at a report that only 639.23 hectares remained burning across six provinces, having expected tens of thousands. The Cabinet Secretariat’s own account described those 639 hectares as land undergoing firefighting operations. Syahganda Nainggolan, who heads the government communications office, has called the fires “beyond human error” and “truly nature”.

Arniyanti of Lembaga Gemawan says over 70 percent of the fire spots sit inside company concessions. Police were investigating 96 companies in August and the government had imposed administrative sanctions on 26. Environmental group Pantau Gambut identifies industrial-scale plantation development and peatland drainage as causes of the degradation that leaves peatlands vulnerable to fire. Boy Jerry Even Sembiring, executive director of Walhi, says accountability must reach those who control and profit from land ownership. In Pontianak a coalition led by Nafas Kalbar, with Indigenous people and religious youth groups among the plaintiffs, is suing the president, the vice-president, ministers and the national police chief for negligence, and asking for a national emergency declaration, free health care for vulnerable groups and prosecutions. Seven residents did this after the 2015 fires, won at district court, and saw the decision overturned in 2022. The plantation is a colonial invention and the concession is its descendant: land organised around a return collected somewhere other than where the smoke settles. Singapore has raised the prospect of fines or charges against companies responsible for the fires. Smoke that crosses a border gets a lawyer. Smoke that stays inside it gets “truly nature.”

I write as an Indonesian, and the part I will not let a ministry’s advice bury is that this ledger runs in one direction everywhere. In Palangka Raya the price of cheap land is booked to children’s lungs. In Gaza it is booked to a flour price, while WFP pleads for $450 million against the $2.8 billion in bombs Washington approved for Israel in September. Households in Iran absorb a blockade whose squeeze on raw materials reaches the medicine they depend on. Jakarta sits inside the same arrangement. In February Prabowo pledged 8,000 troops “or more” to Trump’s Gaza stabilisation force, and Al Jazeera’s 13 October roundup records that no stabilisation force has deployed. The state that signs up to Washington’s arrangements and the state that issued the concessions are one state, and neither answers to the people downwind of either.

The people behind the requests below are downwind of the same decisions. A concession map, a bomb sale and a blockade look like three different stories, and they share one method: capital extracts, the cost is booked to whoever lives closest to it, and the institutions meant to catch the fall are underfunded, looted or answering to someone else. In Kalimantan the fall is a six-year-old’s lungs, while the national disaster agency’s emergency funds are under investigation. In Gaza, it is the soaring cost of staple foods. For a person with overdue rent, medication running out in days or a stalled disability payment, it arrives as a bill. These struggles connect because one system produces them, and because the same absence meets each one: nobody official is coming.

Direct action here means closing the gap ourselves, this week. The ministry says to stay home and buy an N95, which assumes the money exists. Mutual aid supplies it: a transfer from someone with a little to someone with none, with no concession, ministry or committee in between. Every request below belongs to a person who has already tried the official routes. Give to the ones you can, share each one in the group chats where you already hold trust, and ask one person with money to match what you gave. The state is still deciding what to call this. A household needs its answer now.


A note before the list: mutualaidspace.org’s submission form is live. Submitting a request there gets it federated as @comrade, automatically tagged for wider reach, and listed publicly under Comrades & Community or Victims of Empire, whether or not the person asking has a Fediverse account of their own. No verification process, no proof of suffering required. More on the project itself: mutualaidspace.org/about

✨Mutual Aid Roundup✨

@ctrlaltglitch @starryeyes @blaurascon @kitwinter @KestrelSWard @thereaders @sickandtired @tiredpinklover @roxy @lowroarrawr


✨Palestinian Campaign Spotlight✨

95140201 1761672052643598 R

Together for Marah & Mila: Surviving the War in Gaza

Marah has been running a fever above 39°C and was too weak to post for days. She says she has not received enough support, and her health is not okay. Her campaign carries her family through the siege [View original post]

@marahismail


REDISTRIBUTE

107476417 1790618829695995 R

Save Hadeel and her children

Hadeel is a mother of two young daughters living in a tattered tent in Gaza. With winter, storms and bitter cold arriving, rainwater floods the space. She urgently needs a tent and tarpaulins to protect her children [View original post].

@jojojulia


REDISTRIBUTE

Gaza Verified Archive
Verified Palestinian campaigns under $200
These are verified Palestinian accounts whose campaigns received less than $200 in the past 7 days.

Nine of many. The archive holds the rest.
@EngFarahGaza@mastodon.social @HadeelMohammed@mastodon.social @hadeel_2026@mastodon.world @samour1997@mastodon.social @tareqradi@mastodon.social @danyarelkhodari@mastodon.social @mhoeed@mastodon.social @aseelfromgz@mastodon.social @maher553533@mastodon.social
Open the archive, find the campaign link on each account, give directly where possible, and share the campaign links that need movement.
View underfunded campaign list About Gaza Verified Campaigns


@mutualaid @mutualaid @disability @disability @autistics @actuallyadhd @theleftistlawyer @frugalcoffee @wrzky @wrzky @edendestroyer @QasimRashid #Gaza @palestine @indonesia @indonesia #Palestine #genocide #mutualaid #anarchism #internationalism #MutualAidRequest #DisabilityMutualAid #MutualAidSpace #DisabilityCrowdfund #TransMutualAid #QueerMutualAid #lgbtq #politics #EmergencyCrowdfund #GazaMutualAid #poverty #healthcare #mentalhealth #disability #neurodivergence #activism #fedihelp #fediverse #HelpFolksLive2026 #socialmedia #BlackMutualAid #writer #MutualAidVoid #helpsky #press #SEAblings #fediforgaza #Indonesia #wildfires #iran

🗣️Support Corner🗣️

📱Share this article far and wide. Subscribe to get this update in your inbox!

This space is held together by a disabled Indonesian Muslim woman. Monthly support keeps me fed, medicated, and connected, and helps me keep resisting corporate funding and the humanitarian-industrial complex through my writing and mutual aid projects.

If you find this voluntary work worth supporting, please do so by pledging as little as $1 monthly via Liberapay or other tiers available across Liberapay, ko-fi, and Patreon. One-off support helps too. Any amount genuinely helps.

Paid Membership on Patreon

Ko-fi voluntary monthly support

Liberapay voluntary monthly support

Monthly Support Package





The media in this post is not displayed to visitors. To view it, please go to the original post.

Ok so video uploads to #friendica kind of suck, I get it, it is not exactly a video platform, but I have made it my all in one social and website, so I created a complex solution to an easy problem, as I want control over where my content is hosted/served from, I made this convoluted script and process for my video uploads, it starts with opening #filezilla and ftping into my /storage/videos folder in my instance, yes I created a folder in /storage labeled videos, after I move the .mp4 into that folder I run a script that I placed in the root of my instance which is called register-video.php and here is the script,

<?php

ini_set('display_errors', 1);
error_reporting(E_ALL);

// CONFIGURE THESE:
$friendica_root = '/home/someplace/public_html/your.instance.domain/';
$ftp_folder     = $friendica_root . 'storage/videos/';
$uid            = your user number;

// DATABASE CONFIG:
$db_host = 'localhost';
$db_user = 'your db user';
$db_pass = 'your db password';
$db_name = 'your db name';

// Connect to Friendica database
$mysqli = new mysqli($db_host, $db_user, $db_pass, $db_name);

if ($mysqli->connect_errno) {
    die("DB ERROR: " . $mysqli->connect_error . "\n");
}

// Debug: show folder
echo "Checking folder: $ftp_folder\n";

// Find all files in FTP folder
$files = glob($ftp_folder . '*');

if (!$files) {
    echo "No files found.\n";
    exit;
}

$allowed = array('mp4', 'webm', 'mov');

foreach ($files as $file) {

    $ext = strtolower(pathinfo($file, PATHINFO_EXTENSION));

    if (!in_array($ext, $allowed)) {
        continue;
    }

    $basename = basename($file);
    $filesize = filesize($file);
    $filetype = mime_content_type($file);

    echo "Registering: $basename\n";

    // Read file contents into memory
    $filedata = file_get_contents($file);

    if ($filedata === false) {
        echo "Failed to read file data.\n";
        continue;
    }

    // Create Friendica hash
    $hash = hash('sha256', $basename . microtime(true));

    $created = date('Y-m-d H:i:s');
    $edited  = $created;

    // Insert into Friendica attach table
    $stmt = $mysqli->prepare("
        INSERT INTO attach 
        (uid, hash, filename, filetype, filesize, data, created, edited)
        VALUES (?, ?, ?, ?, ?, ?, ?, ?)
    ");

    $null = NULL;

    $stmt->bind_param(
        "isssisss",
        $uid,
        $hash,
        $basename,
        $filetype,
        $filesize,
        $filedata,
        $created,
        $edited
    );

    $stmt->send_long_data(5, $filedata);

    $stmt->execute();

    $attach_id = $stmt->insert_id;

    echo "Attachment ID: " . $attach_id . "\n";
    echo "Embed using:\n";
    echo "[video]https://your.instance.domain/attach/" . $attach_id . "[/video]\n\n";

    $stmt->close();
}

echo "Done.\n";

?>

after you have imported your video via ftp to your /storage/videos you go to your cmd that your sshed into and in the root of your instance you run php register-video.php and you should receive

 php register-video.php
Checking folder: /home/someplace/public_html/your.instance.domain/storage/videos/
Registering: somerandom.mp4
Attachment ID: some number will appear here say 00
Embed using:
[video]https://your.instance.domain/attach/00[/video]

Done.
then you can embed into your post, yes I created something no one needs or wants, but I wanted and needed it so I am sharing on the off chance someone may find it useful;


⚖️ License (MIT)
Copyright (c) 2026 pasjrwoctx👽 (Philip A. Swiderski Jr.)

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE

@Friendica Support @Friendica Developers @Friendica Admins

You can encourage my continued useless ideas, and by doing so your helping to feed, house and clothe a #disabled man living in #poverty, $5-10-15 It All Helps, via #cashapp at $woctxphotog or via #paypal at paypal.com/donate?campaign_id=…


The media in this post is not displayed to visitors. To view it, please go to the original post.

Ok so video uploads to #friendica kind of suck, I get it, it is not exactly a video platform, but I have made it my all in one social and website, so I created a complex solution to an easy problem, as I want control over where my content is hosted/served from, I made this convoluted script and process for my video uploads, it starts with opening #filezilla and ftping into my /storage/videos folder in my instance, yes I created a folder in /storage labeled videos, after I move the .mp4 into that folder I run a script that I placed in the root of my instance which is called register-video.php and here is the script,

<?php

ini_set('display_errors', 1);
error_reporting(E_ALL);

// CONFIGURE THESE:
$friendica_root = '/home/someplace/public_html/your.instance.domain/';
$ftp_folder     = $friendica_root . 'storage/videos/';
$uid            = your user number;

// DATABASE CONFIG:
$db_host = 'localhost';
$db_user = 'your db user';
$db_pass = 'your db password';
$db_name = 'your db name';

// Connect to Friendica database
$mysqli = new mysqli($db_host, $db_user, $db_pass, $db_name);

if ($mysqli->connect_errno) {
    die("DB ERROR: " . $mysqli->connect_error . "\n");
}

// Debug: show folder
echo "Checking folder: $ftp_folder\n";

// Find all files in FTP folder
$files = glob($ftp_folder . '*');

if (!$files) {
    echo "No files found.\n";
    exit;
}

$allowed = array('mp4', 'webm', 'mov');

foreach ($files as $file) {

    $ext = strtolower(pathinfo($file, PATHINFO_EXTENSION));

    if (!in_array($ext, $allowed)) {
        continue;
    }

    $basename = basename($file);
    $filesize = filesize($file);
    $filetype = mime_content_type($file);

    echo "Registering: $basename\n";

    // Read file contents into memory
    $filedata = file_get_contents($file);

    if ($filedata === false) {
        echo "Failed to read file data.\n";
        continue;
    }

    // Create Friendica hash
    $hash = hash('sha256', $basename . microtime(true));

    $created = date('Y-m-d H:i:s');
    $edited  = $created;

    // Insert into Friendica attach table
    $stmt = $mysqli->prepare("
        INSERT INTO attach 
        (uid, hash, filename, filetype, filesize, data, created, edited)
        VALUES (?, ?, ?, ?, ?, ?, ?, ?)
    ");

    $null = NULL;

    $stmt->bind_param(
        "isssisss",
        $uid,
        $hash,
        $basename,
        $filetype,
        $filesize,
        $filedata,
        $created,
        $edited
    );

    $stmt->send_long_data(5, $filedata);

    $stmt->execute();

    $attach_id = $stmt->insert_id;

    echo "Attachment ID: " . $attach_id . "\n";
    echo "Embed using:\n";
    echo "[video]https://your.instance.domain/attach/" . $attach_id . "[/video]\n\n";

    $stmt->close();
}

echo "Done.\n";

?>

after you have imported your video via ftp to your /storage/videos you go to your cmd that your sshed into and in the root of your instance you run php register-video.php and you should receive

 php register-video.php
Checking folder: /home/someplace/public_html/your.instance.domain/storage/videos/
Registering: somerandom.mp4
Attachment ID: some number will appear here say 00
Embed using:
[video]https://your.instance.domain/attach/00[/video]

Done.
then you can embed into your post, yes I created something no one needs or wants, but I wanted and needed it so I am sharing on the off chance someone may find it useful;


⚖️ License (MIT)
Copyright (c) 2026 pasjrwoctx👽 (Philip A. Swiderski Jr.)

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE

@Friendica Support @Friendica Developers @Friendica Admins

You can encourage my continued useless ideas, and by doing so your helping to feed, house and clothe a #disabled man living in #poverty, $5-10-15 It All Helps, via #cashapp at $woctxphotog or via #paypal at paypal.com/donate?campaign_id=…


So I kind of set up another level of security well not really more of a gate to help block more bots and scrapers that seem to bypass robots.txt and whatever enhancements and blocks you have in your .htaccess file, these currently are working on my #friendica instance fairly well so maybe they can help someone maybe they do nothing;

First at the very top of your index.php in the root of your friendica directory right after the <? I added the following code,

// --- ALIEN GATE START ---
$request = $_SERVER['REQUEST_URI'] ?? '';

// 0. Signed cookie (prevents bots forging it)
$secret_key = 'Your_Alien_Secret';
$valid_cookie = hash_hmac('sha256', 'verified', $secret_key);
$has_cookie = isset($_COOKIE['instance_access']) &&
              hash_equals($valid_cookie, $_COOKIE['instance_access']);

if (!$has_cookie) {

    // 1. Federation / machine endpoints (never gate)
    $is_fediverse =
        str_contains($request, '/.well-known/') ||
        str_contains($request, '/activitypub/') ||
        str_contains($request, '/api/') ||
        str_contains($request, '/assets/');

    // 2. Static assets (never gate)
    $is_static = preg_match('/\.(css|js|png|jpg|ico|svg|woff2)$/i', $request);

    // 3. Only gate the root URL
    if ($request === '/' && !$is_fediverse && !$is_static) {
        require 'gate.php';
        exit;
    }

    // 4. Prevent bypass via /index.php
    if ($request === '/index.php') {
        header('Location: /');
        exit;
    }
}
// --- ALIEN GATE END ---

then I created in the root directory again, gate.php

 <?php
// 1. VERIFICATION LOGIC
if (isset($_GET['nonce']) && isset($_GET['seed'])) {
    $nonce = (int)$_GET['nonce'];
    $seed = $_GET['seed'];
    $check_hash = hash('sha256', $seed . $nonce);

    // Verify hash matches the "000" requirement
    if (str_starts_with($check_hash, '000')) {
        $secret = 'Your_Alien_Secret';
$token  = hash_hmac('sha256', 'verified', $secret);
setcookie("instance_access", $token, time() + 86400 * 30, "/");
        header("Location: /index.php");
        exit;
    }
}

// 2. CHALLENGE UI
$seed = bin2hex(random_bytes(16));
?>
<html>
<head>
    <title>Access Verification</title>
    <link href="https://fonts.googleapis.com/css2?family=Atkinson+Hyperlegible+Mono&display=swap" rel="stylesheet">
    <style>
        body {
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
            font-family: 'Atkinson Hyperlegible Mono', monospace;
            background-color: #f4f4f9;
            color: #333;
        }
        .container {
            text-align: center;
            padding: 2rem;
            background: white;
            border-radius: 8px;
            box-shadow: 0 4px 6px rgba(0,0,0,0.1);
        }
    </style>
</head>
<body>
    <div class="container">
        <h2>Your Instance Name</h2>
        <h3>Verification Required</h3>
        <p id="status">Your Computer Is Solving A Security Challenge To Prove You Are A Human...</p>
        <p>Your Computer Is Solving A Security Challenge To Prove You Are A Human...</p>
        <p>Your Privacy Matters, No Data Is Recorded...</p>
    </div>

    <script>
        const seed = "<?php echo $seed; ?>";
        let nonce = 0;

        async function sha256(message) {
            const msgUint8 = new TextEncoder().encode(message);
            const hashBuffer = await crypto.subtle.digest('SHA-256', msgUint8);
            return Array.from(new Uint8Array(hashBuffer)).map(b => b.toString(16).padStart(2, '0')).join('');
        }

        async function solve() {
            const startTime = Date.now();
            
            while (true) {
                let hash = await sha256(seed + nonce);
                if (hash.startsWith("000")) {
                    const elapsed = Date.now() - startTime;
                    const remaining = 2000 - elapsed;
                    
                    if (remaining > 0) {
                        document.getElementById('status').innerText = "Verifying human interaction...";
                        await new Promise(r => setTimeout(r, remaining));
                    }
                    
                    window.location.href = `?nonce=${nonce}&seed=${seed}`;
                    break;
                }
                nonce++;
            }
        }
        solve();
    </script>
</body>
</html>

in both places change Your_Alien_Secret for your actual matching secret, and maybe it will help kill some bot and scrapers from hitting your instance so hard;

⚖️ License (MIT)
Copyright (c) 2026 pasjrwoctx👽 (Philip A. Swiderski Jr.)

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE

@Friendica Support @Friendica Developers @Friendica Admins

You can encourage my continued useless ideas, and by doing so your helping to feed, house and clothe a #disabled man living in #poverty, $5-10-15 It All Helps, via #cashapp at $woctxphotog or via #paypal at paypal.com/donate?campaign_id=…


Ok so recently I ran into a hiccup with an issue that effects how my jetstream and daemons run on my #friendica instance, as I am still working on the what I created a workaround that makes sure that they run as they should, I made one more semi useful script for a resource control hack, that helps throttle lsphp to reduce server loads on limited resources without compromising flow of feeds, then I have made some cron adjustments that may or may not help your #friendica instance; I am sharing my little scripts and hacks for those who may have resource issues where their daemon and jetstream keep getting killed, or where they are on a limited server environment, I offer no promise nor support, but for me it is working nicely;
Again I make no claims of actual usability or benefit, as of posting this it seems to be working well on my #friendica instance;


Crons

# --- Friendica Automation Suite ---
MAILTO="your-email@domain.com"
SHELL="/bin/bash"

# Core background tasks
0 */1 * * * /home/USER/friendica_cron.sh >/dev/null 2>&1
*/15 * * * * /usr/bin/flock -n /tmp/fc_worker.lock -c cd /home/USER/public_html && bin/console worker >/dev/null 2>&1

# Maintenance: Monthly Smarty purge (1st of the month)
0 0 1 * * /usr/bin/rm -rf /home/USER/public_html/view/smarty/compile/* >/dev/null 2>&1

# Maintenance: Weekly Storage & Cache clearing (Sundays)
0 1 * * 0 cd /home/USER/public_html; bin/console storage clear >/dev/null 2>&1
30 1 * * 0 cd /home/USER/public_html; bin/console cache clear >/dev/null 2>&1

# Watchdogs: StayAlive & Bouncer
@reboot /bin/bash /home/USER/scripts/StayAlive.sh > /dev/null 2>&1 &
0 * * * * pgrep -f StayAlive.sh > /dev/null || /bin/bash /home/USER/scripts/StayAlive.sh > /dev/null 2>&1 &

@reboot /bin/bash /home/USER/scripts/bouncer.sh > /dev/null 2>&1 &
* * * * * pgrep -f bouncer.sh > /dev/null || /bin/bash /home/USER/scripts/bouncer.sh > /dev/null 2>&1 &

README

⚙️ The Friendica Automation Suite (Crontab)
Scheduled Maintenance & Self-Healing Guards
This configuration file acts as the "Brain" of your Friendica instance. It manages the scheduling for background tasks, periodic cache cleaning, and—most importantly—ensures your custom stability scripts (Bouncer and StayAlive) never stop running.

⚠️ Implementation Note: Replace YOUR_HOME, YOUR_USER, and YOUR_INSTANCE_ROOT with your actual server paths.

These Crons are provided "as-is" for educational and personal use.

They will not be maintained or updated.

No support or bug fixes will be provided.

Use at your own risk..

🛠 What This Schedule Manages
1. Core Background Tasks
Hourly Maintenance: Runs friendica_cron.sh to handle general background cleanup.

Frequent Worker: Executes the Friendica worker every 15 minutes to keep the federation queue moving.

2. Housekeeping & Performance
To prevent disk bloat and keep the interface snappy, the following cleanup tasks are automated:

Monthly Smarty Purge: Clears compiled template files on the 1st of every month to refresh the UI engine.

Weekly Storage Cleanup: Clears the avatar and storage cache every Sunday at 1:00 AM.

Weekly Node Cache: Flushes the node cache every Sunday at 1:30 AM to keep remote directory info fresh.

3. The "Immortal" Guard System
The most critical part of this setup is the Watchdog for the Watchdogs.

Boot Persistence: Both the StayAlive.sh (Service Guard) and bouncer.sh (Resource Throttle) are set to trigger immediately upon a server reboot (@reboot).

The Safety Check: Every hour (for StayAlive) and every minute (for the Bouncer), the system checks if the scripts are still running. If they’ve been killed by the system, it automatically restarts them.

📋 Installation
To apply these rules to your server:

Open your crontab editor:

Bash
crontab -e
Paste the configuration, ensuring your paths are correct.

Save and exit.

🔍 Pro-Tip: Monitoring
You have MAILTO set at the top. If your server is configured for mail, any errors from these tasks will be sent directly to your inbox. If you prefer to log to a file instead, you can change the >/dev/null 2>&1 at the end of the lines to >> ~/cron_log.txt 2>&1.


Bouncer

#!/bin/bash

# These are the Bouncer's Rules
MAX_KIDS=3        # Only 3 people in the kitchen at once
MAX_HEAT=2        # Only 2% energy allowed
CHECK_TIME=5      # Wait 5 seconds before checking again

while true
do
  # 1. Count how many 'lsphp' workers are busy with your site
  CURRENT_KIDS=$(pgrep -f "lsphp.*YOUR_INSTANCE_ROOT" | wc -l)

 # Lower priority for all lsphp processes to keep the server cool
    pgrep -u *YOUR_USER lsphp | xargs -r renice -n 15 > /dev/null 2>&1

  # 2. If there are more than 3...
  if [ "$CURRENT_KIDS" -gt "$MAX_KIDS" ]; then
    echo "Bouncer: Too many kids! Making the extras wait in the hallway."
    
    # This finds the newest workers and tells them to 'STOP' (Pause)
    # They stay in line, but they don't use any CPU while paused.
    pgrep -f "lsphp.*YOUR_INSTANCE_ROOT" | tail -n +$((MAX_KIDS+1)) | xargs kill -STOP
    
    # Wait for things to cool down
    sleep $CHECK_TIME
    
    # Tell them they can 'CONT' (Continue) ONE BY ONE
        echo "$EXTRAS" | while read -r kid_pid; do
            if [ ! -z "$kid_pid" ]; then
                kill -CONT "$kid_pid"
                echo "Bouncer: Letting kid $kid_pid back in."
                sleep 1 
            fi
        done
  fi

  # Take a small breath so the Bouncer doesn't get tired
  sleep 1
done

README

🚪 The LSPHP Bouncer
Resource Throttle & Process Queue for Shared Hosting
The LSPHP Bouncer is a lightweight Bash watchdog designed for users on LiteSpeed-based hosting. It prevents your account from hitting "Resource Limit Reached" errors (508 errors) by pausing excess PHP processes (lsphp) instead of letting them crash the site or trigger a provider-level kill.

⚠️ Maintenance Notice
This project is provided "as-is" for educational and personal use.

It will not be maintained or updated.

No support or bug fixes will be provided.

Use at your own risk..

🧐 How It Works
LiteSpeed servers often spawn many lsphp workers to handle incoming traffic. If too many start at once, your host might lock your account for exceeding CPU or process limits.

The Headcount: Every second, the Bouncer counts how many PHP workers are active for your specific site.

The Velvet Rope: If the count exceeds your MAX_KIDS limit, the Bouncer sends a SIGSTOP signal to the extra processes. This pauses them—they stay in the queue but stop consuming CPU cycles.

The Entry: After a short cooldown (CHECK_TIME), the Bouncer sends a SIGCONT signal, letting those processes finish their work one by one.

🛠 Configuration
Open the script and adjust these "House Rules" to match your hosting plan:

MAX_KIDS: The maximum number of PHP processes you are allowed (e.g., 3).

CHECK_TIME: How many seconds to pause the "extras" before letting them work again.

Process Filter: The script looks for "lsphp.*your.domain". Ensure the string matches what shows up in your process monitor (usually top or htop).

🚀 Setup & Execution
1. Make it Executable
Bash
chmod +x bouncer.sh
2. Run the Bouncer
To keep the Bouncer running even after you log out of SSH:

Bash
nohup ./bouncer.sh > /dev/null 2>&1 &
📈 Why use this?
Avoids 508 Errors: Instead of the server showing a "Limit Reached" page, the site just feels a tiny bit slower while the Bouncer staggers the load.

CPU Friendly: Paused processes (kill -STOP) consume zero CPU, helping you stay under the "Energy" or "Heat" limits of your host.

Specific Targeting: Using pgrep -f, it only targets your specific site's workers, leaving other processes alone.


Persistent Service Guard

#!/bin/bash

# --- CONFIGURATION (Users change these) ---
# The absolute path to your application root
SITE_ROOT="/path/to/your/app"

# The path to the PHP binary (usually 'php' or a specific version)
PHP_CLI="/usr/bin/php"

# Name of the console executable
CONSOLE_APP="bin/console.php"

# Where to save the logs
LOG_FILE="./guard_log.txt"

# List of services to monitor
SERVICES=("daemon" "jetstream")

# --- CORE LOGIC (Do not edit below) ---
CONSOLE_PHP="$SITE_ROOT/$CONSOLE_APP"

echo "$(date): Persistent Guard started for services: ${SERVICES[*]}" >> "$LOG_FILE"

while true; do
    for SERVICE in "${SERVICES[@]}"; do
        # Check status
        STATUS=$($PHP_CLI $CONSOLE_PHP $SERVICE status 2>&1)

        if [[ "$STATUS" != *"is running"* ]]; then
            echo "$(date): $SERVICE is DOWN. Attempting start..." >> "$LOG_FILE"
            $PHP_CLI $CONSOLE_PHP $SERVICE start >> "$LOG_FILE" 2>&1
        fi
    done
    sleep 60
done

README

Persistent Service Guard
A robust, lightweight Bash-based watchdog script designed to monitor and automatically restart background services (such as Friendica daemons or Jetstream workers) for PHP-based applications.

⚠️ Maintenance Notice
This project is provided "as-is" for educational and personal use.

It will not be maintained or updated.

No support or bug fixes will be provided.

Use at your own risk.

🚀 What It Does
The Service Guard addresses the common issue where background processes or daemons on shared or private hosting may crash or be killed by the system.

Active Monitoring: It loops indefinitely, checking the status of defined services every 60 seconds.

Automatic Recovery: If a service is reported as "not running," the script immediately attempts to restart it.

Logging: Every check, failure, and restart attempt is timestamped and recorded for auditing.

🛠 Setup & Usage
1. Configuration
Before running, ensure the following variables in guard.sh match your environment:

SITE_ROOT: The absolute path to your application root.

PHP_CLI: The path to the PHP binary (e.g., /usr/bin/php).

SERVICES: The names of the services to monitor (e.g., "daemon" "jetstream").

2. Permissions
Grant execution rights to the script:

Bash
chmod +x guard.sh
3. Execution
Run the script in the background to ensure it persists after your session ends:

Bash
nohup ./guard.sh > /dev/null 2>&1 &
📊 Managing Logs
The script appends data to guard_log.txt. To prevent this file from consuming excessive disk space, use one of the following methods:

Manual Truncation
Clear the log without stopping the script:

Bash
> guard_log.txt
Automatic Log Rotation (Improvement Example)
To automate log management, add this logic inside the while loop of the script:

Bash
# Improvement: Simple Log Rotation
MAX_SIZE=1048576 # 1MB in bytes
FILE_SIZE=$(stat -c%s "$LOG_FILE")

if [ "$FILE_SIZE" -gt "$MAX_SIZE" ]; then
echo "$(date): Log rotated (size limit reached)" > "$LOG_FILE"
fi
📈 Potential Improvements
Users wishing to extend the script's functionality can implement the following:

1. Auto-Discovery
Replace the hardcoded PHP_CLI path with dynamic discovery:

Bash
PHP_CLI=$(which php)
2. Failure Notifications
Integrate curl to send alerts to Discord or Telegram when a service fails:

Bash
# Discord Notification Example
curl -H "Content-Type: application/json" -X POST -d "{\"content\": \"⚠️ Alert: $SERVICE has crashed. Restarting...\"}" YOUR_WEBHOOK_URL
3. Dependency Validation
Add a check to verify the application exists before the loop starts:

Bash
if [ ! -f "$CONSOLE_PHP" ]; then
echo "Error: Console application not found at $CONSOLE_PHP"
exit 1
fi


⚖️ License (MIT)
Copyright (c) 2026 pasjrwoctx👽 (Philip A. Swiderski Jr.)

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE

@Friendica Support @Friendica Developers @Friendica Admins

You can encourage my continued useless ideas, and by doing so your helping to feed, house and clothe a #disabled man living in #poverty, $5-10-15 It All Helps, via #cashapp at $woctxphotog or via #paypal at paypal.com/donate?campaign_id=…

⇧