Making a frame in a aluminum case, using rivets and nut rivets.
The nut rivet tool (suggestion by Duncan) is a superb addition in my tool shed!
There is place for 4 modules in this “test” case. I need to move the holes for the rivet-nuts, because the modules should go in every position. (Also 4 rounded corners)
Drag and drop image for displaying on a kodi instance
Button to start slideshow of a directory
Open image in browser with obfuscated image url (not shown in movie)
Stop image playing
Json RPC used:
# Playing a single file
curl -H "content-type:application/json" -i -X POST -d '{"jsonrpc":"2.0","id":1,"method":"Player.Open","params":{"item":{"file":"'.$dir2.'"}}}' http://KODI-IP:8080/jsonrpc &';
# Playing a directory
curl -H "content-type:application/json" -i -X POST -d '{"jsonrpc":"2.0","id":1,"method":"Player.Open","params":{"item":{"directory":"/path/'.$dir.'"}}}' http://KODI-IP:8080/jsonrpc &';
# Stop playing (i'm stopping player 1 and 2) You can query which player is active, this works also
curl -H "content-type:application/json" -i -X POST -d '{"jsonrpc": "2.0", "method": "Player.Stop", "params": { "playerid": 1 }, "id": 1}' http://10.1.0.73:8080/jsonrpc';
Kodi enable http control and disable authentication (if you want to use authentication, change the curl commands accordingly)
Below the multiple PHP files, i’ve removed a lot of code specific for my manager.
By the way, I love this trick:
header("HTTP/1.1 204 NO CONTENT");
I’ve you put this in the top of your php script which is linked from the first page, you won’t open this link in your browser, but it gets executed nevertheless!
::::::::::::::
push.php
::::::::::::::
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="dropbox">Drop Image</div><br>
<a href="playpush.php?dir=TEMP/Sake">playdir</a>
<a href="stoppush.php">stop</a>
# Here i have a generated part to list my photoalbum photos in this format
<a href='getimg.php?imagepath=/mnt/fileserver/TEMP/1.jpg'><img src='getimg2.php?imagepath=/mnt/fileserver/TEMP/1.jpg' width=300 title='1.jpg'></a>
<a href='getimg.php?imagepath=/mnt/fileserver/TEMP/2.jpg'><img src='getimg2.php?imagepath=/mnt/fileserver/TEMP/2.jpg' width=300 title='2.jpg'></a>
<script
type="text/javascript"
src="javascript2.js"
></script>
</body></html>
::::::::::::::
getimg.php - Displays photo in browser (forgotten in movie)
::::::::::::::
<?php
Header("Content-Type: image/jpeg");
$file = $_GET['imagepath'];
$file = str_replace("%20", "\ ", $file);
$file = str_replace("(", "\(", $file);
$file = str_replace(")", "\)", $file);
$log = 'imggetlog';
file_put_contents($log, $file, FILE_APPEND);
file_put_contents($log, "\n\r", FILE_APPEND);
header('Content-Length: ' . filesize($file));
readfile($file);
?>
::::::::::::::
getimg2.php - makes a caching thumbnail
/long/image/path/to/photo.jpg -> cachedir/longimagepathtophoto.jpg
::::::::::::::
<?php
Header("Content-Type: image/jpeg");
$file = $_GET['imagepath'];
$file = str_replace("%28", "\(", $file);
$file = str_replace("%29", "\)", $file);
$file = str_replace("%20", "\ ", $file);
$cachename = str_replace("/", "", $file);
$cachename = str_replace(" ", "", $cachename);
$cachename = "cachedir/$cachename";
$log = 'imggetlog';
file_put_contents($log, $file, FILE_APPEND);
file_put_contents($log, "\n\r", FILE_APPEND);
if (!file_exists("$cachename")) {
exec("convert -resize 300x300 \"$file\" \"$cachename\"");
}
header('Content-Length: ' . filesize("$cachename"));
readfile("$cachename");
?>
::::::::::::::
playpush.php - Pushes DIRECTORY play to Kodi
::::::::::::::
<?PHP
header("HTTP/1.1 204 NO CONTENT");
header("Cache-Control: no-cache, no-store, must-revalidate"); // HTTP 1.1.
header("Pragma: no-cache"); // HTTP 1.0.
header("Expires: 0"); // Proxies.
$dir=$_GET['dir'];
$command='nohup curl -H "content-type:application/json" -i -X POST -d \'{"jsonrpc":"2.0","id":1,"method":"Player.Open","params":{"item":{"directory":"/mnt/fileserver/'.$dir.'"}}}\' http://IPKODI:8080/jso
nrpc &';
exec($command, $output, $retval);
?>
::::::::::::::
stoppush.php - stops displaying
::::::::::::::
<?PHP
header("HTTP/1.1 204 NO CONTENT");
header("Cache-Control: no-cache, no-store, must-revalidate"); // HTTP 1.1.
header("Pragma: no-cache"); // HTTP 1.0.
header("Expires: 0"); // Proxies.
$command='curl -H "content-type:application/json" -i -X POST -d \'{"jsonrpc": "2.0", "method": "Player.Stop", "params": { "playerid": 1 }, "id": 1}\' http://IPKODI:8080/jsonrpc';
exec($command, $output, $retval);
$command='curl -H "content-type:application/json" -i -X POST -d \'{"jsonrpc": "2.0", "method": "Player.Stop", "params": { "playerid": 2 }, "id": 1}\' http://IPKODI:8080/jsonrpc';
exec($command, $output, $retval);
?>
::::::::::::::
javascript2.js
::::::::::::::
function getAllElementsWith(tag, attribute, value)
{
var matchingElements = [];
var allElements = document.getElementsByTagName(tag);
for (var i = 0; i < allElements.length; i++)
{
if (value.indexOf(allElements[i].getAttribute(attribute)) != -1)
{
// Element exists with attribute. Add to array.
matchingElements.push(allElements[i]);
}
}
return matchingElements;
}
// onDrop
function onDrop(evt) {
evt.stopPropagation();
evt.preventDefault();
var imageUrl = evt.dataTransfer.getData("URL");
var links = getAllElementsWith("a", "href", imageUrl);
var image;
console.log(links, evt);
if(links.length){
image = links[0].getElementsByTagName("img");
if(image.length)
imageUrl = image[0].getAttribute("src");
else
imageUrl = "#no-image";
}
/// alert(imageUrl);
var res = imageUrl.replace(/getimg/, "pushplay2");
location.href = (res);
};
// onDragOver
function onDragOver(evt){
evt.preventDefault();
}
var dropbox = document.getElementById('dropbox');
dropbox.addEventListener('drop', onDrop);
dropbox.addEventListener("dragover", onDragOver, false);
Random picture push
file=$(find /mnt/fileserver/examples -type f | shuf | head -1)
post_data="{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"Player.Open\",\"params\":{\"item\":{\"file\":\"$file\"}}}"
curl --user user:pass -H "content-type:application/json" -i -X POST --data "${post_data}" http://KODI-IP:8080/jsonrpc
Below a example of what your can do with the code above
I’ve got an old Speaker Phat, and a Raspberry Zero
An audio add-on board for Raspberry ( same size as the Zero )
Connections
My initial idea was to have the “High Voltage Sid Collection” (Downloaded the 55000 pack) On a mini device, battery operated and with a little keypad.
On the keypad i can select the Sidtune to play, or pressing A and a number the Sids from a certain artist.
The display gives you information about the tune being played. ( The display has an I2C hat to convert 8bits to I2C )
See pinout phat above. I’ve got three choices for I2C connection (green/blue to the Phat)
Direct connect and use different addresses
Use a I2C hub and different addresses
Define a secondary I2C on the raspberry
So I made the first test setup …
Underrun occurred .. So back to the drawingboard. I probably need a better Audio Hat. First to try .. Zero fast enough for sidplay2? Maybe audio over hdmi works??
Only cards worth mentioning. I will add more information to this page
Graphics:
Hercules ???? – Did a lot of machinecode on this one. (Which?) CGA/EGA Card ??? – Machinecode hacking VGA .. first card also machine code hacking Matrox Some cards i knew a lot about, i did some manipulations using assembly that were very interesting, but only worked on that specific brand.
The Catweasel is a family of enhanced floppy-disk controllers from German company Individual Computers. These controllers are designed to allow more recent computers, such as PCs, to access a wide variety of older or non-native disk formats using standard floppy drives.
You could connect joysticks and there is a socket for a SID chip on the card.
The script below helps me to copy located files to a temporary directory. (Which is excluded in al kinds of other find tools)
It will remove the slashes in a path, but keeps the rest.
You can pipe to this script
All files in 1 directory, but NO overwrite of files (keeps path). This allows for easy browsing with a picture viewer.
Want to know original path, look at the filename .. think of where the slashes should go
Example:
Lets find all jpg’s which linux in its name
# this will list all found files
locate -i linux | grep -i jpg$
output example (see below) (With slashes and spaces)
/tank/WorkDirectory/TMP/UITZOEKEN/cds uitzoeken/div/141/31/cd3/done/gfx/linux-from-scratch.jpg
cplocatescript
#!/bin/bash
mkdir -p /mnt/private/TEMP/$$
cat - | while read line ; do cp "$line" /mnt/private/TEMP/$$/$(echo "$line" | tr -cd 'A-Za-z0-9._-' ; echo "" ) ;done
#!/bin/bash # Set shebang .. interpreter (sh/python/bash)
#set -x # debug flag, shows all output and variables
set -e # exit when an error occurs, Dont use this when sourcing a scriptor using bash ./scriptnaam gebruikt.
set -u # exit when a variable isn't defined
set -o pipefail # exit when a pipe command fails
# Add comments to your scripts!
PIPEFAIL Example
grep string /nonexistenddir/file | sort # Does NOT give an error, sort works!
So echo $? gives 0
When set -o pipefail is set, above example will print 1 or 2
Bash options example
#!/bin/bash
usage ()
{
echo >&2 "usage: $0 <list-of-options>"
}
main ()
{
[ $# -lt 1 ] && usage
INSTALL_DIR=`dirname $0`
for i in $@; do
echo "$INSTALL_DIR $i"
done
}
main $@
Execute output from a script.
Sometimes i write scripts which print the command I want to have executed. Most of the times to check the generated commandline. simple example
ls | grep 2000 | while read ; do echo rm -f "$REPLY" ;done
Above only prints the lines rm -f <filename with 2000> rm -f <other filename with 2000>
Instead of removing the echo command, you can add a | bash , to have it executed.
ls | grep 2000 | while read ; do echo rm -f "$REPLY" ;done | bash
Or even shorter ( Use !! for previous command )
!! | bash
History
Search with CTRL-R in your command history, and use !<number> to execute this command again.
touch file1 file2 file3 file4
chmod 664 !* # will chmod only the files
When you used typed systemctl stop httpd and want to start again use replace ^stop^start This will take previous command containing stop and places stop with start and executes this.
Toggle history on/off with “set -o history”, depending on your setup you can use “<space>command to be executed”
History log original username per date when sudo is being used (creates .history.20230103.fash in /root/ )
HISTFILE=~/.history.$(date +%y%b%d).$(who am i | awk '{ print $1 }')
Skip first 2 lines and join 2 lines
#skip 2 lines
tail -n +3
#join 2 lines
sed 'N;s/\n/,/'
#3rd line from a file
sed "3q;d" /etc/hosts
#join on line line using comma's
paste -sd "," -
Find Tricks
#Remove empty directories
find ??? -empty -type d -delete
#Find multiple extentions
find archieven/ \( -name "*.png" -o -name "*.xml" \)
-print0 to handle filenames with spaces
Remove huge directory structures FAST
mkdir /tmp/empty ; rsync -a --delete /tmp/empty /path/blah
Check program installed and in path
which zenity >/dev/null 2>/tmp/err || ( echo "zenity not found, please install" ; exit 1 )
Change directory to location script for relative path usage
cd $(dirname $0)
ls relativesubdir/
IFS (Internal Field Separator)
IFS=$' ' # internal field separator, strings split here
for f in $(cat /etc/hosts) ; do echo $f ;done
#outputs 127.0.0.1
# localhost
IFS=$'\n\t' # internal field separator, split end of line
for f in $(cat /etc/hosts) ; do echo $f ;done
# Outputs 127.0.0.1 localhost
Difference for and while read example
echo "This will print every word" > text # Places text in file
echo "second line" >> text # Append text
for f in $(cat text) ; do echo $f ;done # for example
This
will
print
every
word
second
line
cat text | while read f ; do echo $f ; done # Read example
This will print every word
second line
Correct way to make a tempfile
tempfile=$(mktemp -d -t /tmp/log.$$) # Temp file, with unique name $$ is the process number
Usage in script :
ls > $tempfile
Cleanup:
rm -f "/tmp/$tempfile" # Remove
Direcory empty test
[ "$(ls -A /tmp)" ] && echo "Not empty" || echo "Empty" # test directory Empty/filled
test -d /tmp/1 && rmdir /tmp/1 # Removes a directory when it exists, will give an error when NOT empty
Using Expand
On directories archive30_tmp till archive35_tmp setting recursive chmod 2775
find achief{30..35}_tmp -type d -exec chmod 2775 {} \;
or
mkdir tmp{1..3} # will create tmp1 tmp2 tmp3
echo pr{ut,utser}s # Outputs "pruts prutsers"
Test root user
if [ $USER == "root" ] ; then … ; fi # execute only when root
if $USER is empty, this will give an error.
if [ w$USER == "wroot" ] works
qouting $USER also, but qouting a number using less/greater test could be problematic
Mount test
grep -qs /media /proc/mounts && echo "/media is mounted"
Date tricks
datum=$(date +%Y%m%d) # datum is yyyymmdd 20230103
today=$(date +%F)
tomorrow=$(date --date="next day" +%F)
p3=$(date --date="$p2" +%F)
dater=$p3
#now=$(date +%s --date="1 days ago")
now=$(date -d $(date --date="1 days ago" +%F) +%s)
p3epoch=$(date --date="$p3" +%s)
dater=$(date -d "$p3 1 year" +%F)
date -d @<UNIX timestamp> # Timestamp to date
Size test in directory
if [ "$(df /tmp |grep -v Available | awk {' print $4 }')" -lt 1000000 ] ; then echo "not enough free in /tmp" ;fi
Parallel Tasks
4 parallel jobs
find jpg -type f -name \*.jpg -print0 | xargs -0 -n1 -P4 ./convert.sh
Cluster ssh trick
Using Clusterssh at work
## clusterssh trick
Only needed to do stuff on server having a certain directory
clusterssh storageservers # ssh to 24 storage servers
sudo su -
cd /bricks/*/backup2 # change directory to this if exists
cd /alternatedir/brick0*/backup2 # change to this alternate directory if it exists
# directories not found? then you are still in /root
pwd | grep testdir || logout # no testdir in found subdirs? (there are non in /root so you will be logged out)
id | grep myuser && logout # if mortal user? then logout again .. you will be disconnected from servers not containing the backup2 directories
Do your work as root
Forgot to sudo?
systemctl restart httpd (wont work as user)
sudo !!
(this will do "sudo systemctl restart httpd")
Top 5 homedir users
du -hsx /home/* | sort -rh | head -5
Removing a huge file takes a long time .. lets truncate it
: > hugefile
rm hugefile
Check memory banks using dmidecode
sudo dmidecode| grep -i -B1 "Form Factor" (B1 means BEFORE 1 line, A is AFTER)
Size: 8192 MB
Form Factor: DIMM
--
Size: 8192 MB
Form Factor: DIMM
--
Size: No Module Installed
Form Factor: DIMM
--
sudo dmidecode -t memory | grep -i size
Size: 4096 MB
--
sudo lshw -short -C memory
H/W path Device Class Description
==========================================================
/0/0 memory 96KiB BIOS
/0/1000 memory 4GiB System Memory
/0/1000/0 memory 4GiB DIMM RAM
cat file | grep -o 'skip_reason.*' # till end
cat file | grep -o 'skip_reason.*tillhere'
Remove space filename
mv *\ * a
rm *\ *
Upper to lower case
tr '[:upper:]' '[:lower:]'
Whole directories to lowercase
#!/bin/bash
#print usage
if [ -z $1 ];then
echo "Usage :$(basename $0) parent-directory"
exit 1
fi
#process all subdirectories and files in parent directory
all="$(find $1 -depth)"
for name in ${all}; do
#set new name in lower case for files and directories
new_name="$(dirname "${name}")/$(basename "${name}" | tr '[A-Z]' '[a-z]')"
#check if new name already exists
if [ "${name}" != "${new_name}" ]; then
[ ! -e "${new_name}" ] && mv -T "${name}" "${new_name}"; echo "${name} was renamed to ${new_name}" || echo "${name} wasn't renamed!"
fi
done
echo
echo
#list directories and file new names in lowercase
echo "Directories and files with new names in lowercase letters"
find $(echo $1 | tr 'A-Z' 'a-z') -depth
exit 0
ChatGPT is a large language model chatbot developed by OpenAI based on GPT-3.5. It has a remarkable ability to interact in conversational dialogue form and provide responses that can appear surprisingly human.
So i asked stuff like:
Thats a pretty good joke about a 6502 CPU. I tought it would be a hard question
The question : “what are women looking for in a man” Gave a lot of lines : No generic answer Lines with Respect, Humor, Kindness, Confidence
Then it stopped with:
Typical .. even AI is baffled by women.
Below a chat session from a great friend of mine Tyrone
Tyrone: Ok could you write me a commodore c64 assembly routine to make the screen white?
Certainly! Here is a simple assembly routine that will clear the screen and set all of the pixels to white on a Commodore 64:
Copy code
ldx #$00
ldy #$00
clear_screen:
sta $d800,x
inx
cpx #$40
bne clear_screen
This code will loop through all of the screen memory locations and set the value at each location to $00, which will turn all of the pixels white. The inx and iny instructions are used to increment the X and Y registers, which are used to keep track of the current screen position. The cpy instruction is used to compare the value in the Y register to $20, and the bne instruction is used to branch back to the clear_screen label if the values are not equal, causing the loop to continue until the entire screen has been cleared.
I hope this helps! Let me know if you have any questions.

Tyrone: Well a big code but i wanted to make the screen the color white not with a character space .. this is also white but it's more logical that the color is named then the white space this code should be three lines of could can you do this?
Certainly! Here is a simple assembly routine that will clear the screen and set all of the pixels to white on a Commodore 64:
Copy code
ldx #$00
ldy #$00
clear_screen:
sta $d800,x
inx
cpx #$40
bne clear_screen
This code will loop through all of the screen memory locations and set the value at each location to $ff, which will turn all of the pixels white. The inx instruction is used to increment the X register, which is used to keep track of the current screen position. The cpx instruction is used to compare the value in the X register to $40, and the bne instruction is used to branch back to the clear_screen label if the values are not equal, causing the loop to continue until the entire screen has been cleared.
I hope this helps! Let me know if you have any questions.

Tyrone: This is wrong here is a hint use registers d020 and d021 for screen and border color
I apologize for the mistake in my previous response. Here is the corrected code that will set the screen and border colors to white on a Commodore 64:
Copy code
lda #$0f
sta $d020
sta $d021
This code will store the value $0f in the memory locations at $d020 and $d021, which are the registers that control the screen and border colors on the Commodore 64. The value $0f corresponds to the color white.
I hope this helps! Let me know if you have any questions.

Thank you ai