Getting the BAND back together? – STAZHIT.COM

  1. When I finished coding the “notes” app 2 years ago, I wasn’t really sure I’d ever touch the site again.
  2. It’s still very BETA, broken, unfinished. I have a lot of work to do if I want to get serious.
  3. It has potential, especially if I were 20 years younger and could crank out the mad code.
  4. Now feels right, and I’ve been talking to Justin (iykyk).
  5. Let’s see what happens …

STAZHIT.COM

SWI PROLOG: interfacing as a process singleton

Link to SWI page: https://www.swi-prolog.org/contrib/DotNetInterface.md

RUBY SCRIPT:

#!/usr/bin/env ruby

$prologRef = nil
$prologTempDir = "/Users/daniel/Desktop/Temp/"
$prologExe = "/opt/local/bin/swipl"
$isHalted = false

def StartProlog
$prologRef = IO.popen($prologExe,"w")
$isHalted = false
end

def StopProlog
$prologRef.close_write
$isHalted = true
end

def CallProlog(statement)
$prologRef.puts "call((" + statement + "))."
end

def IsTrueProlog(statement)
t = Time.now
srand(t.to_i)
randNum = rand(10000)
$prologRef.puts "tell('" + $prologTempDir + "TEST" + randNum.to_s + "')."
$prologRef.puts "(" + statement + ") -> write('true') ; write('false')."
$prologRef.puts "told."
accumulate = ""
isRead = false
while not isRead
if $isHalted == true
return false
end
begin
File.open($prologTempDir + "TEST" + randNum.to_s) do |query_result|
query_result.each do |line|
accumulate += line
end
isRead = true
end
rescue

end
end
File.delete($prologTempDir + "TEST" + randNum.to_s)
if accumulate != "true"
return false
else
return true
end
end

def QueryProlog(variablelist,query)
t = Time.now
srand(t.to_i)
randNum = rand(10000)
$prologRef.puts "tell('" + $prologTempDir + "QUERY" + randNum.to_s + "')."
$prologRef.puts "findall((" + variablelist + "),(" + query + "),Z),write(Z),fail."
$prologRef.puts "told."
accumulate = ""
isRead = false
while not isRead
if $isHalted == true
return ""
end
begin
File.open($prologTempDir + "QUERY" + randNum.to_s) do |query_result|
query_result.each do |line|
accumulate += line
end
isRead = true
end
rescue
puts "error"
end
end
File.delete($prologTempDir + "QUERY" + randNum.to_s)
return accumulate
end


StartProlog()
CallProlog("assert(dog(dan))")
CallProlog("assert(dog(jim))")
CallProlog("assert(dog(pete))")

for i in 0 ... 100
CallProlog("assert(person(fname(dan" + i.to_s + "),lname(sull" + i.to_s + ")))")
end

f = File.open("/Users/daniel/Desktop/Temp/results.md","w")

f.puts QueryProlog("X,Y","person(X,Y)")

f.puts QueryProlog("X","dog(X)")

f.puts IsTrueProlog("dog(ddddddan)")

f.close_write

StopProlog()

C# wrapper:

using System;
using System.Diagnostics;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;

namespace LogicEngineLib
{
public class LogicEXE
{
public Process p = null;
public int PID = -999;
private string _dumpDir;
private string _plcon;
private int _timeOut;
public LogicEXE(string dumpDir, string plCon, int timeoutMilliseconds)
{
this._timeOut = timeoutMilliseconds;
this.p = new Process();
this.p.StartInfo.FileName = plCon;
this.p.StartInfo.RedirectStandardInput = true;
this.p.StartInfo.UseShellExecute = false;
this.p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
this.p.StartInfo.CreateNoWindow = true;
this._dumpDir = dumpDir;
this._plcon = plCon;
this.p.Start();
this.PID = this.p.Id;
}
public string ReStart()
{
this.p = new Process();
this.p.StartInfo.FileName = this._plcon;
this.p.StartInfo.RedirectStandardInput = true;
this.p.StartInfo.UseShellExecute = false;
this.p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
this.p.StartInfo.CreateNoWindow = true;
this.p.Start();
this.PID = this.p.Id;
return "Restarted service.";
}
public void Write(string statement)
{
this.p.StandardInput.WriteLine(statement);
}
public string Stop()
{
this.p.Close();
return "Process Stopped.";
}
public string Assert(string query)
{
this.Write("assert(" + query + ").");
return "Assert performed.";
}
public string Call(string execString)
{
execString = execString.Replace('.',' ');
string sres = Guid.NewGuid().ToString();
Write("tell('" + this._dumpDir.Replace('\\', '/') + sres + "').");
this.Write("call(" + execString + ") -> write('Call Succeeded') ; write('Call Failed').");
Write("told.");
string rstr = string.Empty;
rstr = SpinAndWaitRead(this._dumpDir + sres);
return rstr;
}
public void Consult(string file)
{
this.Write("consult('" + file.Replace('\\', '/') + "').");
}
public string Save(string fileNamePath)
{
Write("tell('" + fileNamePath.Replace("\\","/") + "').");
Write("listing.");
Write("told.");
return "Save Accomplished";
}
public bool IsTrue(string query)
{
query = query.Replace('.', ' ');
StringBuilder sb = new StringBuilder();
Hashtable ht = new Hashtable(20);
bool hasVariables = false;
string[] vars = GetTokens(query);
foreach (string s in vars)
{
if (s.Trim().Length > 0)
{
char[] carr = s.ToCharArray();

if (Char.IsUpper(carr[0]))
{
string tmp = s.Trim();

if (!ht.Contains(tmp))
{
ht[tmp] = tmp;
sb.Append(" " + s);
}
hasVariables = true;
}
}
}
if (hasVariables) return false;
string sres = Guid.NewGuid().ToString();
Write("tell('" + this._dumpDir.Replace('\\', '/') + sres + "').");
Write("(" + query + ") -> write('True') ; write('False').");
Write("told.");
string rstr = string.Empty;
rstr = SpinAndWaitRead(this._dumpDir + sres);
if (rstr.Trim().Length < 4) return false;
bool result = false;
try
{
result = bool.Parse(rstr);
return result;
}
catch
{
return false;
}
}
public string Query(string query, bool distinctResults)
{
query = query.Replace('.',' ');
StringBuilder sb = new StringBuilder();
Hashtable ht = new Hashtable(20);
bool hasVariables = false;
string[] vars = GetTokens(query);
foreach (string s in vars)
{
if (s.Trim().Length > 0)
{
string tmp1 = s.Trim();

char[] carr = tmp1.ToCharArray();

if (Char.IsUpper(carr[0]))
{
string tmp = s.Trim();

if (!ht.Contains(tmp))
{
ht[tmp] = tmp;
sb.Append(" " + s);
}
hasVariables = true;
}
}
}
string sres = Guid.NewGuid().ToString();
Write("tell('" + this._dumpDir.Replace('\\', '/') + sres + "').");
if (hasVariables)
{
if (distinctResults)
{
Write("setof((" + sb.ToString().Trim().Replace(" ", ",") + ") ,(" + query + "),Z),write(Z),fail.");
}
else
{
string tres = "findall((" + sb.ToString().Trim().Replace(" ", ",") + ") ,(" + query + "),Z),write(Z),fail.";
Write(tres);
}
}
else
{
Write(query + ".");
}
Write("told.");
string rstr = string.Empty;
rstr = SpinAndWaitRead(this._dumpDir + sres);
return rstr;
}
public string Listing()
{
string sres = Guid.NewGuid().ToString();
Write("tell('" + this._dumpDir.Replace('\\', '/') + sres + "').");
Write("listing.");
Write("told.");
string rstr = string.Empty;
rstr = SpinAndWaitRead(this._dumpDir + sres);
return rstr;
}
private string SpinAndWaitRead(string fileName)
{
StreamReader sr = null;
string rstr = string.Empty;
int counter = 0;
bool done = false;
while (!done)
{
try
{
if (File.Exists(fileName))
{
sr = new StreamReader(fileName);
rstr = sr.ReadToEnd();
sr.Close();
done = true;
}
}
catch
{
continue;
}
counter++;
System.Threading.Thread.Sleep(1);
if (counter == this._timeOut) break;
}
try
{
File.Delete(fileName);
}
catch { }
return rstr;
}
private string[] GetTokens(string prologStatement)
{
string[] vars = Regex.Split(prologStatement, @"[,)(=;+:%$@~^/\-><@&*!]");
return vars;
}
}
}

Your own daily dose … (of the news)

  1. Below is a general recipe for experimenting with RSS feeds AND speech synthesizers.
  2. For the speech synthesis there are two scripts, very similar, one will work with ESPEAK (free open source), the other works with Microsoft SAPI.
  3. In order to run these scripts you will need MYSQL installed. You will need a minimum level of understanding of how MYSQL works. You can easily translate the database piece to ODBC, and the rest to PowerShell or whatever. That’s your business, not mine.
  4. Once you’ve installed MYSQL and the server is running, create a database called “NEWS”: create database NEWS;
  5. After you’ve created the NEWS database, using the CLI (command line interface) as above, type command: use NEWS;
  6. Once you are in the NEWS database, copy and paste the entire script below into the CLI or save as text file and consult from the CLI using the command: source rss.sql (assuming you stored the create table text below in that file)
  7. In the example I’m using the ROOT database, why? – because IDGAF. But best practice is to create special database users with limited permissions. If you’ve installed your MYSQL database without granting permission to external (port) connections? – then it’s not a concern.
  8. Running the aggregator might trigger a site to block you or even your own network. This behavior, which was innocuous 20 years ago, is now attacked and classified as an aggressive network behavior. Just be careful.
  9. After you’ve run the aggregation script (and the script can be run by CRON or Task Manager daily or hourly if you like), then you can run one of the speech synthesis apps, reading headlines.
  10. If you have a compatible shortwave radio, with upper and lower side band, and a LINUX computer running JS8 Call with appropriate libraries for CAT control? – then look into this and you can set up a headline service over shortwave: https://planetarystatusreport.com/?p=7432

Have fun getting your daily dose of the fucking news.

Create Table Script for RSS Database

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET AUTOCOMMIT = 0;
START TRANSACTION;
SET time_zone = "+00:00";

CREATE TABLE `RSS` (
`ID` bigint(20) NOT NULL,
`SOURCE` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
`LINK` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`TITLE` varchar(400) COLLATE utf8_unicode_ci NOT NULL,
`PUBLISHED` datetime NOT NULL,
`ARTICLE` text COLLATE utf8_unicode_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

ALTER TABLE `RSS`
ADD PRIMARY KEY (`ID`),
ADD UNIQUE KEY `unique_link` (`LINK`);

ALTER TABLE `RSS`
MODIFY `ID` bigint(20) NOT NULL AUTO_INCREMENT;
COMMIT;

Python Script for Aggregating RSS Feeds and storing stories locally

from __future__ import print_function

import os
import feedparser
import os.path, time
import json
import math
import time
import urllib.parse as pr
import xml.etree.ElementTree as ET
from bs4 import BeautifulSoup as BS
from requests import get
from os.path import exists
from socket import socket, AF_INET, SOCK_STREAM
from decimal import Decimal
from datetime import datetime, date, timedelta
from anyascii import anyascii
import mysql.connector

usern = "root"
passw = "password"
dbn = "NEWS"
servern = "localhost"
portn = 3306

newsServiceM3 = "ZEROHEDGE"

retHeadlines = 4

newsMode = 3

bigSleep = 90

def GetArt(number):
# Connect with the MySQL Server
cnx = mysql.connector.connect(user=usern, database=dbn, password=passw, host=servern, port=portn)
qry = "select ARTICLE, SOURCE, LINK from RSS where ID = %s" % (number)
cur = cnx.cursor(buffered=True)
cur.execute(qry)
retRes = cur.fetchall()
cnx.close()
return retRes[0]

def GetTopHourly(source):
# Connect with the MySQL Server
cnx = mysql.connector.connect(user=usern, database=dbn, password=passw, host=servern, port=portn)
qry = "select ID, TITLE, PUBLISHED, SOURCE, length(ARTICLE) as LOF from RSS where SOURCE = '%s' order by PUBLISHED desc limit 1" % source
cur = cnx.cursor(buffered=True)
cur.execute(qry)
retRes = cur.fetchall()
cnx.close()
return retRes

def GetTop(source, number):
# Connect with the MySQL Server
cnx = mysql.connector.connect(user=usern, database=dbn, password=passw, host=servern, port=portn)
qry = "select ID, TITLE, PUBLISHED, SOURCE, length(ARTICLE) as LOF from RSS where SOURCE = '%s' order by PUBLISHED desc limit %s" % (source, number)
cur = cnx.cursor(buffered=True)
cur.execute(qry)
retRes = cur.fetchall()
cnx.close()
return retRes

def AlreadySaved(link):
# Connect with the MySQL Server
cnx = mysql.connector.connect(user=usern, database=dbn, password=passw, host=servern, port=portn)
qry = "select ID from RSS where LINK = '" + link + "'"
cur = cnx.cursor(buffered=True)
cur.execute(qry)
cur.fetchall()
rc = cur.rowcount
cnx.close()
if rc > 0:
return True
else:
return False

def SaveRSS(source, title, link, published, article):

tit = title.replace("'", "''")

clean_text = anyascii(article)

art = str(clean_text)

art = art.replace("'", "''")

if len(art) > 5000:
art = art[0:5000]

cnx = mysql.connector.connect(user=usern, database=dbn, password=passw, host=servern, port=portn)

cur = cnx.cursor()

qry = """
INSERT INTO RSS
(SOURCE,
LINK,
TITLE,
PUBLISHED,
ARTICLE)
VALUES
(%s,%s,%s,%s,%s)
"""

val = (source, link, tit, published, art)

cur.execute(qry, val)

cnx.commit()

cnx.close()

def GrabRSS(RssURL, SourceName):

hdrs = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36'}

NewsFeed = feedparser.parse(RssURL)

for na in NewsFeed.entries:

try:
print(na.title)
print(na.link)
print(na.published)
print(na.published_parsed)
except:
continue

if AlreadySaved(na.link):
continue

print("*************************")

response = get(na.link, None, headers=hdrs)

print(na.keys())

soup = BS(response.content, 'html.parser')

txtChunk = ""

for data in soup.find_all("p"):
txtval = data.get_text()
txtval = txtval.strip()
txtarr = txtval.split()

if len(txtarr) == 1:
continue

if "posted" in txtval and ("hours" in txtval or "days" in txtval) and len(txtarr) == 4:
continue

if txtval == "No Search Results Found":
continue

if txtval == "Terms of Service":
continue

if txtval == "Advertise with us":
continue

if txtval == "Media Inquiries":
continue

txtChunk += " " + txtval + "\n"

tyr = na.published_parsed[0]
tmn = na.published_parsed[1]
tdy = na.published_parsed[2]
thr = na.published_parsed[3]
tmi = na.published_parsed[4]
tsc = na.published_parsed[5]

ptms = "%s-%s-%s %s:%s:%s" % (tyr, tmn, tdy, thr, tmi, tsc)

SaveRSS(SourceName, na.title, na.link, ptms, txtChunk.strip())

print(txtChunk.strip())

def debugHere():
input("Press enter to continue ...")

def clearConsole():
command = 'clear'
if os.name in ('nt', 'dos'): # If Machine is running on Windows, use cls
command = 'cls'
os.system(command)

def CycleFeeds():
infowars = "https://www.infowars.com/rss.xml"
zh = "https://feeds.feedburner.com/zerohedge/feed"
yahoo = "https://news.yahoo.com/rss/"
cnn = "http://rss.cnn.com/rss/cnn_topstories.rss"
bbc = "http://feeds.bbci.co.uk/news/world/us_and_canada/rss.xml"
nyt = "https://rss.nytimes.com/services/xml/rss/nyt/HomePage.xml"
onion = "https://www.theonion.com/rss"
bb = "https://babylonbee.com/feed"
print("Grabbing Babylon Bee ...")
GrabRSS(bb, "BB")
print("Grabbing ONION ...")
GrabRSS(onion, "ONION")
print("Grabbing INFOWARS ...")
GrabRSS(infowars, "INFOWARS")
print("Grabbing ZEROHEDGE ...")
GrabRSS(zh, "ZEROHEDGE")
#print("Grabbing YAHOO ...")
#GrabRSS(yahoo, "YAHOO")
print("Grabbing CNN ...")
GrabRSS(cnn, "CNN")
print("Grabbing BBC ...")
GrabRSS(bbc, "BBC")
print("Grabbing NYT ...")
GrabRSS(nyt, "NYT")

# FEEDS:
# 1. INFOWARS: https://www.infowars.com/rss.xml
# 2. ZEROHEDGE: https://feeds.feedburner.com/zerohedge/feed
# 3. YAHOO: https://news.yahoo.com/rss/
# 4. CNN: http://rss.cnn.com/rss/cnn_topstories.rss

time.sleep(1)

CycleFeeds()

Python Speech Synthesis Scripts

A: Windows – SAPI

#this script reads headlines from the RSS news feed
#database.

import win32com.client

speaker = win32com.client.Dispatch("SAPI.SpVoice")

import os
import time
import mysql.connector

usern = "root"
passw = "password"
dbn = "NEWS"
servern = "localhost"
portn = 3306

def TOS(text):
os.system(f"espeak -s 130 -v en+m1 '{text}'")

def GetSql(qry):
# Connect with the MySQL Server
cnx = mysql.connector.connect(user=usern, database=dbn, password=passw, host=servern, port=portn)
cur = cnx.cursor(buffered=True)
cur.execute(qry)
retRes = cur.fetchall()
cnx.close()
return retRes

#+-----------+--------------+------+-----+---------+----------------+
#| Field | Type | Null | Key | Default | Extra |
#+-----------+--------------+------+-----+---------+----------------+
#| ID | bigint(20) | NO | PRI | NULL | auto_increment |
#| SOURCE | varchar(100) | NO | | NULL | |
#| LINK | varchar(255) | NO | UNI | NULL | |
#| TITLE | varchar(400) | NO | | NULL | |
#| PUBLISHED | datetime | NO | | NULL | |
#| ARTICLE | text | NO | | NULL | |
#+-----------+--------------+------+-----+---------+----------------+

qry1 = "select SOURCE, TITLE from RSS where PUBLISHED > curdate()-1 order by PUBLISHED desc;"

res = GetSql(qry1)

for rec in res:
src = rec[0]
tit = rec[1].replace("''", "")
print(src + ": " + tit)

phrase = "From " + src + ", HEAD LINE, " + tit

speaker.Speak(phrase)

time.sleep(2)

B: Linux – ESPEAK

import os
import time
import mysql.connector

usern = "root"
passw = "password"
dbn = "NEWS"
servern = "localhost"
portn = 3306

def TOS(text):
os.system(f"espeak -s 130 -v en+m1 '{text}'")

def GetSql(qry):
# Connect with the MySQL Server
cnx = mysql.connector.connect(user=usern, database=dbn, password=passw, host=servern, port=portn)
cur = cnx.cursor(buffered=True)
cur.execute(qry)
retRes = cur.fetchall()
cnx.close()
return retRes

#+-----------+--------------+------+-----+---------+----------------+
#| Field | Type | Null | Key | Default | Extra |
#+-----------+--------------+------+-----+---------+----------------+
#| ID | bigint(20) | NO | PRI | NULL | auto_increment |
#| SOURCE | varchar(100) | NO | | NULL | |
#| LINK | varchar(255) | NO | UNI | NULL | |
#| TITLE | varchar(400) | NO | | NULL | |
#| PUBLISHED | datetime | NO | | NULL | |
#| ARTICLE | text | NO | | NULL | |
#+-----------+--------------+------+-----+---------+----------------+

qry1 = "select SOURCE, TITLE from RSS where PUBLISHED > curdate()-1 order by PUBLISHED desc;"

res = GetSql(qry1)

for rec in res:
src = rec[0]
tit = rec[1].replace("''", "")
print(src + ": " + tit)
phrase = "From " + src + ", HEAD LINE, " + tit
TOS(phrase)
time.sleep(0.5)

I’m beginning to think …

I’m beginning to think the approach I’ve been taking with JS8 call is a bridge too far – and that I would be better off learning to compile the code, and just create my own branch. Make the changes I want in C++ to include interop with websites that are accessible on some given network using standard REST calls. Also, allow it a scripted response model so that any given JS8Call app can act as a “radio service” taking messages, and replying. Also, add in flexible topology and multi-app running instances on the same computer. Who knows, add in a built in connector for MYSQL for data logging and event logging for outside of process coding and scripting by other consumers … so I don’t know if I can, I’m 53 and burnt out and believe the world could explode, figuratively, in a few months.

But is it the end of the world? – no, not by a long shot …

So maybe I try.

Will it be easy? – don’t know … I think

And here’s the other thing …

JS8Call, RIGHT NOW, AS IS would allow you to build an organic twitter style decentralized relationship with other people using CB radio and this network WORKS even if the WWW is down … is it good for secrets, as is? – no … is it good enough for the public square? – yes.

You could sell eggs, right now, using JS8Call on CB Radio – just need to expand the network, more users, bigger world.

And I would think a lot of real anarchists and libertarians would be into this …

CB RADIO – NO HAM LICENSE …

(and then we go from there)

And this is all in JS8CALL.COM right now.

With some work? – who the fuck knows what’s possible.

I feel like the world of shortwave radio, and CB, needs a revolution – and this could be the beginning.

RADENGINEERING.TECH

RAD-TERMINAL: HOW TO HAVE FREE OFF GRID INTERNET 4-LIFE!

Where: https://www.preppershowsusa.com/prepper-show/be-prepared-expo-2022/

When: 4/23/2022, 11 AM MST (Utah Time)

Room: Classroom B

What: Class/Presentation “RAD ENGINEERING: FIFL”

Presenters: Justin Land and Dan Sullivan

Outline:

  1. Introduction: How we got into this, the story of RAD ENGINEERING. WHAT IS THE RAD TERMINAL? (5 minutes)
  2. Hardware: a) radio, b) computer, c) linkages and wiring … history of the radio tech and how it’s being used. JS8 (20 minutes)
  3. Software: history of WWW, what happened to TECH in the 70’s … why couldn’t we hook up TRS-80 / C64 computers to a CB in 1983 … what are bulletin boards? – how is radio LIKE a bulletin board … encryption strategies … encoding … ARS: Amateur Radio Services … what is an ARS? – remote procedure calls over CB radio, hitting python-agent receivers, hooking into actions … >sendto: >email: >payment: … command tags … EDI for radio? – small compact messaging AND payment services using voice recognition (20 minutes)
  4. Q/A (15 minutes)