]> pere.pagekite.me Git - homepage.git/blobdiff - blog/index.rss
Generated.
[homepage.git] / blog / index.rss
index 44bb237b9e08ec5c3296ede2052fa729e47b95b5..bba4e9eb148095cb2dba8eb41f3a45a4c4f029b1 100644 (file)
@@ -6,6 +6,41 @@
                 <link>https://people.skolelinux.org/pere/blog/</link>
                 <atom:link href="https://people.skolelinux.org/pere/blog/index.rss" rel="self" type="application/rss+xml" />
        
+       <item>
+               <title>The 2024 LinuxCNC Norwegian developer gathering</title>
+               <link>https://people.skolelinux.org/pere/blog/The_2024_LinuxCNC_Norwegian_developer_gathering.html</link>
+               <guid isPermaLink="true">https://people.skolelinux.org/pere/blog/The_2024_LinuxCNC_Norwegian_developer_gathering.html</guid>
+                <pubDate>Fri, 31 May 2024 07:45:00 +0200</pubDate>
+               <description>&lt;p&gt;&lt;a href=&quot;https://linuxcnc.org/&quot;&gt;The LinuxCNC project&lt;/a&gt; is still
+going strong.  And I believe this great software system for numerical control of
+machines such as milling machines, lathes, plasma cutters, routers,
+cutting machines, robots and hexapods, would do even better with more
+in-person developer gatherings, so we plan to organise such gathering
+this summer too.&lt;/p&gt;
+
+&lt;p&gt;The Norwegian LinuxCNC developer gathering take place the weekend
+Friday July 5th to 7th this year, and is open for everyone interested
+in contributing to LinuxCNC and free software manufacturing.  Up to
+date information about the gathering can be found in
+&lt;a href=&quot;https://sourceforge.net/p/emc/mailman/emc-developers/thread/123eaae0-f3b9-4170-a251-b7d608f1e974%40bofh.no/&quot;&gt;the
+developer mailing list thread&lt;/a&gt; where the gathering was announced.
+Thanks to the good people at
+
+&lt;a href=&quot;https://www.debian.org/&quot;&gt;Debian&lt;/a&gt; as well as leftover money
+from last years gathering from
+&lt;a href=&quot;https://www.redpill-linpro.com/&quot;&gt;Redpill-Linpro&lt;/a&gt; and
+&lt;a href=&quot;https://www.nuugfoundation.no/no/&quot;&gt;NUUG Foundation&lt;/a&gt;, we
+have enough sponsor funds to pay for food, and probably also shelter
+for the people traveling from afar to join us.  If you would like to
+join the gathering, get in touch and add your details on
+&lt;a href=&quot;https://pad.efn.no/p/linuxcnc-2024-norway&quot;&gt;the pad&lt;/a&gt;.&lt;/p&gt;
+&lt;p&gt;As usual, if you use Bitcoin and want to show your support of my
+activities, please send Bitcoin donations to my address
+&lt;b&gt;&lt;a href=&quot;bitcoin:15oWEoG9dUPovwmUL9KWAnYRtNJEkP1u1b&quot;&gt;15oWEoG9dUPovwmUL9KWAnYRtNJEkP1u1b&lt;/a&gt;&lt;/b&gt;.&lt;/p&gt;
+</description>
+       </item>
+       
        <item>
                <title>45 orphaned Debian packages moved to git, 391 to go</title>
                <link>https://people.skolelinux.org/pere/blog/45_orphaned_Debian_packages_moved_to_git__391_to_go.html</link>
@@ -1192,479 +1227,5 @@ betaling med bitcoin er ikke anonymt. :)&lt;/p&gt;
 </description>
        </item>
        
-       <item>
-               <title>New and improved sqlcipher in Debian for accessing Signal database</title>
-               <link>https://people.skolelinux.org/pere/blog/New_and_improved_sqlcipher_in_Debian_for_accessing_Signal_database.html</link>
-               <guid isPermaLink="true">https://people.skolelinux.org/pere/blog/New_and_improved_sqlcipher_in_Debian_for_accessing_Signal_database.html</guid>
-                <pubDate>Sun, 12 Nov 2023 12:00:00 +0100</pubDate>
-               <description>&lt;p&gt;For a while now I wanted to have direct access to the
-&lt;a href=&quot;https://signal.org/&quot;&gt;Signal&lt;/a&gt; database of messages and
-channels of my Desktop edition of Signal.  I prefer the enforced end
-to end encryption of Signal these days for my communication with
-friends and family, to increase the level of safety and privacy as
-well as raising the cost of the mass surveillance government and
-non-government entities practice these days.  In August I came across
-a nice
-&lt;a href=&quot;https://www.yoranbrondsema.com/post/the-guide-to-extracting-statistics-from-your-signal-conversations/&quot;&gt;recipe
-on how to use sqlcipher to extract statistics from the Signal
-database&lt;/a&gt; explaining how to do this.  Unfortunately this did not
-work with the version of sqlcipher in Debian.  The
-&lt;a href=&quot;http://tracker.debian.org/sqlcipher/&quot;&gt;sqlcipher&lt;/a&gt;
-package is a &quot;fork&quot; of the sqlite package with added support for
-encrypted databases.  Sadly the current Debian maintainer
-&lt;a href=&quot;https://bugs.debian.org/961598&quot;&gt;announced more than three
-years ago that he did not have time to maintain sqlcipher&lt;/a&gt;, so it
-seemed unlikely to be upgraded by the maintainer.  I was reluctant to
-take on the job myself, as I have very limited experience maintaining
-shared libraries in Debian.  After waiting and hoping for a few
-months, I gave up the last  week, and set out to update the package.  In
-the process I orphaned it to make it more obvious for the next person
-looking at it that the package need proper maintenance.&lt;/p&gt;
-
-&lt;p&gt;The version in Debian was around five years old, and quite a lot of
-changes had taken place upstream into the Debian maintenance git
-repository.  After spending a few days importing the new upstream
-versions, realising that upstream did not care much for SONAME
-versioning as I saw library symbols being both added and removed with
-minor version number changes to the project, I concluded that I had to
-do a SONAME bump of the library package to avoid surprising the
-reverse dependencies.  I even added a simple
-autopkgtest script to ensure the package work as intended.  Dug deep
-into the hole of learning shared library maintenance, I set out a few
-days ago to upload the new version to Debian experimental to see what
-the quality assurance framework in Debian had to say about the result.
-The feedback told me the pacakge was not too shabby, and yesterday I
-uploaded the latest version to Debian unstable.  It should enter
-testing today or tomorrow, perhaps delayed by
-&lt;a href=&quot;https://bugs.debian.org/1055812&quot;&gt;a small library
-transition&lt;/a&gt;.&lt;/p&gt;
-
-&lt;p&gt;Armed with a new version of sqlcipher, I can now have a look at the
-SQL database in ~/.config/Signal/sql/db.sqlite.  First, one need to
-fetch the encryption key from the Signal configuration using this
-simple JSON extraction command:&lt;/p&gt;
-
-&lt;pre&gt;/usr/bin/jq -r &#39;.&quot;key&quot;&#39; ~/.config/Signal/config.json&lt;/pre&gt;
-
-&lt;p&gt;Assuming the result from that command is &#39;secretkey&#39;, which is a
-hexadecimal number representing the key used to encrypt the database.
-Next, one can now connect to the database and inject the encryption
-key for access via SQL to fetch information from the database.  Here
-is an example dumping the database structure:&lt;/p&gt;
-
-&lt;pre&gt;
-% sqlcipher ~/.config/Signal/sql/db.sqlite
-sqlite&gt; PRAGMA key = &quot;x&#39;secretkey&#39;&quot;;
-sqlite&gt; .schema
-CREATE TABLE sqlite_stat1(tbl,idx,stat);
-CREATE TABLE conversations(
-      id STRING PRIMARY KEY ASC,
-      json TEXT,
-
-      active_at INTEGER,
-      type STRING,
-      members TEXT,
-      name TEXT,
-      profileName TEXT
-    , profileFamilyName TEXT, profileFullName TEXT, e164 TEXT, serviceId TEXT, groupId TEXT, profileLastFetchedAt INTEGER);
-CREATE TABLE identityKeys(
-      id STRING PRIMARY KEY ASC,
-      json TEXT
-    );
-CREATE TABLE items(
-      id STRING PRIMARY KEY ASC,
-      json TEXT
-    );
-CREATE TABLE sessions(
-      id TEXT PRIMARY KEY,
-      conversationId TEXT,
-      json TEXT
-    , ourServiceId STRING, serviceId STRING);
-CREATE TABLE attachment_downloads(
-    id STRING primary key,
-    timestamp INTEGER,
-    pending INTEGER,
-    json TEXT
-  );
-CREATE TABLE sticker_packs(
-    id TEXT PRIMARY KEY,
-    key TEXT NOT NULL,
-
-    author STRING,
-    coverStickerId INTEGER,
-    createdAt INTEGER,
-    downloadAttempts INTEGER,
-    installedAt INTEGER,
-    lastUsed INTEGER,
-    status STRING,
-    stickerCount INTEGER,
-    title STRING
-  , attemptedStatus STRING, position INTEGER DEFAULT 0 NOT NULL, storageID STRING, storageVersion INTEGER, storageUnknownFields BLOB, storageNeedsSync
-      INTEGER DEFAULT 0 NOT NULL);
-CREATE TABLE stickers(
-    id INTEGER NOT NULL,
-    packId TEXT NOT NULL,
-
-    emoji STRING,
-    height INTEGER,
-    isCoverOnly INTEGER,
-    lastUsed INTEGER,
-    path STRING,
-    width INTEGER,
-
-    PRIMARY KEY (id, packId),
-    CONSTRAINT stickers_fk
-      FOREIGN KEY (packId)
-      REFERENCES sticker_packs(id)
-      ON DELETE CASCADE
-  );
-CREATE TABLE sticker_references(
-    messageId STRING,
-    packId TEXT,
-    CONSTRAINT sticker_references_fk
-      FOREIGN KEY(packId)
-      REFERENCES sticker_packs(id)
-      ON DELETE CASCADE
-  );
-CREATE TABLE emojis(
-    shortName TEXT PRIMARY KEY,
-    lastUsage INTEGER
-  );
-CREATE TABLE messages(
-        rowid INTEGER PRIMARY KEY ASC,
-        id STRING UNIQUE,
-        json TEXT,
-        readStatus INTEGER,
-        expires_at INTEGER,
-        sent_at INTEGER,
-        schemaVersion INTEGER,
-        conversationId STRING,
-        received_at INTEGER,
-        source STRING,
-        hasAttachments INTEGER,
-        hasFileAttachments INTEGER,
-        hasVisualMediaAttachments INTEGER,
-        expireTimer INTEGER,
-        expirationStartTimestamp INTEGER,
-        type STRING,
-        body TEXT,
-        messageTimer INTEGER,
-        messageTimerStart INTEGER,
-        messageTimerExpiresAt INTEGER,
-        isErased INTEGER,
-        isViewOnce INTEGER,
-        sourceServiceId TEXT, serverGuid STRING NULL, sourceDevice INTEGER, storyId STRING, isStory INTEGER
-        GENERATED ALWAYS AS (type IS &#39;story&#39;), isChangeCreatedByUs INTEGER NOT NULL DEFAULT 0, isTimerChangeFromSync INTEGER
-        GENERATED ALWAYS AS (
-          json_extract(json, &#39;$.expirationTimerUpdate.fromSync&#39;) IS 1
-        ), seenStatus NUMBER default 0, storyDistributionListId STRING, expiresAt INT
-        GENERATED ALWAYS
-        AS (ifnull(
-          expirationStartTimestamp + (expireTimer * 1000),
-          9007199254740991
-        )), shouldAffectActivity INTEGER
-        GENERATED ALWAYS AS (
-          type IS NULL
-          OR
-          type NOT IN (
-            &#39;change-number-notification&#39;,
-            &#39;contact-removed-notification&#39;,
-            &#39;conversation-merge&#39;,
-            &#39;group-v1-migration&#39;,
-            &#39;keychange&#39;,
-            &#39;message-history-unsynced&#39;,
-            &#39;profile-change&#39;,
-            &#39;story&#39;,
-            &#39;universal-timer-notification&#39;,
-            &#39;verified-change&#39;
-          )
-        ), shouldAffectPreview INTEGER
-        GENERATED ALWAYS AS (
-          type IS NULL
-          OR
-          type NOT IN (
-            &#39;change-number-notification&#39;,
-            &#39;contact-removed-notification&#39;,
-            &#39;conversation-merge&#39;,
-            &#39;group-v1-migration&#39;,
-            &#39;keychange&#39;,
-            &#39;message-history-unsynced&#39;,
-            &#39;profile-change&#39;,
-            &#39;story&#39;,
-            &#39;universal-timer-notification&#39;,
-            &#39;verified-change&#39;
-          )
-        ), isUserInitiatedMessage INTEGER
-        GENERATED ALWAYS AS (
-          type IS NULL
-          OR
-          type NOT IN (
-            &#39;change-number-notification&#39;,
-            &#39;contact-removed-notification&#39;,
-            &#39;conversation-merge&#39;,
-            &#39;group-v1-migration&#39;,
-            &#39;group-v2-change&#39;,
-            &#39;keychange&#39;,
-            &#39;message-history-unsynced&#39;,
-            &#39;profile-change&#39;,
-            &#39;story&#39;,
-            &#39;universal-timer-notification&#39;,
-            &#39;verified-change&#39;
-          )
-        ), mentionsMe INTEGER NOT NULL DEFAULT 0, isGroupLeaveEvent INTEGER
-        GENERATED ALWAYS AS (
-          type IS &#39;group-v2-change&#39; AND
-          json_array_length(json_extract(json, &#39;$.groupV2Change.details&#39;)) IS 1 AND
-          json_extract(json, &#39;$.groupV2Change.details[0].type&#39;) IS &#39;member-remove&#39; AND
-          json_extract(json, &#39;$.groupV2Change.from&#39;) IS NOT NULL AND
-          json_extract(json, &#39;$.groupV2Change.from&#39;) IS json_extract(json, &#39;$.groupV2Change.details[0].aci&#39;)
-        ), isGroupLeaveEventFromOther INTEGER
-        GENERATED ALWAYS AS (
-          isGroupLeaveEvent IS 1
-          AND
-          isChangeCreatedByUs IS 0
-        ), callId TEXT
-        GENERATED ALWAYS AS (
-          json_extract(json, &#39;$.callId&#39;)
-        ));
-CREATE TABLE sqlite_stat4(tbl,idx,neq,nlt,ndlt,sample);
-CREATE TABLE jobs(
-        id TEXT PRIMARY KEY,
-        queueType TEXT STRING NOT NULL,
-        timestamp INTEGER NOT NULL,
-        data STRING TEXT
-      );
-CREATE TABLE reactions(
-        conversationId STRING,
-        emoji STRING,
-        fromId STRING,
-        messageReceivedAt INTEGER,
-        targetAuthorAci STRING,
-        targetTimestamp INTEGER,
-        unread INTEGER
-      , messageId STRING);
-CREATE TABLE senderKeys(
-        id TEXT PRIMARY KEY NOT NULL,
-        senderId TEXT NOT NULL,
-        distributionId TEXT NOT NULL,
-        data BLOB NOT NULL,
-        lastUpdatedDate NUMBER NOT NULL
-      );
-CREATE TABLE unprocessed(
-        id STRING PRIMARY KEY ASC,
-        timestamp INTEGER,
-        version INTEGER,
-        attempts INTEGER,
-        envelope TEXT,
-        decrypted TEXT,
-        source TEXT,
-        serverTimestamp INTEGER,
-        sourceServiceId STRING
-      , serverGuid STRING NULL, sourceDevice INTEGER, receivedAtCounter INTEGER, urgent INTEGER, story INTEGER);
-CREATE TABLE sendLogPayloads(
-        id INTEGER PRIMARY KEY ASC,
-
-        timestamp INTEGER NOT NULL,
-        contentHint INTEGER NOT NULL,
-        proto BLOB NOT NULL
-      , urgent INTEGER, hasPniSignatureMessage INTEGER DEFAULT 0 NOT NULL);
-CREATE TABLE sendLogRecipients(
-        payloadId INTEGER NOT NULL,
-
-        recipientServiceId STRING NOT NULL,
-        deviceId INTEGER NOT NULL,
-
-        PRIMARY KEY (payloadId, recipientServiceId, deviceId),
-
-        CONSTRAINT sendLogRecipientsForeignKey
-          FOREIGN KEY (payloadId)
-          REFERENCES sendLogPayloads(id)
-          ON DELETE CASCADE
-      );
-CREATE TABLE sendLogMessageIds(
-        payloadId INTEGER NOT NULL,
-
-        messageId STRING NOT NULL,
-
-        PRIMARY KEY (payloadId, messageId),
-
-        CONSTRAINT sendLogMessageIdsForeignKey
-          FOREIGN KEY (payloadId)
-          REFERENCES sendLogPayloads(id)
-          ON DELETE CASCADE
-      );
-CREATE TABLE preKeys(
-        id STRING PRIMARY KEY ASC,
-        json TEXT
-      , ourServiceId NUMBER
-        GENERATED ALWAYS AS (json_extract(json, &#39;$.ourServiceId&#39;)));
-CREATE TABLE signedPreKeys(
-        id STRING PRIMARY KEY ASC,
-        json TEXT
-      , ourServiceId NUMBER
-        GENERATED ALWAYS AS (json_extract(json, &#39;$.ourServiceId&#39;)));
-CREATE TABLE badges(
-        id TEXT PRIMARY KEY,
-        category TEXT NOT NULL,
-        name TEXT NOT NULL,
-        descriptionTemplate TEXT NOT NULL
-      );
-CREATE TABLE badgeImageFiles(
-        badgeId TEXT REFERENCES badges(id)
-          ON DELETE CASCADE
-          ON UPDATE CASCADE,
-        &#39;order&#39; INTEGER NOT NULL,
-        url TEXT NOT NULL,
-        localPath TEXT,
-        theme TEXT NOT NULL
-      );
-CREATE TABLE storyReads (
-        authorId STRING NOT NULL,
-        conversationId STRING NOT NULL,
-        storyId STRING NOT NULL,
-        storyReadDate NUMBER NOT NULL,
-
-        PRIMARY KEY (authorId, storyId)
-      );
-CREATE TABLE storyDistributions(
-        id STRING PRIMARY KEY NOT NULL,
-        name TEXT,
-
-        senderKeyInfoJson STRING
-      , deletedAtTimestamp INTEGER, allowsReplies INTEGER, isBlockList INTEGER, storageID STRING, storageVersion INTEGER, storageUnknownFields BLOB, storageNeedsSync INTEGER);
-CREATE TABLE storyDistributionMembers(
-        listId STRING NOT NULL REFERENCES storyDistributions(id)
-          ON DELETE CASCADE
-          ON UPDATE CASCADE,
-        serviceId STRING NOT NULL,
-
-        PRIMARY KEY (listId, serviceId)
-      );
-CREATE TABLE uninstalled_sticker_packs (
-        id STRING NOT NULL PRIMARY KEY,
-        uninstalledAt NUMBER NOT NULL,
-        storageID STRING,
-        storageVersion NUMBER,
-        storageUnknownFields BLOB,
-        storageNeedsSync INTEGER NOT NULL
-      );
-CREATE TABLE groupCallRingCancellations(
-        ringId INTEGER PRIMARY KEY,
-        createdAt INTEGER NOT NULL
-      );
-CREATE TABLE IF NOT EXISTS &#39;messages_fts_data&#39;(id INTEGER PRIMARY KEY, block BLOB);
-CREATE TABLE IF NOT EXISTS &#39;messages_fts_idx&#39;(segid, term, pgno, PRIMARY KEY(segid, term)) WITHOUT ROWID;
-CREATE TABLE IF NOT EXISTS &#39;messages_fts_content&#39;(id INTEGER PRIMARY KEY, c0);
-CREATE TABLE IF NOT EXISTS &#39;messages_fts_docsize&#39;(id INTEGER PRIMARY KEY, sz BLOB);
-CREATE TABLE IF NOT EXISTS &#39;messages_fts_config&#39;(k PRIMARY KEY, v) WITHOUT ROWID;
-CREATE TABLE edited_messages(
-        messageId STRING REFERENCES messages(id)
-          ON DELETE CASCADE,
-        sentAt INTEGER,
-        readStatus INTEGER
-      , conversationId STRING);
-CREATE TABLE mentions (
-        messageId REFERENCES messages(id) ON DELETE CASCADE,
-        mentionAci STRING,
-        start INTEGER,
-        length INTEGER
-      );
-CREATE TABLE kyberPreKeys(
-        id STRING PRIMARY KEY NOT NULL,
-        json TEXT NOT NULL, ourServiceId NUMBER
-        GENERATED ALWAYS AS (json_extract(json, &#39;$.ourServiceId&#39;)));
-CREATE TABLE callsHistory (
-        callId TEXT PRIMARY KEY,
-        peerId TEXT NOT NULL, -- conversation id (legacy) | uuid | groupId | roomId
-        ringerId TEXT DEFAULT NULL, -- ringer uuid
-        mode TEXT NOT NULL, -- enum &quot;Direct&quot; | &quot;Group&quot;
-        type TEXT NOT NULL, -- enum &quot;Audio&quot; | &quot;Video&quot; | &quot;Group&quot;
-        direction TEXT NOT NULL, -- enum &quot;Incoming&quot; | &quot;Outgoing
-        -- Direct: enum &quot;Pending&quot; | &quot;Missed&quot; | &quot;Accepted&quot; | &quot;Deleted&quot;
-        -- Group: enum &quot;GenericGroupCall&quot; | &quot;OutgoingRing&quot; | &quot;Ringing&quot; | &quot;Joined&quot; | &quot;Missed&quot; | &quot;Declined&quot; | &quot;Accepted&quot; | &quot;Deleted&quot;
-        status TEXT NOT NULL,
-        timestamp INTEGER NOT NULL,
-        UNIQUE (callId, peerId) ON CONFLICT FAIL
-      );
-[ dropped all indexes to save space in this blog post ]
-CREATE TRIGGER messages_on_view_once_update AFTER UPDATE ON messages
-      WHEN
-        new.body IS NOT NULL AND new.isViewOnce = 1
-      BEGIN
-        DELETE FROM messages_fts WHERE rowid = old.rowid;
-      END;
-CREATE TRIGGER messages_on_insert AFTER INSERT ON messages
-      WHEN new.isViewOnce IS NOT 1 AND new.storyId IS NULL
-      BEGIN
-        INSERT INTO messages_fts
-          (rowid, body)
-        VALUES
-          (new.rowid, new.body);
-      END;
-CREATE TRIGGER messages_on_delete AFTER DELETE ON messages BEGIN
-        DELETE FROM messages_fts WHERE rowid = old.rowid;
-        DELETE FROM sendLogPayloads WHERE id IN (
-          SELECT payloadId FROM sendLogMessageIds
-          WHERE messageId = old.id
-        );
-        DELETE FROM reactions WHERE rowid IN (
-          SELECT rowid FROM reactions
-          WHERE messageId = old.id
-        );
-        DELETE FROM storyReads WHERE storyId = old.storyId;
-      END;
-CREATE VIRTUAL TABLE messages_fts USING fts5(
-        body,
-        tokenize = &#39;signal_tokenizer&#39;
-      );
-CREATE TRIGGER messages_on_update AFTER UPDATE ON messages
-      WHEN
-        (new.body IS NULL OR old.body IS NOT new.body) AND
-         new.isViewOnce IS NOT 1 AND new.storyId IS NULL
-      BEGIN
-        DELETE FROM messages_fts WHERE rowid = old.rowid;
-        INSERT INTO messages_fts
-          (rowid, body)
-        VALUES
-          (new.rowid, new.body);
-      END;
-CREATE TRIGGER messages_on_insert_insert_mentions AFTER INSERT ON messages
-      BEGIN
-        INSERT INTO mentions (messageId, mentionAci, start, length)
-        
-    SELECT messages.id, bodyRanges.value -&gt;&gt; &#39;mentionAci&#39; as mentionAci,
-      bodyRanges.value -&gt;&gt; &#39;start&#39; as start,
-      bodyRanges.value -&gt;&gt; &#39;length&#39; as length
-    FROM messages, json_each(messages.json -&gt;&gt; &#39;bodyRanges&#39;) as bodyRanges
-    WHERE bodyRanges.value -&gt;&gt; &#39;mentionAci&#39; IS NOT NULL
-  
-        AND messages.id = new.id;
-      END;
-CREATE TRIGGER messages_on_update_update_mentions AFTER UPDATE ON messages
-      BEGIN
-        DELETE FROM mentions WHERE messageId = new.id;
-        INSERT INTO mentions (messageId, mentionAci, start, length)
-        
-    SELECT messages.id, bodyRanges.value -&gt;&gt; &#39;mentionAci&#39; as mentionAci,
-      bodyRanges.value -&gt;&gt; &#39;start&#39; as start,
-      bodyRanges.value -&gt;&gt; &#39;length&#39; as length
-    FROM messages, json_each(messages.json -&gt;&gt; &#39;bodyRanges&#39;) as bodyRanges
-    WHERE bodyRanges.value -&gt;&gt; &#39;mentionAci&#39; IS NOT NULL
-  
-        AND messages.id = new.id;
-      END;
-sqlite&gt;
-&lt;/pre&gt;
-
-&lt;p&gt;Finally I have the tool needed to inspect and process Signal
-messages that I need, without using the vendor provided client.  Now
-on to transforming it to a more useful format.&lt;/p&gt;
-
-&lt;p&gt;As usual, if you use Bitcoin and want to show your support of my
-activities, please send Bitcoin donations to my address
-&lt;b&gt;&lt;a href=&quot;bitcoin:15oWEoG9dUPovwmUL9KWAnYRtNJEkP1u1b&quot;&gt;15oWEoG9dUPovwmUL9KWAnYRtNJEkP1u1b&lt;/a&gt;&lt;/b&gt;.&lt;/p&gt;
-</description>
-       </item>
-       
         </channel>
 </rss>