Astroport layer for Xbian

This commit is contained in:
qo-op 2020-12-12 01:26:39 +01:00
parent 08c50eb478
commit d56393af34
112 changed files with 18569 additions and 0 deletions

View File

@ -0,0 +1,9 @@
[Desktop Entry]
Type=Application
Exec=~/.zen/astroport/1stRUNconfig.sh
X-GNOME-Autostart-enabled=true
NoDisplay=false
Hidden=false
Name[fr_FR]=Astroport_X_config.desktop
Comment[fr_FR]=First time RUN config script
X-GNOME-Autostart-Delay=0

File diff suppressed because it is too large Load Diff

33
.install/export_colors.sh Executable file
View File

@ -0,0 +1,33 @@
#!/bin/bash
[[ -f ~/.bash_aliases && ! -z $(cat ~/.bash_aliases | grep c_red) ]] && exit 0
echo 'export c_blinkfast="\033[6m"
export c_light="\033[1m"
export c_white_bg="\033[47m"
export c_blue="\033[34m"
export c_red_bg="\033[41m"
export c_hide="\033[8m"
export c_purple_bg="\033[45m"
export c_yellow_bg="\033[43m"
export c_dark="\033[2m"
export c_reverse="003[7m"
export c_underline="\033[4m"
export c_blinkslow="\033[5m"
export c_red="\033[31m"
export c_white="\033[37m"
export c_cyan_bg="\033[46m"
export c_italic="\033[3m"
export c_black="\033[30m"
export c_cross="\033[9m"
export c_green="\033[32m"
export c_purple="\033[35m"
export c_="\033[0m"
export c_cyan="\033[36m"
export c_black_bg="\033[40m"
export c_yellow="\033[33m"
export c_blue_bg="\033[44m"
export c_green_bg="\033[42m"' >> ~/.bash_aliases
source ~/.bash_aliases

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

View File

@ -0,0 +1,31 @@
#!/usr/bin/env bash
# Enable camera on Raspberry Pi
# set_config_var taken from raspi-config
set_config_var() {
lua - "$1" "$2" "$3" <<EOF > "$3.bak"
local key=assert(arg[1])
local value=assert(arg[2])
local fn=assert(arg[3])
local file=assert(io.open(fn))
local made_change=false
for line in file:lines() do
if line:match("^#?%s*"..key.."=.*$") then
line=key.."="..value
made_change=true
end
print(line)
end
if not made_change then
print(key.."="..value)
end
EOF
sudo mv "$3.bak" "$3"
}
# Command extracted from raspi-config
sed /boot/config.txt -i -e "s/^startx/#startx/"
sed /boot/config.txt -i -e "s/^fixup_file/#fixup_file/"
set_config_var start_x 1 /boot/config.txt
set_config_var gpu_mem 128 /boot/config.txt

52
.install/ipfs-pi-stream/install Executable file
View File

@ -0,0 +1,52 @@
#!/usr/bin/env bash
set -e
BASE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# Enable camera on the Raspberry Pi
sudo "$BASE_DIR/enable-camera.sh"
# Install ffmpeg and supporting tools
sudo apt-get install -y ffmpeg lsof inotify-tools nginx
# Copy placeholder for audio-only streams
cp "$BASE_DIR/audio.jpg" "$HOME/audio.jpg"
# Add user to be able to modify nginx directories
sudo usermod -a -G "$USER" www-data
sudo chmod g+rw /var/www/html
# TODO: why is this needed?
sudo chmod a+rw /var/www/html
sudo cp -f "$BASE_DIR/process-stream.sh" /usr/bin/process-stream.sh
sudo cp -f "$BASE_DIR/process-stream.service" /etc/systemd/system/process-stream.service
sudo systemctl daemon-reload
sudo systemctl enable process-stream
# Add hourly job to clear out old data
echo "41 * * * * $USER /usr/local/bin/ipfs repo gc" | sudo tee --append /etc/crontab
# Install the ipfs video player
mkdir "$BASE_DIR/tmp"
current_dir="$(pwd)"
git clone https://github.com/tomeshnet/ipfs-live-streaming.git "$BASE_DIR/tmp/ipfs-live-streaming"
cd "$BASE_DIR/tmp/ipfs-live-streaming"
git checkout b9be352582317e5336ddd7183ecf49042dafb33e
cd "$current_dir"
VIDEO_PLAYER_PATH="$BASE_DIR/tmp/ipfs-live-streaming/terraform/shared/video-player"
sed -i s#__IPFS_GATEWAY_SELF__#/ipfs/# "$VIDEO_PLAYER_PATH/js/common.js"
sed -i s#__IPFS_GATEWAY_ORIGIN__#https://ipfs.io/ipfs/# "$VIDEO_PLAYER_PATH/js/common.js"
IPFS_ID=$(ipfs id | grep ID | head -n 1 | awk -F\" '{print $4}')
sed -i "s#live.m3u8#/ipns/$IPFS_ID#" "$VIDEO_PLAYER_PATH/js/common.js"
sed -i s#__M3U8_HTTP_URLS__#\ # "$VIDEO_PLAYER_PATH/js/common.js"
cp -r "$VIDEO_PLAYER_PATH" /var/www/html/video-player
rm -rf "$BASE_DIR/tmp"
# Add entry into nginx home screen
APP="<div class='app'><h2>IPFS Pi Stream Player</h2>IPFS Video player for Pi Stream. <br />M3U8 Stream located <a href='/ipns/$IPFS_ID'>over ipns</a> <br/><a href='/video-player/'>Go </a> and play with built in video player</div>"
sudo sed -i "s#<\!--APPLIST-->#$APP\n<\!--APPLIST-->#" "/var/www/html/index.html"

View File

@ -0,0 +1,16 @@
[Unit]
Description=Service to process RTMP stream
Wants=network.target
After=ipfs.service
[Service]
Type=simple
User=pi
Group=pi
ExecStart=/usr/bin/process-stream.sh
ExecStop=/bin/kill -s QUIT $MAINPID
Restart=on-failure
RestartSec=10s
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,124 @@
#!/usr/bin/env bash
HLS_TIME=40
M3U8_SIZE=3
IPFS_GATEWAY="https://ipfs.io"
# Load settings
# Prepare Pi Camera
sudo modprobe bcm2835-v4l2
sudo v4l2-ctl --set-ctrl video_bitrate=100000
function startFFmpeg() {
while true; do
mv ~/ffmpeg.log ~/ffmpeg.1
echo 1 > ~/stream-reset
# Stream Raspberry Pi Camera
ffmpeg -f video4linux2 -input_format h264 -video_size 1280x720 -framerate 30 -i /dev/video0 -vcodec copy -hls_time "${HLS_TIME}" "${what}.m3u8" > ~/ffmpeg.log 2>&1
# Stream FM Station from a SDR module (see contrib/pi-stream to install drivers)
# Frequency ends in M IE 99.9M
# rtl_fm -f 99.9M -M fm -s 170k -A std -l0 -E deemp -r 44.1k | ffmpeg -r 15 -loop 1 -i ../audio.jpg -f s16le -ac 1 -i pipe:0 -c:v libx264 -tune stillimage -preset ultrafast -hls_time "${HLS_TIME}" "${what}.m3u8" > ~/ffmpeg 2>&1
sleep 0.5
done
}
# Create directory for HLS content
currentpath="$HOME/live"
sudo umount "${currentpath}"
rm -rf "${currentpath}"
mkdir "${currentpath}"
sudo mount -t tmpfs tmpfs "${currentpath}"
# shellcheck disable=SC2164
cd "${currentpath}"
what="$(date +%Y%m%d%H%M)-LIVE"
# Start ffmpeg in background
startFFmpeg &
while true; do
#TODO# Fix this one
# shellcheck disable=SC2086,SC2012
nextfile=$(ls -tr ${what}*.ts 2>/dev/null | head -n 1)
if [ -n "${nextfile}" ]; then
# Check if the next file on the list is still being written to by ffmpeg
if lsof "${nextfile}" | grep -1 ffmpeg; then
# Wait for file to finish writing
# If not finished in 45 seconds something is wrong, timeout
inotifywait -e close_write "${nextfile}" -t ${HLS_TIME}
fi
# Grab the timecode from the m3u8 file so we can add it to the log
timecode=$(grep -B1 "${nextfile}" "${what}.m3u8" | head -n1 | awk -F : '{print $2}' | tr -d ,)
attempts=5
until [[ "${timecode}" || ${attempts} -eq 0 ]]; do
# Wait and retry
sleep 0.5
timecode=$(grep -B1 "${nextfile}" "${what}.m3u8" | head -n1 | awk -F : '{print $2}' | tr -d ,)
attempts=$((attempts-1))
done
if ! [[ "${timecode}" ]]; then
# Set approximate timecode
timecode="${HLS_TIME}.000000"
fi
reset_stream=$(cat ~/stream-reset)
reset_stream_marker=''
if [[ ${reset_stream} -eq '1' ]]; then
reset_stream_marker=" #EXT-X-DISCONTINUITY"
fi
echo 0 > ~/stream-reset
# Current UTC date for the log
time=$(date "+%F-%H-%M-%S")
# Add ts file to IPFS
ret=$(ipfs add --pin=false "${nextfile}" 2>/dev/null > ~/tmp.txt; echo $?)
attempts=5
until [[ ${ret} -eq 0 || ${attempts} -eq 0 ]]; do
# Wait and retry
sleep 0.5
ret=$(ipfs add --pin=false "${nextfile}" 2>/dev/null > ~/tmp.txt; echo $?)
attempts=$((attempts-1))
done
if [[ ${ret} -eq 0 ]]; then
# Update the log with the future name (hash already there)
echo "$(cat ~/tmp.txt) ${time}.ts ${timecode}${reset_stream_marker}" >> ~/process-stream.log
# Remove nextfile and tmp.txt
rm -f "${nextfile}" ~/tmp.txt
# Write the m3u8 file with the new IPFS hashes from the log
totalLines="$(wc -l ~/process-stream.log | awk '{print $1}')"
sequence=0
if ((totalLines>M3U8_SIZE)); then
sequence=$((totalLines-M3U8_SIZE))
fi
{
echo "#EXTM3U"
echo "#EXT-X-VERSION:3"
echo "#EXT-X-TARGETDURATION:${HLS_TIME}"
echo "#EXT-X-MEDIA-SEQUENCE:${sequence}"
} > current.m3u8
tail -n ${M3U8_SIZE} ~/process-stream.log | awk '{print $6"#EXTINF:"$5",\n'${IPFS_GATEWAY}'/ipfs/"$2}' | sed 's/#EXT-X-DISCONTINUITY#/#EXT-X-DISCONTINUITY\n#/g' >> current.m3u8
# Add m3u8 file to IPFS and IPNS publish
m3u8hash=$(ipfs add current.m3u8 | awk '{print $2}')
ipfs name publish --timeout=5s "${m3u8hash}" &
# Copy files to web server
cp current.m3u8 /var/www/html/live.m3u8
cp ~/process-stream.log /var/www/html/live.log
fi
else
sleep 5
fi
done

View File

@ -0,0 +1,18 @@
#!/usr/bin/env bash
set -e
BASE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
sudo systemctl stop process-stream
sudo systemctl disable process-stream
sudo rm -f /usr/bin/process-stream.sh
sudo rm -f /etc/systemd/system/process-stream.service
sudo systemctl daemon-reload
# Remove ffmpeg and supporting tools
sudo apt-get -y remove ffmpeg lsof inotify-tools
# Revert permissions
sudo chmod 755 /var/www/html
sed -i "/ipfs repo gc/d" | sudo tee --append /etc/crontab

69
.install/ipfs.sh Executable file
View File

@ -0,0 +1,69 @@
#!/bin/bash
ipfs() {
# Install IPFS
MY_PATH="`dirname \"$0\"`" # relative
MY_PATH="`( cd \"$MY_PATH\" && pwd )`" # absolutized and normalized
## Config
templates="$MY_PATH/.install/templates/ipfs"
if [ "$EUID" -eq 0 ]
then echo -e "${c_red}DO NOT EXECUTE AS root. Choose a user for your Astroport Station (we like pi)$c_"
exit 1
else echo -e "${c_yellow}OK $USER, let's go!$c_";
fi
[[ -d ~/.ipfs ]] && echo "IPFS install exist, please remove backup before execute this script" && exit 1
echo -e "${c_yellow}Onboarding IPFS...$c_"
[[ -f /usr/local/bin/ipfs ]] && sudo service ipfs stop
if [[ $ARM == "yes" ]]; then
wget https://dist.ipfs.io/ipfs-update/v1.5.2/ipfs-update_v1.5.2_linux-arm.tar.gz -O $MY_PATH/ipfs-update.tar.gz || err+="Download ipfs-update"
else
wget https://dist.ipfs.io/ipfs-update/v1.5.2/ipfs-update_v1.5.2_linux-amd64.tar.gz -O $MY_PATH/ipfs-update.tar.gz || err+="Download ipfs-update"
fi
echo "INSTALL ipfs-update"
sudo tar -xvzf $MY_PATH/ipfs-update.tar.gz -C /usr/src/ || err+="Untar ipfs-update"
rm $MY_PATH/ipfs-update.tar.gz
cd /usr/src/ipfs-update/
sudo ./install.sh || err+="Install ipfs-update"
cd $MY_PATH
echo "INSTALL latest ipfs"
sudo ipfs-update install latest || err+="Install IPFS"
echo "CREATE SYSTEMD ipfs SERVICE"
sudo cp -f $templates/ipfs.service /etc/systemd/system/
sudo sed -i "s/_USER/$USER/g" /etc/systemd/system/ipfs.service
sudo systemctl daemon-reload || err+="Restart IPFS"
sudo systemctl enable ipfs || err+="Enable IPFS daemon"
# INIT ipfs
ipfs init -p lowpower
# ipfs init -p server ## Uncomment for server infrastructure
# ACTIVATE CONFIG OPTIONS
# PUBSUB
ipfs config Pubsub.Router gossipsub
# MAXSTORAGE
availableDiskSize=$(df -P ~/ | awk 'NR>1{sum+=$4}END{print sum}')
diskSize="$((availableDiskSize / 2))"
ipfs config Datastore.StorageMax $diskSize
## PORT FORWARD (SSH)
ipfs config --json Experimental.Libp2pStreamMounting true
######### UPDATE BOOTSTRAP LIST ###########
ipfs bootstrap rm --all
sudo systemctl restart ipfs || err+="Restart IPFS daemon"
exit 0
}
$@

135
.install/ipfs_alone.sh Executable file
View File

@ -0,0 +1,135 @@
#!/bin/bash
########################################################################
{ # this ensures the entire script is downloaded #
MY_PATH="`dirname \"$0\"`" # relative
MY_PATH="`( cd \"$MY_PATH\" && pwd )`" # absolutized and normalized
ME="${0##*/}"
# CHECK not root user !!
if [ "$EUID" -eq 0 ]
then echo -e "${c_red}DO NOT EXECUTE AS root. Choose a user for your Astroport Station (we like pi)$c_"
exit 1
else echo -e "${c_yellow}OK $USER, let's go!$c_";
fi
# Ask user password on start
sudo true
## Error funciton
err() {
echo -e "${c_red}$1$c_"
exit 1
}
# CHECK if daemon is already running
if [[ $(ps auxf --sort=+utime | grep -w ipfs | grep -v -E 'color=auto|grep' | tail -n 1 | cut -d " " -f 1) ]]; then
echo "ipfs daemon already running...! Must STOP ipfs AND remove ~/.ipfs to install again !!"
ipfs id && echo "ipfs swarm peers: " && ipfs swarm peers
echo "ipfs bootstrap list: " && ipfs bootstrap list
echo "Please RUN : sudo systemctl stop ipfs"
exit 1
fi
[[ -d ~/.ipfs ]] && echo "IPFS install exist! Please remove or backup before executing this script" && exit 1
echo -e "${c_yellow}Astroport IPFS Layer installation...$c_"
# CHECK node IP isLAN?
myIP=$(hostname -I | awk '{print $1}')
isLAN=$(echo $myIP | grep -E "/(^127\.)|(^192\.168\.)|(^10\.)|(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|(^::1$)|(^[fF][cCdD])/")
MACHINE_TYPE=`uname -m`
if [ ${MACHINE_TYPE} == 'x86_64' ]; then
curl -s https://dist.ipfs.io/ipfs-update/v1.6.0/ipfs-update_v1.6.0_linux-amd64.tar.gz -o $MY_PATH/ipfs-update.tar.gz
elif [ ${MACHINE_TYPE:0:3} == 'arm' ]; then
curl -s https://dist.ipfs.io/ipfs-update/v1.6.0/ipfs-update_v1.6.0_linux-arm.tar.gz -o $MY_PATH/ipfs-update.tar.gz
else
[ ! -f $MY_PATH/ipfs-update.tar.gz ] && err "Your $MACHINE_TYPE is not supported yet... Please add an issue."
fi
echo "INSTALL ipfs-update >>>>>>>>>>>>>>>>>>>>>>>>>>"
sudo tar -xvzf $MY_PATH/ipfs-update.tar.gz -C /usr/src/ || err "Untar ipfs-update"
rm $MY_PATH/ipfs-update.tar.gz
cd /usr/src/ipfs-update/
sudo ./install.sh || err "Install ipfs-update"
cd $MY_PATH
echo "INSTALL ipfs 0.7.0 >>>>>>>>>>>>>>>>>>>>>>>>>>"
sudo ipfs-update install 0.7.0 || err "Install IPFS"
## DEBIAN
echo "CREATE SYSTEMD ipfs SERVICE >>>>>>>>>>>>>>>>>>"
cat > /tmp/ipfs.service <<EOF
[Unit]
Description=IPFS daemon
After=network.target
[Service]
User=_USER_
ExecStart=/usr/local/bin/ipfs daemon --enable-pubsub-experiment --enable-namesys-pubsub --enable-gc
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
sudo cp -f /tmp/ipfs.service /etc/systemd/system/
sudo sed -i "s/_USER_/$USER/g" /etc/systemd/system/ipfs.service
[[ -d ~/.ipfs ]] && sudo chown -R $USER:$USER ~/.ipfs
sudo systemctl daemon-reload || err "Restart IPFS"
sudo systemctl enable ipfs || err "Enable IPFS daemon"
## Special Xbian init.d config
if [[ $USER == "xbian" && -f ~/.zen/astroport/.install/templates/ipfs/ipfs-initV.sh ]]; then
sudo cp ~/.zen/astroport/.install/templates/ipfs/ipfs-initV.sh /etc/init.d/ipfs
sudo chmod 755 /etc/init.d/ipfs
sudo touch /var/log/ipfs.log && chown xbian /var/log/ipfs.log
sudo service ipfs enable
fi
# INIT ipfs
[[ $isLAN ]] && ipfs init -p lowpower \
|| ipfs init -p server
# TODO try ipfs init --profile=badgerds (for better performance)
# https://discuss.ipfs.io/t/adding-content-to-ipfs-is-quite-slow-any-ideas-on-why-and-how-to-speed-things-up/8135/3
sudo chown -R $USER:$USER ~/.ipfs || exit 1
###########################################
# ACTIVATE IPFS OPTIONS: #swarm0 INIT
###########################################
### IMPORTANT !!!!!!! IMPORTANT !!!!!!
###########################################
# DHT PUBSUB mode
ipfs config Pubsub.Router gossipsub
# MAXSTORAGE = 1/2 available
availableDiskSize=$(df -P ~/ | awk 'NR>1{sum+=$4}END{print sum}')
diskSize="$((availableDiskSize / 2))"
ipfs config Datastore.StorageMax $diskSize
## Activate Rapid "ipfs p2p"
ipfs config --json Experimental.Libp2pStreamMounting true
ipfs config --json Experimental.P2pHttpProxy true
######### MAKE DEFAULT BOOTSTRAP TO oasis.astroport.com 2jQUH4HfHxdTesjCjvMCx1VJgA5AnpuvrWRq1swfRdsS ###########
ipfs bootstrap rm --all
ipfs bootstrap add /dnsaddr/oasis.astroport.com/tcp/4001/ipfs/12D3KooWBYme2BsNUrtx4mEdNX6Yioa9AV7opWzQp6nrPs6ZKabN
ipfs bootstrap add /ip4/51.15.166.54/tcp/4001/p2p/12D3KooWBYme2BsNUrtx4mEdNX6Yioa9AV7opWzQp6nrPs6ZKabN
ipfs bootstrap add /ip4/51.15.166.54/udp/4001/quic/p2p/12D3KooWBYme2BsNUrtx4mEdNX6Yioa9AV7opWzQp6nrPs6ZKabN
ipfs bootstrap add /ip6/fe80::208:a2ff:fe0c:20d8/tcp/4001/p2p/12D3KooWBYme2BsNUrtx4mEdNX6Yioa9AV7opWzQp6nrPs6ZKabN
###########################################
# TODO: ADD some other bootstrap NODES
###########################################
sudo systemctl start ipfs || err "Start IPFS daemon"
sleep 3
echo "Peers: " && ipfs swarm peers && sleep 0.3
#[[ ! $(ipfs swarm peers) =~ "/ip4/" ]] && err "No peers found in swarm. Please open issue :https://git.p2p.legal/axiom-team/astroport/issues"
} # this ensures the entire script is downloaded #
# IPFS CONFIG documentation: https://github.com/ipfs/go-ipfs/blob/master/docs/config.md#addressesswarm

Binary file not shown.

Binary file not shown.

264
.install/loveland.sh Executable file
View File

@ -0,0 +1,264 @@
#!/bin/bash
########################################################################
# Author: Fred (support@qo-op.com)
# Version: 0.3
# License: AGPL-3.0 (https://choosealicense.com/licenses/agpl-3.0/)
########################################################################
{
MY_PATH="`dirname \"$0\"`" # relative
MY_PATH="`( cd \"$MY_PATH\" && pwd )`" # absolutized and normalized
ME="${0##*/}"
########################################################################
YOU=$(ps auxf --sort=+utime | grep -w ipfs | grep -v -E 'color=auto|grep' | tail -n 1 | cut -d " " -f 1) || er+=" ipfs daemon not running"
IPFSNODEID=$(ipfs id -f='<id>\n') || er+=" ipfs id problem"
WHOAMI=$(sbotc whoami | jq -r .id) || er+=" sbotc whoami problem"
[[ "$YOU" == "" || "$IPFSNODEID" == "" || "$WHOAMI" == "" ]] && echo "ERROR : $er " && exit 1
########################################################################
#### DO NOT RUN AS ROOT
[[ $USER == "root" ]] && echo "DO NOT RUN AS root!! Use regular USER with sudo AUTHORISATION" && exit 1
#### APACHE NOT SUPPORTED
is_apache_running=$(ps auxf --sort=+utime | grep -w apache | grep -v -E 'color=auto|grep' | tail -n 1 | cut -d " " -f 1);
[[ $is_apache_running ]] && echo "SORRY ONLY nginx is supported. EXIT" && exit 1
#### ARM / X64 NOT USED THERE
MACHINE_TYPE=`uname -m`
[ ${MACHINE_TYPE:0:3} == 'arm' ] && isARM="YES"
### UPDATE apt cache
sudo apt-get update
### Adding YOU to www-data group
sudo adduser $YOU www-data
##################################
## INSTALL RAINBOW ASCII ;)
[[ ! $(which figlet) ]] && sudo apt install figlet -y
[[ ! $(which lolcat) ]] && sudo apt install lolcat -y
echo '
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
______ __ ____ ___
/ ____/___ ____ __ __/ / ____ _/ __ \____ _____/ (_)___
/ / / __ \/ __ \/ / / / / / __ `/ /_/ / __ `/ __ / / __ \
/ /___/ /_/ / /_/ / /_/ / /___/ /_/ / _, _/ /_/ / /_/ / / /_/ /
\____/\____/ .___/\__, /_____/\__,_/_/ |_|\__,_/\__,_/_/\____/
/_/ /____/
Multimedia Layer (https://www.copylaradio.com)
' | lolcat
## MULTIMEDIA
## VIDEO & AUDIO & PLAYLISTS ~/.zen/ DIR
mkdir -p ~/.zen/video
mkdir -p ~/.zen/audio
mkdir -p ~/.zen/playlists
######## YOUTUBE-DL ##########
if [[ ! $(which youtube-dl) ]]; then
sudo wget https://yt-dl.org/downloads/latest/youtube-dl -O /usr/local/bin/youtube-dl || err=1
sudo chmod a+rx /usr/local/bin/youtube-dl
sudo chown $YOU /usr/local/bin/youtube-dl
fi
###############################
# MPD/MPC RompR AUDIO LAYER
###############################
if [[ ! $(which mpd) ]]; then
sudo apt-get install libid3-tools mpd mpc lame ffmpeg lsof lltag inotify-tools bc -y || err=1
sudo apt-get install lame sox libsox-fmt-mp3 eyed3 python-chardet imagemagick curl -y || err=1 #libav-tools unavailable on some system
sudo apt-get install ca-certificates git-core binutils rsync alsa-utils bc espeak mpg321 fuse atomicparsley -y || err=1
## CONFIG MPD
sudo cp -f /home/$YOU/.zen/astroport/.install/templates/copylaradio/mpd.conf /etc/mpd.conf
sudo sed -i "s/_USER_/$YOU/g" /etc/mpd.conf || err=1
mkdir ~/.config/mpd && sudo cp -f /etc/mpd.conf ~/.config/mpd/mpd.conf && sudo chown $YOU ~/.config/mpd/mpd.conf
## CHOWN mpd FILES STRUCTURE
sudo chown -R $YOU /var/lib/mpd/ /var/run/mpd /run/mpd /var/log/mpd
sudo service mpd restart || err=1
fi
### INSTALL NGINX
echo '++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
_
____ ____ _(_)___ _ __
/ __ \/ __ `/ / __ \| |/_/
/ / / / /_/ / / / / /> <
/_/ /_/\__, /_/_/ /_/_/|_|
/____/
install
' | lolcat
sudo apt-get install fail2ban nginx ssl-cert php-curl php-sqlite3 php-gd php-json php-xml php-mbstring php-fpm sqlite -y || err=1
[[ ! $(which nslookup) ]] && sudo apt-get install lolcat dnsutils -y
echo '++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
__ ___ _ ___
/ |/ /_ __ ____ ____ _____ ___ ___ (_)___/__ \
/ /|_/ / / / / / __ \/ __ `/ __ `__ \/ _ \ / / ___// _/
/ / / / /_/ / / / / / /_/ / / / / / / __/ / (__ )/_/
/_/ /_/\__, / /_/ /_/\__,_/_/ /_/ /_/\___/ /_/____/(_)
/____/
' | lolcat
myIP=$(hostname -I | awk '{print $1}' | head -n 1)
isLAN=$(echo $myIP | grep -E "/(^127\.)|(^192\.168\.)|(^10\.)|(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|(^::1$)|(^[fF][cCdD])/")
# Ask to the router its name (BOX DNS or system defined)
[[ -f /home/$YOU/.zen/astroport/zen/tools/nodename ]] && NODENAME=$(/home/$YOU/.zen/astroport/zen/tools/nodename) \
|| NODENAME=$(curl -s https://git.p2p.legal/axiom-team/astroport/raw/master/zen/tools/nodename | bash) ## RUNNING ALONE !!
echo $NODENAME
######################################
### LAUNCHIN OASIS = SSB HTTP interface
######################################
echo '
_
____ ____ ______(_)____
/ __ \/ __ `/ ___/ / ___/
/ /_/ / /_/ (__ ) (__ )
\____/\__,_/____/_/____/
SSB DEMO HTTP interface
' | lolcat
# IN CASE, KILL RUNNING OASIS
isOASIS=$(ps auxf --sort=+utime | grep -w oasis | grep -v -E 'color=auto|grep' | tail -n 1 | awk '{print $2}')
[[ $isOASIS ]] && sudo kill -9 $isOASIS
echo "Starting OASIS with good $NODENAME & network config"
echo "TODO: add to your /etc/rc.local or systemd or initV !!!"
#if [[ ! $isLAN ]]; then
# ### TODO: unlock oasis restrictions!! CANNOT MAKE PRIVATE MESSAGE => Feddless.social CAN add it as module on loveland portal!!)
# oasis --allow-host $NODENAME --host $NODENAME --public 2>&1>/dev/null &
# echo "--public = OASIS STATION IS IN VIEWING MODE ONLY..."
#else
# oasis --allow-host $NODENAME --host $NODENAME 2>&1>/dev/null &
#fi
#sleep 5
echo '
__ ____ _ __________ __
/ / / __ \ | / / ____/ / ____ _____ ____/ /
/ / / / / / | / / __/ / / / __ `/ __ \/ __ /
/ /___/ /_/ /| |/ / /___/ /___/ /_/ / / / / /_/ /
/_____/\____/ |___/_____/_____/\__,_/_/ /_/\__,_/
Portal
' | lolcat
###
echo "INSTALL LOVELand WebSite. Linking to /var/www ..."
if [[ ! -L /var/www/loveland ]]; then
sudo ln -s /home/$YOU/.zen/astroport/www/LOVELand /var/www/loveland
fi
echo "JUKEBOX init"
[[ -d /var/www/loveland/jukebox/albumart ]] && sudo chmod -R 777 /var/www/loveland/jukebox/albumart
[[ -d /var/www/loveland/jukebox/prefs ]] && sudo chmod -R 777 /var/www/loveland/jukebox/prefs
[[ -d /var/www/loveland/g1barre/img/qrcodes ]] && sudo chmod -R 777 /var/www/loveland/g1barre/img/qrcodes
# CONFIG NGINX - LOVE LAND FRONTAL WEB PAGE
echo "$NODENAME" | figlet -f slant | lolcat
## Write NODENAME to IPFS
echo "$NODENAME" > /home/$YOU/.zen/ipfs/.$IPFSNODEID/G1SSB/_nodename
PHPVERSION=$(ps auxf | grep php-fpm | grep -v -E 'color=auto|grep' | head -n 1 | grep -oP '(?<=\().*(?=\))' | awk -F '/' '{print $4}')
### ASTROPORT STATION LOVELAND PORTAL
sudo sed "s/_PHPVERSION_/$PHPVERSION/g" /home/$YOU/.zen/astroport/www/loveland.conf > /tmp/loveland.conf
sudo sed -i "s/_MY_NODE_NAME_/$NODENAME/g" /tmp/loveland.conf
sudo sed -i "s/_PORT_/10010/g" /tmp/loveland.conf
sudo sed -i "s/_APPLI_//g" /tmp/loveland.conf
sudo cp -f /tmp/loveland.conf /etc/nginx/conf.d/loveland.conf
### GCHANGE G1 Zen
sudo rm -f /etc/nginx/conf.d/gchange.conf
sudo sed "s/_PHPVERSION_/$PHPVERSION/g" /home/$YOU/.zen/astroport/www/loveland.conf > /tmp/gchange.conf
sudo sed -i "s/_MY_NODE_NAME_/$NODENAME/g" /tmp/gchange.conf
sudo sed -i "s/_PORT_/10020/g" /tmp/gchange.conf
sudo sed -i "s/_APPLI_/gchange/g" /tmp/gchange.conf
sudo cp -f /tmp/gchange.conf /etc/nginx/conf.d/gchange.conf
### CESIUM G1 Zen
sudo sed "s/_PHPVERSION_/$PHPVERSION/g" /home/$YOU/.zen/astroport/www/loveland.conf > /tmp/cesium.conf
sudo sed -i "s/_MY_NODE_NAME_/$NODENAME/g" /tmp/cesium.conf
sudo sed -i "s/_PORT_/10030/g" /tmp/cesium.conf
sudo sed -i "s/_APPLI_/cesium/g" /tmp/cesium.conf
sudo cp -f /tmp/cesium.conf /etc/nginx/conf.d/cesium.conf
### JUKEBOX RompR CopyLaRadio
if [[ $(which mpd) ]]; then
sudo sed "s/_PHPVERSION_/$PHPVERSION/g" /home/$YOU/.zen/astroport/www/loveland.conf > /tmp/jukebox.conf
sudo sed -i "s/_MY_NODE_NAME_/$NODENAME/g" /tmp/jukebox.conf
sudo sed -i "s/_PORT_/10011/g" /tmp/jukebox.conf
sudo sed -i "s/_APPLI_/jukebox/g" /tmp/jukebox.conf
sudo cp -f /tmp/jukebox.conf /etc/nginx/conf.d/jukebox.conf
fi
### SSB OASIS Zen (PROXY MODE 10040 -> 3000)
if [[ $(which oasis) ]]; then
sudo sed "s/_MY_NODE_NAME_/$NODENAME/g" /home/$YOU/.zen/astroport/www/oasis.conf > /tmp/oasis.conf
sudo sed -i "s/_PORT_/10040/g" /tmp/oasis.conf
sudo sed -i "s/_LHOST_/$NODENAME:3000/g" /tmp/oasis.conf
sudo sed -i "s/_APPLI_//g" /tmp/oasis.conf
sudo cp -f /tmp/oasis.conf /etc/nginx/conf.d/oasis.conf
# TRICK: COULD BE USED TO ADD .htpasswod ACCESS CONTROL AND REMOVE --public
# TODO use "ipfs p2p" to AGREGATE ALL OASIS on ONE (not ALL like G1SMS) ?
# NEED G1PUB to be identified with same MEMBER owner in 'zen/ipfs_OPEN_ports.sh'?
fi
### G1SMS propagation to localhost:10099 / 10097 ("ipfs p2p" forwarded)
if [[ $(which gammu) ]]; then
# DIRECT MODE
sudo sed "s/_PHPVERSION_/$PHPVERSION/g" /home/$YOU/.zen/astroport/www/loveland.conf > /tmp/g1sms.conf
sudo sed -i "s/_MY_NODE_NAME_/$NODENAME/g" /tmp/g1sms.conf
sudo sed -i "s/_PORT_/10099/g" /tmp/g1sms.conf
sudo sed -i "s/_APPLI_/g1sms/g" /tmp/g1sms.conf
sudo cp -f /tmp/g1sms.conf /etc/nginx/conf.d/g1sms.conf
else
# PROXY MODE (10099 -> 10097) ### ipfs p2p PROPAGATION WITH 'zen/ipfs_OPEN_ports.sh'
sudo sed "s/_MY_NODE_NAME_/$NODENAME/g" /home/$YOU/.zen/astroport/www/oasis.conf > /tmp/g1sms_proxy.conf
sudo sed -i "s/_PORT_/10099/g" /tmp/g1sms_proxy.conf
sudo sed -i "s/_LHOST_/127\.0\.0\.1\:10097/g" /tmp/g1sms_proxy.conf
sudo sed -i "s/_APPLI_/g1sms/g" /tmp/g1sms_proxy.conf
sudo cp -f /tmp/g1sms_proxy.conf /etc/nginx/conf.d/g1sms_proxy.conf
fi
##### RESTART NGINX
sudo systemctl restart nginx || err=1
if [[ $err ]]; then
echo -e "${c_red}Installation de LOVELand bizarre??$c_"
echo "PLEASE... POST YOUR ISSUE! https://git.p2p.legal/axiom-team/astroport/issues"
exit 1
else
echo -e "${c_green}LOVE Land a été installé avec succès$c_"
echo -e "LoveLand Portal link http://$NODENAME:10010 (TRY ME)
Add ScuttleButt Astroport PUB Invitation:
${c_green}With Patchwork: "Join a server"$c_
Or with Oasis: http://$NODENAME:3000/settings (dev mode, still buggy)
${c_light}oasis.astroport.com:8008::@UeiA9iqZ0/XTjmYBht230KGr44bsr+Tl5BXSUDFv8vo=.ed25519~jd9Z4y/d/xZCF7bfuSgQSiSGLMeWFhwMosKUFhFxeEY=" $c_
fi
# Open LOVEland in browser
URL="http://$NODENAME"
path=$(which xdg-open || which gnome-open)
xo ()
{
for var in "$@"; do
$path "$var";
sleep 0.5
done
}
[[ -n $path ]] && xo $URL:10010 $URL:10020 $URL:10030 > /dev/null
} # for script being completely downloaded before run

188
.install/mpd_rompr.sh Executable file
View File

@ -0,0 +1,188 @@
#!/bin/bash
########################################################################
# Author: Fred (support@qo-op.com)
# Version: 0.3
# License: AGPL-3.0 (https://choosealicense.com/licenses/agpl-3.0/)
########################################################################
{
MY_PATH="`dirname \"$0\"`" # relative
MY_PATH="`( cd \"$MY_PATH\" && pwd )`" # absolutized and normalized
ME="${0##*/}"
########################################################################
YOU=$(ps auxf --sort=+utime | grep -w ipfs | grep -v -E 'color=auto|grep' | tail -n 1 | cut -d " " -f 1) || er+=" ipfs daemon not running"
IPFSNODEID=$(ipfs id -f='<id>\n') || er+=" ipfs id problem"
WHOAMI=$(sbotc whoami | jq -r .id) || er+=" sbotc whoami problem"
[[ "$YOU" == "" || "$IPFSNODEID" == "" || "$WHOAMI" == "" ]] && echo "ERROR : $er " && exit 1
########################################################################
#### DO NOT RUN AS ROOT
[[ $USER == "root" ]] && echo "DO NOT RUN AS root!! Use regular USER with sudo AUTHORISATION" && exit 1
#### APACHE NOT SUPPORTED
is_apache_running=$(ps auxf --sort=+utime | grep -w apache | grep -v -E 'color=auto|grep' | tail -n 1 | cut -d " " -f 1);
[[ $is_apache_running ]] && echo "SORRY ONLY nginx is supported. EXIT" && exit 1
#### ARM / X64 NOT USED THERE
MACHINE_TYPE=`uname -m`
[ ${MACHINE_TYPE:0:3} == 'arm' ] && isARM="YES"
### UPDATE apt cache
sudo apt-get update
### Adding YOU to www-data group
sudo adduser $YOU www-data
##################################
## INSTALL RAINBOW ASCII ;)
[[ ! $(which figlet) ]] && sudo apt install figlet -y
[[ ! $(which lolcat) ]] && sudo apt install lolcat -y
echo '
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
______ __ ____ ___
/ ____/___ ____ __ __/ / ____ _/ __ \____ _____/ (_)___
/ / / __ \/ __ \/ / / / / / __ `/ /_/ / __ `/ __ / / __ \
/ /___/ /_/ / /_/ / /_/ / /___/ /_/ / _, _/ /_/ / /_/ / / /_/ /
\____/\____/ .___/\__, /_____/\__,_/_/ |_|\__,_/\__,_/_/\____/
/_/ /____/
Multimedia Layer (https://www.copylaradio.com)
' | lolcat
## MULTIMEDIA
## VIDEO & AUDIO & PLAYLISTS ~/.zen/ DIR
mkdir -p ~/astroport/films
mkdir -p ~/astroport/animes
mkdir -p ~/astroport/series
mkdir -p ~/astroport/docus
mkdir -p ~/astroport/musiques
mkdir -p ~/.zen/video
mkdir -p ~/.zen/audio
mkdir -p ~/.zen/playlists
######## YOUTUBE-DL ##########
if [[ ! $(which youtube-dl) ]]; then
sudo wget https://yt-dl.org/downloads/latest/youtube-dl -O /usr/local/bin/youtube-dl || err=1
sudo chmod a+rx /usr/local/bin/youtube-dl
sudo chown $YOU /usr/local/bin/youtube-dl
fi
###############################
# MPD/MPC RompR AUDIO LAYER
###############################
if [[ ! $(which mpd) ]]; then
sudo apt-get install libid3-tools mpd mpc lame ffmpeg lsof lltag inotify-tools bc -y || err=1
sudo apt-get install lame sox libsox-fmt-mp3 eyed3 python-chardet imagemagick curl -y || err=1 #libav-tools unavailable on some system
sudo apt-get install ca-certificates git-core binutils rsync alsa-utils bc espeak mpg321 fuse atomicparsley -y || err=1
## CONFIG MPD
sudo cp -f /home/$YOU/.zen/astroport/.install/templates/copylaradio/mpd.conf /etc/mpd.conf
sudo sed -i "s/_USER_/$YOU/g" /etc/mpd.conf || err=1
mkdir ~/.config/mpd && sudo cp -f /etc/mpd.conf ~/.config/mpd/mpd.conf && sudo chown $YOU ~/.config/mpd/mpd.conf
## CHOWN mpd FILES STRUCTURE
sudo chown -R $YOU /var/lib/mpd/ /var/run/mpd /run/mpd /var/log/mpd
sudo service mpd restart || err=1
fi
### INSTALL NGINX
echo '++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
_
____ ____ _(_)___ _ __
/ __ \/ __ `/ / __ \| |/_/
/ / / / /_/ / / / / /> <
/_/ /_/\__, /_/_/ /_/_/|_|
/____/
install
' | lolcat
sudo apt-get install fail2ban nginx ssl-cert php-curl php-sqlite3 php-gd php-json php-xml php-mbstring php-fpm sqlite -y || err=1
[[ ! $(which nslookup) ]] && sudo apt-get install lolcat dnsutils -y
echo '++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
__ ___ _ ___
/ |/ /_ __ ____ ____ _____ ___ ___ (_)___/__ \
/ /|_/ / / / / / __ \/ __ `/ __ `__ \/ _ \ / / ___// _/
/ / / / /_/ / / / / / /_/ / / / / / / __/ / (__ )/_/
/_/ /_/\__, / /_/ /_/\__,_/_/ /_/ /_/\___/ /_/____/(_)
/____/
' | lolcat
myIP=$(hostname -I | awk '{print $1}' | head -n 1)
isLAN=$(echo $myIP | grep -E "/(^127\.)|(^192\.168\.)|(^10\.)|(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|(^::1$)|(^[fF][cCdD])/")
# Ask to the router its name (BOX DNS or system defined)
[[ -f /home/$YOU/.zen/astroport/zen/tools/nodename ]] && NODENAME=$(/home/$YOU/.zen/astroport/zen/tools/nodename) \
|| NODENAME=$(curl -s https://git.p2p.legal/axiom-team/astroport/raw/master/zen/tools/nodename | bash) ## RUNNING ALONE !!
echo $NODENAME
echo '
__ ____ _ __________ __
/ / / __ \ | / / ____/ / ____ _____ ____/ /
/ / / / / / | / / __/ / / / __ `/ __ \/ __ /
/ /___/ /_/ /| |/ / /___/ /___/ /_/ / / / / /_/ /
/_____/\____/ |___/_____/_____/\__,_/_/ /_/\__,_/
Portal
' | lolcat
###
echo "INSTALL LOVELand WebSite. Linking to /var/www ..."
if [[ ! -L /var/www/loveland ]]; then
sudo ln -s /home/$YOU/.zen/astroport/www/LOVELand /var/www/loveland
fi
echo "JUKEBOX init"
[[ -d /var/www/loveland/jukebox/albumart ]] && sudo chmod -R 777 /var/www/loveland/jukebox/albumart
[[ -d /var/www/loveland/jukebox/prefs ]] && sudo chmod -R 777 /var/www/loveland/jukebox/prefs
[[ -d /var/www/loveland/g1barre/img/qrcodes ]] && sudo chmod -R 777 /var/www/loveland/g1barre/img/qrcodes
# CONFIG NGINX - LOVE LAND FRONTAL WEB PAGE
echo "$NODENAME" | figlet -f slant | lolcat
## Write NODENAME to IPFS
echo "$NODENAME" > /home/$YOU/.zen/ipfs/.$IPFSNODEID/G1SSB/_nodename
PHPVERSION=$(ps auxf | grep php-fpm | grep -v -E 'color=auto|grep' | head -n 1 | grep -oP '(?<=\().*(?=\))' | awk -F '/' '{print $4}')
### JUKEBOX RompR CopyLaRadio
if [[ $(which mpd) ]]; then
sudo sed "s/_PHPVERSION_/$PHPVERSION/g" /home/$YOU/.zen/astroport/www/loveland.conf > /tmp/jukebox.conf
sudo sed -i "s/_MY_NODE_NAME_/$NODENAME/g" /tmp/jukebox.conf
sudo sed -i "s/_PORT_/80/g" /tmp/jukebox.conf
sudo sed -i "s/_APPLI_/jukebox/g" /tmp/jukebox.conf
sudo cp -f /tmp/jukebox.conf /etc/nginx/conf.d/jukebox.conf
fi
##### RESTART NGINX
sudo systemctl restart nginx || err=1
if [[ $err ]]; then
echo -e "${c_red}Installation de bizarre??$c_"
echo "PLEASE... POST YOUR ISSUE! https://git.p2p.legal/axiom-team/astroport/issues"
exit 1
else
echo -e "${c_green}Installation réalisée avec succès$c_"
echo -e "Astroport JUKEBOX http://$NODENAME (TRY ME)"
fi
# Open in browser
URL="http://$NODENAME"
path=$(which xdg-open || which gnome-open)
xo ()
{
for var in "$@"; do
$path "$var";
sleep 0.5
done
}
[[ -n $path ]] && xo $URL:80 > /dev/null
} # for script being completely downloaded before run

View File

@ -0,0 +1,35 @@
# Automatic install of Nextcloud on Debian 8/9/10
## Use
Set good variables for your use case at the beginning of install.sh:
```
nc_domain="" # Votre nom de domaine pour votre nextcloud. Si vide il prendra le premier argument que vous passerez, sinon le hostname de votre machine
nc_port=80 # Numéro de port d'écoute de nginx
admin_user="admin" # Le pseudo du compte admin
admin_pass="admin" # Le mot de passe que vous désirez pour le compte admin
db_pass="" # Le mot de passe que vous désirez pour MariaDB. Si vide, un mot de passe aléatoire sécurisé sera choisi
isSSL=false # true si nextcloud et nginx doivent être configuré en https
configMaria=auto # Mettez manual ou auto, attention auto est expérimental et vraiment pas recommendé
p2env=false # true si vous êtes dans un environnement p2p.legal
```
Then:
```
chmod u+x install.sh
./install.sh
```
You can change the ssl state of your instance after the installation if you need.
Just execute ssl.sh:
`./ssl.sh`
If you prefere, you can download this script directly via:
```
wget https://dev-nextcloud.p2p.legal/installeur/install-nextcloud.tar.gz
tar -zxvf install-nextcloud.tar.gz
./install.sh 2>&1 | tee loginstall.log
```

186
.install/nextcloud/install.sh Executable file
View File

@ -0,0 +1,186 @@
#!/bin/bash
################################################################################
# Author: poka (poka@p2p.legal)
# Version: 0.1
# License: AGPL-3.0 (https://choosealicense.com/licenses/agpl-3.0/)
################################################################################
### Variables ###
nc_domain="" # Votre nom de domaine pour votre nextcloud. Si vide il prendra le premier argument que vous passerez, sinon le hostname de votre machine
nc_port=10050 # Numéro de port d'écoute de nginx
YOU=$(ps auxf --sort=+utime | grep -w ipfs | grep -v -E 'color=auto|grep' | tail -n 1 | cut -d " " -f 1)
admin_user="$YOU" # Le pseudo du compte admin
admin_pass="0penS0urce!" # Le mot de passe que vous désirez pour le compte admin
db_pass="" # Le mot de passe que vous désirez pour MariaDB. Si vide, un mot de passe aléatoire sécurisé sera choisi
data_dir="/home/$YOU/.zen/nextcloud" # Le répertoir data de nextcloud, toutes les données utilisateurs s'y trouvent
isSSL=false # true si nextcloud et nginx doivent être configuré en https
configMaria=auto # Mettez manual ou auto, attention auto est expérimental et vraiment pas recommendé
p2env=false # true si vous êtes dans un environnement p2p.legal
#################
if [ "$EUID" -ne 0 ]
then echo -e "${c_red}Veuillez executez ce script en root$c_"
exit 1
fi
## Atroport config
echo -e "${c_yellow}Getting local hostname...$c_"
nc_domain=$(/home/$YOU/.zen/astroport/zen/tools/nodename)
templates="/home/$YOU/.zen/astroport/.install/nextcloud/templates"
## Set var
[[ -z $nc_domain ]] && nc_domain=$1
[[ -z $nc_domain ]] && nc_domain=$(echo $HOSTNAME.p2p.legal)
[[ -z $db_pass ]] && db_pass="$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1)" && echo "Votre mot de passe mysql nextcloud est : $db_pass" >> /root/nextcloud_mysql_pwd.txt
db_pass_root="$(cat /dev/urandom | tr -dc 'a-zA-Z0-9~!@#$%^&*_-' | fold -w 32 | head -n 1)"
if [[ p2env == "true" ]]; then
cd /nextcloud/templates/
else
[[ ! -e $templates ]] && echo -e "${c_red}Erreur: Le dossier templates n'existe pas, installation impossible.$c_" && exit 1
cd $templates
fi
## Update system packages
apt install -y lsb-release apt-transport-https ca-certificates
apt update -y
apt install nginx mariadb-server apt-transport-https curl gnupg2 git lsb-release ssl-cert ca-certificates apt-transport-https tree locate software-properties-common dirmngr screen htop net-tools zip unzip curl ffmpeg ghostscript libfile-fcntllock-perl -y
systemctl start nginx || (echo -e "${c_red}Erreur quelque part ...$c_" && exit 1)
systemctl start mariadb || (echo -e "${c_red}Erreur quelque part ...$c_" && exit 1)
systemctl enable mariadb || (echo -e "${c_red}Erreur quelque part ...$c_" && exit 1)
systemctl enable nginx || (echo -e "${c_red}Erreur quelque part ...$c_" && exit 1)
echo -e "${c_yellow} === Installing php ... ===$c_"
apt install php php-fpm php-xml php-curl php-gd php php-cgi php-cli php-zip php-mysql php-mbstring php-intl php-json php-bz2 php-ldap php-apcu imagemagick php-imagick php-smbclient -y
export PHPVERSION=$(ps auxf | grep php-fpm | grep -v -E 'color=auto|grep' | head -n 1 | grep -oP '(?<=\().*(?=\))' | awk -F '/' '{print $4}')
echo -e "${c_yellow} === Configuring php ... ===$c_"
[[ ! -e /etc/php/$PHPVERSION/cli/php.ini.bak ]] && (bash configure_php.sh || (echo -e "${c_red}Erreur quelque part ...$c_" && exit 1)) || echo "PHP déjà configuré, skip"
echo -e "${c_yellow} === Configure MariaDB ===$c_"
configMariaManual() {
mysql_secure_installation || (echo -e "${c_red}Erreur quelque part ...$c_" && exit 1)
}
configMariaAuto() {
mysql -e "UPDATE mysql.user SET Password = PASSWORD('$db_pass_root') WHERE User = 'root'"
isLocalhostUsers=$(mysql -e "select user from mysql.user;" | grep "localhost")
isTestDB=$(mysql -e "show databases" | grep "test")
[[ -n $isLocalhostUsers ]] && mysql -e "DROP USER ''@'localhost'; DROP USER ''@'$(hostname)'"
[[ -n $isTestDB ]] && mysql -e "DROP DATABASE test"
mysql -e "FLUSH PRIVILEGES"
}
[[ $configMaria == "auto" ]] && configMariaAuto || configMariaManual
[[ ! -e /etc/mysql/my.cnf.bak ]] && (mv /etc/mysql/my.cnf /etc/mysql/my.cnf.bak && cp my.cnf /etc/mysql/ && service mysql restart) || echo "MariaDB déjà configuré, skip"
echo -e "${c_yellow} === Create and configure database... ===$c_"
isDBCreate=$(mysql -e "show databases" | grep "nextcloud")
[[ -z $isDBCreate ]] && mysql -e "CREATE DATABASE nextcloud;CREATE USER 'nextcloud'@'localhost' IDENTIFIED BY \"$db_pass\";GRANT ALL PRIVILEGES ON nextcloud.* TO 'nextcloud'@'localhost';FLUSH PRIVILEGES;ALTER DATABASE nextcloud CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;" || echo "La base de donnée de nextcloud est déjà créé, skip"
echo -e "${c_yellow} === Installing and configure Redis... ===$c_"
apt install redis-server php-redis -y
[[ ! -e /etc/redis/redis.conf.bak ]] && cp /etc/redis/redis.conf /etc/redis/redis.conf.bak || echo "Redis est déjà configuré, skip"
sed -i "s/port 6379/port 0/" /etc/redis/redis.conf
sed -i "s/redis.sock/redis-server.sock/" /etc/redis/redis.conf
sed -i s/\#\ unixsocket/\unixsocket/g /etc/redis/redis.conf
sed -i "s/unixsocketperm 700/unixsocketperm 770/" /etc/redis/redis.conf
sed -i "s/# maxclients 10000/maxclients 512/" /etc/redis/redis.conf
usermod -a -G redis www-data || (echo -e "${c_red}Erreur quelque part ...$c_" && exit 1)
[[ ! -e /etc/sysctl.conf.bak ]] && cp /etc/sysctl.conf /etc/sysctl.conf.bak || echo "sysctl est déjà configuré, skip"
sed -i '$avm.overcommit_memory = 1' /etc/sysctl.conf
service redis-server restart || (echo -e "${c_red}Erreur quelque part ...$c_" && exit 1)
echo -e "${c_yellow} === Installing NextCloud... ===$c_"
if [[ ! -e /var/www/nextcloud ]]; then
mkdir /var/www/nextcloud
chown www-data:www-data /var/www/nextcloud
chmod 750 /var/www/nextcloud || (echo -e "${c_red}Erreur quelque part ...$c_" && exit 1)
wget https://download.nextcloud.com/server/releases/latest.tar.bz2
tar -xjf latest.tar.bz2 -C /var/www && chown -R www-data:www-data /var/www/ && rm -f latest.tar.bz2
fi
if [[ ! -e $data_dir ]]; then
mkdir -p $data_dir
chown www-data:www-data $data_dir
chmod 750 $data_dir || (echo -e "${c_red}Erreur quelque part ...$c_" && exit 1)
fi
## Add local IP as secondary trust domain
# Prefere occ methode ...
# sed -i "/0 => '$nc_domain'.*/a \ 1 => '$ip_local:$nc_port'," /var/www/nextcloud/config/config.php
ip_local=$(/sbin/ifconfig | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p')
[[ $nc_port == 80 ]] && nc_port_loc="" || nc_port_loc=":$nc_port"
[[ -e /var/www/nextcloud/config/config.php ]] && isNCConfig=$(cat /var/www/nextcloud/config/config.php | grep "'installed' => true")
[[ -z "$isNCConfig" ]] && sudo -u www-data php /var/www/nextcloud/occ maintenance:install --database "mysql" --database-name "nextcloud" --database-user "nextcloud" --database-pass "$db_pass" --admin-user "$admin_user" --admin-pass "$admin_pass" --data-dir "$data_dir"
sleep 0.2
sudo -u www-data php /var/www/nextcloud/occ config:system:set mysql.utf8mb4 --type boolean --value="true"
sudo -u www-data php /var/www/nextcloud/occ config:system:set trusted_domains 0 --value=$nc_domain
sudo -u www-data php /var/www/nextcloud/occ config:system:set trusted_domains 1 --value=$ip_local$nc_port_loc
sudo -u www-data php /var/www/nextcloud/occ config:system:set overwrite.cli.url --value=$nc_domain
isNCConfigAdd=$(cat /var/www/nextcloud/config/config.php | grep "activity_expire_days")
if [[ -z "$isNCConfigAdd" ]]; then
sudo -u www-data sed -i 's/^[ ]*//' /var/www/nextcloud/config/config.php
sudo -u www-data sed -i '/);/d' /var/www/nextcloud/config/config.php
cat config_complete.php >> /var/www/nextcloud/config/config.php
fi
sudo -u www-data sed -i "s/output_buffering=.*/output_buffering=0/" /var/www/nextcloud/.user.ini
sudo -u www-data php /var/www/nextcloud/occ app:disable survey_client
sudo -u www-data php /var/www/nextcloud/occ app:disable firstrunwizard
sudo -u www-data php /var/www/nextcloud/occ app:enable admin_audit
sudo -u www-data php /var/www/nextcloud/occ app:enable files_pdfviewer
echo -e "${c_yellow} === Configure nginx ... ===$c_"
cp nextcloud.conf /etc/nginx/conf.d/
cp *optimization.conf /etc/nginx/
sed -i "s/NC_DOMAIN/$nc_domain/" /etc/nginx/conf.d/nextcloud.conf
sed -i "s/NC_PORT/$nc_port/" /etc/nginx/conf.d/nextcloud.conf
sed -i "s/_PHPVERSION/$PHPVERSION/" /etc/nginx/conf.d/nextcloud.conf
sed -i "s/80 default_server;/81 default_server;/" /etc/nginx/sites-enabled/default
chmod u+x ../ssl.sh
if [[ $isSSL == "false" ]]; then
../ssl.sh nonssl
else
../ssl.sh certif
../ssl.sh ssl
fi
echo -e "${c_yellow} === Mise en place des scripts et crons ... ===$c_"
[[ ! -e /opt/scripts ]] && mkdir /opt/scripts
cp nc_optimize.sh /opt/scripts/
cp upgrade.sh /opt/scripts/
cp occ /opt/scripts/
echo "alias occ='/opt/scripts/occ'" >> ~/.bashrc
alias occ='/opt/scripts/occ'
[[ -z $(crontab -l | grep "/var/www/nextcloud/cron.php") ]] && (crontab -l ; echo "*/5 * * * * sudo -u www-data /usr/bin/php -f /var/www/nextcloud/cron.php > /dev/null 2>&1") | crontab -u root - || echo "cron nextcloud ever set, skip"
[[ -z $(crontab -l | grep "/opt/scripts/optimize.sh") ]] && (crontab -l ; echo "5 1 * * * /opt/scripts/optimize.sh > /dev/null 2>&1") | crontab -u root - || echo "cron optimize ever set, skip"
sudo -u www-data php /var/www/nextcloud/occ background:cron
sudo -u www-data php /var/www/nextcloud/occ db:add-missing-indices
sudo -u www-data php /var/www/nextcloud/occ db:convert-filecache-bigint
echo -e "${c_yellow} === Restarting services ... ===$c_"
service php$PHPVERSION-fpm restart && service nginx restart && service mysql restart && service redis-server restart || (echo -e "${c_red}Impossible de reloader les service$c_" && exit 1)
bash /opt/scripts/nc_optimize.sh
usermod -aG www-data $YOU
echo -e "${c_green}Nextcloud a été installé avec succès !\nOuverture...$c_"
URL="http://$nc_domain:$nc_port"
[[ -x $BROWSER ]] && su -c "exec \"$BROWSER\" \"$URL\"" $YOU > /dev/null
path=$(which xdg-open || which gnome-open) && su -c "exec \"$path\" \"$URL\"" $YOU > /dev/null
echo -e "${c_yellow}Can't find browser$c_"

69
.install/nextcloud/ssl.sh Executable file
View File

@ -0,0 +1,69 @@
#!/bin/bash
if [ "$EUID" -ne 0 ]
then echo "Veuillez executez ce script en root"
exit 1
fi
domain=$(cat /etc/nginx/conf.d/nextcloud.conf | grep server_name | awk '{ print $2 }')
domain=$(echo ${domain::-1})
[[ ! $1 =~ ^(ssl|nonssl|certif)$ ]] && echo "Veuillez choisir ssl, nonssl ou certif pour créer un certificat ssl" && exit 1
ssl(){
sed -i "s/'overwriteprotocol' => 'http'/'overwriteprotocol' => 'https'/" /var/www/nextcloud/config/config.php
sed -i "s/http/https/" /etc/nginx/conf.d/nextcloud.conf
sed -i "s/fastcgi_param HTTPS off/fastcgi_param HTTPS on/" /etc/nginx/conf.d/nextcloud.conf
sed -i "s/listen 443;/listen 443 ssl;/" /etc/nginx/conf.d/nextcloud.conf
[[ ! -e /etc/nginx/includes ]] && mkdir /etc/nginx/includes
cp .install_templates/ssl.conf /etc/nginx/includes/
sed -i "/fastcgi_hide_header X-Powered-By;/a \ include includes/ssl.conf;\n ssl_certificate /etc/letsencrypt/live/$domain/fullchain.pem;\n ssl_certificate_key /etc/letsencrypt/live/$domain/privkey.pem;" /etc/nginx/conf.d/nextcloud.conf
}
nonssl(){
sed -i "s/'overwriteprotocol' => 'https'/'overwriteprotocol' => 'http'/" /var/www/nextcloud/config/config.php
sed -i "s/https/http/" /etc/nginx/conf.d/nextcloud.conf
sed -i "s/fastcgi_param HTTPS on/fastcgi_param HTTPS off/" /etc/nginx/conf.d/nextcloud.conf
sed -i '/ssl.conf;/d' /etc/nginx/conf.d/nextcloud.conf
sed -i '/ssl_certificate/d' /etc/nginx/conf.d/nextcloud.conf
}
install_certbot(){
sudo apt update
if [[ $(grep buster /etc/os-release) ]]; then
[[ -z $(cat /etc/apt/sources.list | grep "buster-backports main") ]] && echo "deb http://deb.debian.org/debian buster-backports main" >> /etc/apt/sources.list
sudo apt install certbot python-certbot-nginx -t buster-backports -y
elif [[ $(grep stretch /etc/os-release) ]]; then
sudo apt install certbot python-certbot-nginx -y
elif [[ $(grep -E '16.|17.|18.|19.' /etc/os-release) ]]; then
sudo apt install software-properties-common
sudo add-apt-repository universe
sudo add-apt-repository ppa:certbot/certbot
sudo apt update
sudo apt install certbot python-certbot-nginx
else
echo "OS non supporté pour certbot." && exit 1
fi
}
create_certificate() {
cd .install_templates
certbot --nginx certonly --non-interactive --agree-tos -m $USER@$domain -d $domain && echo "Le certificat de $domain a bien été déployé" || echo "Une erreur s'est produite lors de la création du certificat SSL"
## Cronification
[[ ! -e /opt/scripts ]] && mkdir /opt/scripts
cp ssl_renew.sh /opt/scripts/
[[ -z $(crontab -l | grep "/opt/scripts/ssl_renew.sh") ]] && (crontab -l ; echo "12 2 * * 1 /opt/scripts/ssl_renew.sh") | crontab -u root -
}
certif() {
[[ -z $(which certbot) ]] && install_certbot
[[ -n /etc/letsencrypt/live/$domain/fullchain.pem ]] && create_certificate
}
$@
service nginx reload
exit 0

View File

@ -0,0 +1,52 @@
'activity_expire_days' => 14,
'auth.bruteforce.protection.enabled' => true,
'blacklisted_files' =>
array (
0 => '.htaccess',
1 => 'Thumbs.db',
2 => 'thumbs.db',
),
'cron_log' => true,
'enable_previews' => true,
'enabledPreviewProviders' =>
array (
0 => 'OC\\Preview\\PNG',
1 => 'OC\\Preview\\JPEG',
2 => 'OC\\Preview\\GIF',
3 => 'OC\\Preview\\BMP',
4 => 'OC\\Preview\\XBitmap',
5 => 'OC\\Preview\\Movie',
6 => 'OC\\Preview\\PDF',
7 => 'OC\\Preview\\MP3',
8 => 'OC\\Preview\\TXT',
9 => 'OC\\Preview\\MarkDown',
),
'filesystem_check_changes' => 0,
'filelocking.enabled' => 'true',
'htaccess.RewriteBase' => '/',
'integrity.check.disabled' => false,
'knowledgebaseenabled' => false,
'logfile' => '/var/log/nextcloud.log',
'loglevel' => 2,
'logtimezone' => 'Europe/Paris',
'log_rotate_size' => 104857600,
'maintenance' => false,
'memcache.local' => '\\OC\\Memcache\\APCu',
'memcache.locking' => '\\OC\\Memcache\\Redis',
'overwriteprotocol' => 'https',
'preview_max_x' => 1024,
'preview_max_y' => 768,
'preview_max_scale_factor' => 1,
'redis' =>
array (
'host' => '/var/run/redis/redis-server.sock',
'port' => 0,
'timeout' => 0.0,
),
'quota_include_external_storage' => false,
'share_folder' => '/Shares',
'skeletondirectory' => '',
'theme' => '',
'trashbin_retention_obligation' => 'auto, 7',
'updater.release.channel' => 'stable',
);

View File

@ -0,0 +1,50 @@
cp /etc/php/$PHPVERSION/fpm/pool.d/www.conf /etc/php/$PHPVERSION/fpm/pool.d/www.conf.bak
cp /etc/php/$PHPVERSION/cli/php.ini /etc/php/$PHPVERSION/cli/php.ini.bak
cp /etc/php/$PHPVERSION/fpm/php.ini /etc/php/$PHPVERSION/fpm/php.ini.bak
cp /etc/php/$PHPVERSION/fpm/php-fpm.conf /etc/php/$PHPVERSION/fpm/php-fpm.conf.bak
sed -i "s/;env\[HOSTNAME\] = /env[HOSTNAME] = /" /etc/php/$PHPVERSION/fpm/pool.d/www.conf
sed -i "s/;env\[TMP\] = /env[TMP] = /" /etc/php/$PHPVERSION/fpm/pool.d/www.conf
sed -i "s/;env\[TMPDIR\] = /env[TMPDIR] = /" /etc/php/$PHPVERSION/fpm/pool.d/www.conf
sed -i "s/;env\[TEMP\] = /env[TEMP] = /" /etc/php/$PHPVERSION/fpm/pool.d/www.conf
sed -i "s/;env\[PATH\] = /env[PATH] = /" /etc/php/$PHPVERSION/fpm/pool.d/www.conf
sed -i "s/pm.max_children = .*/pm.max_children = 240/" /etc/php/$PHPVERSION/fpm/pool.d/www.conf
sed -i "s/pm.start_servers = .*/pm.start_servers = 20/" /etc/php/$PHPVERSION/fpm/pool.d/www.conf
sed -i "s/pm.min_spare_servers = .*/pm.min_spare_servers = 10/" /etc/php/$PHPVERSION/fpm/pool.d/www.conf
sed -i "s/pm.max_spare_servers = .*/pm.max_spare_servers = 20/" /etc/php/$PHPVERSION/fpm/pool.d/www.conf
sed -i "s/;pm.max_requests = 500/pm.max_requests = 500/" /etc/php/$PHPVERSION/fpm/pool.d/www.conf
sed -i "s/output_buffering =.*/output_buffering = 'Off'/" /etc/php/$PHPVERSION/cli/php.ini
sed -i "s/max_execution_time =.*/max_execution_time = 1800/" /etc/php/$PHPVERSION/cli/php.ini
sed -i "s/max_input_time =.*/max_input_time = 3600/" /etc/php/$PHPVERSION/cli/php.ini
sed -i "s/post_max_size =.*/post_max_size = 10240M/" /etc/php/$PHPVERSION/cli/php.ini
sed -i "s/upload_max_filesize =.*/upload_max_filesize = 10240M/" /etc/php/$PHPVERSION/cli/php.ini
sed -i "s/max_file_uploads =.*/max_file_uploads = 100/" /etc/php/$PHPVERSION/cli/php.ini
sed -i "s/;date.timezone.*/date.timezone = Europe\/\Paris/" /etc/php/$PHPVERSION/cli/php.ini
## sed -i "s/;session.cookie_secure.*/session.cookie_secure = True/" /etc/php/$PHPVERSION/cli/php.ini # Bug if not using ssl
sed -i "s/memory_limit = 128M/memory_limit = 512M/" /etc/php/$PHPVERSION/fpm/php.ini
sed -i "s/output_buffering =.*/output_buffering = 'Off'/" /etc/php/$PHPVERSION/fpm/php.ini
sed -i "s/max_execution_time =.*/max_execution_time = 1800/" /etc/php/$PHPVERSION/fpm/php.ini
sed -i "s/max_input_time =.*/max_input_time = 3600/" /etc/php/$PHPVERSION/fpm/php.ini
sed -i "s/post_max_size =.*/post_max_size = 10240M/" /etc/php/$PHPVERSION/fpm/php.ini
sed -i "s/upload_max_filesize =.*/upload_max_filesize = 10240M/" /etc/php/$PHPVERSION/fpm/php.ini
sed -i "s/max_file_uploads =.*/max_file_uploads = 100/" /etc/php/$PHPVERSION/fpm/php.ini
sed -i "s/;date.timezone.*/date.timezone = Europe\/\Paris/" /etc/php/$PHPVERSION/fpm/php.ini
## sed -i "s/;session.cookie_secure.*/session.cookie_secure = True/" /etc/php/$PHPVERSION/fpm/php.ini # Bug if not using ssl
sed -i "s/;opcache.enable=.*/opcache.enable=1/" /etc/php/$PHPVERSION/fpm/php.ini
sed -i "s/;opcache.enable_cli=.*/opcache.enable_cli=1/" /etc/php/$PHPVERSION/fpm/php.ini
sed -i "s/;opcache.memory_consumption=.*/opcache.memory_consumption=128/" /etc/php/$PHPVERSION/fpm/php.ini
sed -i "s/;opcache.interned_strings_buffer=.*/opcache.interned_strings_buffer=8/" /etc/php/$PHPVERSION/fpm/php.ini
sed -i "s/;opcache.max_accelerated_files=.*/opcache.max_accelerated_files=10000/" /etc/php/$PHPVERSION/fpm/php.ini
sed -i "s/;opcache.revalidate_freq=.*/opcache.revalidate_freq=1/" /etc/php/$PHPVERSION/fpm/php.ini
sed -i "s/;opcache.save_comments=.*/opcache.save_comments=1/" /etc/php/$PHPVERSION/fpm/php.ini
sed -i "s/;emergency_restart_threshold =.*/emergency_restart_threshold = 10/" /etc/php/$PHPVERSION/fpm/php-fpm.conf
sed -i "s/;emergency_restart_interval =.*/emergency_restart_interval = 1m/" /etc/php/$PHPVERSION/fpm/php-fpm.conf
sed -i "s/;process_control_timeout =.*/process_control_timeout = 10s/" /etc/php/$PHPVERSION/fpm/php-fpm.conf
sed -i "s/09,39.*/# &/" /etc/cron.d/php
(crontab -l ; echo "09,39 * * * * /usr/lib/php/sessionclean 2>&1") | crontab -u root -
cp /etc/ImageMagick-6/policy.xml /etc/ImageMagick-6/policy.xml.bak
sed -i "s/rights\=\"none\" pattern\=\"PS\"/rights\=\"read\|write\" pattern\=\"PS\"/" /etc/ImageMagick-6/policy.xml
sed -i "s/rights\=\"none\" pattern\=\"EPI\"/rights\=\"read\|write\" pattern\=\"EPI\"/" /etc/ImageMagick-6/policy.xml
sed -i "s/rights\=\"none\" pattern\=\"PDF\"/rights\=\"read\|write\" pattern\=\"PDF\"/" /etc/ImageMagick-6/policy.xml
sed -i "s/rights\=\"none\" pattern\=\"XPS\"/rights\=\"read\|write\" pattern\=\"XPS\"/" /etc/ImageMagick-6/policy.xml
service php$PHPVERSION-fpm restart && service nginx restart

View File

@ -0,0 +1,79 @@
[client]
default-character-set = utf8mb4
port = 3306
socket = /var/run/mysqld/mysqld.sock
[mysqld_safe]
log_error=/var/log/mysql/mysql_error.log
nice = 0
socket = /var/run/mysqld/mysqld.sock
[mysqld]
basedir = /usr
bind-address = 127.0.0.1
binlog_format = ROW
bulk_insert_buffer_size = 16M
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci
concurrent_insert = 2
connect_timeout = 5
datadir = /var/lib/mysql
default_storage_engine = InnoDB
expire_logs_days = 10
general_log_file = /var/log/mysql/mysql.log
general_log = 0
innodb_buffer_pool_size = 1024M
innodb_buffer_pool_instances = 1
innodb_flush_log_at_trx_commit = 2
innodb_log_buffer_size = 32M
innodb_max_dirty_pages_pct = 90
innodb_large_prefix = on
innodb_file_format = barracuda
innodb_file_per_table = 1
innodb_open_files = 400
innodb_io_capacity = 4000
innodb_flush_method = O_DIRECT
key_buffer_size = 128M
lc_messages_dir = /usr/share/mysql
lc_messages = en_US
log_bin = /var/log/mysql/mariadb-bin
log_bin_index = /var/log/mysql/mariadb-bin.index
log_error=/var/log/mysql/mysql_error.log
log_slow_verbosity = query_plan
log_warnings = 2
long_query_time = 1
max_allowed_packet = 16M
max_binlog_size = 100M
max_connections = 200
max_heap_table_size = 64M
myisam_recover_options = BACKUP
myisam_sort_buffer_size = 512M
port = 3306
pid-file = /var/run/mysqld/mysqld.pid
query_cache_limit = 2M
query_cache_size = 64M
query_cache_type = 1
query_cache_min_res_unit = 2k
read_buffer_size = 2M
read_rnd_buffer_size = 1M
skip-external-locking
skip-name-resolve
slow_query_log_file = /var/log/mysql/mariadb-slow.log
slow-query-log = 1
socket = /var/run/mysqld/mysqld.sock
sort_buffer_size = 4M
table_open_cache = 400
thread_cache_size = 128
tmp_table_size = 64M
tmpdir = /tmp
transaction_isolation = READ-COMMITTED
user = mysql
wait_timeout = 600
[mysqldump]
max_allowed_packet = 16M
quick
quote-names
[isamchk]
key_buffer = 16M

View File

@ -0,0 +1,10 @@
#!/bin/bash
redis-cli -s /var/run/redis/redis-server.sock <<EOF
FLUSHALL
quit
EOF
sudo -u www-data php /var/www/nextcloud/occ files:scan --all
sudo -u www-data php /var/www/nextcloud/occ files:scan-app-data
exit 0

View File

@ -0,0 +1,149 @@
upstream php-handler {
server unix:/var/run/php/php_PHPVERSION-fpm.sock;
}
server {
listen NC_PORT;
listen 443;
listen [::]:443 ssl;
server_name NC_DOMAIN;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header X-Robots-Tag none;
add_header X-Download-Options noopen;
add_header X-Permitted-Cross-Domain-Policies none;
add_header Referrer-Policy no-referrer;
set_real_ip_from 192.168.9.1;
set_real_ip_from 192.168.9.6;
# Remove X-Powered-By, which is an information leak
fastcgi_hide_header X-Powered-By;
add_header X-Frame-Options "SAMEORIGIN";
# Path to the root of your installation
root /var/www/nextcloud/;
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
# The following 2 rules are only needed for the user_webfinger app.
# Uncomment it if you're planning to use this app.
#rewrite ^/.well-known/host-meta /public.php?service=host-meta last;
#rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json
# last;
location = /.well-known/carddav {
return 301 https://$host/remote.php/dav;
}
location = /.well-known/caldav {
return 301 https://$host/remote.php/dav;
}
# set max upload size
client_max_body_size 512M;
fastcgi_buffers 64 4K;
# Enable gzip but do not remove ETag headers
gzip on;
gzip_vary on;
gzip_comp_level 4;
gzip_min_length 256;
gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
# Uncomment if your server is build with the ngx_pagespeed module
# This module is currently not supported.
#pagespeed off;
location / {
rewrite ^ /index.php;
}
location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)/ {
deny all;
}
location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) {
deny all;
}
location ~ ^\/(?:index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+)\.php(?:$|\/) {
fastcgi_split_path_info ^(.+?\.php)(\/.*|)$;
try_files $fastcgi_script_name =404;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param HTTPS on;
# Avoid sending the security headers twice
fastcgi_param modHeadersAvailable true;
# Enable pretty urls
fastcgi_param front_controller_active true;
fastcgi_pass php-handler;
fastcgi_intercept_errors on;
fastcgi_request_buffering off;
}
location ~ ^\/(?:updater|oc[ms]-provider)(?:$|\/) {
try_files $uri/ =404;
index index.php;
}
# Adding the cache control header for js and css files
# Make sure it is BELOW the PHP block
location ~ \.(?:css|js|woff2?|svg|gif)$ {
try_files $uri /index.php$request_uri;
add_header Cache-Control "public, max-age=15778463";
# Add headers to serve security related headers (It is intended to
# have those duplicated to the ones above)
# Before enabling Strict-Transport-Security headers please read into
# this topic first.
# add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;";
#
# WARNING: Only add the preload option once you read about
# the consequences in https://hstspreload.org/. This option
# will add the domain to a hardcoded list that is shipped
# in all major browsers and getting removed from this list
# could take several months.
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header X-Robots-Tag none;
add_header X-Download-Options noopen;
add_header X-Permitted-Cross-Domain-Policies none;
add_header Referrer-Policy no-referrer;
# Optional: Don't log access to assets
access_log off;
}
location ~ \.(?:png|html|ttf|ico|jpg|jpeg)$ {
try_files $uri /index.php$request_uri;
# Optional: Don't log access to other assets
access_log off;
}
location ^~ /apps/rainloop/app/data {
deny all;
}
location ~ \.(?:flv|mp4|mov|m4a)$ {
# mp4;
# mp4_buffer_size 100M;
# mp4_max_buffer_size 1024M;
fastcgi_split_path_info ^(.+?.php)(\/.*|)$;
include fastcgi_params;
include php_optimization.conf;
fastcgi_pass php-handler;
fastcgi_param HTTPS on;
}
location ~ ^\/nextcloud/(?:updater|oc[ms]-provider)(?:$|\/) {
try_files $uri/ =404;
index index.php;
}
}

View File

@ -0,0 +1,6 @@
#/bin/bash
sudo -u www-data php /var/www/nextcloud/occ $@
exit 0

View File

@ -0,0 +1,17 @@
fastcgi_hide_header X-Powered-By;
fastcgi_read_timeout 3600;
fastcgi_send_timeout 3600;
fastcgi_connect_timeout 3600;
fastcgi_buffers 64 64K;
fastcgi_buffer_size 256k;
fastcgi_busy_buffers_size 3840K;
fastcgi_cache_key $http_cookie$request_method$host$request_uri;
fastcgi_cache_use_stale error timeout invalid_header http_500;
fastcgi_ignore_headers Cache-Control Expires Set-Cookie;
gzip on;
gzip_vary on;
gzip_comp_level 4;
gzip_min_length 256;
gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
gzip_disable "MSIE [1-6]\.";

View File

@ -0,0 +1,8 @@
#!/bin/bash
find /var/www/ -type f -print0 | xargs -0 chmod 0640
find /var/www/ -type d -print0 | xargs -0 chmod 0750
chown -R www-data:www-data /var/www/
chown -R www-data:www-data /var/nextcloud/
chmod 0644 /var/www/nextcloud/.htaccess
chmod 0644 /var/www/nextcloud/.user.ini
exit 0

View File

@ -0,0 +1,9 @@
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param modHeadersAvailable true;
fastcgi_param front_controller_active true;
fastcgi_intercept_errors on;
fastcgi_request_buffering off;
fastcgi_cache_valid 404 1m;
fastcgi_cache_valid any 1h;
fastcgi_cache_methods GET HEAD;

View File

@ -0,0 +1,16 @@
ssl_session_timeout 4h;
ssl_session_cache shared:SSL:50m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-CBC-SHA:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';
ssl_prefer_server_ciphers on;
add_header Strict-Transport-Security max-age=15768000;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=86400;
resolver_timeout 10;
ssl_session_tickets on;

View File

@ -0,0 +1,26 @@
#!/bin/bash
log="/var/log/ssl_renew.log"
date=$(date +%d-%m-%Y)
renew=$(certbot renew --pre-hook "service nginx stop" --post-hook "service nginx start")
echo "####################################################################################" >> $log
echo "#################################### $date ####################################" >> $log
echo "####################################################################################" >> $log
echo "$renew" >> $log
if [[ $renew = *"No hooks were run"* ]]; then
echo "Rien n'a été fait" >> $log
else
sleep 5
/etc/init.d/nginx stop
sleep 1
killall nginx
sleep 3
/etc/init.d/nginx restart &>> $log
echo "Des certificats ont été renouvellés" >> $log
fi
exit 0

View File

@ -0,0 +1,15 @@
#!/bin/bash
/usr/sbin/service nginx stop
sudo -u www-data php /var/www/nextcloud/updater/updater.phar
sudo -u www-data php /var/www/nextcloud/occ status
sudo -u www-data php /var/www/nextcloud/occ -V
sudo -u www-data php /var/www/nextcloud/occ db:add-missing-indices
sudo -u www-data php /var/www/nextcloud/occ db:convert-filecache-bigint
sudo -u www-data sed -i "s/output_buffering=.*/output_buffering=O/" /var/www/nextcloud/.user.ini
sudo -u www-data php /var/www/nextcloud/occ update:check
sudo -u www-data php /var/www/nextcloud/occ app:update --all
/usr/sbin/service php7.3-fpm restart
/usr/sbin/service nginx restart
exit 0

130
.install/scuttlebutt.sh Executable file
View File

@ -0,0 +1,130 @@
#!/bin/bash
scuttlebutt() {
echo -e "${c_yellow}Onboarding SCUTTLEBUTT...$c_"
where_is_ssb_installed=$(which ssb-server)
where_is_oasis_installed=$(which oasis)
mkdir -p ~/.zen
BASE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
if [[ ! $where_is_ssb_installed ]]; then
# KILL the BRUTAL WAY...
kill -9 $(ps auxf --sort=+utime | grep -w ssb-server| grep -v -E 'color=auto|grep' | tail -n 1 | awk '{print $2}')
# Install dependencies
sudo apt-get install -y socat python3-dev libtool python3-setuptools autoconf automake
# Install nvm
if [[ ! $(which nvm) ]]; then
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.2/install.sh | bash
source ~/.bashrc
export NVM_DIR="$HOME/.nvm"
nvm install --lts
fi
cd ~/.ssb
### Install module
npm install -g sodium-native ssb-backlinks ssb-ws ssb-links ssb-query ssb-secret-blob ssb-private
npm install -g ssb-server
# TODO plugin activation !??
# sbot plugins.enable
### Install oasis & ssb-cli (could replace ssb-server?? TODO: try it)
npm -g install fraction/oasis#semver:
npm install -g fraction/ssb-daemon
# npm install -g ssb-cli
# INSTALL sbotc
if [[ ! $(which sbotc) ]]; then
sudo apt install libsodium-dev jq -y
git submodule add https://git.scuttlebot.io/%25133ulDgs%2FoC1DXjoK04vDFy6DgVBB%2FZok15YJmuhD5Q%3D.sha256 sbotc
cd sbotc
make
sudo make install
fi
fi
# TEST ssb-server Install
ssbSERVER=$(which ssb-server)
[[ $ssbSERVER == "" ]] && echo "Check your ssb-server install... Cannot find it !!" && exit 1
# If exists backup ~/.ssb to ~/.ssb_$USER SSB (one time only !)
[[ -d ~/.ssb_$USER ]] && echo "BACKUP already existing... ~/.ssb_$USER !!! Manual check please..." && exit 1
[[ -d ~/.ssb ]] && [[ ! -d ~/.ssb_$USER ]] && mv ~/.ssb ~/.ssb_$USER
# CREATE ~/.ssb_astroport
[[ ! -d ~/.ssb_astroport ]] && mkdir -p ~/.ssb_astroport && cd ~/.ssb_astroport
# if exists, keep ~/.ssb_$USER/secret*
[[ ! -f ~/.ssb_astroport/secret ]] && [[ -f ~/.ssb_$USER/secret ]] && cp -f ~/.ssb_$USER/secret* ~/.ssb_astroport/
# Symlink ~/.ssb -> ~/.ssb_astroport
[[ -L ~/.ssb ]] && rm ~/.ssb
[[ -d ~/.ssb_astroport ]] && ln -s ~/.ssb_astroport ~/.ssb
## #TODO get ~/.ssb/manifest.json from template
cp ./templates/ssb/manifest.json ~/.ssb/manifest.json
# Create config (TODO: adapt if public Pub or Local Node)
# TODO: Create unique hostname in swarm !! uidna
nodename=$(cat /etc/hostname)
extension=$(echo $nodename | cut -d '.' -f 2)
if [[ $extension == $nodename ]]; then
PUB="false"
nodename=$nodename.local
else
PUB="true"
fi
cat > ~/.ssb/config <<EOF
{
"connections": {
"incoming": {
"net": [
{ "scope": "public", "host": "0.0.0.0", "external": ["$nodename"], "transform": "shs", "port": 8008 }
],
"ws": [
{ "scope": ["public", "local", "device"], "host": "0.0.0.0", "port": 8989, "transform": "shs", "http": true }
]
},
"outgoing": {
"net": [{ "transform": "shs" }]
}
}
}
EOF
cat > ~/.zen/launch-oasis.sh <<EOF
#!/bin/bash
oasis --allow-host $nodename --host $nodename
EOF
echo "
_ __ __ _
_ _ .__|_o _ (_ (_ |_)
(_(_)| || |(_| __)__)|_)
_|
$nodename
"
echo '
__ _ _ _ _
(_ |_|_)\ /|_|_) o._ o_|_
__)|_| \ \/ |_| \ || || |_ ... SCUTTLEBUTT ... OK?
'
echo "Launching oasis"
oasis --allow-host $nodename --host $nodename &
echo " http://$nodename:3000 "
echo
echo "ADD ~/.zen/launch-oasis.sh TO YOUR '/etc/rc.local' !!! Or use patchwork. "
sleep $((1 + RANDOM % 5))
echo "LAUNCHING OASIS NODE MANAGER http://$nodename:3000"
echo "IF YOU ARE A PUB consider protect it behind password nginx redirect !!!"
echo "3 seconds before ssb_INIT.sh..."
sleep 3
$MY_PATH/zen/ssb_INIT.sh
}
$@

66
.install/silkaj-php-mysql.sh Executable file
View File

@ -0,0 +1,66 @@
#!/bin/bash
###########################################
echo "NO READY TO USE. REWRITING..." && exit 1
###########################################
MY_PATH="`dirname \"$0\"`" # relative
MY_PATH="`( cd \"$MY_PATH\" && pwd )`" # absolutized and normalized
OS=$(head -n1 $MY_PATH/.OS)
isARM=$(cat $MY_PATH/.OS | grep YES)
unset err
# Basics
sudo apt update
echo -e "${c_yellow}Mise à jours des prérequis...$c_"
sudo apt install curl jq zip unzip htop tree ntpdate gnupg mpack imagemagick qrencode build-essential base58 bc -y
# Silkaj + Duniterpy
silkaj() {
echo -e "${c_yellow}Installation de Silkaj...$c_"
libsodium=$(sudo apt-cache search libsodium 2>/dev/null | grep -v -E "header|debug symbols" | grep "Network communication" -B1 | head -n1 | awk -F '-' '{ print $1 }')
[[ $libsodium =~ " " ]] && libsodium=$(echo $libsodium | awk '{ print $2 }')
sudo apt install libsodium-dev libssl-dev libffi-dev python3-pip python3-wheel $libsodium -y || err+="Install python3 and $libsodium"
pip3 install duniterpy || err+="Install duniterpy"
pip3 install silkaj --user || err+="Install Silkaj"
source .profile ## PATH="$HOME/.local/bin:$PATH"
}
# Install PHP + MySQL (TODO: REWRITE!!)
php() {
echo -e "${c_yellow}Installation de PHP et MySQL$c_"
if [[ $OS == "buster" ]]; then
sudo apt -y install software-properties-common nginx php php-common php-fpm php-gettext php-gd php-mysql php-curl php-imap php-mbstring php-xml php-cli mariadb-server || err+="Install PHP and MySQL"
elif [[ $OS == "stretch" ]]; then
sudo apt -y install lsb-release apt-transport-https ca-certificates || err+="Install apt-transport-https"
sudo wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg || err+="Download PHP key"
echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/php7.3.list
sudo apt update
sudo apt -y install software-properties-common dirmngr nginx php7.3 php7.3-common php7.3-gettext php7.3-fpm php7.3-gd php7.3-mysql php7.3-curl php7.3-imap php7.3-mbstring php7.3-xml php7.3-cli mariadb-server || err+="Install PHP and MySQL"
else
echo "${c_red}Votre système n'est pas pris en charge par ce script d'installation.$c_"
exit 1
fi
isLocalhostUsers=$(sudo mysql -e "select user from mysql.user;" | grep "localhost")
isTestDB=$(sudo mysql -e "show databases" | grep "test")
[[ -n $isLocalhostUsers ]] && sudo mysql -e "DROP USER ''@'localhost'; DROP USER ''@'$(hostname)'"
[[ -n $isTestDB ]] && sudo mysql -e "DROP DATABASE test"
sudo mysql -e "FLUSH PRIVILEGES"
}
# Read arguments
for i in $@; do
echo -e "${c_yellow}Installation de $c_light$i$c_"
$i
done
if [[ $err ]]; then
echo -e "${c_red}Installation des prérequis incomplète: $err$c_"
exit 1
else
echo -e "${c_green}Les prérequis ont été correctement installés$c_"
exit 0
fi

View File

@ -0,0 +1,7 @@
{
"plugins": {
"ssb-private": true,
"ssb-backlinks": true,
"patchfoo": true
}
}

65
.install/ssb-patchfoo/install Executable file
View File

@ -0,0 +1,65 @@
#!/usr/bin/env bash
# shellcheck disable=SC1091
true
VERSION="TO-V0.5"
BASE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
CURRENT_DIR="$(pwd)"
# Install node.js shared module
# shellcheck source=../shared/node.js/install
source "$BASE_DIR/../shared/node.js/install"
# Make folder if service did not
mkdir -p ~/.ssb/node_modules || true
# shellcheck disable=SC2164
cd ~/.ssb/node_modules
# Install dependencies
npm install --unsafe-perm asyncmemo hashlru pull-stream pull-cat multicb hyperscript pull-paramap ssb-contact ssb-sort stream-to-pull-stream emoji-server pull-paginate ssb-mentions busboy mime-types pull-identify-filetype human-time pull-hyperscript jpeg-autorotate pull-catch diff pull-split pull-utf8-decoder ssb-web-resolver highlight.js pull-box-stream base64-url ssb-backlinks ssb-private
# Install patchfoo and enable plugin
git clone https://github.com/tomeshnet/patchfoo.git patchfoo
(
# shellcheck disable=SC2164
cd patchfoo
git checkout ${VERSION}
)
# Replace ssb-server plugins.install with a static config file
# This will prevent the installation of these modules a second time
# and compiling downlevel for a 3rd time
cp "$BASE_DIR/config" ~/.ssb
#ssb-server plugins.install ssb-private
#ssb-server plugins.install ssb-backlinks
#ssb-server plugins.enable patchfoo
# Stop ssb service to process plugin
sudo systemctl stop ssb
# Disable the git-ssb and npm-ssb prerequisite
# Comment out two lines in patchwork that create a prerequisite for git-ssb and npm-ssb
# but don't seem to serve any purpose. git-ssb and and npm-ssbis not available on npm
sed -i 's#var Git#//var Git#' patchfoo/lib/app.js patchfoo/lib/app.js
sed -i 's#this.git = new Git(this.sbot, this.config)#//this.git = new Git(this.sbot, this.config)#' patchfoo/lib/app.js
sed -i 's#var SsbNpmRegistry#//var SsbNpmRegistry#' patchfoo/lib/app.js patchfoo/lib/app.js
sed -i 's#this.serveSsbNpmRegistry = SsbNpmRegistry.respond(this.sbot, this.config)#//this.serveSsbNpmRegistry = SsbNpmRegistry.respond(this.sbot, this.config)#' patchfoo/lib/app.js
# Comment out line that breaks things
sed -i "s#h('input', {type: 'file', name: 'upload'})#//h('input', {type: 'file', name: 'upload'})#" patchfoo/lib/serve.js
# Start service again to start patchfoo
sudo systemctl start ssb
# Install nginx reverse proxy file
sudo cp "$BASE_DIR/ssb-patchfoo.conf" /etc/nginx/site-path-enabled/ssb-patchfoo.conf
# Add entry into nginx home screen
APP="<div class='app'><h2>Patch Foo</h2>Plain SSB web UI. <br/><a href='/patchfoo'>Go</a></div>"
sudo sed -i "s#<\!--APPLIST-->#$APP\n<\!--APPLIST-->#" "/var/www/html/index.html"
# shellcheck disable=SC2164
cd "$CURRENT_DIR"

View File

@ -0,0 +1,9 @@
location /patchfoo {
proxy_pass http://127.0.0.1:8027/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
sub_filter "=\"/" "=\"/patchfoo/";
sub_filter_once off;
}

74
.install/ssl.sh Executable file
View File

@ -0,0 +1,74 @@
#!/bin/bash
MY_PATH="`dirname \"$0\"`" # relative
MY_PATH="`( cd \"$MY_PATH\" && pwd )`" # absolutized and normalized
### Vars
args=$(echo $@ | tr " " "\n")
if [[ "$args" =~ "DOMAIN=" ]]; then
DOMAIN=$(echo "$args" | grep "\<DOMAIN=" | awk -F '=' '{ print $2 }')
else
echo "Veuillez sélectionner un domaine avec DOMAIN=mondommain.com"
exit 1
fi
if [[ "$args" =~ "APP=" ]]; then
APP=$(echo "$args" | grep "\<APP=" | awk -F '=' '{ print $2 }')
else
echo "Veuillez sélectionner une application avec APP=monapp"
exit 1
fi
action=$(echo "$args" | grep -v "=")
[[ ! $action =~ ^(on|off|certif)$ ]] && echo "Veuillez choisir on, off ou certif pour créer un certificat ssl" && exit 1
###
install_certbot(){
sudo apt update
if [[ $(grep -E 'stretch|buster' /etc/os-release) ]]; then
sudo apt install certbot python-certbot-nginx -y
elif [[ $(grep -E '16.|17.|18.|19.' /etc/os-release) ]]; then
sudo apt install software-properties-common
sudo add-apt-repository universe
sudo add-apt-repository ppa:certbot/certbot
sudo apt update
sudo apt install certbot python-certbot-nginx
else
echo "OS non supporté pour certbot." && exit 1
fi
}
create_certificate() {
sudo certbot --nginx certonly --non-interactive --agree-tos -m $USER@$DOMAIN -d $DOMAIN && echo "Le certificat de $DOMAIN a bien été déployé" || echo "Une erreur s'est produite lors de la création du certificat SSL"
## Cronification
[[ ! -e /opt/scripts ]] && sudo mkdir /opt/scripts
sudo cp $MY_PATH/templates/rproxy/ssl_renew.sh /opt/scripts/
[[ -z $(sudo crontab -l | grep "/opt/scripts/ssl_renew.sh") ]] && (sudo crontab -l ; sudo echo "12 2 * * 1 /opt/scripts/ssl_renew.sh") | sudo crontab -u root -
}
case $action in
on)
sudo sed -i 's/ #if/ if/g' /etc/nginx/conf.d/$APP.conf
sudo sed -i 's/ #add/ add/g' /etc/nginx/conf.d/$APP.conf
sudo sed -i "s/listen 443;/listen 443 ssl;/g" /etc/nginx/conf.d/$APP.conf
[[ ! -d /etc/nginx/includes ]] && sudo mkdir /etc/nginx/includes
sudo cp $MY_PATH/templates/rproxy/ssl.conf /etc/nginx/includes/
sudo sed -i "/Content-Security-Policy/a \ include includes/ssl.conf;\n ssl_certificate /etc/letsencrypt/live/$DOMAIN/fullchain.pem;\n ssl_certificate_key /etc/letsencrypt/live/$DOMAIN/privkey.pem;" /etc/nginx/conf.d/$APP.conf
;;
off)
sudo sed -i "s/ if/ #if/g" /etc/nginx/conf.d/$APP.conf
sudo sed -i "s/ add/ #add/g" /etc/nginx/conf.d/$APP.conf
sudo sed -i "/ssl.conf;/d" /etc/nginx/conf.d/$APP.conf
sudo sed -i "/ssl_certificate/d" /etc/nginx/conf.d/$APP.conf
;;
certif)
[[ ! $(which certbot) ]] && install_certbot
if sudo test ! -f /etc/letsencrypt/live/$DOMAIN/fullchain.pem; then create_certificate; fi
;;
esac

37
.install/sys_checkOS.sh Executable file
View File

@ -0,0 +1,37 @@
#!/bin/bash
astroVars="OS ARM YOU ipfsnodeid ASTROZEN ASTRONODE myProfile"
export YOU=$(ps auxf --sort=+utime | grep -w ipfs | grep -v -E 'color=auto|grep' | tail -n 1 | cut -d " " -f 1)
export ipfsnodeid=$(ipfs id -f='<id>\n')
export ASTROZEN="/home/$YOU/.zen"
export ASTRONODE="$ASTROZEN/ipfs/.$ipfsnodeid"
export myProfile="$ASTRONODE/profile"
[[ ! -d $ASTRONODE ]] && mkdir -p $ASTRONODE
## Check system kind
[[ $(uname -a | grep arm) ]] && export ARM=yes || unset ARM
if [[ $(grep -E '19.3|19.4' /etc/os-release) ]]; then export OS=buster;
elif [[ $(grep -E 'stretch|18.|19.' /etc/os-release) ]]; then export OS=stretch;
else export OS=buster;
fi
[[ -e $myProfile ]] && rm $myProfile
touch $myProfile
for i in $astroVars; do
[[ ! $(grep "$i=" $myProfile) && -n ${!i} ]] && echo "export $i=${!i}" >> $myProfile
done
# Export for user
[[ -n $(grep "/.zen/ipfs/" ~/.bashrc) ]] && sed -i -n '/\/.zen\/ipfs/!p' ~/.bashrc
[[ -n $(grep "# ASTROPORT " ~/.bashrc) ]] && sed -i -n '/# ASTROPORT /!p' ~/.bashrc
echo -e "# ASTROPORT ENVIRONMENT VARIABLE\n. /home/$YOU/.zen/ipfs/.$ipfsnodeid/profile" >> ~/.bashrc
# Export for root (obsolete)
#[[ -n $(sudo grep "/.zen/ipfs/" /root/.bashrc) ]] && sudo sed -i -n '/\/.zen\/ipfs/!p' /root/.bashrc
#[[ -n $(sudo grep "# ASTROPORT " /root/.bashrc) ]] && sudo sed -i -n '/# ASTROPORT /!p' /root/.bashrc
#echo -e "# ASTROPORT ENVIRONMENT VARIABLE\n. /home/$YOU/.zen/ipfs/.$ipfsnodeid/profile" | sudo tee -a /root/.bashrc
[[ $1 != "noexec" ]] && exec bash

View File

@ -0,0 +1,36 @@
music_directory "/home/_USER_/.zen/audio"
playlist_directory "/home/_USER_/.zen/playlists"
user "_USER_"
bind_to_address "localhost"
auto_update "yes"
zeroconf_enabled "yes"
zeroconf_name "Astroport CopyLaRadio Jukebox"
connection_timeout "120"
filesystem_charset "UTF-8"
id3v1_encoding "UTF-8"
log_file "syslog"
###############################
audio_output {
type "pulse"
name "My Pulse Output"
server "127.0.0.1"
}
audio_output {
type "httpd"
name "CopyLaRadio HTTP Stream"
encoder "lame"
port "8000"
quality "5.0"
# bitrate "128"
format "44100:16:1"
}
audio_output {
type "fifo"
name "my pipe"
path "/tmp/snapfifo"
format "48000:16:2"
mixer_type "software"
}

View File

@ -0,0 +1,101 @@
#!/bin/sh
### BEGIN INIT INFO
# Provides: ipfs daemon
# Required-Start: $local_fs $remote_fs $network $syslog $named
# Required-Stop: $local_fs $remote_fs $network $syslog $named
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Starts the ipfs daemon
# Description: Starts the ipfs daemon using the start-stop-daemon
### END INIT INFO
# Author: Dylan Powers <dylan.kyle.powers@gmail.com
PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/bin
DESC="ipfs daemon"
NAME=ipfs
DAEMON=/usr/local/bin/ipfs
DAEMON_ARGS="daemon --enable-pubsub-experiment --enable-namesys-pubsub --enable-gc"
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME
IPFS_PATH=/home/xbian/.ipfs
IPFS_USER=xbian
# Exit if the package is not installed
[ -x "$DAEMON" ] || exit 0
# Read configuration variable file if it is present
[ -r /etc/default/$NAME ] && . /etc/default/$NAME
# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh
# Define LSB log_* functions.
# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
# and status_of_proc is working.
. /lib/lsb/init-functions
#
# Function that starts the daemon/service
#
do_start() {
# Return
# 0 if daemon has been started
# 1 if daemon was already running
# 2 if daemon could not be started
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test >/dev/null \
|| return 1
start-stop-daemon --start --quiet --pidfile $PIDFILE --make-pidfile \
--background --chuid $IPFS_USER --no-close \
--exec /usr/bin/env IPFS_PATH="$IPFS_PATH" $DAEMON 2>>/var/log/ipfs.log 1>/dev/null \
-- $DAEMON_ARGS \
|| return 2
}
#
# Function that stops the daemon/service
#
do_stop() {
# Return
# 0 if daemon has been stopped
# 1 if daemon was already stopped
# 2 if daemon could not be stopped
# other if a failure occurred
start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME
RETVAL="$?"
[ "$RETVAL" = 2 ] && return 2
# Delete the pid
rm -f $PIDFILE
return "$RETVAL"
}
case "$1" in
start)
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
do_start
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
stop)
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
do_stop
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
status)
status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
;;
restart)
do_stop
do_start
;;
*)
echo "Usage: $SCRIPTNAME {start|stop|status|restart}" >&2
exit 3
;;
esac

View File

@ -0,0 +1,11 @@
[Unit]
Description=IPFS daemon
After=network.target
[Service]
User=_USER
ExecStart=/usr/local/bin/ipfs daemon --enable-pubsub-experiment --enable-namesys-pubsub --routing=dhtclient --enable-gc
Restart=on-failure
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,28 @@
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name _;
location /g1billet {
proxy_pass http://127.0.0.1:9980;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
location /ipfs {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
location /ipns {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
}

View File

@ -0,0 +1,14 @@
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 100m;
client_body_buffer_size 128k;
client_header_buffer_size 64k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 16k;
proxy_buffers 32 16k;
proxy_busy_buffers_size 64k;

View File

@ -0,0 +1,118 @@
{
"auth": "async",
"address": "sync",
"manifest": "sync",
"multiserver": {
"parse": "sync",
"address": "sync"
},
"multiserverNet": {},
"get": "async",
"createFeedStream": "source",
"createLogStream": "source",
"messagesByType": "source",
"createHistoryStream": "source",
"createUserStream": "source",
"createWriteStream": "sink",
"links": "source",
"add": "async",
"publish": "async",
"getAddress": "sync",
"getLatest": "async",
"latest": "source",
"latestSequence": "async",
"whoami": "sync",
"progress": "sync",
"status": "sync",
"getVectorClock": "async",
"version": "sync",
"help": "sync",
"seq": "async",
"usage": "sync",
"clock": "async",
"plugins": {
"install": "source",
"uninstall": "source",
"enable": "async",
"disable": "async",
"help": "sync"
},
"gossip": {
"add": "sync",
"remove": "sync",
"connect": "async",
"disconnect": "async",
"changes": "source",
"reconnect": "sync",
"disable": "sync",
"enable": "sync",
"ping": "duplex",
"get": "sync",
"peers": "sync",
"help": "sync"
},
"replicate": {
"changes": "source",
"upto": "source",
"request": "sync",
"block": "sync"
},
"friends": {
"hopStream": "source",
"onEdge": "sync",
"isFollowing": "async",
"isBlocking": "async",
"hops": "async",
"help": "sync",
"get": "async",
"createFriendStream": "source",
"stream": "source"
},
"blobs": {
"get": "source",
"getSlice": "source",
"add": "sink",
"rm": "async",
"ls": "source",
"has": "async",
"size": "async",
"meta": "async",
"want": "async",
"push": "async",
"changes": "source",
"createWants": "source",
"help": "sync"
},
"backlinks": {
"read": "source"
},
"invite": {
"create": "async",
"use": "async",
"accept": "async"
},
"query": {
"read": "source",
"explain": "sync",
"help": "sync"
},
"search": {
"query": "source",
"help": "sync"
},
"links2": {
"read": "source"
},
"ws": {},
"ebt": {
"replicate": "duplex",
"request": "sync",
"block": "sync",
"peerStatus": "sync"
},
"ooo": {
"stream": "duplex",
"get": "async",
"help": "sync"
}
}

34
.install/update_bashrc.sh Executable file
View File

@ -0,0 +1,34 @@
#!/bin/bash
########################################################################
# Author: Fred (support@qo-op.com)
# Version: 2020.12.06
# License: AGPL-3.0 (https://choosealicense.com/licenses/agpl-3.0/)
########################################################################
# update_bashrc.sh
# Add $YOU $IPFSNODEID $G1PUB to ~/.bashrc
source ~/.bashrc
[[ $YOU != "" && $IPFSNODEID != "" && $G1PUB != "" ]] && er+="bashrc already updated"
YOU=$(ps auxf --sort=+utime | grep -w ipfs | grep -v -E 'color=auto|grep' | tail -n 1 | cut -d " " -f 1) || er+=" ipfs daemon not running"
IPFSNODEID=$(ipfs id -f='<id>\n') || er+=" ipfs id problem"
[[ -f ~/.zen/secret.dunikey ]] && G1PUB=$(cat ~/.zen/secret.dunikey | grep 'pub:' | cut -d ' ' -f 2) || er+=" ~/.zen/secret.dunikey missing cannot find G1PUB"
[[ $er != "" ]] && echo "$er" && exit 1
echo "### ASTROPORT IDENTITY ###" >> ~/.bashrc
echo "YOU=$YOU" >> ~/.bashrc
echo "G1PUB=$G1PUB" >> ~/.bashrc
echo "IPFSNODEID=$IPFSNODEID" >> ~/.bashrc
## Add jaklis/.env ?
# cat ~/.zen/astroport/zen/jaklis/.env >> ~/.bashrc
source ~/.bashrc
echo "UPDATE ~/.bashrc OK"
tail -n 4 ~/.bashrc
exit 0

8
.install/youtube-dl.sh Executable file
View File

@ -0,0 +1,8 @@
#!/bin/bash
########################################################################
######## YOUTUBE-DL ##########
if [[ ! $(which youtube-dl) ]]; then
sudo wget https://yt-dl.org/downloads/latest/youtube-dl -O /usr/local/bin/youtube-dl || exit 1
sudo chmod a+rx /usr/local/bin/youtube-dl
sudo chown $USER /usr/local/bin/youtube-dl
fi

113
1stRUNconfig.sh Executable file
View File

@ -0,0 +1,113 @@
#!/bin/bash
########################################################################
# Author: Fred (support@qo-op.com)
# Version: 2020.12.04
# License: AGPL-3.0 (https://choosealicense.com/licenses/agpl-3.0/)
########################################################################
#
# This script is run from ~/.config/autostart/Astroport_X_config.desktop
#
########################################################################
# Create secret key files
# ~/.zen/secret.june
# ~/.zen/secret.dunikey
# ~/.zen/secret.ipfs & /tmp/config.ipfs
# ~/.zen/ipfs.sync
########################################################################
[[ $(which zenity) == "" ]] && echo "Please! sudo apt install zenity. EXIT" && exit 1
[[ -f ~/.zen/ipfs.sync ]] && echo "CONFIG ALREADY DONE" && source ~/.zen/ipfs.sync && exit 0
function cleanTMP
{
rm -f /tmp/secret.june /tmp/secret.dunikey /tmp/config.ipfs /tmp/secret.ipfs /tmp/secret.all
}
# NB: 2> >(grep -v 'GtkDialog' >&2) remove zenity console warning
zenity --question --width 300 --text "Initialiser votre station Astroport?" 2> >(grep -v 'GtkDialog' >&2)
[ $? == 1 ] && exit 1
########################################################################
# LOGIN (=SALT)
salt="$(~/.zen/astroport/zen/tools/diceware.sh 3 | xargs)"
# PASS (=PEPPER)
pepper="$(~/.zen/astroport/zen/tools/diceware.sh 3 | xargs)"
g1_profil=$(zenity --entry --width 300 --text "Nom de votre machine" --title "Astroport -- Profil" --entry-text="$(hostname)" 2> >(grep -v 'GtkDialog' >&2));
g1_salt=$(zenity --entry --width 300 --text "Identifiant gchange/cesium (sel)" --title "Astroport - Sel" --entry-text="$salt" 2> >(grep -v 'GtkDialog' >&2));
[ ${#g1_salt} -lt 8 ] && zenity --warning --width 300 --text "Identifiant doit faire plus de 8 caractères!!" 2> >(grep -v 'GtkDialog' >&2) && cleanTMP && exit 1
g1_pepper=$(zenity --entry --width 300 --text "Mot de passe gchange/cesium (poivre)" --title "Astroport - Poivre" --entry-text="$pepper" 2> >(grep -v 'GtkDialog' >&2));
echo "CREATING /tmp/secret.june"
echo "$g1_salt" > /tmp/secret.june
echo "$g1_pepper" >> /tmp/secret.june
echo "________________ https://gchange.fr ________________" > /tmp/secret.all
cat /tmp/secret.june >> /tmp/secret.all
########################################################################
echo "CREATING /tmp/secret.dunikey"
python3 ~/.zen/astroport/zen/tools/key_create_dunikey.py "$g1_salt" "$g1_pepper"
g1pub=$(cat /tmp/secret.dunikey | grep "pub" | cut -d ' ' -f 2)
g1sec=$(cat /tmp/secret.dunikey | grep "sec" | cut -d ' ' -f 2)
echo "" >> /tmp/secret.all
echo "_________________ https://cesium.app _______________" >> /tmp/secret.all
cat /tmp/secret.dunikey >> /tmp/secret.all
echo "" >> /tmp/secret.all
########################################################################
echo "CREATING /tmp/config.ipfs"
ipfs_ID=$(python3 ~/.zen/astroport/zen/tools/create_ipfsnodeid_from_tmp_secret.dunikey.py)
echo $ipfs_ID > /tmp/secret.ipfs && source /tmp/secret.ipfs
jq -r --arg PeerID "$PeerID" '.Identity.PeerID=$PeerID' ~/.ipfs/config > /tmp/config.tmp
jq -r --arg PrivKEY "$PrivKEY" '.Identity.PrivKey=$PrivKEY' /tmp/config.tmp > /tmp/config.ipfs
rm /tmp/config.tmp
echo "" >> /tmp/secret.all
echo "_____________________ IPFS ________________________" >> /tmp/secret.all
cat /tmp/secret.ipfs >> /tmp/secret.all
echo "" >> /tmp/secret.all
## Which directory to sync with IPFS
IPFS_sync_directory=$(zenity --file-selection --title="Choisissez le répertoire à partager par IPFS avec vos amis" --directory 2> >(grep -v 'GtkDialog' >&2))
[[ ! -d $IPFS_sync_directory ]] && zenity --warning --width 300 --text "Aucun répertoire... ANNULATION" 2> >(grep -v 'GtkDialog' >&2) && cleanTMP && exit 1
echo "IPFS_SYNC_DIR=$IPFS_sync_directory" >> /tmp/secret.all
########################################################################
echo "Copy new keys?"
zenity --width=971 --height=600 --title "Validation de votre configuration" --text-info --filename="/tmp/secret.all" 2> >(grep -v 'GtkDialog' >&2)
[ $? == 1 ] && cleanTMP && exit 1
[[ -f ~/.zen/secret.dunikey.old ]] && zenity --warning --width 300 --text "ANNULATION! Il existe déjà une sauvegarde d'anciennes clefs... support@qo-op.com" 2> >(grep -v 'GtkDialog' >&2) && cleanTMP && exit 1
mv ~/.zen/secret.june ~/.zen/secret.june.old
mv /tmp/secret.june ~/.zen/secret.june
mv ~/.zen/secret.dunikey ~/.zen/secret.dunikey.old
mv /tmp/secret.dunikey ~/.zen/secret.dunikey
mv ~/.zen/secret.ipfs ~/.zen/secret.ipfs.old
mv /tmp/secret.ipfs ~/.zen/secret.ipfs
mv ~/.ipfs/config ~/.ipfs/config.old
mv /tmp/config.ipfs ~/.ipfs/config
rm /tmp/secret.all
# WRITE ~/.zen/ipfs.sync CONFIG
echo "IPFS_SYNC_DIR=$IPFS_sync_directory" > ~/.zen/ipfs.sync
# CREATE gchange+ profile
# cd ~/.zen/astroport/zen/jaklis
# ./jaklis.py --key "~/.zen/secret.dunikey" --node "https://data.gchange.fr" set --name "$g1_profil" --avatar "~/.zen/astroport/logo.png"
# ERROR
echo "OK. Restart now"
zenity --warning --width 300 --text "Veuillez redémarrer l'ordinateur pour activer votre configuration..." 2> >(grep -v 'GtkDialog' >&2)
exit 0

204
ISOconfig.sh Executable file
View File

@ -0,0 +1,204 @@
#!/bin/bash
########################################################################
# Author: Fred (support@qo-op.com)
# Version: 2020.12.05
# License: AGPL-3.0 (https://choosealicense.com/licenses/agpl-3.0/)
########################################################################
# AUTOMATIC version of interactive 1stRUNconfig.sh
# This script can run from ~/.config/autostart/Astroport_X_config.desktop
#
########################################################################
# Create secret key files
# ~/.zen/secret.june
# ~/.zen/secret.dunikey
# ~/.zen/secret.ipfs & /tmp/config.ipfs
# ~/.zen/ipfs.sync
########################################################################
# CHECK IF CONFIG ALREADY DONE !! Remove ~/.zen/ipfs ~/.zen/secret ~/.zen/ipfs.sync
if [[ -f ~/.zen/ipfs.sync ]]; then
echo "CONFIG ALREADY DONE"
source ~/.zen/ipfs.sync
# NEW BOOT! SEND ipfstryme message to my friends...
cd ~/.zen/astroport/zen/jaklis
# GET LIST of issuer(s) who likes me
for liking_me in $(./jaklis.py like | jq -r '.likes[].issuer');
do
# CHECk if I am liking him either
friend_of_mine=$(./jaklis.py like -p $liking_me | jq -r '.yours');
echo "Sending IPFSTRYME message to $liking_me"
[[ $friend_of_mine != null ]] && ./jaklis.py send -d $liking_me -t "ipfstryme" -f ~/.zen/ipfs/.${IPFSNODEID}/tryme.addr
done
cd -
exit 0
fi
# CHECK INTERNET CONNECTIVITY !!
ping -q -w 1 -c 1 `ip r | grep default | cut -d ' ' -f 3` > /dev/null && echo ok || (echo "NO INTERNET CONNEXION" && exit 1)
########################################################################
########################################################################
echo "CREATING Gchange credentials"
########################################################################
salt="$(~/.zen/astroport/zen/tools/diceware.sh 3 | xargs)"
[[ $salt == "" ]] && echo "ERROR" && exit 1
pepper="$(~/.zen/astroport/zen/tools/diceware.sh 3 | xargs)"
g1_profil=$(hostname)
g1_salt="$salt"
g1_pepper="$pepper"
echo "CREATING /tmp/secret.june"
echo "$g1_salt" > /tmp/secret.june
echo "$g1_pepper" >> /tmp/secret.june
########################################################################
########################################################################
echo "CREATING /tmp/secret.dunikey"
########################################################################
python3 ~/.zen/astroport/zen/tools/key_create_dunikey.py "$g1_salt" "$g1_pepper"
g1pub=$(cat /tmp/secret.dunikey | grep "pub" | cut -d ' ' -f 2)
g1sec=$(cat /tmp/secret.dunikey | grep "sec" | cut -d ' ' -f 2)
########################################################################
########################################################################
echo "CREATING /tmp/config.ipfs"
########################################################################
ipfs_ID=$(python3 ~/.zen/astroport/zen/tools/create_ipfsnodeid_from_tmp_secret.dunikey.py)
echo $ipfs_ID > /tmp/secret.ipfs && source /tmp/secret.ipfs
[[ $PrivKEY == "" ]] && echo "ERROR" && exit 1
jq -r --arg PeerID "$PeerID" '.Identity.PeerID=$PeerID' ~/.ipfs/config > /tmp/config.tmp
jq -r --arg PrivKEY "$PrivKEY" '.Identity.PrivKey=$PrivKEY' /tmp/config.tmp > /tmp/config.ipfs
rm /tmp/config.tmp
#
IPFSNODEID=$PeerID
echo $IPFSNODEID
## Declare directory transfered in IPFS
IPFS_sync_directory="$HOME/astroport"
########################################################################
# INSTALL KEYS
########################################################################
mv ~/.zen/secret.june ~/.zen/secret.june.old
mv /tmp/secret.june ~/.zen/secret.june
mv ~/.zen/secret.dunikey ~/.zen/secret.dunikey.old
mv /tmp/secret.dunikey ~/.zen/secret.dunikey
mv ~/.zen/secret.ipfs ~/.zen/secret.ipfs.old
mv /tmp/secret.ipfs ~/.zen/secret.ipfs
mv ~/.ipfs/config ~/.ipfs/config.old
mv /tmp/config.ipfs ~/.ipfs/config
# WRITE ~/.zen/ipfs.sync CONFIG
echo "IPFS_SYNC_DIR=$IPFS_sync_directory" > ~/.zen/ipfs.sync
########################################################################
echo "INIT ~/.zen/ipfs/.${IPFSNODEID}"
########################################################################
rm -Rf ~/.zen/ipfs
mkdir -p ~/.zen/ipfs/.${IPFSNODEID}/G1SSB
########################################################################
# Give $XZUID to your (gchange friends) to add in Vstream Astroport and access your sharings
# IPNS link to "pastebin list" http://localhost:8080/ipns/$IPNSKEY/xbian/$XZUID
########################################################################
XZUID=$(~/.zen/astroport/zen/tools/diceware.sh 1 | xargs)-$(~/.zen/astroport/zen/tools/diceware.sh 1 | xargs)$(hostname -I | cut -d ' ' -f 1 | cut -d "." -f 4 )
echo "CREATE ~/.zen/ipfs/xbian/$XZUID"
touch ~/.zen/ipfs/xbian/$XZUID
# https://github.com/Kodi-vStream/venom-xbmc-addons/wiki/Voir-et-partager-sa-biblioth%C3%A8que-priv%C3%A9e#d%C3%A9clarer-des-films
echo "$XZUID" > ~/.zen/ipfs/.${IPFSNODEID}/_xbian.zuid
########################################################################
########################################################################
echo "CREATE gchange+ profile"
########################################################################
cd ~/.zen/astroport/zen/jaklis
./jaklis.py set --name "$XZUID" --avatar "$HOME/.zen/astroport/logo.png"
########################################################################
########################################################################
echo "BECOME FRIEND with oasis (1st bootstrap)"
########################################################################
./jaklis.py like -p 2jQUH4HfHxdTesjCjvMCx1VJgA5AnpuvrWRq1swfRdsS -s 5
########################################################################
echo "RESTART ipfs"
########################################################################
sudo service ipfs restart
echo ".... WAIT for SWARM to connect ..."
sleep 10
ipfs swarm peers
########################################################################
echo 'EXTEND ~/.bashrc'
########################################################################
~/.zen/astroport/.install/update_bashrc.sh
echo "Configure .kodi/addons/plugin.video.vstream/resources/sites/astroport.py"
cp -f ~/.zen/astroport/.install/.kodi/addons/plugin.video.vstream/resources/sites/astroport.py \
~/.kodi/addons/plugin.video.vstream/resources/sites/astroport.py
# CREATE xbian IPNSKEY used to publish ~/.zen/ipfs_swarm/xbian (contains all XZUID pastebin files)
ipfs key rm xbian
IPNSKEY=$(ipfs key gen xbian)
sed -i s/_IPNSKEY_/$IPNSKEY/g ~/.kodi/addons/plugin.video.vstream/resources/sites/astroport.py
sed -i s/_PROFIL_/$XZUID/g ~/.kodi/addons/plugin.video.vstream/resources/sites/astroport.py
sed -i s/_LOGIN_/$salt/g ~/.kodi/addons/plugin.video.vstream/resources/sites/astroport.py
sed -i s/_MDP_/$pepper/g ~/.kodi/addons/plugin.video.vstream/resources/sites/astroport.py
~/.zen/astroport/zen/gchange_IPFS_swarm.sh
~/.zen/astroport/zen/ipfs_SWARM_refresh.sh
# Optionnal PUBLISH actual (later done by cron_MINUTE.sh)
IXBIAN=$(ipfs add -qr ~/.zen/ipfs_swarm/xbian | tail -n 1)
JXBIAN=$(ipfs name publish -k xbian $I)
########################################################################
echo 'SEND "ipfstryme" message'
########################################################################
echo "" > ~/.zen/ipfs/.${IPFSNODEID}/tryme.addr # ERASE
for tryme in $(ipfs id | jq -r .Addresses[]);
do
isLAN=$(echo $tryme | cut -f3 -d '/' | grep -E "(^127\.)|(^192\.168\.)|(^fd42\:)|(^10\.)|(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|(^::1$)|(^[fF][cCdD])/")
[[ ! $isLAN && $tryme != "" ]] && echo "$tryme" >> ~/.zen/ipfs/.${IPFSNODEID}/tryme.addr && echo "$tryme"
done
echo 'SEND ipfstryme to oasis' # Add your bootstrap Pub here
./jaklis.py send -d 2jQUH4HfHxdTesjCjvMCx1VJgA5AnpuvrWRq1swfRdsS -t "ipfstryme" -f ~/.zen/ipfs/.${IPFSNODEID}/tryme.addr
########################################################################
echo 'INSTALL Astroport cron_MINUTE'
########################################################################
~/.zen/astroport/zen/tools/cron_VRFY.sh
# Run only once: comment /etc/rc.local (su - xbian -c "~/.zen/astroport/ISOconfig.sh")
# sudo sed -i s/su/\#su/g /etc/rc.local
# BETTER NOT: Send new 'ipfstryme' message on each boot is done instead
echo "CHANGE hostname"
sudo sed -i s/astrxbian/$XZUID/g /etc/hostname
sudo sed -i s/astrxbian/$XZUID/g /etc/hosts
echo "CHANGE DNS" # Avoid provider restrictions
sudo cat > /etc/resolv.conf <<EOF
domain home
search home
nameserver 80.67.169.12 80.67.169.40 94.247.43.254 2001:67c:13e4:1::37
# FFDN.org opennic.org = ns8.he.de + ns5.ru
EOF
sudo chattr +i /etc/resolv.conf
# OTHER LANGUAGE KEYBOARD dpkg-reconfigure keyboard-configuration
########################################################################
echo 'REBOOT NOW...'
########################################################################
sudo reboot
exit 0

196
cron_MINUTE.sh Executable file
View File

@ -0,0 +1,196 @@
#!/bin/bash
########################################################################
# Author: Fred (support@qo-op.com)
# Version: 0.3
# License: AGPL-3.0 (https://choosealicense.com/licenses/agpl-3.0/)
########################################################################
MY_PATH="`dirname \"$0\"`" # relative
MY_PATH="`( cd \"$MY_PATH\" && pwd )`" # absolutized and normalized
ME="${0##*/}"
source $HOME/.profile
# CORRECT PATH
[[ ! $(echo $PATH | grep "/usr/local/bin") ]] && export PATH="$PATH:/usr/local/bin"
[[ ! $(echo $PATH | grep "HOME/.local/bin") ]] && export PATH="$PATH:$HOME/.local/bin"
[[ ! $(echo $PATH | grep "/usr/games") ]] && export PATH="$PATH:/usr/games"
#### INIT STATION PARAMETERS
[[ -f $MY_PATH/../secret.astroport.key ]] && source $MY_PATH/../secret.astroport.key # DEPRECATED now using ~/.bashrc
export YOU=$(ps auxf --sort=+utime | grep -w ipfs | grep -v -E 'color=auto|grep' | tail -n 1 | cut -d " " -f 1)
source /home/$YOU/.profile
[[ $IPFSNODEID ]] && export IPFSNODEID=$IPFSNODEID || export IPFSNODEID=$(ipfs id -f='<id>\n')
########################################################################
# HELP DEVLT: Search "TODO" in code
# Write what you thing about the situation
# AND how you would like to 'fix it'...
# Then friends can read and enhance solution.
# WARNING: This script must be processing less than 1 minute, so do not charge too much this script
# _ _____ ____ _ _______ ________ ____
# | | / / | / __ \/ | / / _/ | / / ____/ / / /
# | | /| / / /| | / /_/ / |/ // // |/ / / __ / / /
# | |/ |/ / ___ |/ _, _/ /| // // /| / /_/ / /_/_/
# |__/|__/_/ |_/_/ |_/_/ |_/___/_/ |_/\____/ (_|_)
########################################################################
# NB: 'figlet' is used for labeling code trunks
########################################################################
### MODIFY WITH GREAT CARE!!! MUST BE BUG FREE !!!!!
### EVERY STATION RUN THIS SCRIPT EVERY MINUTE.
export isMinetestRunning=$(ps auxf --sort=+utime | grep -w minetest | grep -v -E 'color=auto|grep' | tail -n 1 | cut -d ' ' -f 1)
export isG1smsRunning=$(ps auxf --sort=+utime | grep -w gammu | grep -v -E 'color=auto|grep' | tail -n 1 | cut -d ' ' -f 1)
export isKodiRunning=$(ps auxf --sort=+utime | grep -w kodi | grep -v -E 'color=auto|grep' | tail -n 1 | cut -d ' ' -f 1)
# ? isNextcloudRunning=$(ps auxf --sort=+utime | grep -w ipfs | grep -v -E 'color=auto|grep' | tail -n 1 | cut -d ' ' -f 1)
### DETECT FLAVOURS (TODO: Publish and share into ipfs/.12D3KooW***/ )
########################################################################
cd $MY_PATH
# WHAT UNIVERSAL TIME is it ?
minute=$(date -u +%M)
heure=$(date -u +%H)
timebar="$heure:$minute"
dayoftheweek=$(date +%w)
dayofthemonth=$(date +%d)
weeknumber=$(date +%V)
echo $timebar
#
# _________
# / ____< /________ ___ _____
# / / __ / / ___/ __ `__ \/ ___/
#/ /_/ // (__ ) / / / / (__ )
#\____//_/____/_/ /_/ /_/____/
#
# $MY_PATH/g1sms/sms_ASTROPORT.sh
# TIME NTP SYNC: TODO: Problem being root (stickybit INSTALL?)
# G1Tx. G1sms. G1Dab Zen economy needs precise time sync (RpiZero !!)
# Tx rates is limited by Station time synchronisation.
# sudo ntpdate ntp.pool.org
# ____ _______ __ __
# / __ \/ ____/ | / / ____ ___ ____ ____/ /__
# / / / / __/ | | / / / __ `__ \/ __ \/ __ / _ \
# / /_/ / /___ | |/ / / / / / / / /_/ / /_/ / __/
# /_____/_____/ |___/ /_/ /_/ /_/\____/\__,_/\___/
#
#
# ACTIVATE 5 MN "git pull" update
if [[ $(($minute % 5)) == 0 ]]; then
#######################################
sleep $((1 + RANDOM % 12))
git pull
fi
# __ __ _____ ____
# __/ // /_/ ___/ ______ __________ ___ / __ \
# /_ _ __/\__ \ | /| / / __ `/ ___/ __ `__ \/ / / /
# /_ _ __/___/ / |/ |/ / /_/ / / / / / / / / /_/ /
# /_//_/ /____/|__/|__/\__,_/_/ /_/ /_/ /_/\____/
#
##################################################################
# REFRESH IPFS SWARM DATA EVERY 12 & 15 minutes
[[ $(($minute % 12)) == 0 ]] && sleep $((1 + RANDOM % 10)) && $MY_PATH/zen/gchange_IPFS_swarm.sh &
[[ $(($minute % 15)) == 0 ]] && sleep $((1 + RANDOM % 10)) && $MY_PATH/zen/ipfs_SWARM_refresh.sh &
# Transfert ~/astroport/films to IPFS and make Vstream/ASTROPORT indexes on IPNS
if [[ "$timebar" == "03:03" ]]; then
$MY_PATH/zen/xbian_vstream.sh &
fi
## TODO investigate could breaks "ipfs p2p" forwards ?
##################################################################
# _________ _______ __ _ __
# / ____< / /_ __/ |/ / ____ ___ ____ ____ (_) /_____ _____
# / / __ / / / / | / / __ `__ \/ __ \/ __ \/ / __/ __ \/ ___/
# / /_/ // / / / / | / / / / / / /_/ / / / / / /_/ /_/ / /
# \____//_/ /_/ /_/|_| /_/ /_/ /_/\____/_/ /_/_/\__/\____/_/
#
##################################################################
# MONITOR INPUT TX (TODO: DEBUG)
# Activate later for DAB ZenTx Machines
# [[ $(($minute % 5)) == 0 ]] && sleep $((1 + RANDOM % 10)) && $MY_PATH/zen/g1_MONITOR_zen.sh "5 minutes"
##################################################################
##################################################################
##################################################################
# MIDNIGHT:01 : ZENBOT CLEANING & UPDATE
##################################################################
##################################################################
if [[ "$timebar" == "00:01" ]]; then
echo '
# ____ ____ ____ ___
# / __ \/ __ \ _ / __ < /
# / / / / / / / (_) / / / / /
# / /_/ / /_/ / _ / /_/ / /
# \____/\____/ (_) \____/_/
#
# MAINTENANCE
'
sleep $((1 + RANDOM % 5)) ### Be careful if random sleep is not activated...
############################## That swarm could become an aggressive blob !!
### PEACE & LOVE software is processing... We are HyperWeb people here.
# DEFCON 5 quiet behaviour so Please keep cool, take care and be zen.
# GOOD BYE GOOGLE, AMAZON, FACEBOOK, APPLE, MICROSOFT. We don't need you.
##################################################################
# REFRESH & UPGRADE youtube-dl
youtube-dl --rm-cache-dir
youtube-dl -U
#### DESYNC
sleep $((1 + RANDOM % 5))
##################################################################
# ssb_INIT + LOG ROTATE EVERY SUNDAY # TODO /var/log/ + logrotate (& tempfiles in /tmp in RAMFS)
if [[ $dayoftheweek == 0 ]]; then
$MY_PATH/zen/gchange_INIT.sh &
# ACTIVATE IF CRON LOGGING
#tar cvzf ~/.zen/astroport.$weeknumber.log.tgz /tmp/astroport.log # LOG BACKUP FOR 1 YEAR !!
fi
#### DESYNC
sleep $((1 + RANDOM % 5))
##################################################################
# GIT UPDATE
./git-update.sh
git pull # UPDATE CODE git pull
##################################################################
echo '
_________ ______
____ ___ ____ /_ __/ | / ____/
/_ / / _ \/ __ \ / / / /| |/ / __
/ /_/ __/ / / / / / / ___ / /_/ /
/___/\___/_/ /_/ /_/ /_/ |_\____/
REFRESHing ZenTAG nano DHTs = Zen File ECONOMY
'
# ./zen/ipns_TAG_refresh.sh
##################################################################
if [[ $dayofthemonth == 7 ]]; then
availableDiskSize=$(df -P ~/ | awk 'NR>1{sum+=$4}END{print sum}')
diskSize="$((availableDiskSize / 2))"
ipfs config Datastore.StorageMax $diskSize
echo '
_____ __ __ ___
/ ___// /_____ _________ _____ ____ / |/ /___ __ __
\__ \/ __/ __ \/ ___/ __ `/ __ `/ _ \ / /|_/ / __ `/ |/_/
___/ / /_/ /_/ / / / /_/ / /_/ / __/ / / / / /_/ /> <
/____/\__/\____/_/ \__,_/\__, /\___/ /_/ /_/\__,_/_/|_|
/____/
# 1/2 HDD for IPFS size - dicotomic adaptation 7th EVERY MONTH
#
# TODO: Read parameters from ipfs, publish status to swarm, could be use for youtube-dl or other kind of heavy ipfs input Station election.
#
'
echo "StorageMax = $diskSize"
fi
##################################################################
fi

49
install.sh Executable file
View File

@ -0,0 +1,49 @@
#!/bin/bash
{
# Check requirements
sudo apt update
sudo apt install git curl net-tools -y
gitpath="https://git.p2p.legal/axiom-team/astroport/raw/master"
echo "Add colors ..."
curl -s $gitpath/.install/export_colors.sh | bash || exit 1
[[ -n $(grep ".bash_aliases" ~/.bashrc) ]] && echo ". ~/.bash_aliases" ~/.bashrc
. ~/.bash_aliases
# Get arguments
args="$@"
# IPFS install
echo -e "${c_green}Astroport installer
###
1. IPFS Swarm Layer$c_"
# Full automatic (you trust this git depot)
curl -s $gitpath/.install/ipfs_alone.sh | bash || exit 1
# Set environment variables
curl -s $gitpath/.install/sys_checkOS.sh noexec | bash || exit 1
# SSB install (now using cesium+/gchange+)
# echo -e "${c_green}2. Ḡ1/ScuttleButt anoptical layer$c_"
# ONCE YOU READ and AGREE. Run TrustFull QUICK Install !!
# curl -s $gitpath/zen/tools/make_G1SSB_secret.sh | bash || exit 1
# LOVEland install
curl -s $gitpath/.install/loveland.sh | bash || exit 1
# Customs install
## Nextcloud
[[ $args =~ nextcloud ]] && cd /home/$USER/.zen/astroport && sudo -E bash .install/nextcloud/install.sh
echo -e "${c_green}Installation complete$c_"
exec bash
}

129
zen/README.md Normal file
View File

@ -0,0 +1,129 @@
# INSIDE ZEN REACTOR
```
~/.zen # Astroport Metaverse Files
~/.zen/astroport # CODE
~/.zen/secret.astroport.key # MULTI UNIVERSE KEY
~/.zen/cache/g1_TX_inputs/ # G1 Wallet INPUT Tx cache
~/.zen/cache/ssb_contact # Data from ./ssb_SURVEY_contact.sh
~/.zen/tag/ # CONTAINS "ZenTAG counters"
la ~/.zen/tag/9c6354a1db832e51ea0acd9342822dc49ba42c7035e830a2d59fcf4f86a13821/
_chain _g1.node.creator _ipns _passenger.ipfs.crypt _QRCODE.write.png _tag.zen
_chain.n _ipfs.node.creator _passenger.contract.sh _passenger.park _tag.BB.sha _tag.zensource
_chain.nanodate _ipfs.publishkey.BB.aes _passenger.filename _passenger.read _tag.issuer
_chain.prev _ipfs.publishkey.crypt _passenger.ipfs.BB.aes _QRCODE.read.png _tag.uid
~/.zen/miam/ # youtube-dl Stomac
# IPFS Shared Data Frameworks
~/.zen/ipfs
~/.zen/ipfs_swarm
# Each "G1SSBIPFS" Node publish ID and DATA indexes
~/.zen/ipfs_swarm/.12D3KooW***/
# Other Swarm Node access with "ipfs ls /ipns/Qm***/.12D3KooW***"
```
> ~/.zen/ipfs_swarm/.12D3KooW*** sub directory is used for exchanging messages between peers
> cron_MINUTE.sh monitor all LOCAL channels populated/monitored through to ~/.zen/ipfs_swarm
# IMPORTANT TODO!!
- timeout.sh CPU problem happen once
# MOVE swarm.key
```
mv ~/.ipfs/swarm.key ~/.ipfs/swarm.key.old
sudo systemctl restart ipfs
```
# Problem with ~/.ssb/manifest.json
```
# Restart ssb-server
kill -9 $(ps auxf --sort=+utime | grep -w ssb-daemon| grep -v -E 'color=auto|grep' | tail -n 1 | awk '{print $2}');
kill -9 $(ps auxf --sort=+utime | grep -w ssb-server| grep -v -E 'color=auto|grep' | tail -n 1 | awk '{print $2}');
kill -9 $(ps auxf --sort=+utime | grep -w oasis | grep -v -E 'color=auto|grep' | tail -n 1 | awk '{print $2}')
printf '{"manifest":"sync"}' > ~/.ssb/manifest.json
ssb-server start &
sbotc -t async manifest > ~/.ssb/manifest.json
```
# New SSB message type
```
# ssb_INIT.sh
~/.zen/ipfs/.$ipfsnodeid/G1SSB/_ssb.whoami
~/.zen/ipfs/.$ipfsnodeid/G1SSB/_g1.pubkey
~/.zen/ipfs/.$ipfsnodeid/G1SSB/_g1.qrcode.png
~/.zen/ipfs/.${ipfsnodeid}/Addresses
~/.zen/ipfs/.${ipfsnodeid}/AgentVersion
~/.zen/ipfs/.${ipfsnodeid}/repo.stat
~/.zen/ipfs/.${ipfsnodeid}/tryme.addr
```
# IPFS FILESYSTEM STRUCTURE
```
# ssb_INIT.sh
~/.zen/ipfs/.$ipfsnodeid/G1SSB/_ssb.whoami
~/.zen/ipfs/.$ipfsnodeid/G1SSB/_g1.pubkey
~/.zen/ipfs/.$ipfsnodeid/G1SSB/_g1.qrcode.png
~/.zen/ipfs/.${ipfsnodeid}/Addresses
~/.zen/ipfs/.${ipfsnodeid}/AgentVersion
~/.zen/ipfs/.${ipfsnodeid}/repo.stat
~/.zen/ipfs/.${ipfsnodeid}/tryme.addr
# zen_MAKE.sh
~/.zen/ipfs/.$ipfsnodeid/TAG/${J}
~/.zen/ipfs/.$ipfsnodeid/TAG/${J}/_tag.uid
~/.zen/ipfs/.$ipfsnodeid/TAG/${J}/_tag.passenger.filename
~/.zen/ipfs/.$ipfsnodeid/TAG/${J}/_tag.passenger.metadata.json
~/.zen/ipfs/.$ipfsnodeid/TAG/${J}/_tag.passenger.fulltitle
# ssb_SURVEY_contact.sh
~/.zen/ipfs/.${ipfsnodeid}/CONTACT/${g1author}
~/.zen/ipfs/.${ipfsnodeid}/CONTACT/${g1author}/ipfs_swarm.key.crypt
~/.zen/ipfs/.${ipfsnodeid}/Addresses
~/.zen/ipfs/.${ipfsnodeid}/AgentVersion
~/.zen/ipfs/.${ipfsnodeid}/repo.stat
~/.zen/ipfs/.${ipfsnodeid}/CHAN/sha256(id@channel)
# ipfs_SWARM_refresh.sh
```
# IPFS CHANNELS ARE SYNC FROM LOCAL NODE
```
LOCAL:
~/.zen/ipfs/channels/channel_id/_uid
IPFS SWARM :
~/.zen/ipfs/sha256(id@channel)/_uid
~/.zen/ipfs/sha256(+33647683646@SMS_+33667676767)/_uid
```
# natools CRYPT/DECRYPT a FILE
```
g1pub=$(cat ~/.ssb/secret.dunikey | grep 'pub:' | cut -d ' ' -f 2)
~/.zen/astroport/zen/tools/natools.py encrypt -p $g1pub -i file -o file.crypt
~/.zen/astroport/zen/tools/natools.py decrypt -f pubsec -k ~/.ssb/secret.dunikey -i file.crypt -o file
```

116
zen/cesium_INIT.sh Normal file
View File

@ -0,0 +1,116 @@
#!/bin/bash
########################################################################
# Author: Fred (support@qo-op.com)
# Version: 2020.11.30
# License: AGPL-3.0 (https://choosealicense.com/licenses/agpl-3.0/)
########################################################################
MY_PATH="`dirname \"$0\"`" # relative
MY_PATH="`( cd \"$MY_PATH\" && pwd )`" # absolutized and normalized
ME="${0##*/}"
########################################################################
# ENVIRONEMENT DETECTION + IPFS ~/.zen/ipfs/.$IPFSNODEID/G1SSB/_info
########################################################################
YOU=$(ps auxf --sort=+utime | grep -w ipfs | grep -v -E 'color=auto|grep' | tail -n 1 | cut -d " " -f 1);
IPFSNODEID=$(ipfs id -f='<id>\n')
[[ $IPFSNODEID == "" ]] && echo "ERROR missing IPFS Node id !! EXIT" && exit 1
########################################################################
[[ ! -f ~/.zen/secret.dunikey ]] && echo "Missing ~/.zen/secret.dunikey. EXIT" && exit 1
G1PUB=$(cat ~/.zen/secret.dunikey | grep 'pub:' | cut -d ' ' -f 2)
[[ $G1PUB == "" ]] && echo "ERROR G1PUB empty !! EXIT" && exit 1
########################################################################
# GET NODE disk performance. TODO, publish and use as IPFS repartition
echo "DISK SIZE AVAILABLE & PERFORMANCE TESTING"
[[ -f ~/.ipfs/test.disk ]] && rm -f ~/.ipfs/test.disk
diskperf=$(dd if=/dev/zero of=~/.ipfs/test.disk bs=10M count=1 oflag=dsync 2>&1 | tail -n 1 | sed s/\,\ /\ -/g | cut -d '-' -f 4)
# echo $diskperf
# IPFS LOCAL REPOSITORY for Node Identity
mkdir -p ~/.zen/ipfs/.$IPFSNODEID/G1SSB
# find IPFSTRYME public address
echo "" > ~/.zen/ipfs/.${IPFSNODEID}/tryme.addr
for tryme in $(ipfs id | jq -r .Addresses[]);
do
isLAN=$(echo $tryme | cut -f3 -d '/' | grep -E "(^127\.)|(^192\.168\.)|(^fd42\:)|(^10\.)|(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|(^::1$)|(^[fF][cCdD])/")
[[ ! $isLAN ]] && echo "$tryme" >> ~/.zen/ipfs/.${IPFSNODEID}/tryme.addr
done
cat ~/.zen/ipfs/.${IPFSNODEID}/tryme.addr
################################
# ADD Cesium+ informations
CESIUMPLUS="https://g1.data.le-sou.org"
# PREPARE title
# Made from Gchange+ profile tittle and city OR user@hostname
title=$(curl -s ${CESIUMPLUS}/user/profile/${G1PUB} | jq -r '._source.title')
[[ -f ~/.zen/ipfs/.$IPFSNODEID/G1SSB/_uidna ]] && uidna=$(cat ~/.zen/ipfs/.$IPFSNODEID/G1SSB/_uidna)
# Put in .$IPFSNODEID INDEX: _g1.uidna & _g1.cesium_name (used by Minetest flavour and others)
[[ $uidna ]] && echo "$uidna" > ~/.zen/ipfs/.$IPFSNODEID/G1SSB/_g1.uidna
[[ $title ]] && echo "$title" > ~/.zen/ipfs/.$IPFSNODEID/G1SSB/_g1.gchange_name
[[ $uidna ]] && [[ "$title" == "null" ]] && title="Station $uidna"
[[ "$title" == "null" ]] && title="Station $USER@$(cat /etc/hostname)"
city=$(curl -s ${CESIUMPLUS}/user/profile/${G1PUB} | jq -r '._source.city')
[[ "$city" != "null" ]] && title="$title in $city"
# ADD "cesium_geoPoint.lat" AND "cesium_geoPoint.lon" messages in SSB feed
# This way any SSB account is connected to its Cesium+ Geolocalisation.
geopointlat=$(curl -s ${CESIUMPLUS}/user/profile/${G1PUB} | jq '._source.geoPoint.lat')
geopointlon=$(curl -s ${CESIUMPLUS}/user/profile/${G1PUB} | jq '._source.geoPoint.lon')
# REFRESH Cesium+ Avatar image
curl -s ${CESIUMPLUS}/user/profile/${G1PUB} | jq -r '._source.avatar._content' | base64 -d > "/tmp/_gchange.avatar.png"
# Get nodename
[[ -f /home/$YOU/.zen/ipfs/.$IPFSNODEID/G1SSB/_nodename ]] && nodename=$(cat /home/$YOU/.zen/ipfs/.$IPFSNODEID/G1SSB/_nodename)
if [[ $nodename == "" ]]; then
nodename=$(cat /etc/hostname)
extension=$(echo $nodename | cut -d '.' -f 2)
if [[ $extension == $nodename ]]; then
nodename=$nodename.home
fi
echo "$nodename" > /home/$YOU/.zen/ipfs/.$IPFSNODEID/G1SSB/_nodename
fi
########################################################################
# DUNITER G1 Wallet balance
export LC_ALL=C.UTF-8 #attipix
export LANG=C.UTF-8 #attipix
# COPY NODE G1SSB ID to IPFS
echo "$G1PUB" > ~/.zen/ipfs/.${IPFSNODEID}/G1SSB/_g1.pubkey
# IPFS Node PUBLISH Adresses so Pub can become bootstrap for ${g1author}
ipfs id | jq -r .Addresses[] > ~/.zen/ipfs/.${IPFSNODEID}/Addresses
# IPFS Node PUBLISH AgentVersion & repo.stat
ipfs id | jq -r .AgentVersion > ~/.zen/ipfs/.${IPFSNODEID}/AgentVersion
ipfs repo stat > ~/.zen/ipfs/.${IPFSNODEID}/repo.stat
echo "$diskperf" > ~/.zen/ipfs/.${IPFSNODEID}/disk.perf
echo $(df ~/.ipfs/ | tail -n 1 | awk '{print $4}') > ~/.zen/ipfs/.${IPFSNODEID}/disk.bytes
IWALLETS=$(ipfs add -rHq ~/.zen/ipfs | tail -n 1)
NODEIPNS=$(ipfs name publish --allow-offline --quieter /ipfs/$IWALLETS)
###
# GET ALL MY CESIUMPLUS FRIENDS AND SEND THEM my IPFS Address
cd ~/.zen/astroport/zen/jaklis
# GET LIST of issuer(s) who likes me
for liking_me in $(./jaklis.py like | jq -r '.likes[].issuer');
do
# CHECk if I am liking him either
friend_of_mine=$(./jaklis.py like -p $liking_me | jq -r '.yours');
echo "Sending IPFSTRYME message to $liking_me"
[[ $friend_of_mine != null ]] && ./jaklis.py send -d $liking_me -t "ipfstryme" -f ~/.zen/ipfs/.${IPFSNODEID}/tryme.addr
done
cd -
exit 0

34
zen/cron_VRFY.sh Executable file
View File

@ -0,0 +1,34 @@
#!/bin/bash
########################################################################
# Author: Fred (support@qo-op.com)
# Version: 2020.03.21
# License: AGPL-3.0 (https://choosealicense.com/licenses/agpl-3.0/)
########################################################################
MY_PATH="`dirname \"$0\"`" # relative
MY_PATH="`( cd \"$MY_PATH\" && pwd )`" # absolutized and normalized
ME="${0##*/}"
echo '
########################################################################
# \\///
# qo-op
############# '$MY_PATH/$ME'
########################################################################
# ex: ./'$ME'
# VERIFY CRON for cron_MINUTE.sh and ACTIVATE it
########################################################################'
# Get crontab
crontab -l > /tmp/mycron
# Remove any previous line containing "cron_MINUTE"
awk -i inplace -v rmv="cron_MINUTE" '!index($0,rmv)' /tmp/mycron && echo "Astroport cron was there"
# DOUBLE CHECK (awk = nawk or gawk -i ?)
crontest=$(cat /tmp/mycron | grep -F 'cron_MINUTE')
# ADD cron_MINUTE.sh TO cron ?
if [[ ! $crontest ]]; then
echo "* * * * * $MY_PATH/../cron_MINUTE.sh >> /tmp/astroport.log 2>&1>/dev/null" >> /tmp/mycron && crontab /tmp/mycron \
else
echo "No operation needed. Your crontab is: " && crontab -l
fi
# Clean
rm -f /tmp/mycron
exit 0

189
zen/g1_MONITOR_zen.sh Executable file
View File

@ -0,0 +1,189 @@
#!/bin/bash
########################################################################
# Author: Fred (support@qo-op.com)
# Version: 1.0
# License: AGPL-3.0 (https://choosealicense.com/licenses/agpl-3.0/)
########################################################################
MY_PATH="`dirname \"$0\"`" # relative
MY_PATH="`( cd \"$MY_PATH\" && pwd )`" # absolutized and normalized
ME="${0##*/}"
########################################################################
# \\///
# qo-op
############# $ME DELAY
########################################################################
echo "
_(_)_ _(_)_
@@@@ (_)@(_) @@@@ (_)@(_) @@@@
@@()@@ wWWWw (_)\ @@()@@ wWWWw (_)\ @@()@@ wWWWw
@@@@ (___) \|/ @@@@ (___) \|/ @@@@ (___)
/ Y \| / Y \| / Y
\ | \ |/ | / \ | \ |/ | / \ | \ |/
\\|// \\|/// \\\|// \\|// \\|/// \\\|// \\|// \\|///
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# [ASTROPORT](https://astroport.com)
# ex: ./$ME \"10 days\"
# Survey Node G1 Wallet for TX/IN Commands in received comments ...
########################################################################
"
DELAY="$1"
ipfsnodeid=$(ipfs id -f='<id>\n')
[[ "$ipfsnodeid" == "" ]] && echo "$USER Please Install IPFS !!" && exit 1
[[ ! -d ~/.zen/cache/g1_TX_inputs ]] && mkdir -p ~/.zen/cache/g1_TX_inputs # Directory containing G1 blockchain incoming TX Scan
[[ ! -d ~/.zen/ipfs ]] && mkdir -p ~/.zen/ipfs # Directory where NODE store SMS & other Channel Wallets
[[ ! -d ~/.zen/ipfs_swarm ]] && mkdir -p ~/.zen/ipfs_swarm # Local copy of all SSB friends IPFS Nodes published ipfs
#########################################################################################################
# GET G1 PUBKEY FROM SCUTTLEBUTT or $2 (DEBUG)
[[ $DELAY == "" ]] && DELAY="60 days" && echo "*** HELP ***" && echo "./$ME \"duration\" (default $DELAY)" && echo "************" && echo
DELAYUNIT=$(echo $DELAY | cut -d ' ' -f 2)
# g1pub=$2 # DEBUG
[[ ! -f ~/.ssb/secret.dunikey ]] && $MY_PATH/tools/secret2dunikey.sh
g1pub=$(cat ~/.ssb/secret.dunikey | grep 'pub:' | cut -d ' ' -f 2)
[[ "$g1pub" == "" ]] && echo "$USER Missing ~/.ssb/secret : Please Install Scuttlebutt server !" && exit 1;
#########################################################################################################
echo "======================================="
echo "IPFS Node ID = $ipfsnodeid
__
_|_ _ _| |\ | _ _| _ /__/| _.|| __|_
(_| |(/_(_|< | \|(_)(_|(/_ \_| | \/\/(_|||(/_|_
last $DELAY
G1 PUBKEY = $g1pub
"
# PREPARE TIMESTAMP LIMITS
TIMEBEFORE=$(date -u --date="-$DELAY" +"%s")
TIMESTAMP=$(date -u +"%s")
# GET DUNITER SERVER
DUNITERNODE=$($MY_PATH/tools/duniter_getnode.sh)
DUNITERURL="https://$DUNITERNODE"
# GET BLOCKCHAIN TX FOR TIME WINDOW
curl -s $DUNITERURL/tx/history/$g1pub/times/$TIMEBEFORE/$TIMESTAMP > /tmp/g1_TX.scan.txt
TXNB=$(cat /tmp/g1_TX.scan.txt | wc -l)
echo "
$DUNITERURL/tx/history/$g1pub/times/$TIMEBEFORE/$TIMESTAMP
___
|\/ ._ ._ _ |_ _ ._
G1 |/\ | ||_|| | ||_)(/_|
$TXNB
"
# Choose between "history.received" OR "history.pending" depending on DELAY
if [[ $DELAYUNIT != "minutes" && $DELAYUNIT != "minute" ]]; then
# HOW MANY TX DO WE HAVE...
TXnb=$(cat /tmp/g1_TX.scan.txt | jq '.history.received[].hash' | wc -l)
echo "During $DELAY, detected $TXnb TX... Now looking for INPUT TX..."
# PARSE $TXnb TX
line=1
while [[ $line -le $TXnb ]]; do
# GET TX HASH
TXhash=$(cat /tmp/g1_TX.scan.txt | jq -r '.history.received[].hash' | head -n $line | tail -n 1 )
# IT IS A NEW TX?
if [[ ! -f ~/.zen/cache/g1_TX_inputs/zen.$TXhash ]]; then
# GET LAST TX ISSUER
ISSUER=$(cat /tmp/g1_TX.scan.txt | jq -r '.history.received[].issuers[0]' | head -n $line | tail -n 1)
[[ $ISSUER == $g1pub ]] && ((line++)) && continue ## TX/OUT CONTINUE
echo $ISSUER > ~/.zen/cache/g1_TX_inputs/zen.$TXhash
# GET OUTPUTS AND MAKE ZEN=G1*100 SUM
ZEN=$(cat /tmp/g1_TX.scan.txt | jq -r '.history.received[].outputs[]' | grep $g1pub | head -n $line | tail -n 1 | cut -d ':' -f 1)
# GET COMMENT
COMMENT=$(cat /tmp/g1_TX.scan.txt | jq '.history.received' | jq -r '.[].comment' | head -n $line | tail -n 1)
# echo "TX-IN $ISSUER => $g1pub"
echo "Received $ZEN Zen From $ISSUER :: $COMMENT :: ($TXhash)"
CMD=$(echo "$COMMENT" | awk '{print toupper($1)}')
echo "
___ ___ _ ___ _
|\/ | |\ ||_)| || |_) _ _ _ o _ _|
|/\ _|_| \|| |_|| | \(/_(_(/_|\/(/_(_|
"
case "$CMD" in
ZEN)
# Create ZenTAG QRCode
$MY_PATH/zen_MAKE.sh $ZEN $TXhash
;;
*)
echo "$TXhash = $ZEN ZEN ($COMMENT)"
# $MY_PATH/zen_MAKE.sh "ME" $TXhash
;;
esac
fi
((line++))
done
else
# MINUTE DELAY = pending // TODO: if anyone succeed in passing $VAR in jq command, both can be merge...
# HOW MANY TX DO WE HAVE...
TXnb=$(cat /tmp/g1_TX.scan.txt | jq '.history.pending[].hash' | wc -l)
echo "During $DELAY, detected $TXnb TX... Now looking for INPUT TX..."
# PARSE $TXnb TX
line=1
while [[ $line -le $TXnb ]]; do
TXhash=$(cat /tmp/g1_TX.scan.txt | jq -r '.history.pending[].hash' | head -n $line | tail -n 1)
# IT IS A NEW TX/IN?
if [[ ! -f ~/.zen/cache/g1_TX_inputs/zen.$TXhash ]]; then
# GET LAST RX ISSUER
ISSUER=$(cat /tmp/g1_TX.scan.txt | jq -r '.history.pending[].issuers[0]' | head -n $line | tail -n 1)
[[ $ISSUER == $g1pub ]] && ((line++)) && continue ## TX/OUT CONTINUE
echo $ISSUER > ~/.zen/cache/g1_TX_inputs/zen.$TXhash
# GET OUTPUTS AND MAKE ZEN SUM
ZEN=$(cat /tmp/g1_TX.scan.txt | jq -r '.history.pending[].outputs[]' | grep $g1pub | head -n $line | tail -n 1 | cut -d ':' -f 1)
# GET COMMENT
COMMENT=$(cat /tmp/g1_TX.scan.txt | jq '.history.pending' | jq -r '.[].comment' | head -n $line | tail -n 1)
# echo "TX-IN $ISSUER => $g1pub"
echo "Pending $ZEN Zen From $ISSUER :: $COMMENT :: ($TXhash)"
CMD=$(echo "$COMMENT" | awk '{print toupper($1)}')
echo "
___ ___ _ ___ _
|\/ | |\ ||_)| || |_)_ ._ _|o._ _
|/\ _|_| \|| |_|| | (/_| |(_||| |(_|
_|
"
case "$CMD" in
ZEN)
# Create ZenTAG QRCode
$MY_PATH/zen_MAKE.sh $ZEN $TXhash
;;
*)
echo "$TXhash = $ZEN ZEN ($COMMENT)"
# $MY_PATH/zen_MAKE.sh "ME" $TXhash
;;
esac
fi
((line++))
done
fi
echo "FINISH ! ls ~/.zen/cache/g1_TX_inputs/
__
|\ | _ _| _ /__/| \ /_.|| __|_ |_ _.| _.._ _ _
| \|(_)(_|(/_ \_| | \/\/(_|||(/_|_ |_)(_||(_|| |(_(/_
silkaj -p $DUNITERNODE balance $g1pub
"
exit 0

117
zen/gchange_INIT.sh Executable file
View File

@ -0,0 +1,117 @@
#!/bin/bash
########################################################################
# Author: Fred (support@qo-op.com)
# Version: 2020.11.30
# License: AGPL-3.0 (https://choosealicense.com/licenses/agpl-3.0/)
########################################################################
MY_PATH="`dirname \"$0\"`" # relative
MY_PATH="`( cd \"$MY_PATH\" && pwd )`" # absolutized and normalized
ME="${0##*/}"
########################################################################
# ENVIRONEMENT DETECTION + IPFS ~/.zen/ipfs/.$IPFSNODEID/G1SSB/_info
########################################################################
YOU=$(ps auxf --sort=+utime | grep -w ipfs | grep -v -E 'color=auto|grep' | tail -n 1 | cut -d " " -f 1);
IPFSNODEID=$(ipfs id -f='<id>\n')
[[ $IPFSNODEID == "" ]] && echo "ERROR missing IPFS Node id !! EXIT" && exit 1
########################################################################
[[ ! -f ~/.zen/secret.dunikey ]] && echo "Missing ~/.zen/secret.dunikey. EXIT" && exit 1
G1PUB=$(cat ~/.zen/secret.dunikey | grep 'pub:' | cut -d ' ' -f 2)
[[ $G1PUB == "" ]] && echo "ERROR G1PUB empty !! EXIT" && exit 1
########################################################################
# GET NODE disk performance. TODO, publish and use as IPFS repartition
echo "DISK SIZE AVAILABLE & PERFORMANCE TESTING"
[[ -f ~/.ipfs/test.disk ]] && rm -f ~/.ipfs/test.disk
diskperf=$(dd if=/dev/zero of=~/.ipfs/test.disk bs=10M count=1 oflag=dsync 2>&1 | tail -n 1 | sed s/\,\ /\ -/g | cut -d '-' -f 4)
# echo $diskperf
# IPFS LOCAL REPOSITORY for Node Identity
mkdir -p ~/.zen/ipfs/.$IPFSNODEID/G1SSB
# find IPFSTRYME public address
echo "" > ~/.zen/ipfs/.${IPFSNODEID}/tryme.addr
for tryme in $(ipfs id | jq -r .Addresses[]);
do
isLAN=$(echo $tryme | cut -f3 -d '/' | grep -E "(^127\.)|(^192\.168\.)|(^fd42\:)|(^10\.)|(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|(^::1$)|(^[fF][cCdD])/")
[[ ! $isLAN ]] && echo "$tryme" >> ~/.zen/ipfs/.${IPFSNODEID}/tryme.addr
done
cat ~/.zen/ipfs/.${IPFSNODEID}/tryme.addr
################################
# ADD GCHANGE+ informations
GCHANGE="https://data.gchange.fr"
# PREPARE title
# Made from Gchange+ profile tittle and city OR user@hostname
title=$(curl -s ${GCHANGE}/user/profile/${G1PUB} | jq -r '._source.title')
[[ -f ~/.zen/ipfs/.$IPFSNODEID/G1SSB/_uidna ]] && uidna=$(cat ~/.zen/ipfs/.$IPFSNODEID/G1SSB/_uidna)
# Put in .$IPFSNODEID INDEX: _g1.uidna & _g1.cesium_name (used by Minetest flavour and others)
[[ $uidna ]] && echo "$uidna" > ~/.zen/ipfs/.$IPFSNODEID/G1SSB/_g1.uidna
[[ $title ]] && echo "$title" > ~/.zen/ipfs/.$IPFSNODEID/G1SSB/_g1.gchange_name
[[ $uidna ]] && [[ "$title" == "null" ]] && title="Station $uidna"
[[ "$title" == "null" ]] && title="Station $USER@$(cat /etc/hostname)"
city=$(curl -s ${GCHANGE}/user/profile/${G1PUB} | jq -r '._source.city')
[[ "$city" != "null" ]] && title="$title in $city"
# ADD "cesium_geoPoint.lat" AND "cesium_geoPoint.lon" messages in SSB feed
# This way any SSB account is connected to its Cesium+ Geolocalisation.
geopointlat=$(curl -s ${GCHANGE}/user/profile/${G1PUB} | jq '._source.geoPoint.lat')
geopointlon=$(curl -s ${GCHANGE}/user/profile/${G1PUB} | jq '._source.geoPoint.lon')
# REFRESH Cesium+ Avatar image
curl -s ${GCHANGE}/user/profile/${G1PUB} | jq -r '._source.avatar._content' | base64 -d > "/tmp/_gchange.avatar.png"
# Get nodename
[[ -f /home/$YOU/.zen/ipfs/.$IPFSNODEID/G1SSB/_nodename ]] && nodename=$(cat /home/$YOU/.zen/ipfs/.$IPFSNODEID/G1SSB/_nodename)
if [[ $nodename == "" ]]; then
nodename=$(cat /etc/hostname)
extension=$(echo $nodename | cut -d '.' -f 2)
if [[ $extension == $nodename ]]; then
nodename=$nodename.home
fi
echo "$nodename" > /home/$YOU/.zen/ipfs/.$IPFSNODEID/G1SSB/_nodename
fi
########################################################################
# DUNITER G1 Wallet balance
export LC_ALL=C.UTF-8 #attipix
export LANG=C.UTF-8 #attipix
# COPY NODE G1SSB ID to IPFS
echo "$G1PUB" > ~/.zen/ipfs/.${IPFSNODEID}/G1SSB/_g1.pubkey
# IPFS Node PUBLISH Adresses so Pub can become bootstrap for ${g1author}
ipfs id | jq -r .Addresses[] > ~/.zen/ipfs/.${IPFSNODEID}/Addresses
# IPFS Node PUBLISH AgentVersion & repo.stat
ipfs id | jq -r .AgentVersion > ~/.zen/ipfs/.${IPFSNODEID}/AgentVersion
ipfs repo stat > ~/.zen/ipfs/.${IPFSNODEID}/repo.stat
echo "$diskperf" > ~/.zen/ipfs/.${IPFSNODEID}/disk.perf
echo $(df ~/.ipfs/ | tail -n 1 | awk '{print $4}') > ~/.zen/ipfs/.${IPFSNODEID}/disk.bytes
## PUBLISH ~/.zen/ipfs on self key IPNS
IWALLETS=$(ipfs add -rHq ~/.zen/ipfs | tail -n 1)
NODEIPNS=$(ipfs name publish --allow-offline --quieter /ipfs/$IWALLETS)
###
# GET ALL MY GCHANGE FRIENDS AND SEND THEM my IPFS Address
cd ~/.zen/astroport/zen/jaklis
# GET LIST of issuer(s) who likes me
for liking_me in $(./jaklis.py like | jq -r '.likes[].issuer');
do
# CHECk if I am liking him either
friend_of_mine=$(./jaklis.py like -p $liking_me | jq -r '.yours');
echo "Sending IPFSTRYME message to $liking_me"
[[ $friend_of_mine != null ]] && ./jaklis.py send -d $liking_me -t "ipfstryme" -f ~/.zen/ipfs/.${IPFSNODEID}/tryme.addr
done
cd -
exit 0

113
zen/gchange_IPFS_swarm.sh Executable file
View File

@ -0,0 +1,113 @@
#!/bin/bash
########################################################################
# Author: Fred (support@qo-op.com)
# Version: 2020.12.03
# License: AGPL-3.0 (https://choosealicense.com/licenses/agpl-3.0/)
########################################################################
MY_PATH="`dirname \"$0\"`" # relative
MY_PATH="`( cd \"$MY_PATH\" && pwd )`" # absolutized and normalized
ME="${0##*/}"
# Connect to IPFS peers with bidirectionnal "like" (gchange friends)
#
########################################################################
# \\///
# qo-op
############# '$MY_PATH/$ME'
########################################################################
# ex: ./'$ME'
# GET GCHANGE FRIENDS AND FIND THEIR IPFS ID TO "ipfs swarm connect" THEM
########################################################################'
## TODO : Beware of liking_me FLOOD & Invite $liking_me people to my #Swarm0
########################################################################
# ENVIRONEMENT DETECTION + IPFS ~/.zen/ipfs/.$IPFSNODEID/G1SSB/_info
########################################################################
IPFSNODEID=$(ipfs id -f='<id>\n')
[[ $IPFSNODEID == "" ]] && echo "ERROR missing IPFS Node id !! IPFS is not installed !?" && exit 1
isIPFSRunning=$(ps auxf --sort=+utime | grep -w ipfs | grep -v -E 'color=auto|grep' | tail -n 1 | cut -d ' ' -f 1)
[[ ! $isIPFSRunning ]] && echo "ERROR! ipfs daemon is not running. EXIT" && exit 1
########################################################################
# Force Strict #swarm0 !!?
# ipfs bootstrap rm --all
echo "" > ~/.zen/A_allow_ip.txt
echo "" > ~/.zen/A_liking_me_NO_ipfstryme.txt # contains "friends" with no "ipfstryme" incoming message
liking_me_count=0
friend_of_mine_count=0
########################################################################
# Let's look for Friends and "IPFS swarm connect" with them
########################################################################
cd ~/.zen/astroport/zen/jaklis
# 1. Get Gchange "liking_me" people list
for liking_me in $(./jaklis.py like | jq -r '.likes[].issuer');
do
# Check if my like is reverse
friend_of_mine=$(./jaklis.py like -p $liking_me | jq -r '.yours');
[[ $friend_of_mine != null ]] && echo "Connect to my friend $liking_me" && friend_of_mine_count=$((friend_of_mine_count+1)) && ipfsadd=0 \
&& for peer in $(./jaklis.py read -n50 -j | jq -r --arg friendKEY "$liking_me" '.[] | select(.pubkey == $friendKEY)' | jq 'select(.title == "ipfstryme")' | jq -r '.content');
# 2. Searching "ipfstryme" message from friend_of_mine
do
ip=$(echo "$peer" | awk -F '/' '{print $3}') && [[ $ip == "" ]] && continue || echo "Adding $ip to ~/.zen/A_allow_ip.txt"
# Fill a file with friend of mine ip
echo $ip >> ~/.zen/A_allow_ip.txt
# Get its ipfsnodeid
ipfsnodeid=$(echo "$peer" | awk -F '/' '{print $7}')
# 3. ADD liking_me friend_of_mine to my swarm & bootstrap
ipfs swarm connect $peer;
ipfs bootstrap add $peer;
ipfsadd=$((ipfsadd+1))
done;
#g1id=$(~/.zen/astroport/zen/tools/ipfs_to_g1.py "$ipfsnodeid")
#echo "G1 ID : $g1id"
if [[ $friend_of_mine != null ]]; then
if [[ $ipfsadd == 0 ]]; then
# Friend of mine with no ipfstryme message (did not install astroport)
echo "No 'ipfstryme' message... from $liking_me"
echo "$liking_me" >> ~/.zen/A_liking_me_NO_ipfstryme.txt
else
# REMOVING DUPLICATES OLD ipfstryme MESSAGES
nbmessage=0
for messageid in $(./jaklis.py read -n50 -j | jq -r --arg friendKEY "$liking_me" '.[] | select(.pubkey == $friendKEY)' | jq 'select(.title == "ipfstryme")' | jq -r '.id')
do
nbmessage=$((nbmessage+1))
[ $nbmessage -gt 1 ] && echo "Delete OLD 'ipfstryme' messages from $liking_me" && ./jaklis.py delete -i $messageid
done
fi
fi
# Automatic level_1 like from oasis.astroport.com (TODO add other default bootstrap)
# TODO get $g1pub from ~/.zen/ipfs/.$IPFSNODEID/G1SSB/_g1.pubkey ??
# [[ $friend_of_mine == null && $G1PUB == "2jQUH4HfHxdTesjCjvMCx1VJgA5AnpuvrWRq1swfRdsS" ]] && ./jaklis.py like -p $g1pub -s 1
echo "__________________________________________"
liking_me_count=$((liking_me_count+1))
done
echo "####################################################
I have $friend_of_mine_count friends amoung $liking_me_count liking me people
__________________________________________
My actual #SWARM0"
ipfs swarm peers
echo "__________________________________________"
echo
## Could send message to friends with 'ipfstryme' message
for line in $(cat ~/.zen/A_liking_me_NO_ipfstryme.txt | uniq); do
echo "Liking each other, but no ipfstryme received..."
echo "cd ~/.zen/astroport/zen/jaklis"
echo "./jaklis.py send -d $line -t 'Astroport' -m 'Rejoins mon #Swarm0 https://copylaradio.com'"
done
cd -

118
zen/gchange_MONITOR.sh Executable file
View File

@ -0,0 +1,118 @@
#!/bin/bash
################################################################################
# Author: Fred (support@qo-op.com)
# Version: 0.1
# License: AGPL-3.0 (https://choosealicense.com/licenses/agpl-3.0/)
################################################################################
# Extract last ads
# Thank you @kimamila for cesium & gchange
# ES backend http://www.elasticsearchtutorial.com/spatial-search-tutorial.html
MY_PATH="`dirname \"$0\"`" # relative
MY_PATH="`( cd \"$MY_PATH\" && pwd )`" # absolutized and normalized
mkdir ~/.zen/cache/gchange -p
ipfsnodeid=$(ipfs id -f='<id>\n')
[[ ! -f ~/.ssb/secret.dunikey ]] && $MY_PATH/tools/secret2dunikey.sh
g1pub=$(cat ~/.ssb/secret.dunikey | grep 'pub:' | cut -d ' ' -f 2)
CESIUM="https://g1.data.le-sou.org"
GCHANGE="https://data.gchange.fr" # /user/profile/2L8vaYixCf97DMT8SistvQFeBj7vb6RQL7tvwyiv1XVH?&_source_exclude=avatar._content
#curl -sk ${CESIUM}/user/profile/${g1pub} -o ~/.zen/cache/cesium_profile.json
LON=$(cat ~/.zen/cache/cesium_profile.json | jq '._source.geoPoint.lon')
LAT=$(cat ~/.zen/cache/cesium_profile.json | jq '._source.geoPoint.lat')
curl -sk ${GCHANGE}/user/profile/${g1pub} -o ~/.zen/cache/GCHANGE_profile.json
LON=$(cat ~/.zen/cache/GCHANGE_profile.json | jq '._source.geoPoint.lon')
LAT=$(cat ~/.zen/cache/GCHANGE_profile.json | jq '._source.geoPoint.lat')
RAD="$1"
[[ ! $RAD ]] && RAD="50km"
if [[ "$LON" != "null" ]]; then
curl -sk -XPOST 'https://data.gchange.fr/market/record/_search?pretty&_source=title' -d '
{
"size": 200,
"query": {
"bool": {
"filter": [{
"geo_distance": {
"distance": "'$RAD'",
"geoPoint": {
"lat": '$LAT',
"lon": '$LON'
}
}
}]
}
}
}' > /tmp/gchange.json || exit 1
else
echo "Aucune coordonnées geoPoint pour $g1pub"
sbotc publish '{"type":"post","text":"Ajouter sa géolocalisation dans Cesium+ permet de publier les annonces autour de chez soi..."}'
exit 1
fi
TIMEBEFORE=$(date -u --date="-$DELAY" +"%s")
TIMESTAMP=$(date -u +"%s")
TOTAL=$(cat /tmp/gchange.json | jq .hits.total)
echo 'tail -f ~/.zen/cache/gchange.txt'
echo 'Annonces_Gchange' > ~/.zen/cache/gchange.txt
echo "Portefeuille_[June_:heart:](https://demo.cesium.app/#/app/wot/$g1pub/)" >> ~/.zen/cache/gchange.txt
echo "Carte_[$RAD](https://www.openstreetmap.org/#map=10/$LAT/$LON) " >> ~/.zen/cache/gchange.txt
chunk=0
fullcount=0
DUNITERNODE=$($MY_PATH/tools/duniter_getnode.sh)
DUNITERURL="https://$DUNITERNODE"
LASTDU=$(curl -s ${DUNITERURL}/blockchain/with/ud | jq '.result.blocks[]' | tail -n 1);
[[ $LASTDU != "" ]] && LASTDU=$(curl -s ${DUNITERURL}/blockchain/block/${LASTDU} | jq '.dividend')
echo "DU = $LASTDU G1"
for gID in $(cat /tmp/gchange.json | jq -r .hits.hits[]._id); do
NEW=""
[[ ! -f ~/.zen/cache/gchange/$gID.json ]] &&
NEW="true" \
&& curl -s --create-dirs -o ~/.zen/cache/gchange/$gID.json -s https://data.gchange.fr/market/record/$gID?_source=category,title,description,issuer,time,creationTime,location,address,city,price,unit,currency,thumbnail._content_type,thumbnail._content,picturesCount,type,stock,fees,feesCurrency,geoPoint \
&& sleep $((1 + RANDOM % 3))
type=$(cat ~/.zen/cache/gchange/$gID.json | jq -r ._source.type)
stock=$(cat ~/.zen/cache/gchange/$gID.json | jq -r ._source.stock)
[[ $stock == 0 ]] && continue
# [[ $type == "need" ]] && continue
creationTime=$(cat ~/.zen/cache/gchange/$gID.json | jq -r ._source.creationTime)
title=$(cat ~/.zen/cache/gchange/$gID.json | jq -r ._source.title)
currency=$(cat ~/.zen/cache/gchange/$gID.json | jq -r ._source.currency)
price=$(cat ~/.zen/cache/gchange/$gID.json | jq -r ._source.price)
categoryname=$(cat ~/.zen/cache/gchange/$gID.json | jq -r ._source.category.name)
[[ $price == null ]] && price="0"
[[ $currency == "g1" ]] && love=$(bc -l <<< "scale=2; $price / $LASTDU * 100") || love="?.??"
love="$love_LOVE"
price=$(bc -l <<< "scale=2; $price / 100")
fullcount=$((fullcount+1)) && echo "DEBUG : $fullcount - $type - $price $currency - $title "
[[ $price == "0" ]] && love="..." && price="A débattre "
[[ $type == "offer" ]] && LINE="___OFFRE___[$title](https://data.gchange.fr/market/record/$gID/_share)_$love"
[[ $type == "need" ]] && LINE="__DEMANDE__[$title](https://data.gchange.fr/market/record/$gID/_share)_$love"
[[ $NEW == "true" ]] && echo "$LINE" >> ~/.zen/cache/gchange.txt && chunk=$((chunk+1)) && echo $chunk
done
echo "$chunk_nouvelles_annonces_($TOTAL)" >> ~/.zen/cache/gchange.txt
## TODO AUTOMATIC PUBLISHING \n and message size problem ??
if [[ $(cat ~/.zen/cache/gchange.txt | wc -c) -lt 8000 ]]; then
export raw="$(cat ~/.zen/cache/gchange.txt)"
annonces=$(node -p "JSON.stringify(process.env.raw)")
sbotc publish '{"type":"post","text":'$annonces'}'
fi
# EXTRA COULD CREATE IT'S OWN MAP with https://github.com/zicmama/tile-stitch.git
# And magick to overlay... But best would be a local map proxy...

61
zen/ipfs_EMPTY.sh Executable file
View File

@ -0,0 +1,61 @@
#!/bin/bash
########################################################################
# Author: Fred (support@qo-op.com)
# Version: 0.1
# License: AGPL-3.0 (https://choosealicense.com/licenses/agpl-3.0/)
########################################################################
########################################################################
# IPFS CLEANING (MANUAL OPERATION)
########################################################################
ipfsnodeid=$(ipfs id -f='<id>\n')
echo "
_ _ ___ _ _ __
/ | |_ /\ |\ | | |_)|_(_
\_|_|_/--\| \| _|_| | __)
LOVE BANK RAZ
You will have to do it yourself...
I cannot erase me. I will loose all my memory.
Please be nice. Take care.
_ _ _ _
(_) | | ___ __ __ ___ | | | |
| | | | / _ \ \ \ / / / _ \ | | | |
| | | | | (_) | \ V / | __/ | |_| |
|_| |_| \___/ \_/ \___| \___/
### CLEAN IPFS REPO
##################################################################
ipfs pin ls -q --type recursive | xargs ipfs pin rm && ipfs repo gc
echo 'Are you sure? LOVE economy is made of LOVE...' && exit 1
### FORGET ZenTAG Wallets
##################################################################
rm -f ~/.ipfs/keystore/*.key
rm -Rf ~/.zen/tag/*
rm -Rf ~/.zen/ipfs/.$ipfsnodeid/TAG
rm -Rf ~/.zen/ipfs_swarm/.12D3KooW*
rm -Rf ~/.zen/ipfs_swarm/*
### EMPTY miam STOMACK
##################################################################
rm -Rf ~/.zen/miam/*
### FORGET G1 TX MEMORY
##################################################################
rm -Rf ~/.zen/cache/g1_TX_inputs/*
##################################################################
# TODO: Howto Make ERASE reversable ??
# BACKUP MYSELF in IPFS and Give pieces of my key to my friends... So if a part of you decide to keep me alive, I will still BE.
# TODO BACKUP BREAK MY KEY INTO ssss shards and put them in ~/.zen/ipfs/.QmFriends**/QmMeshard^* cyphered with its pubkey)
##################################################################
# WWWWOOOO, and what if Human life was the same...
# For you not to die, you need a minimum consciencious attention from part of the others that you are alive to continue living?
# Astonomical thought don't you thinks ;)
"

37
zen/ipfs_OPEN_ports.sh Executable file
View File

@ -0,0 +1,37 @@
#!/bin/bash
################################################################################
# Author: Fred (support@qo-op.com)
# Version: 0.1
# License: AGPL-3.0 (https://choosealicense.com/licenses/agpl-3.0/)
################################################################################
# Activate SUPPORT MODE: open ssh over IPFS
MY_PATH="`dirname \"$0\"`" # relative
MY_PATH="`( cd \"$MY_PATH\" && pwd )`" # absolutized and normalized
########################################################################
YOU=$(ps auxf --sort=+utime | grep -w ipfs | grep -v -E 'color=auto|grep' | tail -n 1 | cut -d " " -f 1) || er+=" ipfs daemon not running"
IPFSNODEID=$(ipfs id -f='<id>\n') || er+=" ipfs id problem"
WHOAMI=$(sbotc whoami | jq -r .id) || er+=" sbotc whoami problem"
[[ "$YOU" == "" || "$IPFSNODEID" == "" || "$WHOAMI" == "" ]] && echo "ERROR : $er " && exit 1
########################################################################
# TODO ESTABLISH A PORT FORWARD STRATEGY (depending on Node Flavour)
# Arrange local port forwarded to swarm
# GET _uidna (means g1sms/init.sh been run)
[[ -f /home/$YOU/.zen/ipfs/.$IPFSNODEID/G1SSB/_uidna ]] && UIDNA=$(cat /home/$YOU/.zen/ipfs/.$IPFSNODEID/G1SSB/_uidna)
if [[ $(which gammu) ]]; then
# I am a g1sms NODE, pushing my web interface
ipfs p2p listen /x/g1sms /ip4/127.0.0.1/tcp/10099
else
# Looking for g1sms NODE in my swarm
SMSNODE=$(ls /home/$YOU/.zen/ipfs_swarm/.12D3KooW*/G1SSB/_g1sms | shuf -n 1 | cut -d '/' -f 6 | cut -d '.' -f 2)
sleep $((1 + RANDOM % 10)) # Wait for DHT to propagate.... Then forward /x/g1sms
[[ $SMSNODE ]] && ipfs p2p forward /x/g1sms /ip4/127.0.0.1/tcp/10097 /p2p/$SMSNODE
fi
# ipfs p2p close --all
# ipfs p2p listen /x/ssh-$UIDNA /ip4/127.0.0.1/tcp/22
# ipfs p2p listen /x/http-$UIDNA /ip4/127.0.0.1/tcp/80
# ipfs p2p listen /x/https-$UIDNA /ip4/127.0.0.1/tcp/443
ipfs p2p ls

85
zen/ipfs_SWARM_refresh.sh Executable file
View File

@ -0,0 +1,85 @@
#!/bin/bash
########################################################################
# Author: Fred (support@qo-op.com)
# Version: 2020.03.24
# License: AGPL-3.0 (https://choosealicense.com/licenses/agpl-3.0/)
########################################################################
MY_PATH="`dirname \"$0\"`" # relative
MY_PATH="`( cd \"$MY_PATH\" && pwd )`" # absolutized and normalized
ME="${0##*/}"
########################################################################
# \\///
# qo-op
############# '$MY_PATH/$ME'
########################################################################
# ex: ./'$ME'
########################################################################
# This script is controling IPFS swarm
# Sync friends peers ~/.zen/ipfs/ into ~/.zen/ipfs_swarm/.IPFSNODEID's/ directories
# add not friend_of_mine IPs to fail2ban
########################################################################
# TODO remove because now it is in~/.bashrc
export YOU=$(ps auxf --sort=+utime | grep -w ipfs | grep -v -E 'color=auto|grep' | tail -n 1 | cut -d " " -f 1)
export IPFSNODEID=$(ipfs id -f='<id>\n')
########################################################################
mkdir -p ~/.zen/ipfs_swarm
echo '
___ _ _ __ __ _ _ _ _ _ _ __
| |_)|_(_ (_\ //\ |_)|\/| |_)|_|_|_)|_(_ |_|
_|_| | __) __)\/\//--\| \| | | \|_| | \|___)| |
'
echo "I am $IPFSNODEID"
echo "REFRESHING /home/$YOU/.zen/ipfs_swarm/ from my SWARM peers"
rm -Rf /home/$YOU/.zen/ipfs_swarm/.12D3KooW*
rm -Rf /home/$YOU/.zen/ipfs_swarm/.Qm*
rm -Rf /home/$YOU/.zen/ipfs_swarm/*
count=1
for peer in $(ipfs swarm peers);
do
ipfsnodeid=$(echo "$peer" | awk -F '/' '{print $7}')
ip=$(echo "$peer" | awk -F '/' '{print $3}')
nowdate=$(date)
timestamp=$(date -u +%s%N | cut -b1-13)
echo "$nowdate - $id - $ip"
foundIp=$(cat ~/.zen/A_allow_ip.txt | grep "$ip")
isLAN=$(echo $ip | cut -f3 -d '/' | grep -E "(^127\.)|(^192\.168\.)|(^fd42\:)|(^10\.)|(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|(^::1$)|(^[fF][cCdD])/")
if [[ ! $foundIp && ! $isLAN ]] ; then
echo "${ip} of peer ${id} is not in the authorized ip list."
echo "${peer} will be removed from the swarm"
ipfs swarm disconnect $peer
ipfs bootstrap rm $peer
echo "# FAIL2BAN # $USER must activate no password sudo (Rpi & Xbian OK)"
[[ $USER == "pi" || $USER == "xbian" ]] && echo "BAN $ip" \
&& sudo fail2ban-client add recidive \
&& sudo fail2ban-client set recidive banip $ip
else
echo "${peer}"
echo "REFRESH /ipns/$ipfsnodeid INTO ~/.zen/ipfs_swarm/"
$MY_PATH/tools/timeout.sh -t 20 ipfs get --output=/home/$YOU/.zen/ipfs_swarm/ /ipns/$ipfsnodeid
fi
done
echo "$IPFSNODEID PUBLISHING /home/$YOU/.zen/ipfs/ to SWARM"
[[ ! -d /home/$YOU/.zen/ipfs ]] && echo "ERROR : /home/$YOU/.zen/ipfs/ NOT FOUND" && exit 1
IWALLETS=$(ipfs add -rHq /home/$YOU/.zen/ipfs | tail -n 1)
NODEIPNS=$(ipfs name publish --quieter /ipfs/$IWALLETS)
# Put my own data in /home/$YOU/.zen/ipfs_swarm/
ipfs get --output=/home/$YOU/.zen/ipfs_swarm/ /ipns/$IPFSNODEID
# NB: could start sync IPNS from "swarm peers" and check ~/.zen/ipfs_swarm/.$ipfsnodeid/G1SSB/_g1.pubkey
# if it is a gchange friend of mine... Then decide to bannish or keep.
# But IPNS sync with bad node could lead to a filesystem concistency corruption...
# Should be sync in a temp separate folder... So keeping IP control for now.
exit 0

65
zen/ipfs_TASK_do.sh Executable file
View File

@ -0,0 +1,65 @@
#!/bin/bash
########################################################################
# Author: Fred (support@qo-op.com)
# Version: 0.1
# License: AGPL-3.0 (https://choosealicense.com/licenses/agpl-3.0/)
########################################################################
# AJAX REQUEST TRACKER : ASTROPORT ON BOARDING
# GETTING : PHONE + PARRAIN + NAISSANCE
#
# DataFlow : index.html + ajaxform.js + zen_loveland_entrance.php
########################################################################
MY_PATH="`dirname \"$0\"`" # relative
MY_PATH="`( cd \"$MY_PATH\" && pwd )`" # absolutized and normalized
YOU=$(ps auxf --sort=+utime | grep -w ipfs | grep -v -E 'color=auto|grep' | tail -n 1 | cut -d " " -f 1);
IPFSNODEID=$(ipfs id -f='<id>\n')
NANODATE=$(date -u +%s%N)
# SEARCH FOR NEW TASK OTHER NODE "todo.timestamp"
echo "REWRITING AND CHECK NEDDED"
exit 1
if [[ -d /home/$YOU/.zen/ipfs_swarm/.$IPFSNODEID/TASK ]]; then
############################################################################"
for task in $( ls /home/$YOU/.zen/ipfs_swarm/.$IPFSNODEID/TASK/todo.*); # "done.$NANODATE" FILES
do
FTASK=$( echo $task | cut -d '/' -f 8 ) # todo.$NANODATE
TNANO=$( echo $FTASK | cut -d '.' -f 2 ) # $NANODATE
echo "FOUND TASK FOR ME ($IPFSNODEID) : $FTASK "
# MAKE LOCAL .$IPFSNODEID directory
mkdir -p /home/$YOU/.zen/ipfs/.$IPFSNODEID/TASK/
# TODO: CHECK BETTER NOT DONE YET and $NANODATE > $TNANO (=> detect NODES writing in the future!!)
if [[ ! -f /home/$YOU/.zen/ipfs/.$IPFSNODEID/TASK/done.$TNANO ]]; then # NOT DONE YET: NEW TASK!
tdiff=$(bc -l <<< "$NANODATE - $TNANO")
if [[ $tdiff -gt 0 ]]; then
# todo.NANODATE is from past: OK. DO IT
echo "DOING it...."
chmod +x /home/$YOU/.zen/ipfs_swarm/.$IPFSNODEID/TASK/todo.$TNANO
cat /home/$YOU/.zen/ipfs_swarm/.$IPFSNODEID/TASK/todo.$TNANO
echo "WRITE todo RESULT in done.$TNANO"
else
# TODO: Bad NODE in the Future task !!! Make better BAD Node detection = Swarm Banish?
echo "KO.$tdiff" > /home/$YOU/.zen/ipfs/.$IPFSNODEID/TASK/done.$TNANO
echo " .$IPFSNODEID($FTASK) ERROR! DATE PROBLEM: $NANODATE < $TNANO :: KO"
fi
fi
done
echo "REMOVE OLD TASK MARKED AS DONE"
for scan in /home/$YOU/.zen/ipfs_swarm/.12D3KooW*/TASK/done.*; do
lscan=$(echo $scan | sed s/_swarm//g ) ## Remove _swarm
lid=$(echo $scan | cut -d '/' -f 6 | cut -d '.' -f 2 ) ## Get matching IPFSNODEID
lnano=$(echo $scan | cut -d '/' -f 8 | cut -d '.' -f 2 ) ## Get done timestamp
if [[ "$lid" != "$IPFSNODEID" ]]; then
echo "CLEANING done OLD TASK ${lscan} SENT to $lid ($lnano.bin)"
rm -f ./wallets/.$lid/TASK/todo.$lnano
fi
done
else
echo ".$IPFSNODEID :: NO TASK ! "
############################################################################"
fi

64
zen/ipns_TAG_refresh.sh Executable file
View File

@ -0,0 +1,64 @@
#!/bin/bash
########################################################################
# Author: Fred (support@qo-op.com)
# Version: 2020.04.28
# License: AGPL-3.0 (https://choosealicense.com/licenses/agpl-3.0/)
########################################################################
MY_PATH="`dirname \"$0\"`" # relative
MY_PATH="`( cd \"$MY_PATH\" && pwd )`" # absolutized and normalized
ME="${0##*/}"
########################################################################
# \\///
# qo-op
############# '$MY_PATH/$ME'
########################################################################
# ex: ./'$ME'
# SYNC IPFS SWARM PEERS SHARED DATA .12D3KooW****
########################################################################'
########################################################################
# ENVIRONEMENT DETECTION + IPFS ~/.zen/ipfs/.$IPFSNODEID/G1SSB/_info
########################################################################
IPFSNODEID=$(ipfs id -f='<id>\n')
[[ $IPFSNODEID == "" ]] && echo "ERROR missing IPFS Node id !! IPFS is not installed !?" && exit 1
########################################################################
[[ ! -f ~/.ssb/secret.dunikey ]] && $MY_PATH/tools/secret2dunikey.sh
G1PUB=$(cat ~/.ssb/secret.dunikey | grep 'pub:' | cut -d ' ' -f 2)
########################################################################
echo '
_ _ _ _
/ \ / \ / \ / \
( I | P | N | S )
\_/ \_/ \_/ \_/
ZENTAG REFRESH
'
echo "I am /ipns/$IPFSNODEID controling and refreshing my ZenTag"
count=0
[[ ! -d ~/.zen/tag/ ]] && exit 1
for id in ~/.zen/tag/*; # Alternative search
do
count=$((count+1))
ipnskey=$(cat $id/_tag.uid)
zenvalue=$(cat $id/_tag.zen)
passengername=$(cat $id/_passenger.filename)
echo "ZenTag $count : $ipnskey ($zenvalue Zen) $passengername"
# TODO: Add control to alert ZenTags strange behaviour
# TODO :SECURITY BREACH: DO NOT PUBLISH _QRCODE.write.png !!!
I=$(ipfs add -qr ${id} | tail -n 1)
# ZenTag IPNS name publish
Tkey=$(ipfs key list | grep -F ${ipnskey}.key)
J=$(ipfs name publish -k ${Tkey} --quieter /ipfs/${I})
echo "http://127.0.0.1/ipns/$J"
done

4
zen/jaklis/.env Normal file
View File

@ -0,0 +1,4 @@
DUNIKEY="/.zen/secret.dunikey" # Chemin du fichier de trousseau Ḡ1 de l'émetteur, au format PubSec
#POD="https://data.gchange.fr" # Noeud Gchange utilisé pour l'envoi du message
#POD="https://g1.data.duniter.fr" # Noeud Cecium+ utilisé pour l'envoi du message
POD="https://g1.data.le-sou.org" # Adresse du pod Cesium de secours

4
zen/jaklis/.env.template Normal file
View File

@ -0,0 +1,4 @@
DUNIKEY="" # Chemin de la clé privé Ḡ1 de l'émetteur, au format PubSec
#POD="https://g1.data.duniter.fr" # Adresse du pod Cesium ou Gchange à utiliser
POD="https://g1.data.le-sou.org" # Adresse du pod Cesium de secours
#POD="https://data.gchange.fr" # Adresse du pod ḠChange à utiliser

70
zen/jaklis/README.md Normal file
View File

@ -0,0 +1,70 @@
# Client CLI for Cesium+/Ḡchange pod
## Installation
Linux:
```
bash setup.sh
```
Autre:
```
Débrouillez-vous.
```
## Utilisation
Renseignez optionnellement le fichier **.env** (Généré lors de la première tentative d'execution, ou à copier depuis .env.template).
```
./jaklis.py -h
```
```
usage: jaklis.py [-h] [-v] [-k KEY] [-n NODE] {read,send,delete,get,set,erase,like,unlike} ...
positional arguments:
{read,send,delete,get,set,erase,like,unlike}
read Lecture des messages
send Envoi d'un message
delete Supression d'un message
get Voir un profile Cesium+
set Configurer son profile Cesium+
erase Effacer son profile Cesium+
like Voir les likes d'un profile / Liker un profile (option -s NOTE)
unlike Supprimer un like
optional arguments:
-h, --help show this help message and exit
-v, --version Affiche la version actuelle du programme
-k KEY, --key KEY Chemin vers mon trousseau de clé (PubSec)
-n NODE, --node NODE Adresse du noeud Cesium+ ou Gchange à utiliser
```
Utilisez `./jaklis CMD -h``CMD` est la commande souhaité pour obtenir l'aide détaillé de cette commande.
### Exemples:
Lire les 10 derniers messages de mon compte indiqué dans le fichier `.env` (par defaut 3 messages):
```
./jaklis read -n10
```
Envoyer un message à la clé publique `Do99s6wQR2JLfhirPdpAERSjNbmjjECzGxHNJMiNKT3P` avec un fichier de trousseau particulier:
```
./jaklis.py -k /home/saucisse/mon_fichier_de_trousseau.dunikey send -d Do99s6wQR2JLfhirPdpAERSjNbmjjECzGxHNJMiNKT3P -t "Objet du message" -m "Corps de mon message"
```
Noter 4 étoiles le profile `S9EJbjbaGPnp26VuV6fKjR7raE1YkNhUGDgoydHvAJ1` sur gchange:
```
./jaklis.py -n https://data.gchange.fr like -p S9EJbjbaGPnp26VuV6fKjR7raE1YkNhUGDgoydHvAJ1 -s 4
```
Paramétrer mon profile Cesium+:
```
./jaklis.py set -n "Sylvain Durif" -v "Bugarach" -a "42 route de Vénus" -d "Christ cosmique" -pos 48.539927 2.6608169 -s https://www.creationmonetaire.info -A mon_avatar.png
```
Effacer mon profile Gchange:
```
./jaklis.py -n https://data.gchange.fr erase
```

166
zen/jaklis/jaklis.py Executable file
View File

@ -0,0 +1,166 @@
#!/usr/bin/env python3
import argparse, sys, os, random, string, getpass, json
from os.path import join, dirname
from shutil import copyfile
from dotenv import load_dotenv
from duniterpy.key import SigningKey
from lib.cesium import ReadFromCesium, SendToCesium, DeleteFromCesium, Profiles
from lib.likes import ReadLikes, SendLikes, UnLikes
VERSION = "0.0.1"
# Get variables environment
if not os.path.isfile('.env'):
copyfile(".env.template", ".env")
dotenv_path = join(dirname(__file__), '.env')
load_dotenv(dotenv_path)
# Parse arguments
parser = argparse.ArgumentParser(description="Client CLI pour Cesium+ et Ḡchange")
parser.add_argument('-v', '--version', action='store_true', help="Affiche la version actuelle du programme")
parser.add_argument('-k', '--key', help="Chemin vers mon trousseau de clé (PubSec)")
parser.add_argument('-n', '--node', help="Adresse du noeud Cesium+ ou Gchange à utiliser")
subparsers = parser.add_subparsers(title="Commandes de jaklis", dest="cmd")
read_cmd = subparsers.add_parser('read', help="Lecture des messages")
send_cmd = subparsers.add_parser('send', help="Envoi d'un message")
delete_cmd = subparsers.add_parser('delete', help="Supression d'un message")
getProfile_cmd = subparsers.add_parser('get', help="Voir un profile Cesium+")
setProfile_cmd = subparsers.add_parser('set', help="Configurer son profile Cesium+")
eraseProfile_cmd = subparsers.add_parser('erase', help="Effacer son profile Cesium+")
like_cmd = subparsers.add_parser('like', help="Voir les likes d'un profile / Liker un profile (option -s NOTE)")
unlike_cmd = subparsers.add_parser('unlike', help="Supprimer un like")
# Messages management
read_cmd.add_argument('-n', '--number',type=int, default=3, help="Affiche les NUMBER derniers messages")
read_cmd.add_argument('-j', '--json', action='store_true', help="Sort au format JSON")
read_cmd.add_argument('-o', '--outbox', action='store_true', help="Lit les messages envoyés")
send_cmd.add_argument('-d', '--destinataire', required=True, help="Destinataire du message")
send_cmd.add_argument('-t', '--titre', help="Titre du message à envoyer")
send_cmd.add_argument('-m', '--message', help="Message à envoyer")
send_cmd.add_argument('-f', '--fichier', help="Envoyer le message contenu dans le fichier 'FICHIER'")
send_cmd.add_argument('-o', '--outbox', action='store_true', help="Envoi le message sur la boite d'envoi")
delete_cmd.add_argument('-i', '--id', action='append', nargs='+', required=True, help="ID(s) du/des message(s) à supprimer")
delete_cmd.add_argument('-o', '--outbox', action='store_true', help="Suppression d'un message envoyé")
# Profiles management
setProfile_cmd.add_argument('-n', '--name', help="Nom du profile")
setProfile_cmd.add_argument('-d', '--description', help="Description du profile")
setProfile_cmd.add_argument('-v', '--ville', help="Ville du profile")
setProfile_cmd.add_argument('-a', '--adresse', help="Adresse du profile")
setProfile_cmd.add_argument('-pos', '--position', nargs=2, help="Points géographiques (lat + lon)")
setProfile_cmd.add_argument('-s', '--site', help="Site web du profile")
setProfile_cmd.add_argument('-A', '--avatar', help="Chemin vers mon avatar en PNG")
getProfile_cmd.add_argument('-p', '--profile', help="Nom du profile")
getProfile_cmd.add_argument('-a', '--avatar', action='store_true', help="Récupérer également l'avatar au format raw base64")
# Likes management
like_cmd.add_argument('-p', '--profile', help="Profile cible")
like_cmd.add_argument('-s', '--stars', type=int, help="Nombre d'étoile")
unlike_cmd.add_argument('-p', '--profile', help="Profile à déliker")
args = parser.parse_args()
cmd = args.cmd
if not cmd:
parser.print_help()
sys.exit(1)
if args.version:
print(VERSION)
sys.exit(0)
def createTmpDunikey():
# Generate pseudo-random nonce
nonce=[]
for _ in range(32):
nonce.append(random.choice(string.ascii_letters + string.digits))
nonce = ''.join(nonce)
keyPath = "/tmp/secret.dunikey-" + nonce
key = SigningKey.from_credentials(getpass.getpass("Identifiant: "), getpass.getpass("Mot de passe: "), None)
key.save_pubsec_file(keyPath)
return keyPath
if args.node:
pod = args.node
else:
pod = os.getenv('POD')
if not pod:
pod="https://g1.data.le-sou.org"
if args.key:
dunikey = args.key
keyPath = False
else:
dunikey = os.getenv('DUNIKEY')
if not dunikey:
keyPath = createTmpDunikey()
dunikey = keyPath
else:
keyPath = False
if not os.path.isfile(dunikey):
HOME = os.getenv("HOME")
dunikey = HOME + dunikey
if not os.path.isfile(dunikey):
sys.stderr.write('Le fichier de trousseau {0} est introuvable.\n'.format(dunikey))
sys.exit(1)
# Build cesiumMessaging class
if cmd == "read":
messages = ReadFromCesium(dunikey, pod)
messages.read(args.number, args.outbox, args.json)
elif cmd == "send":
if args.fichier:
with open(args.fichier, 'r') as f:
msgT = f.read()
titre = msgT.splitlines(True)[0].replace('\n', '')
msg = ''.join(msgT.splitlines(True)[1:])
if args.titre:
titre = args.titre
msg = msgT
elif args.titre and args.message:
titre = args.titre
msg = args.message
else:
titre = input("Indiquez le titre du message: ")
msg = input("Indiquez le contenu du message: ")
messages = SendToCesium(dunikey, pod, args.destinataire, args.outbox)
messages.send(titre, msg)
elif cmd == "delete":
messages = DeleteFromCesium(dunikey, pod, args.outbox)
messages.delete(args.id[0])
# Build cesium+ profiles class
elif cmd in ('set','get','erase'):
cesium = Profiles(dunikey, pod)
if cmd == "set":
cesium.set(args.name, args.description, args.ville, args.adresse, args.position, args.site, args.avatar)
elif cmd == "get":
cesium.get(args.profile, args.avatar)
elif cmd == "erase":
cesium.erase()
# Build cesium+ likes class
elif cmd == "like":
if args.stars or args.stars == 0:
gchange = SendLikes(dunikey, pod)
gchange.like(args.stars, args.profile)
else:
gchange = ReadLikes(dunikey, pod)
gchange.readLikes(args.profile)
elif cmd == "unlike":
gchange = UnLikes(dunikey, pod)
gchange.unLike(args.profile)
if keyPath:
os.remove(keyPath)

Binary file not shown.

Binary file not shown.

Binary file not shown.

557
zen/jaklis/lib/cesium.py Normal file
View File

@ -0,0 +1,557 @@
#!/usr/bin/env python3
import os, sys, ast, requests, json, base58, base64, time, string, random, re
from lib.natools import fmt, sign, get_privkey, box_decrypt, box_encrypt
from time import sleep
from hashlib import sha256
from datetime import datetime
from termcolor import colored
PUBKEY_REGEX = "(?![OIl])[1-9A-Za-z]{42,45}"
def pp_json(json_thing, sort=True, indents=4):
# Print beautifull JSON
if type(json_thing) is str:
print(json.dumps(json.loads(json_thing), sort_keys=sort, indent=indents))
else:
print(json.dumps(json_thing, sort_keys=sort, indent=indents))
return None
class ReadFromCesium:
def __init__(self, dunikey, pod):
# Get my pubkey from my private key
try:
self.dunikey = dunikey
if not dunikey:
raise ValueError("Dunikey is empty")
except:
sys.stderr.write("Please fill the path to your private key (PubSec)\n")
sys.exit(1)
self.recipient = get_privkey(dunikey, "pubsec").pubkey
self.pod = pod
if not re.match(PUBKEY_REGEX, self.recipient) or len(self.recipient) > 45:
sys.stderr.write("La clé publique n'est pas au bon format.\n")
sys.exit(1)
# Configure JSON document to send
def configDoc(self, nbrMsg, outbox):
boxType = "issuer" if outbox else "recipient"
data = {}
data['sort'] = { "time": "desc" }
data['from'] = 0
data['size'] = nbrMsg
data['_source'] = ['issuer','recipient','title','content','time','nonce','read_signature']
data['query'] = {}
data['query']['bool'] = {}
data['query']['bool']['filter'] = {}
data['query']['bool']['filter']['term'] = {}
data['query']['bool']['filter']['term'][boxType] = self.recipient
document = json.dumps(data)
return document
def sendDocument(self, nbrMsg, outbox):
boxType = "outbox" if outbox else "inbox"
document = self.configDoc(nbrMsg, outbox)
headers = {
'Content-type': 'application/json',
}
# Send JSON document and get JSON result
result = requests.post('{0}/message/{1}/_search'.format(self.pod, boxType), headers=headers, data=document)
if result.status_code == 200:
return result.json()["hits"]
else:
sys.stderr.write("Echec de l'envoi du document de lecture des messages...\n" + result.text)
# Parse JSON result and display messages
def readMessages(self, msgJSON, nbrMsg, outbox):
def decrypt(msg):
msg64 = base64.b64decode(msg)
return box_decrypt(msg64, get_privkey(self.dunikey, "pubsec"), self.issuer, nonce).decode()
# Get terminal size
rows = int(os.popen('stty size', 'r').read().split()[1])
totalMsg = msgJSON["total"]
if nbrMsg > totalMsg:
nbrMsg = totalMsg
if totalMsg == 0:
print(colored("Aucun message à afficher.", 'yellow'))
return True
else:
infoTotal = " Nombre de messages: " + str(nbrMsg) + "/" + str(totalMsg) + " "
print(colored(infoTotal.center(rows, '#'), "yellow"))
for hits in msgJSON["hits"]:
self.idMsg = hits["_id"]
msgSrc = hits["_source"]
self.issuer = msgSrc["issuer"]
nonce = msgSrc["nonce"]
nonce = base58.b58decode(nonce)
self.dateS = msgSrc["time"]
date = datetime.fromtimestamp(self.dateS).strftime(", le %d/%m/%Y à %H:%M ")
if outbox:
startHeader = " À " + msgSrc["recipient"]
else:
startHeader = " De " + self.issuer
headerMsg = startHeader + date + "(ID: {})".format(self.idMsg) + " "
print('-'.center(rows, '-'))
print(colored(headerMsg, "blue").center(rows+9, '-'))
print('-'.center(rows, '-'))
try:
self.title = decrypt(msgSrc["title"])
self.content = decrypt(msgSrc["content"])
except Exception as e:
sys.stderr.write(colored(str(e), 'red') + '\n')
pp_json(hits)
continue
print('\033[1m' + self.title + '\033[0m')
print(self.content)
print(colored(infoTotal.center(rows, '#'), "yellow"))
# Parse JSON result and display messages
def jsonMessages(self, msgJSON, nbrMsg, outbox):
def decrypt(msg):
msg64 = base64.b64decode(msg)
return box_decrypt(msg64, get_privkey(self.dunikey, "pubsec"), self.issuer, nonce).decode()
totalMsg = msgJSON["total"]
if nbrMsg > totalMsg:
nbrMsg = totalMsg
if totalMsg == 0:
print("Aucun message à afficher")
return True
else:
data = []
# data.append({})
# data[0]['total'] = totalMsg
for i, hits in enumerate(msgJSON["hits"]):
self.idMsg = hits["_id"]
msgSrc = hits["_source"]
self.issuer = msgSrc["issuer"]
nonce = msgSrc["nonce"]
nonce = base58.b58decode(nonce)
self.date = msgSrc["time"]
if outbox:
pubkey = msgSrc["recipient"]
else:
pubkey = self.issuer
try:
self.title = decrypt(msgSrc["title"])
self.content = decrypt(msgSrc["content"])
except Exception as e:
sys.stderr.write(colored(str(e), 'red') + '\n')
pp_json(hits)
continue
data.append(i)
data[i] = {}
data[i]['id'] = self.idMsg
data[i]['date'] = self.date
data[i]['pubkey'] = pubkey
data[i]['title'] = self.title
data[i]['content'] = self.content
data = json.dumps(data, indent=2)
return data
def read(self, nbrMsg, outbox, isJSON):
jsonMsg = self.sendDocument(nbrMsg, outbox)
if isJSON:
jsonFormat = self.jsonMessages(jsonMsg, nbrMsg, outbox)
print(jsonFormat)
else:
self.readMessages(jsonMsg, nbrMsg, outbox)
#################### Sending class ####################
class SendToCesium:
def __init__(self, dunikey, pod, recipient, outbox):
# Get my pubkey from my private key
try:
self.dunikey = dunikey
if not dunikey:
raise ValueError("Dunikey is empty")
except:
sys.stderr.write("Please fill the path to your private key (PubSec)\n")
sys.exit(1)
self.issuer = get_privkey(dunikey, "pubsec").pubkey
self.pod = pod
self.recipient = recipient
self.outbox = outbox
# Generate pseudo-random nonce
nonce=[]
for _ in range(32):
nonce.append(random.choice(string.ascii_letters + string.digits))
self.nonce = base64.b64decode(''.join(nonce))
if not re.match(PUBKEY_REGEX, recipient) or len(recipient) > 45:
sys.stderr.write("La clé publique n'est pas au bon format.\n")
sys.exit(1)
def encryptMsg(self, msg):
return fmt["64"](box_encrypt(msg.encode(), get_privkey(self.dunikey, "pubsec"), self.recipient, self.nonce)).decode()
def configDoc(self, title, msg):
b58nonce = base58.b58encode(self.nonce).decode()
# Get current timestamp
timeSent = int(time.time())
# Generate custom JSON
data = {}
data['issuer'] = self.issuer
data['recipient'] = self.recipient
data['title'] = title
data['content'] = msg
data['time'] = timeSent
data['nonce'] = b58nonce
data['version'] = 2
document = json.dumps(data)
# Generate hash of document
hashDoc = sha256(document.encode()).hexdigest().upper()
# Generate signature of document
signature = fmt["64"](sign(hashDoc.encode(), get_privkey(self.dunikey, "pubsec"))[:-len(hashDoc.encode())]).decode()
# Build final document
finalDoc = '{' + '"hash":"{0}","signature":"{1}",'.format(hashDoc, signature) + document[1:]
return finalDoc
def sendDocument(self, document):
boxType = "outbox" if self.outbox else "inbox"
headers = {
'Content-type': 'application/json',
}
# Send JSON document and get result
try:
result = requests.post('{0}/message/{1}?pubkey={2}'.format(self.pod, boxType, self.recipient), headers=headers, data=document)
except Exception as e:
sys.stderr.write("Impossible d'envoyer le message:\n" + str(e))
sys.exit(1)
else:
if result.status_code == 200:
print(colored("Message envoyé avec succès !", "green"))
print("ID: " + result.text)
return result
else:
sys.stderr.write("Erreur inconnue:" + '\n')
print(str(pp_json(result.text)) + '\n')
def send(self, title, msg):
finalDoc = self.configDoc(self.encryptMsg(title), self.encryptMsg(msg)) # Configure JSON document to send
self.sendDocument(finalDoc) # Send final signed document
#################### Deleting class ####################
class DeleteFromCesium:
def __init__(self, dunikey, pod, outbox):
# Get my pubkey from my private key
try:
self.dunikey = dunikey
if not dunikey:
raise ValueError("Dunikey is empty")
except:
sys.stderr.write("Please fill the path to your private key (PubSec)\n")
sys.exit(1)
self.issuer = get_privkey(dunikey, "pubsec").pubkey
self.pod = pod
self.outbox = outbox
def configDoc(self, idMsg):
# Get current timestamp
timeSent = int(time.time())
boxType = "outbox" if self.outbox else "inbox"
# Generate document to customize
data = {}
data['version'] = 2
data['index'] = "message"
data['type'] = boxType
data['id'] = idMsg
data['issuer'] = self.issuer
data['time'] = timeSent
document = json.dumps(data)
# Generate hash of document
hashDoc = sha256(document.encode()).hexdigest().upper()
# Generate signature of document
signature = fmt["64"](sign(hashDoc.encode(), get_privkey(self.dunikey, "pubsec"))[:-len(hashDoc.encode())]).decode()
# Build final document
data = {}
data['hash'] = hashDoc
data['signature'] = signature
signJSON = json.dumps(data)
finalJSON = {**json.loads(signJSON), **json.loads(document)}
finalDoc = json.dumps(finalJSON)
return finalDoc
def sendDocument(self, document, idMsg):
headers = {
'Content-type': 'application/json',
}
# Send JSON document and get result
try:
result = requests.post('{0}/history/delete'.format(self.pod), headers=headers, data=document)
if result.status_code == 404:
raise ValueError("Message introuvable")
elif result.status_code == 403:
raise ValueError("Vous n'êtes pas l'auteur de ce message.")
except Exception as e:
sys.stderr.write(colored("Impossible de supprimer le message {0}:\n".format(idMsg), 'red') + str(e) + "\n")
return False
else:
if result.status_code == 200:
print(colored("Message {0} supprimé avec succès !".format(idMsg), "green"))
return result
else:
sys.stderr.write("Erreur inconnue.")
def delete(self, idsMsgList):
for idMsg in idsMsgList:
finalDoc = self.configDoc(idMsg)
self.sendDocument(finalDoc, idMsg)
#################### Profile class ####################
class Profiles:
def __init__(self, dunikey, pod):
# Get my pubkey from my private key
try:
self.dunikey = dunikey
if not dunikey:
raise ValueError("Dunikey is empty")
except:
sys.stderr.write("Please fill the path to your private key (PubSec)\n")
sys.exit(1)
self.pubkey = get_privkey(dunikey, "pubsec").pubkey
self.pod = pod
if not re.match(PUBKEY_REGEX, self.pubkey) or len(self.pubkey) > 45:
sys.stderr.write("La clé publique n'est pas au bon format.\n")
sys.exit(1)
# Configure JSON document SET to send
def configDocSet(self, name, description, city, address, pos, socials, avatar):
timeSent = int(time.time())
data = {}
if name: data['title'] = name
if description: data['description'] = description
if address: data['address'] = address
if city: data['city'] = city
if pos:
geoPoint = {}
geoPoint['lat'] = pos[0]
geoPoint['lon'] = pos[1]
data['geoPoint'] = geoPoint
if socials:
data['socials'] = []
data['socials'].append({})
data['socials'][0]['type'] = "web"
data['socials'][0]['url'] = socials
if avatar:
avatar = open(avatar, 'rb').read()
avatar = base64.b64encode(avatar).decode()
data['avatar'] = {}
data['avatar']['_content'] = avatar
data['avatar']['_content_type'] = "image/png"
data['time'] = timeSent
data['issuer'] = self.pubkey
data['version'] = 2
data['tags'] = []
document = json.dumps(data)
# Generate hash of document
hashDoc = sha256(document.encode()).hexdigest().upper()
# Generate signature of document
signature = fmt["64"](sign(hashDoc.encode(), get_privkey(self.dunikey, "pubsec"))[:-len(hashDoc.encode())]).decode()
# Build final document
data = {}
data['hash'] = hashDoc
data['signature'] = signature
signJSON = json.dumps(data)
finalJSON = {**json.loads(signJSON), **json.loads(document)}
finalDoc = json.dumps(finalJSON)
return finalDoc
# Configure JSON document GET to send
def configDocGet(self, profile, scope='title', getAvatar=None):
if getAvatar:
avatar = "avatar"
else:
avatar = "avatar._content_type"
data = {
"query": {
"bool": {
"should":[
{
"match":{
scope:{
"query": profile,"boost":2
}
}
},{
"prefix": {scope: profile}
}
]
}
},"highlight": {
"fields": {
"title":{},
"tags":{}
}
},"from":0,
"size":100,
"_source":["title", avatar,"description","city","address","socials.url","creationTime","membersCount","type"],
"indices_boost":{"user":100,"page":1,"group":0.01
}
}
document = json.dumps(data)
return document
# Configure JSON document SET to send
def configDocErase(self):
timeSent = int(time.time())
data = {}
data['time'] = timeSent
data['id'] = self.pubkey
data['issuer'] = self.pubkey
data['version'] = 2
data['index'] = "user"
data['type'] = "profile"
document = json.dumps(data)
# Generate hash of document
hashDoc = sha256(document.encode()).hexdigest().upper()
# Generate signature of document
signature = fmt["64"](sign(hashDoc.encode(), get_privkey(self.dunikey, "pubsec"))[:-len(hashDoc.encode())]).decode()
# Build final document
data = {}
data['hash'] = hashDoc
data['signature'] = signature
signJSON = json.dumps(data)
finalJSON = {**json.loads(signJSON), **json.loads(document)}
finalDoc = json.dumps(finalJSON)
return finalDoc
def sendDocument(self, document, type):
headers = {
'Content-type': 'application/json',
}
# Send JSON document and get JSON result
if type == 'set':
reqQuery = '{0}/user/profile?pubkey={1}/_update?pubkey={1}'.format(self.pod, self.pubkey)
elif type == 'get':
reqQuery = '{0}/user,page,group/profile,record/_search'.format(self.pod)
elif type == 'erase':
reqQuery = '{0}/history/delete'.format(self.pod)
result = requests.post(reqQuery, headers=headers, data=document)
if result.status_code == 200:
# print(result.text)
return result.text
else:
sys.stderr.write("Echec de l'envoi du document...\n" + result.text + '\n')
def parseJSON(self, doc):
doc = json.loads(doc)['hits']['hits']
if doc:
pubkey = { "pubkey": doc[0]['_id'] }
rest = doc[0]['_source']
final = {**pubkey, **rest}
else:
final = 'Profile vide'
return json.dumps(final, indent=2)
def set(self, name=None, description=None, ville=None, adresse=None, position=None, site=None, avatar=None):
document = self.configDocSet(name, description, ville, adresse, position, site, avatar)
result = self.sendDocument(document,'set')
print(result)
return result
def get(self, profile=None, avatar=None):
if not profile:
profile = self.pubkey
if not re.match(PUBKEY_REGEX, profile) or len(profile) > 45:
scope = 'title'
else:
scope = '_id'
document = self.configDocGet(profile, scope, avatar)
resultJSON = self.sendDocument(document, 'get')
result = self.parseJSON(resultJSON)
print(result)
return result
def erase(self):
document = self.configDocErase()
result = self.sendDocument(document,'erase')
print(result)
return result

331
zen/jaklis/lib/likes.py Normal file
View File

@ -0,0 +1,331 @@
#!/usr/bin/env python3
import os, sys, ast, requests, json, base58, base64, time, string, random, re
from lib.natools import fmt, sign, get_privkey, box_decrypt, box_encrypt
from time import sleep
from hashlib import sha256
from datetime import datetime
from termcolor import colored
PUBKEY_REGEX = "(?![OIl])[1-9A-Za-z]{42,45}"
class ReadLikes:
def __init__(self, dunikey, pod):
# Get my pubkey from my private key
try:
self.dunikey = dunikey
if not dunikey:
raise ValueError("Dunikey is empty")
except:
sys.stderr.write("Please fill the path to your private key (PubSec)\n")
sys.exit(1)
self.issuer = get_privkey(dunikey, "pubsec").pubkey
self.pod = pod
if not re.match(PUBKEY_REGEX, self.issuer) or len(self.issuer) > 45:
sys.stderr.write("La clé publique n'est pas au bon format.\n")
sys.exit(1)
# Configure JSON document to send
def configDoc(self, profile):
if not profile: profile = self.issuer
# elif len(profile) < 42:
# print(len(profile))
# gProfile = requests.get('{0}/user/profile/{1}'.format(self.pod, issuer))
# gProfile = json.loads(gProfile.text)['_source']
# pseudo = gProfile['title']
data = {}
data['query'] = {}
data['query']['bool'] = {}
data['query']['bool']['filter'] = [
{'term': {'index': 'user'}},
{'term': {'type': 'profile'}},
{'term': {'id': profile}},
{'term': {'kind': 'STAR'}}
]
# data['query']['bool']['should'] = {'term':{'issuer': self.issuer}}
data['size'] = 5000
data['_source'] = ['issuer','level']
data['aggs'] = {
'level_sum': {
'sum': {
'field': 'level'
}
}
}
return json.dumps(data)
def sendDocument(self, document):
headers = {
'Content-type': 'application/json',
}
# Send JSON document and get JSON result
result = requests.post('{0}/like/record/_search'.format(self.pod), headers=headers, data=document)
if result.status_code == 200:
# print(result.text)
return result.text
else:
sys.stderr.write("Echec de l'envoi du document de lecture des messages...\n" + result.text + '\n')
def parseResult(self, result):
result = json.loads(result)
totalLikes = result['hits']['total']
totalValue = result['aggregations']['level_sum']['value']
if totalLikes:
score = totalValue/totalLikes
else:
score = 0
raw = result['hits']['hits']
finalPrint = {}
finalPrint['likes'] = []
for i in raw:
issuer = i['_source']['issuer']
# print(issuer)
gProfile = self.getProfile(issuer)
try:
pseudo = gProfile['title']
except:
pseudo = ''
try:
payTo = gProfile['pubkey']
except:
payTo = ''
id = i['_id']
level = i['_source']['level']
if issuer == self.issuer:
finalPrint['yours'] = { 'id' : id, 'pseudo' : pseudo, 'payTo' : payTo, 'level' : level }
else:
finalPrint['likes'].append({ 'issuer' : issuer, 'pseudo' : pseudo, 'payTo' : payTo, 'level' : level })
finalPrint['score'] = score
return json.dumps(finalPrint)
def getProfile(self, profile):
headers = {
'Content-type': 'application/json',
}
data = {}
data['query'] = {}
data['query']['bool'] = {}
data['query']['bool']['filter'] = [
{'term': {'_index': 'user'}},
{'term': {'_type': 'profile'}},
{'term': {'_id': profile}}
]
data['_source'] = ['title','pubkey']
data = json.dumps(data)
result = requests.post('{0}/user/profile/_search'.format(self.pod), headers=headers, data=data)
result = json.loads(result.text)['hits']['hits'][0]['_source']
return result
def readLikes(self, profile=False):
document = self.configDoc(profile)
result = self.sendDocument(document)
result = self.parseResult(result)
print(result)
return result
#################### Like class ####################
class SendLikes:
def __init__(self, dunikey, pod):
# Get my pubkey from my private key
try:
self.dunikey = dunikey
if not dunikey:
raise ValueError("Dunikey is empty")
except:
sys.stderr.write("Please fill the path to your private key (PubSec)\n")
sys.exit(1)
self.issuer = get_privkey(dunikey, "pubsec").pubkey
self.pod = pod
if not re.match(PUBKEY_REGEX, self.issuer) or len(self.issuer) > 45:
sys.stderr.write("La clé publique n'est pas au bon format.\n")
sys.exit(1)
# Configure JSON document to send
def configDoc(self, profile, likes):
if not profile: profile = self.issuer
if likes not in range(0, 6):
sys.stderr.write(colored('Votre like doit être compris entre 0 et 5.\n', 'red'))
return False
timeSent = int(time.time())
data = {}
data['version'] = 2
data['index'] = "user"
data['type'] = "profile"
data['id'] = profile
data['kind'] = "STAR"
data['level'] = likes
data['time'] = timeSent
data['issuer'] = self.issuer
document = json.dumps(data)
# Generate hash of document
hashDoc = sha256(document.encode()).hexdigest().upper()
# Generate signature of document
signature = fmt["64"](sign(hashDoc.encode(), get_privkey(self.dunikey, "pubsec"))[:-len(hashDoc.encode())]).decode()
# Build final document
data = {}
data['hash'] = hashDoc
data['signature'] = signature
signJSON = json.dumps(data)
finalJSON = {**json.loads(signJSON), **json.loads(document)}
finalDoc = json.dumps(finalJSON)
return finalDoc
def sendDocument(self, document, pubkey):
headers = {
'Content-type': 'application/json',
}
# Send JSON document and get JSON result
result = requests.post('{0}/user/profile/:id/_like'.format(self.pod), headers=headers, data=document)
if result.status_code == 200:
print(colored("Profile liké avec succès !", 'green'))
return result.text
elif result.status_code == 400:
resultJson = json.loads(result.text)
if 'DuplicatedDocumentException' in resultJson['error']:
rmLike = UnLikes(self.dunikey, self.pod)
rmLike.unLike(pubkey, True)
sleep(0.5)
self.sendDocument(document, pubkey)
return resultJson['error']
else:
sys.stderr.write("Echec de l'envoi du document de lecture des messages...\n" + resultJson['error'] + '\n')
else:
resultJson = json.loads(result.text)
sys.stderr.write("Echec de l'envoi du document de lecture des messages...\n" + resultJson['error'] + '\n')
def like(self, stars, profile=False):
document = self.configDoc(profile, stars)
if document:
self.sendDocument(document, profile)
#################### Unlike class ####################
class UnLikes:
def __init__(self, dunikey, pod):
# Get my pubkey from my private key
try:
self.dunikey = dunikey
if not dunikey:
raise ValueError("Dunikey is empty")
except:
sys.stderr.write("Please fill the path to your private key (PubSec)\n")
sys.exit(1)
self.issuer = get_privkey(dunikey, "pubsec").pubkey
self.pod = pod
if not re.match(PUBKEY_REGEX, self.issuer) or len(self.issuer) > 45:
sys.stderr.write("La clé publique n'est pas au bon format.\n")
sys.exit(1)
# Check if you liked this profile
def checkLike(self, pubkey):
readProfileLikes = ReadLikes(self.dunikey, self.pod)
document = readProfileLikes.configDoc(pubkey)
result = readProfileLikes.sendDocument(document)
result = readProfileLikes.parseResult(result)
result = json.loads(result)
if 'yours' in result:
myLike = result['yours']['id']
return myLike
else:
sys.stderr.write("Vous n'avez pas liké ce profile\n")
return False
# Configure JSON document to send
def configDoc(self, idLike):
timeSent = int(time.time())
data = {}
data['version'] = 2
data['index'] = "like"
data['type'] = "record"
data['id'] = idLike
data['issuer'] = self.issuer
data['time'] = timeSent
document = json.dumps(data)
# Generate hash of document
hashDoc = sha256(document.encode()).hexdigest().upper()
# Generate signature of document
signature = fmt["64"](sign(hashDoc.encode(), get_privkey(self.dunikey, "pubsec"))[:-len(hashDoc.encode())]).decode()
# Build final document
data = {}
data['hash'] = hashDoc
data['signature'] = signature
signJSON = json.dumps(data)
finalJSON = {**json.loads(signJSON), **json.loads(document)}
finalDoc = json.dumps(finalJSON)
return finalDoc
def sendDocument(self, document, silent):
headers = {
'Content-type': 'application/json',
}
# Send JSON document and get JSON result
result = requests.post('{0}/history/delete'.format(self.pod), headers=headers, data=document)
if result.status_code == 200:
if not silent:
print(colored("Like supprimé avec succès !", 'green'))
return result.text
else:
sys.stderr.write("Echec de l'envoi du document de lecture des messages...\n" + result.text + '\n')
def unLike(self, pubkey, silent=False):
idLike = self.checkLike(pubkey)
if idLike:
document = self.configDoc(idLike)
self.sendDocument(document, silent)

297
zen/jaklis/lib/natools.py Executable file
View File

@ -0,0 +1,297 @@
#!/usr/bin/env python3
"""
CopyLeft 2020 Pascal Engélibert <tuxmain@zettascript.org>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
__version__ = "1.3.1"
import os, sys, duniterpy.key, libnacl, base58, base64, getpass
def getargv(arg:str, default:str="", n:int=1, args:list=sys.argv) -> str:
if arg in args and len(args) > args.index(arg)+n:
return args[args.index(arg)+n]
else:
return default
def read_data(data_path, b=True):
if data_path == "-":
if b:
return sys.stdin.buffer.read()
else:
return sys.stdin.read()
else:
return open(os.path.expanduser(data_path), "rb" if b else "r").read()
def write_data(data, result_path):
if result_path == "-":
os.fdopen(sys.stdout.fileno(), 'wb').write(data)
else:
open(os.path.expanduser(result_path), "wb").write(data)
def encrypt(data, pubkey):
return duniterpy.key.PublicKey(pubkey).encrypt_seal(data)
def decrypt(data, privkey):
return privkey.decrypt_seal(data)
def box_encrypt(data, privkey, pubkey, nonce=None, attach_nonce=False):
signer = libnacl.sign.Signer(privkey.seed)
sk = libnacl.public.SecretKey(libnacl.crypto_sign_ed25519_sk_to_curve25519(signer.sk))
verifier = libnacl.sign.Verifier(base58.b58decode(pubkey).hex())
pk = libnacl.public.PublicKey(libnacl.crypto_sign_ed25519_pk_to_curve25519(verifier.vk))
box = libnacl.public.Box(sk.sk, pk.pk)
data = box.encrypt(data, nonce) if nonce else box.encrypt(data)
return data if attach_nonce else data[24:]
def box_decrypt(data, privkey, pubkey, nonce=None):
signer = libnacl.sign.Signer(privkey.seed)
sk = libnacl.public.SecretKey(libnacl.crypto_sign_ed25519_sk_to_curve25519(signer.sk))
verifier = libnacl.sign.Verifier(base58.b58decode(pubkey).hex())
pk = libnacl.public.PublicKey(libnacl.crypto_sign_ed25519_pk_to_curve25519(verifier.vk))
box = libnacl.public.Box(sk.sk, pk.pk)
return box.decrypt(data, nonce) if nonce else box.decrypt(data)
def sign(data, privkey):
return privkey.sign(data)
def verify(data, pubkey):
try:
ret = libnacl.sign.Verifier(duniterpy.key.PublicKey(pubkey).hex_pk()).verify(data)
sys.stderr.write("Signature OK!\n")
return ret
except ValueError:
sys.stderr.write("Bad signature!\n")
exit(1)
def get_privkey(privkey_path, privkey_format):
if privkey_format == "pubsec":
if privkey_path == "*":
privkey_path = "privkey.pubsec"
return duniterpy.key.SigningKey.from_pubsec_file(privkey_path)
elif privkey_format == "cred":
if privkey_path == "*":
privkey_path = "-"
if privkey_path == "-":
return duniterpy.key.SigningKey.from_credentials(getpass.getpass("Password: "), getpass.getpass("Salt: "))
else:
return duniterpy.key.SigningKey.from_credentials_file(privkey_path)
elif privkey_format == "seedh":
if privkey_path == "*":
privkey_path = "authfile.seedhex"
return duniterpy.key.SigningKey.from_seedhex(read_data(privkey_path, False))
elif privkey_format == "wif":
if privkey_path == "*":
privkey_path = "authfile.wif"
return duniterpy.key.SigningKey.from_wif_or_ewif_file(privkey_path)
elif privkey_format == "wifh":
if privkey_path == "*":
privkey_path = "authfile.wif"
return duniterpy.key.SigningKey.from_wif_or_ewif_hex(privkey_path)
elif privkey_format == "ssb":
if privkey_path == "*":
privkey_path = "secret"
return duniterpy.key.SigningKey.from_ssb_file(privkey_path)
elif privkey_format == "key":
if privkey_path == "*":
privkey_path = "authfile.key"
return duniterpy.key.SigningKey.from_private_key(privkey_path)
print("Error: unknown privkey format")
def fill_pubkey(pubkey, length=32):
while pubkey[0] == 0:
pubkey = pubkey[1:]
return b"\x00"*(length-len(pubkey)) + pubkey
def pubkey_checksum(pubkey, length=32, clength=3):
return base58.b58encode(libnacl.crypto_hash_sha256(libnacl.crypto_hash_sha256(fill_pubkey(base58.b58decode(pubkey), length)))).decode()[:clength]
# returns (pubkey:bytes|None, deprecated_length:bool)
def check_pubkey(pubkey):
if ":" in pubkey:
parts = pubkey.split(":")
if len(parts[1]) < 3 or len(parts[1]) > 32:
return (None, False)
for i in range(32, 0, -1):
if pubkey_checksum(parts[0], i, len(parts[1])) == parts[1]:
return (parts[0], i < 32)
return (None, False)
return (pubkey, False)
fmt = {
"raw": lambda data: data,
"16": lambda data: data.hex().encode(),
"32": lambda data: base64.b32encode(data),
"58": lambda data: base58.b58encode(data),
"64": lambda data: base64.b64encode(data),
"64u": lambda data: base64.urlsafe_b64encode(data),
"85": lambda data: base64.b85encode(data),
}
defmt = {
"raw": lambda data: data,
"16": lambda data: bytes.fromhex(data),
"32": lambda data: base64.b32decode(data),
"58": lambda data: base58.b58decode(data),
"64": lambda data: base64.b64decode(data),
"85": lambda data: base64.b85decode(data),
}
def show_help():
print("""Usage:
python3 natools.py <command> [options]
Commands:
encrypt Encrypt data
decrypt Decrypt data
box-encrypt Encrypt data (NaCl box)
box-decrypt Decrypt data (NaCl box)
sign Sign data
verify Verify data
pubkey Display pubkey
pk Display b58 pubkey shorthand
Options:
-c Display pubkey checksum
-f <fmt> Private key format (default: cred)
key cred pubsec seedh ssb wif wifh
-i <path> Input file path (default: -)
-I <fmt> Input format: raw 16 32 58 64 85 (default: raw)
-k <path> Privkey file path (* for auto) (default: *)
-n <nonce> Nonce (b64, 24 bytes) (for NaCl box)
-N Attach nonce to output (for NaCl box encryption)
--noinc Do not include msg after signature
-o <path> Output file path (default: -)
-O <fmt> Output format: raw 16 32 58 64 64u 85 (default: raw)
-p <str> Pubkey (base58)
--help Show help
--version Show version
--debug Debug mode (display full errors)
Note: "-" means stdin or stdout.
""")
if __name__ == "__main__":
if "--help" in sys.argv:
show_help()
exit()
if "--version" in sys.argv:
print(__version__)
exit()
privkey_format = getargv("-f", "cred")
data_path = getargv("-i", "-")
privkey_path = getargv("-k", "*")
pubkey = getargv("-p")
result_path = getargv("-o", "-")
output_format = getargv("-O", "raw")
input_format = getargv("-I", "raw")
if pubkey:
pubkey, len_deprecated = check_pubkey(pubkey)
if not pubkey:
print("Invalid pubkey checksum! Please check spelling.")
exit(1)
if len(base58.b58decode(pubkey)) > 32:
print("Invalid pubkey: too long!")
exit(1)
if len_deprecated:
print("Warning: valid pubkey checksum, but deprecated format (truncating zeros)")
try:
if sys.argv[1] == "encrypt":
if not pubkey:
print("Please provide pubkey!")
exit(1)
write_data(fmt[output_format](encrypt(defmt[input_format](read_data(data_path)), pubkey)), result_path)
elif sys.argv[1] == "decrypt":
write_data(fmt[output_format](decrypt(defmt[input_format](read_data(data_path)), get_privkey(privkey_path, privkey_format))), result_path)
elif sys.argv[1] == "box-encrypt":
if not pubkey:
print("Please provide pubkey!")
exit(1)
nonce = getargv("-n", None)
if nonce:
nonce = base64.b64decode(nonce)
attach_nonce = "-N" in sys.argv
write_data(fmt[output_format](box_encrypt(defmt[input_format](read_data(data_path)), get_privkey(privkey_path, privkey_format), pubkey, nonce, attach_nonce)), result_path)
elif sys.argv[1] == "box-decrypt":
if not pubkey:
print("Please provide pubkey!")
exit(1)
nonce = getargv("-n", None)
if nonce:
nonce = base64.b64decode(nonce)
write_data(fmt[output_format](box_decrypt(defmt[input_format](read_data(data_path)), get_privkey(privkey_path, privkey_format), pubkey, nonce)), result_path)
elif sys.argv[1] == "sign":
data = defmt[input_format](read_data(data_path))
signed = sign(data, get_privkey(privkey_path, privkey_format))
if "--noinc" in sys.argv:
signed = signed[:len(signed)-len(data)]
write_data(fmt[output_format](signed), result_path)
elif sys.argv[1] == "verify":
if not pubkey:
print("Please provide pubkey!")
exit(1)
write_data(fmt[output_format](verify(defmt[input_format](read_data(data_path)), pubkey)), result_path)
elif sys.argv[1] == "pubkey":
if pubkey:
if "-c" in sys.argv and output_format == "58":
write_data("{}:{}".format(pubkey, pubkey_checksum(pubkey)).encode(), result_path)
else:
write_data(fmt[output_format](base58.b58decode(pubkey)), result_path)
else:
pubkey = get_privkey(privkey_path, privkey_format).pubkey
if "-c" in sys.argv and output_format == "58":
write_data("{}:{}".format(pubkey, pubkey_checksum(pubkey)).encode(), result_path)
else:
write_data(fmt[output_format](base58.b58decode(pubkey)), result_path)
elif sys.argv[1] == "pk":
if not pubkey:
pubkey = get_privkey(privkey_path, privkey_format).pubkey
if "-c" in sys.argv:
print("{}:{}".format(pubkey, pubkey_checksum(pubkey)))
else:
print(pubkey)
else:
show_help()
except Exception as e:
if "--debug" in sys.argv:
0/0 # DEBUG MODE (raise error when handling error to display backtrace)
sys.stderr.write("Error: {}\n".format(e))
show_help()
exit(1)

View File

@ -0,0 +1,6 @@
wheel
base58
pybase64
duniterpy
termcolor
python-dotenv

12
zen/jaklis/setup.sh Executable file
View File

@ -0,0 +1,12 @@
#!/bin/bash
for i in gcc python3-pip python3-setuptools libpq-dev python3-dev python3-wheel; do
if [ $(dpkg-query -W -f='${Status}' $i 2>/dev/null | grep -c "ok installed") -eq 0 ]; then
[[ ! $j ]] && sudo apt update
sudo apt install -y $i
j=1
fi
done
pip3 install -r requirements.txt
chmod u+x jaklis.py

127
zen/miam_miam.sh Executable file
View File

@ -0,0 +1,127 @@
#!/bin/bash
########################################################################
# Author: Fred (support@qo-op.com)
# Version: 2020.04.16
# License: AGPL-3.0 (https://choosealicense.com/licenses/agpl-3.0/)
########################################################################
MY_PATH="`dirname \"$0\"`" # relative
MY_PATH="`( cd \"$MY_PATH\" && pwd )`" # absolutized and normalized
ME="${0##*/}"
########################################################################
# \\///
# qo-op
############# '$ME' HELLO!! I am getting files from ~/.zen/miam
########################################################################
# ex: '$MY_PATH'/'$ME'
# MOVE ~/.zen/miam/* IN ZenTag AS PASSENGER
# Then find SSB same timestamp message and make a reply ;)
########################################################################
# [ASTROPORT](https://astroport.com)
########################################################################
echo '
___
|\/| | /\ |\/| |_ ._ _ ._
| | _|_ /--\ | | | | |_| | | (_| | \/
_| /
'
tstamp="$1"
# for tstamp in $(ls ~/.zen/miam/); do
[[ $tstamp == "" ]] && echo "MISSING tstamp $tstamp" && exit 1
[ ! -d ~/.zen/miam/$tstamp ] && echo "NOT FOUND ~/.zen/miam/$tstamp" && exit 1
[ -f ~/.zen/miam/$tstamp/msg_key ] && msg_key=$(cat ~/.zen/miam/$tstamp/msg_key) || echo "HEY I cannot find source SSB message in $tstamp" || exit 1
echo "$msg_key"
msg=$(sbotc get '{"id":"'"$msg_key"'"}')
[[ $msg == "" ]] && echo "No SSB message for $tstamp" && continue
msg_root=$(printf %s "$msg" | jq -r .value.content.root)
msg_branch=$(printf %s "$msg" | jq -r .value.content.branch)
# TREATING miam $tstamp FILES
echo "##############################################################"
for file in ~/.zen/miam/$tstamp/*; do
# file --mime-type "$file"
filename=$(basename -- "$file")
extension="${filename##*.}"
filena="${filename%.*}"
case "$extension" in
json)
JSON="$file"
echo "# METADATA FILE"
echo "$filename"
extractor=$(cat "$file" | jq -r '.extractor')
if [[ $extractor == "youtube" ]]; then
id=$(cat "$file" | jq -r '.id')
fulltitle=$(cat "$file" | jq -r '.fulltitle')
description=$(cat "$file" | jq -r '.description')
artist=$(cat "$file" | jq -r '.artist')
album=$(cat "$file" | jq -r '.album')
duration=$(cat "$file" | jq -r '.duration')
upload_date=$(cat "$file" | jq -r '.upload_date')
uploader_id=$(cat "$file" | jq -r '.uploader_id')
echo "YOUTUBE: $id : $fulltitle ($duration s) by $uploader_id "
else
echo "ERROR Unknown METADATA TYPE, please add some code here..." && JSON=""
fi
continue
;;
jpg)
JPG="$file"
echo "# THUMBNAIL FILE"
echo "$filename"
convert "$file" -strip -resize 640 -format jpg ~/.zen/miam/$tstamp/ssb_thumb.jpg
continue
;;
mp4)
MP4="$file"
echo "# VIDEO FILE"
echo "$filename"
continue
;;
mp3)
MP3="$file"
echo "# AUDIO FILE"
echo "$filename"
continue
;;
*)
echo "TYPE is UNKNOWN for $file" && UNKOWN="$file"
continue
;;
esac
done
# File analyse finished...
# WHAT DO WE HAVE THERE?
[[ "$JSON" == "" ]] && echo "NO METADATA !!!!" \
&& echo "BAD PASSENGER ERASING ~/.zen/miam/$tstamp" && rm -Rf ~/.zen/miam/$tstamp \
&& exit 1
[[ -f $MP3 ]] && $MY_PATH/zen_MAKE.sh "1000" "$tstamp" "$MP3" "$JSON" "10" "10"
[[ -f $MP4 ]] && $MY_PATH/zen_MAKE.sh "1000" "$tstamp" "$MP4" "$JSON" "10" "10"
# [[ -f $MP3 ]] && mv "$MP3" "~/.zen/audio/$fulltitle.mp3" # && lltag -a "$artist" -A "$album" -t "$fulltitle" "~/.zen/audio/$fulltitle.mp3"
# [[ -f $MP4 ]] && mv "$MP4" "~/.zen/video/$fulltitle.mp4"
# CLEAN A LITTLE
UNKOWN=""
MP3=""
MP4=""
JPG=""
JSON=""
[[ -d ~/.zen/miam/$tstamp && "$tstamp" != "" ]] && rm -Rf ~/.zen/miam/$tstamp && echo "# DELETE miam, it has been EATEN"
exit 0
#done

44
zen/no_SPAM.sh Executable file
View File

@ -0,0 +1,44 @@
#!/bin/bash
########################################################################
# Author: Fred (support@qo-op.com)
# Version: 2020.03.18
# License: AGPL-3.0 (https://choosealicense.com/licenses/agpl-3.0/)
########################################################################
MY_PATH="`dirname \"$0\"`" # relative
MY_PATH="`( cd \"$MY_PATH\" && pwd )`" # absolutized and normalized
########################################################################
# \\///
# qo-op
#############
##########################
#######################################
####################################################
########################################################################
########################################################################
# check /tmp/cmd_received_$SOURCEH and /tmp/cmd_SPAM_$SOURCEH within 1mn
# Remove older than a minute received COMMAND
find /tmp -cmin +1 -type f -name "cmd_received_*" -exec rm -f '{}' \; 2>/dev/null
# Filter Acknowlegement
if [[ "$CMD" != "ACK" && "$CMD" != "DELIVERED" && "$CMD" != "PENDING" ]]; then
# Still less than a minute with same $SOURCEH
if [[ -f "/tmp/cmd_received_$SOURCEH" ]]; then
# Create SPAM file => Stop answering
if [[ ! -f "/tmp/cmd_SPAM_$SOURCEH" ]]; then
echo $(date) > "/tmp/cmd_SPAM_$SOURCEH"
fi
return 1
fi
echo "$COMMAND" > "/tmp/cmd_received_$SOURCEH"
# Remove SPAM flag older than one day
find /tmp -ctime +1 -type f -name "cmd_SPAM_*" -exec rm -f '{}' \; 2>/dev/null
else
# THIS IS AN AKNOWLEGEMENT
return 1
fi
# Remove SPAM flag older than one day
find /tmp -ctime +1 -type f -name "cmd_SPAM_*" -exec rm -f '{}' \; 2>/dev/null
return 0

113
zen/park4night_MONITOR.sh Executable file
View File

@ -0,0 +1,113 @@
#!/bin/bash
################################################################################
# Author: Fred (support@qo-op.com)
# Version: 0.1
# License: AGPL-3.0 (https://choosealicense.com/licenses/agpl-3.0/)
################################################################################
# Extract last ads
# Thank you @kimamila for cesium & gchange
# ES backend http://www.elasticsearchtutorial.com/spatial-search-tutorial.html
MY_PATH="`dirname \"$0\"`" # relative
MY_PATH="`( cd \"$MY_PATH\" && pwd )`" # absolutized and normalized
mkdir ~/.zen/cache/gchange -p
ipfsnodeid=$(ipfs id -f='<id>\n')
[[ ! -f ~/.ssb/secret.dunikey ]] && $MY_PATH/tools/secret2dunikey.sh
g1pub=$(cat ~/.ssb/secret.dunikey | grep 'pub:' | cut -d ' ' -f 2)
CESIUM="https://g1.data.le-sou.org"
curl -sk ${CESIUM}/user/profile/${g1pub} -o ~/.zen/cache/cesium_profile.json
LON=$(cat ~/.zen/cache/cesium_profile.json | jq '._source.geoPoint.lon')
LAT=$(cat ~/.zen/cache/cesium_profile.json | jq '._source.geoPoint.lat')
RAD="$1"
[[ ! $RAD ]] && RAD="50km"
if [[ "$LON" != "null" ]]; then
curl -sk -XPOST 'https://data.gchange.fr/market/record/_search?pretty&_source=title' -d '
{
"size": 200,
"query": {
"bool": {
"filter": [{
"geo_distance": {
"distance": "'$RAD'",
"geoPoint": {
"lat": '$LAT',
"lon": '$LON'
}
}
}]
}
}
}' > /tmp/gchange.json || exit 1
else
echo "Aucune coordonnées geoPoint pour $g1pub"
sbotc publish '{"type":"post","text":"Ajouter sa géolocalisation dans Cesium+ permet de publier les annonces autour de chez soi..."}'
exit 1
fi
TIMEBEFORE=$(date -u --date="-$DELAY" +"%s")
TIMESTAMP=$(date -u +"%s")
TOTAL=$(cat /tmp/gchange.json | jq .hits.total)
echo 'tail -f ~/.zen/cache/gchange.txt'
echo 'Annonces_Gchange' > ~/.zen/cache/gchange.txt
echo "Portefeuille_[June_:heart:](https://demo.cesium.app/#/app/wot/$g1pub/)" >> ~/.zen/cache/gchange.txt
echo "Carte_[$RAD](https://www.openstreetmap.org/#map=10/$LAT/$LON) " >> ~/.zen/cache/gchange.txt
chunk=0
fullcount=0
DUNITERNODE=$($MY_PATH/tools/duniter_getnode.sh)
DUNITERURL="https://$DUNITERNODE"
LASTDU=$(curl -s ${DUNITERURL}/blockchain/with/ud | jq '.result.blocks[]' | tail -n 1);
[[ $LASTDU != "" ]] && LASTDU=$(curl -s ${DUNITERURL}/blockchain/block/${LASTDU} | jq '.dividend')
echo "DU = $LASTDU G1"
for gID in $(cat /tmp/gchange.json | jq -r .hits.hits[]._id); do
NEW=""
[[ ! -f ~/.zen/cache/gchange/$gID.json ]] &&
NEW="true" \
&& curl -s --create-dirs -o ~/.zen/cache/gchange/$gID.json -s https://data.gchange.fr/market/record/$gID?_source=category,title,description,issuer,time,creationTime,location,address,city,price,unit,currency,thumbnail._content_type,thumbnail._content,picturesCount,type,stock,fees,feesCurrency,geoPoint \
&& sleep $((1 + RANDOM % 3))
type=$(cat ~/.zen/cache/gchange/$gID.json | jq -r ._source.type)
stock=$(cat ~/.zen/cache/gchange/$gID.json | jq -r ._source.stock)
[[ $stock == 0 ]] && continue
# [[ $type == "need" ]] && continue
creationTime=$(cat ~/.zen/cache/gchange/$gID.json | jq -r ._source.creationTime)
title=$(cat ~/.zen/cache/gchange/$gID.json | jq -r ._source.title)
currency=$(cat ~/.zen/cache/gchange/$gID.json | jq -r ._source.currency)
price=$(cat ~/.zen/cache/gchange/$gID.json | jq -r ._source.price)
categoryname=$(cat ~/.zen/cache/gchange/$gID.json | jq -r ._source.category.name)
[[ $price == null ]] && price="0"
[[ $currency == "g1" ]] && love=$(bc -l <<< "scale=2; $price / $LASTDU * 100") || love="?.??"
love="$love_LOVE"
price=$(bc -l <<< "scale=2; $price / 100")
fullcount=$((fullcount+1)) && echo "DEBUG : $fullcount - $type - $price $currency - $title "
[[ $price == "0" ]] && love="..." && price="A débattre "
[[ $type == "offer" ]] && LINE="___OFFRE___[$title](https://data.gchange.fr/market/record/$gID/_share)_$love"
[[ $type == "need" ]] && LINE="__DEMANDE__[$title](https://data.gchange.fr/market/record/$gID/_share)_$love"
[[ $NEW == "true" ]] && echo "$LINE" >> ~/.zen/cache/gchange.txt && chunk=$((chunk+1)) && echo $chunk
done
echo "$chunk_nouvelles_annonces_($TOTAL)" >> ~/.zen/cache/gchange.txt
## TODO AUTOMATIC PUBLISHING \n and message size problem ??
if [[ $(cat ~/.zen/cache/gchange.txt | wc -c) -lt 8000 ]]; then
export raw="$(cat ~/.zen/cache/gchange.txt)"
annonces=$(node -p "JSON.stringify(process.env.raw)")
sbotc publish '{"type":"post","text":'$annonces'}'
fi
# EXTRA COULD CREATE IT'S OWN MAP with https://github.com/zicmama/tile-stitch.git
# And magick to overlay... But best would be a local map proxy...

Binary file not shown.

32
zen/port_SSH_one2one.sh Executable file
View File

@ -0,0 +1,32 @@
#!/bin/bash
################################################################################
# Author: Fred (support@qo-op.com)
# Version: 0.1
# License: AGPL-3.0 (https://choosealicense.com/licenses/agpl-3.0/)
################################################################################
# Activate SUPPORT MODE: open ssh over IPFS
MY_PATH="`dirname \"$0\"`" # relative
MY_PATH="`( cd \"$MY_PATH\" && pwd )`" # absolutized and normalized
########################################################################
YOU=$(ps auxf --sort=+utime | grep -w ipfs | grep -v -E 'color=auto|grep' | tail -n 1 | cut -d " " -f 1) || er+=" ipfs daemon not running"
IPFSNODEID=$(ipfs id -f='<id>\n') || er+=" ipfs id problem"
WHOAMI=$(sbotc whoami | jq -r .id) || er+=" sbotc whoami problem"
[[ "$YOU" == "" || "$IPFSNODEID" == "" || "$WHOAMI" == "" ]] && echo "ERROR : $er " && exit 1
########################################################################
# TODO ESTABLISH A PORT FORWARD STRATEGY (depending on Node Flavour)
# Arrange local port forwarded to swarm
# GET _uidna (means g1sms/init.sh been run)
[[ -f /home/$YOU/.zen/ipfs/.$IPFSNODEID/G1SSB/_uidna ]] && UIDNA=$(cat /home/$YOU/.zen/ipfs/.$IPFSNODEID/G1SSB/_uidna)
# G1sms SSB ID "@t+KD4vY/aLlNjWur6LfIEUqb06+E4cZNg3rokOqbFz0=.ed25519"
# IPFS ID : QmVywXoBSz7JZ5vunYYVwi72SdTizvFt7k7qd3ooyYHvHA
[[ "$IPFSNODEID" == "QmVywXoBSz7JZ5vunYYVwi72SdTizvFt7k7qd3ooyYHvHA" ]] && ipfs p2p listen /x/g1pub-ssh /ip4/127.0.0.1/tcp/22 # or CLOSE ipfs p2p close /x/g1pub-ssh
if [[ "$IPFSNODEID" == "QmVywXoBSz7JZ5vunYYVwi72SdTizvFt7k7qd3ooyYHvHA" ]]; then
# G1Pub : QmVywXoBSz7JZ5vunYYVwi72SdTizvFt7k7qd3ooyYHvHA
# I am a g1sms NODE, pushing my web interface
ipfs p2p listen /x/g1pub-ssh /ip4/127.0.0.1/tcp/22
fi

37
zen/port_ipfsp2p_g1sms_all.sh Executable file
View File

@ -0,0 +1,37 @@
#!/bin/bash
################################################################################
# Author: Fred (support@qo-op.com)
# Version: 0.1
# License: AGPL-3.0 (https://choosealicense.com/licenses/agpl-3.0/)
################################################################################
# Activate SUPPORT MODE: open ssh over IPFS
MY_PATH="`dirname \"$0\"`" # relative
MY_PATH="`( cd \"$MY_PATH\" && pwd )`" # absolutized and normalized
########################################################################
YOU=$(ps auxf --sort=+utime | grep -w ipfs | grep -v -E 'color=auto|grep' | tail -n 1 | cut -d " " -f 1) || er+=" ipfs daemon not running"
IPFSNODEID=$(ipfs id -f='<id>\n') || er+=" ipfs id problem"
WHOAMI=$(sbotc whoami | jq -r .id) || er+=" sbotc whoami problem"
[[ "$YOU" == "" || "$IPFSNODEID" == "" || "$WHOAMI" == "" ]] && echo "ERROR : $er " && exit 1
########################################################################
# TODO ESTABLISH A PORT FORWARD STRATEGY (depending on Node Flavour)
# Arrange local port forwarded to swarm
# GET _uidna (means g1sms/init.sh been run)
[[ -f /home/$YOU/.zen/ipfs/.$IPFSNODEID/G1SSB/_uidna ]] && UIDNA=$(cat /home/$YOU/.zen/ipfs/.$IPFSNODEID/G1SSB/_uidna)
if [[ $(which gammu) ]]; then
# I am a g1sms NODE, pushing my web interface
ipfs p2p listen /x/g1sms /ip4/127.0.0.1/tcp/10099
else
# Looking for g1sms NODE in my swarm
SMSNODE=$(ls /home/$YOU/.zen/ipfs_swarm/.12D3KooW*/G1SSB/_g1sms | shuf -n 1 | cut -d '/' -f 6 | cut -d '.' -f 2)
# Wait for DHT to propagate.... before getting eventual /x/g1sms forward
[[ $SMSNODE ]] && sleep $((1 + RANDOM % 10)) && ipfs p2p forward /x/g1sms /ip4/127.0.0.1/tcp/10097 /p2p/$SMSNODE
fi
# ipfs p2p close --all
# ipfs p2p listen /x/ssh-$UIDNA /ip4/127.0.0.1/tcp/22
# ipfs p2p listen /x/http-$UIDNA /ip4/127.0.0.1/tcp/80
# ipfs p2p listen /x/https-$UIDNA /ip4/127.0.0.1/tcp/443
ipfs p2p ls

107
zen/ssb_GET_zenyta.sh Executable file
View File

@ -0,0 +1,107 @@
#!/bin/bash
########################################################################
# Author: Fred (support@qo-op.com)
# Version: 2020.03.24
# License: AGPL-3.0 (https://choosealicense.com/licenses/agpl-3.0/)
########################################################################
MY_PATH="`dirname \"$0\"`" # relative
MY_PATH="`( cd \"$MY_PATH\" && pwd )`" # absolutized and normalized
ME="${0##*/}"
echo '
########################################################################
# \\///
# qo-op
############# '$MY_PATH/$ME'
########################################################################
# ex: ./'$ME'
# #zenyta = youtube-dl video to ~/.zen/miam/$timestamp
########################################################################
'
######## YOUTUBE-DL ##########
if [[ ! $(which youtube-dl) ]]; then
sudo curl -s https://yt-dl.org/downloads/latest/youtube-dl -o /usr/local/bin/youtube-dl || err=1
sudo chmod a+rx /usr/local/bin/youtube-dl
sudo chown $(whoami) /usr/local/bin/youtube-dl
fi
mkdir -p ~/.zen/miam/
self=$(sbotc whoami | jq -r .id) || exit 1
[[ "$self" == "" ]] && exit 1
g1self=$(echo $self | cut -d '@' -f 2 | cut -d '.' -f 1 | base64 -d | base58)
self_name=$(sbotc query.read '{"query":[{"$filter":{"value":{"author": "'"$self"'", "content":{"type":"about", "about": "'"$self"'"}}}}]}' | jq -r .value?.content?.name | grep -v null | tail -n 1)
ipfsnodeid=$(ipfs id -f='<id>\n')
current_ts=$(date -u +%s%N | cut -b1-13)
[ -s ~/.zen/zenyta.last.ts ] && last_ts=$(cat ~/.zen/zenyta.last.ts) || last_ts=$((current_ts - 24*3600*1000)) # 24h ago
last_ts=$((last_ts + 10))
echo "Hi, i am [$self_name]($self)
last timestamp: $last_ts"
echo '
a u d i o
_ _
__ _ _ _ __| | (_) ___
/ _` | | || | / _` | | | / _ \
\__,_| \_,_| \__,_| |_| \___/
'
#messages=$(sbotc messagesByType '{"type":"post","gt":'$last_ts'}')
# SEARCH "#zenyta" CMD in message text
echo "sbotc backlinks.read '{\"query\":[{\"\$filter\":{\"dest\":\"#zenyta\",\"value\":{\"content\":{\"type\":\"post\"}},\"timestamp\":{\"\$gt\":'\"$last_ts\"'}}}]}'"
messages=$(sbotc backlinks.read '{"query":[{"$filter":{"dest":"#zenyta","value":{"content":{"type":"post"}},"timestamp":{"$gt":'"$last_ts"'}}}]}')
[[ $messages == "" ]] && messages=$(sbotc query.read '{"query":[{"$filter":{"value":{"author": "'"$WHOAMI"'", "content":{"type":"zenyta"}}}}]}') && echo "sbotc query.read '{\"query\":[{\"\$filter\":{\"value\":{\"author\": \"'"$WHOAMI"'\", \"content\":{\"type\":\"zenyta\"}}}}]}'"
while read -r msg
do
# EXTRACT CMD PARAM
msg_key=$(printf %s "$msg" | jq -r .key)
author=$(printf %s "$msg" | jq -r .value.author)
timestamp=$(printf %s "$msg" | jq -r .value.timestamp)
# TEST CURRENT NODE last_ts
[[ $timestamp -lt $last_ts ]] && echo "$last_ts: ALREADY DONE $msg_key timestamp is $timestamp " && continue
# SWARM REFRESH
$MY_PATH/ipfs_SWARM_refresh.sh
# SWARM ALREADY DONE IT ??
# IS LIKE "SELECT FROM ipfs_swarm WHERE _tag.zensource=$timestamp"(or something like that in SQL), means a ZenTag already exists.
CHECKSWARM=$(grep -Rwl "$timestamp" ~/.zen/ipfs_swarm/.12D3KooW*/TAG/*/_tag.zensource | tail -n 1 | cut -f 6 -d '/')
# OR SWARM PROCESS IN ACTION (NB: copy tasks must be asynchronous in swarm)
[[ ! $CHECKSWARM ]] && CHECKSWARM=$(grep -Rwl "$timestamp" ~/.zen/ipfs_swarm/.12D3KooW*/TAG/process.timestamp.ssb | tail -n 1 | cut -f 6 -d '/')
[[ $CHECKSWARM ]] \
&& echo "$timestamp ALREADY on NODE $CHECKSWARM CONTINUE" \
&& echo "$timestamp" > ~/.zen/zenyta.last.ts \
&& continue
# ANTI DOUBLE COPY START
echo "$timestamp" > ~/.zen/ipfs/.$ipfsnodeid/process.timestamp.ssb
$MY_PATH/ipfs_SWARM_refresh.sh
# ANTI DOUBLE COPY
msg_root=$(printf %s "$msg" | jq -r .value.content.root)
msg_branch=$(printf %s "$msg" | jq -r .value.content.branch)
msg_text=$(printf %s "$msg" | jq -r .value.content.text)
msg_ytdlurl=$(echo $msg_text | egrep -o 'https?://[^ ]+' | grep you | cut -d '\' -f 1 | tail -n 1)
# YOUTUBE-DL AUDIO
[[ $timestamp ]] && mkdir -p ~/.zen/miam/$timestamp
[[ $msg_ytdlurl ]] && /usr/local/bin/youtube-dl -x --audio-format mp3 \
--write-thumbnail --write-info-json --add-metadata --embed-thumbnail \
--no-mtime -o "~/.zen/miam/$timestamp/%(id)s.%(ext)s" $msg_ytdlurl
# REFERENCE msg_key AND timestamp
[[ $timestamp ]] && echo "$((timestamp + 1))" > ~/.zen/zenyta.last.ts
[[ $msg_key ]] && echo "$msg_key" > ~/.zen/miam/$timestamp/msg_key
$MY_PATH/miam_miam.sh "$timestamp"
# ANTI DOUBLE COPY END
rm ~/.zen/ipfs/.$ipfsnodeid/process.timestamp.ssb
$MY_PATH/ipfs_SWARM_refresh.sh
# ANTI DOUBLE COPY
done < <(printf '%s\n' "$messages")

109
zen/ssb_GET_zenytv.sh Executable file
View File

@ -0,0 +1,109 @@
#!/bin/bash
########################################################################
# Author: Fred (support@qo-op.com)
# Version: 2020.03.24
# License: AGPL-3.0 (https://choosealicense.com/licenses/agpl-3.0/)
########################################################################
MY_PATH="`dirname \"$0\"`" # relative
MY_PATH="`( cd \"$MY_PATH\" && pwd )`" # absolutized and normalized
ME="${0##*/}"
########################################################################
# \\///
# qo-op
############# '$MY_PATH/$ME'
########################################################################
# ex: ./'$ME'
# #zenytv = youtube-dl video to ~/.zen/miam/$timestamp
########################################################################
######## YOUTUBE-DL ##########
if [[ ! $(which youtube-dl) ]]; then
sudo curl -s https://yt-dl.org/downloads/latest/youtube-dl -o /usr/local/bin/youtube-dl || err=1
sudo chmod a+rx /usr/local/bin/youtube-dl
sudo chown $(whoami) /usr/local/bin/youtube-dl
fi
mkdir -p ~/.zen/miam/
self=$(sbotc whoami | jq -r .id) || exit 1
[[ "$self" == "" ]] && exit 1
g1self=$(echo $self | cut -d '@' -f 2 | cut -d '.' -f 1 | base64 -d | base58)
self_name=$(sbotc query.read '{"query":[{"$filter":{"value":{"author": "'"$self"'", "content":{"type":"about", "about": "'"$self"'"}}}}]}' | jq -r .value?.content?.name | grep -v null | tail -n 1)
ipfsnodeid=$(ipfs id -f='<id>\n')
current_ts=$(date -u +%s%N | cut -b1-13)
[ -s ~/.zen/zenytv.last.ts ] && last_ts=$(cat ~/.zen/zenytv.last.ts) || last_ts=$((current_ts - 24*3600*1000)) # 24h ago
# last_ts=$((last_ts + 10))
echo "Hi, i am [$self_name]($self)
last timestamp: $last_ts"
echo '
v i d e o
_ _
__ __ (_) __| | ___ ___
\ V / | | / _` | / -_) / _ \
\_/ |_| \__,_| \___| \___/
'
#messages=$(sbotc messagesByType '{"type":"post","gt":'$last_ts'}')
# SEARCH "#zenytv" CMD in message text
echo "sbotc backlinks.read '{\"query\":[{\"\$filter\":{\"dest\":\"#zenytv\",\"value\":{\"content\":{\"type\":\"post\"}},\"timestamp\":{\"\$gt\":'\"$last_ts\"'}}}]}'"
messages=$(sbotc backlinks.read '{"query":[{"$filter":{"dest":"#zenytv","value":{"content":{"type":"post"}},"timestamp":{"$gt":'"$last_ts"'}}}]}')
[[ $messages == "" ]] && exit 1
while read -r msg
do
# EXTRACT CMD PARAM
msg_key=$(printf %s "$msg" | jq -r .key)
author=$(printf %s "$msg" | jq -r .value.author)
timestamp=$(printf %s "$msg" | jq -r .value.timestamp)
# TEST CURRENT NODE last_ts
[[ $timestamp -lt $last_ts ]] && echo "ALREADY DONE $msg_key timestamp is $timestamp " && continue
# SWARM REFRESH
$MY_PATH/ipfs_SWARM_refresh.sh
# SWARM ALREADY DONE
CHECKSWARM=$(grep -Rwl "$timestamp" ~/.zen/ipfs_swarm/.12D3KooW*/TAG/*/_tag.zensource | tail -n 1 | cut -f 6 -d '/')
# OR SWARM PROCESS IN ACTION
[[ ! $CHECKSWARM ]] && CHECKSWARM=$(grep -Rwl "$timestamp" ~/.zen/ipfs_swarm/.12D3KooW*/TAG/process.timestamp.ssb | tail -n 1 | cut -f 6 -d '/')
[[ $CHECKSWARM ]] \
&& echo "$timestamp ALREADY on NODE $CHECKSWARM CONTINUE" \
&& echo "$timestamp" > ~/.zen/zenytv.last.ts \
&& continue
# ANTI DOUBLE COPY START
echo "$timestamp" > ~/.zen/ipfs/.$ipfsnodeid/process.timestamp.ssb
$MY_PATH/ipfs_SWARM_refresh.sh
# ANTI DOUBLE COPY
msg_root=$(printf %s "$msg" | jq -r .value.content.root)
msg_branch=$(printf %s "$msg" | jq -r .value.content.branch)
msg_text=$(printf %s "$msg" | jq -r .value.content.text)
msg_ytdlurl=$(echo $msg_text | egrep -o 'https?://[^ ]+' | grep you | cut -d '\' -f 1 | tail -n 1)
# YOUTUBE-DL VIDEO
[[ $timestamp ]] && mkdir -p ~/.zen/miam/$timestamp
[[ $msg_ytdlurl ]] && /usr/local/bin/youtube-dl -f '[height=720]/best' \
--write-thumbnail --all-subs --write-info-json --write-annotations \
--no-mtime -o "~/.zen/miam/$timestamp/%(id)s.%(ext)s" $msg_ytdlurl
# ###### TODO make gif tu push to SSB
# ffmpeg -ss 00:00:00.000 -i yesbuddy.mov -pix_fmt rgb24 -r 10 -s 320x240 -t 00:00:10.000 output.gif
# convert -layers Optimize output.gif output_optimized.gif
# REFERENCE msg_key AND timestamp
[[ $timestamp ]] && echo "$((timestamp))" > ~/.zen/zenytv.last.ts
[[ $msg_key ]] && echo "$msg_key" > ~/.zen/miam/$timestamp/msg_key
$MY_PATH/miam_miam.sh "$timestamp"
# ANTI DOUBLE COPY END
echo "$timestamp" > ~/.zen/ipfs/.$ipfsnodeid/process.timestamp.ssb
$MY_PATH/ipfs_SWARM_refresh.sh
# ANTI DOUBLE COPY
done < <(printf '%s\n' "$messages")

260
zen/ssb_INIT.sh Executable file
View File

@ -0,0 +1,260 @@
#!/bin/bash
########################################################################
# Author: Fred (support@qo-op.com)
# Version: 2020.03.21
# License: AGPL-3.0 (https://choosealicense.com/licenses/agpl-3.0/)
########################################################################
MY_PATH="`dirname \"$0\"`" # relative
MY_PATH="`( cd \"$MY_PATH\" && pwd )`" # absolutized and normalized
ME="${0##*/}"
echo '
########################################################################
# \\///
# qo-op
############# '$MY_PATH/$ME'
########################################################################
# ex: ./'$ME'
# Initialize G1SSB + SSB About + IPFS Node publish
########################################################################
o__ __o __o o__ __o o__ __o o__ __o
/v v\ __|> /v v\ /v v\ <| v\
/> <\ | /> <\ /> <\ / \ <\
o/ <o> _\o____ _\o____ \o/ o/
<| _\__o__ | \_\__o__ \_\__o__ |__ _<|
\\ | < > \ \ | \
\ / | \ / \ / <o> /
o o o o o o o | o
<\__ __/> __|>_ <\__ __/> <\__ __/> / \ __/>
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# [ASTROPORT](https://astroport.com)
########################################################################
'
########################################################################
# ENVIRONEMENT DETECTION + IPFS ~/.zen/ipfs/.$IPFSNODEID/G1SSB/_info
########################################################################
YOU=$(ps auxf --sort=+utime | grep -w ipfs | grep -v -E 'color=auto|grep' | tail -n 1 | cut -d " " -f 1);
IPFSNODEID=$(ipfs id -f='<id>\n')
[[ $IPFSNODEID == "" ]] && echo "ERROR missing IPFS Node id !! IPFS is not installed !?" && exit 1
########################################################################
WHOAMI=$(sbotc whoami 2>/dev/null | jq -r .id)
[[ $WHOAMI == "" ]] && echo "ERROR sbotc NOT running !! Please check it..." && exit 1
########################################################################
[[ ! -f ~/.ssb/secret.dunikey ]] && $MY_PATH/tools/secret2dunikey.sh
G1PUB=$(cat ~/.ssb/secret.dunikey | grep 'pub:' | cut -d ' ' -f 2)
[[ $G1PUB == "" ]] && echo "ERROR G1PUB empty !! Please check it..." && exit 1
########################################################################
# GET NODE disk performance. TODO, publish and use as IPFS repartition
echo "DISK SIZE AVAILABLE & PERFORMANCE TESTING"
[[ -f ~/.zen/test.disk ]] && rm -f ~/.zen/test.disk
diskperf=$(dd if=/dev/zero of=~/.zen/test.disk bs=10M count=1 oflag=dsync 2>&1 | tail -n 1 | sed s/\,\ /\ -/g | cut -d '-' -f 4)
# echo $diskperf
sizeAvail=$(df -h ~/.ipfs/ | tail -n 1 | awk '{print $4}')
# IPFS LOCAL REPOSITORY for Node Identity G1 + SSB
mkdir -p ~/.zen/ipfs/.$IPFSNODEID/G1SSB
# SSB PUBLISH EXTRA ipfs informations !!
# TODO CHECK FOR NOT MAKING DOUBLE PUBLICATION (lower noisy init)
# This SSB messages are read by ./zen/ssb_IPFS_swarm.sh to build your IPFS #Swarm0
sbotc publish '{"type":"ipfsnodeid","text":"'"$(ipfs id -f='<id>\n')"'"}'
# PUBLISH default "eth" NOT isLAN IP addresses for ./zen/ssb_IPFS_swarm.sh
tryme=$(ipfs id | jq -r .Addresses[] | tail -n 1 )
isLAN=$(echo $tryme | cut -f3 -d '/' | grep -E "/(^127\.)|(^192\.168\.)|(^fd42\:)|(^10\.)|(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|(^::1$)|(^[fF][cCdD])/")
[[ ! $isLAN ]] && sbotc publish '{"type":"ipfstryme","text":"'"$tryme"'"}'
trymev4=$(ipfs id | jq -r .Addresses[] | grep $(hostname -I | cut -f 1 -d ' '))
isLANv4=$(echo $trymev4 | cut -f3 -d '/' | grep -E "/(^127\.)|(^192\.168\.)|(^fd42\:)|(^10\.)|(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|(^::1$)|(^[fF][cCdD])/")
[[ $isLAN && ! $isLANv4 ]] && sbotc publish '{"type":"ipfstryme","text":"'"$trymev4"'"}' && tryme="$trymev4"
trymev6=$(ipfs id | jq -r .Addresses[] | grep $(hostname -I | cut -f 2 -d ' '))
isLANv6=$(echo $trymev6 | cut -f3 -d '/' | grep -E "/(^127\.)|(^192\.168\.)|(^fd42\:)|(^10\.)|(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|(^::1$)|(^[fF][cCdD])/")
[[ $isLAN && $isLANv4 && ! $isLANv6 ]] && sbotc publish '{"type":"ipfstryme","text":"'"$trymev6"'"}' && tryme="$trymev6"
################################
# ADD Cesium+ informations
CESIUM="https://g1.data.le-sou.org"
# PREPARE title
# Made from Cesium+ profile tittle and city OR user@hostname
title=$(curl -s ${CESIUM}/user/profile/${G1PUB} | jq -r '._source.title')
[[ -f ~/.zen/ipfs/.$IPFSNODEID/G1SSB/_uidna ]] && uidna=$(cat ~/.zen/ipfs/.$IPFSNODEID/G1SSB/_uidna)
# Put in .$IPFSNODEID INDEX: _g1.uidna & _g1.cesium_name (used by Minetest flavour and others)
[[ $uidna ]] && echo "$uidna" > ~/.zen/ipfs/.$IPFSNODEID/G1SSB/_g1.uidna
[[ $title ]] && echo "$title" > ~/.zen/ipfs/.$IPFSNODEID/G1SSB/_g1.cesium_name
[[ $uidna ]] && [[ "$title" == "null" ]] && title="Station $uidna"
[[ "$title" == "null" ]] && title="Station $USER@$(cat /etc/hostname)"
city=$(curl -s ${CESIUM}/user/profile/${G1PUB} | jq -r '._source.city')
[[ "$city" != "null" ]] && title="$title in $city"
# ADD "cesium_geoPoint.lat" AND "cesium_geoPoint.lon" messages in SSB feed
# This way any SSB account is connected to its Cesium+ Geolocalisation.
geopointlat=$(curl -s ${CESIUM}/user/profile/${G1PUB} | jq '._source.geoPoint.lat')
[[ $geopointlat != null ]] && sbotc publish '{"type":"cesium_geoPoint.lat","text":"'"$geopointlat"'"}'
geopointlon=$(curl -s ${CESIUM}/user/profile/${G1PUB} | jq '._source.geoPoint.lon')
[[ $geopointlon != null ]] && sbotc publish '{"type":"cesium_geoPoint.lon","text":"'"$geopointlon"'"}'
# REFRESH Cesium+ Avatar image
curl -s ${CESIUM}/user/profile/${G1PUB} | jq -r '._source.avatar._content' | base64 -d > "/tmp/_g1.avatar.png"
## PUBLISH ABOUT MESSAGE
##############################################
# PICTURE: IF AVATAR not png take IMAGE of G1 wallet QRCode
qrencode -s 5 -o ~/.zen/ipfs/.$IPFSNODEID/G1SSB/_g1.qrcode.png "$G1PUB"
imagefile=~/.zen/ipfs/.$IPFSNODEID/G1SSB/_g1.qrcode.png
qrname=${imagefile##*/}
qrid="$(sbotc blobs.add < $imagefile)"
qrtype="$(file -b --mime-type $imagefile)"
qrsize="$(wc -c < $imagefile)"
if [[ ! $(file "/tmp/_g1.avatar.png" | grep 'PNG') ]]; then
echo "NO Cesium AVATAR - Using G1Pub QRCode"
rm -f /tmp/_g1.avatar.png
else
echo "AVATAR FOUND"
imagefile=/tmp/_g1.avatar.png
# PUBLISH AVATAR TO IPFS
cp /tmp/_g1.avatar.png ~/.zen/ipfs/.$IPFSNODEID/G1SSB/
fi
# Prepare QRCode File for SSB (add to blobs)
name=${imagefile##*/}
id="$(sbotc blobs.add < $imagefile)"
type="$(file -b --mime-type $imagefile)"
size="$(wc -c < $imagefile)"
echo "
/\ |_ _ _|_
/--\|_)(_)|_||_ : PUBLISH to SSB feed...
$WHOAMI
$title
$imagefile
$id : $type : $size bits
"
# NOT WORKING, sudo inside !!!
#nodename=$(~/.zen/astroport/zen/tools/nodename)
nodename=$(cat /home/$YOU/.zen/ipfs/.$IPFSNODEID/G1SSB/_nodename)
if [[ $nodename == "" ]]; then
nodename=$(cat /etc/hostname)
extension=$(echo $nodename | cut -d '.' -f 2)
if [[ $extension == $nodename ]]; then
nodename=$nodename.home
fi
fi
########################################################################
# DUNITER G1 Wallet balance
export LC_ALL=C.UTF-8 #attipix
export LANG=C.UTF-8 #attipix
DUNITERNODE=$($MY_PATH/tools/duniter_getnode.sh)
echo "DEBUG: silkaj -p $DUNITERNODE balance $G1PUB"
[[ $DUNITERNODE ]] && g1balance=$(silkaj -p $DUNITERNODE balance $G1PUB 2>&1) || g1balance=$(silkaj balance $G1PUB 2>&1)
silkajQuantitativeAmountPattern='Total\sQuantitative\s+=\s+(.*)\s+Ğ1'
if [[ $g1balance =~ $silkajQuantitativeAmountPattern ]]
then
myJune="${BASH_REMATCH[1]}"
else
myJune="0"
fi
DUFACTOR=$(bc <<< "scale=2; $(cat /home/$YOU/.zen/_DU) / 100")
AMOUNTLOVE=$(bc -l <<< "scale=0; $myJune * 100 / $DUFACTOR")
# OLD ssb-server publish
# sbot publish --type about --about $WHOAMI --description "[Astroport Node](https://astroport.com) [$IPFSNODEID](http://localhost:8080/ipns/$IPFSNODEID) - Wallet $G1PUB - $diskperf" --name "$title" --image "$id"
# NEW sbotc publish to oasis
sbotc publish "{\"type\":\"about\",\"about\":\"$WHOAMI\",\"description\":\"![QRCode]($qrid)\\n[Station Astroport](https://astroport.com)\\n - [Mon Marché](https://gchange.fr/#/app/wot/$G1PUB) \\n - [Mon portefeuille ($AMOUNTLOVE :heart:)](https://cesium.app/) \\n Station ID : [$IPFSNODEID](http://localhost:8080/ipns/$IPFSNODEID) \\n Disque: $sizeAvail = $diskperf \\n - [Portail](http://$nodename:10010/) \\n\",\"name\":\"$title\",\"image\":\"$id\"}"
# SSB PUBLISH G1 wallet silkaj balance
json_escape () {
printf '%s' "$1" | python -c 'import json,sys; print(json.dumps(sys.stdin.read()))'
}
INLINE=$(json_escape "$g1balance")
# TODO FIND WHY THIS ***** COMA , IS EVERYWHERE NOT PUBLSHING silkaj
# [[ $INLINE ]] && sbotc publish '{"type":"post","text":'$INLINE'}'
#INLINE="${g1balance@Q}"
#[[ $INLINE ]] && sbotc publish '{"type":"post","text":"'$INLINE'"}'
echo "
_ _
/ \|_) _ _ _| _
\_X| \ (_(_)(_|(/_ ! AVATAR
$g1balance
~/.zen/ipfs/.$IPFSNODEID/G1SSB/_g1.qrcode.png
-- sbotc publish --
"
# IF no AVATAR, publish message with QRCode
if [[ ! $(file "/tmp/_g1.avatar.png" | grep 'PNG') ]]; then
sleep 1
# sbotc publish '{"type":"post","text":"![QRCode]('"$qrid"')\n Scan QRCode with [Cesium](https://cesium.app).\n Thank you\n ONE :heart:","mentions":[{"link":"'"$id"'","name":"'"$name"'","size":'"$size"',"type":"'"$type"'"}]}'
else
# Publish only if new avatar
if [[ $(diff /tmp/_g1.avatar.png ~/.zen/ipfs/.$IPFSNODEID/G1SSB/_g1.avatar.png) ]]; then
sbotc publish '{"type":"post","text":"![Cesium Avatar]('"$id"')\n from my Wallet [Cesium](https://demo.cesium.app/#/app/wot/'"$G1PUB"') '"$G1PUB"'","mentions":[{"link":"'"$id"'","name":"'"$name"'","size":'"$size"',"type":"'"$type"'"}]}'
fi
fi
echo "
___ _ _ __
| |_)|_(_ _. _| _|
_|_| | __) (_|(_|(_|
~/.zen/ipfs
ipfs ls /ipns/$IPFSNODEID
"
# COPY NODE G1SSB ID to IPFS
echo "$WHOAMI" > ~/.zen/ipfs/.$IPFSNODEID/G1SSB/_ssb.whoami
echo "$G1PUB" > ~/.zen/ipfs/.$IPFSNODEID/G1SSB/_g1.pubkey
# IPFS Node PUBLISH Adresses so Pub can become bootstrap for ${g1author}
ipfs id | jq -r .Addresses[] > ~/.zen/ipfs/.${IPFSNODEID}/Addresses
# IPFS Node PUBLISH AgentVersion & repo.stat
ipfs id | jq -r .AgentVersion > ~/.zen/ipfs/.${IPFSNODEID}/AgentVersion
ipfs repo stat > ~/.zen/ipfs/.${IPFSNODEID}/repo.stat
echo "$tryme" > ~/.zen/ipfs/.${IPFSNODEID}/tryme.addr
echo "$diskperf" > ~/.zen/ipfs/.${IPFSNODEID}/disk.perf
echo $(df ~/.ipfs/ | tail -n 1 | awk '{print $4}') > ~/.zen/ipfs/.${IPFSNODEID}/disk.bytes
IWALLETS=$(ipfs add -rHq ~/.zen/ipfs | tail -n 1)
NODEIPNS=$(ipfs name publish --allow-offline --quieter /ipfs/$IWALLETS)
echo "
ipfs ls /ipns/$IPFSNODEID/.$IPFSNODEID/
_ _ _ _ _
(_)_ ____ _(_) |_ __ _| |_(_) ___ _ __
| | _ \ \ / / | __/ _| | __| |/ _ \| _ \
| | | | \ V /| | || (_| | |_| | (_) | | | |
|_|_| |_|\_/ |_|\__\__|_|\__|_|\___/|_| |_|
# This INVITE is to be sent an to 'Astroport Station' willing to Join our IPFS Swarm.
# see 'ssb_SURVEY_contact.sh' for commands executed...
"
echo "INVITATION LINK (only works in LAN or WAN depending on your Node)"
sbotc invite.create 1 2>/dev/null
#read ssb_invit_link
#sbotc invite.accept $ssb_invit_link
exit 0

99
zen/ssb_IPFS_swarm.sh Executable file
View File

@ -0,0 +1,99 @@
#!/bin/bash
########################################################################
# Author: Fred (support@qo-op.com)
# Version: 2020.04.27
# License: AGPL-3.0 (https://choosealicense.com/licenses/agpl-3.0/)
########################################################################
MY_PATH="`dirname \"$0\"`" # relative
MY_PATH="`( cd \"$MY_PATH\" && pwd )`" # absolutized and normalized
ME="${0##*/}"
########################################################################
# \\///
# qo-op
############# '$MY_PATH/$ME'
########################################################################
# ex: ./'$ME'
# GET SSB FRIENDS AND FIND THEIR IPFS ID TO "ipfs swarm connect" THEM
########################################################################'
## TODO: REMOVE DUPLICATES
## TODO: MODE : COOL, STRAIGHT, ARMORED
########################################################################
## CONNECT GLOBAL "ipfs.io" ## DANGEROUS only for short time...
########################################################################
# ADD ipfs.io public bootstrap into your swarm peers
# RUN: cat ~/.zen/astroport/ipfs.swarm.ipfs.io | ipfs swarm connect
# SOON ipfs swarm peers will GROW!!! YOU ARE VSIBLE !!!
# RUN: sudo systemctl restart ipfs # GOES BACK TO SWARM0
########################################################################
########################################################################
# ENVIRONEMENT DETECTION + IPFS ~/.zen/ipfs/.$IPFSNODEID/G1SSB/_info
########################################################################
IPFSNODEID=$(ipfs id -f='<id>\n')
[[ $IPFSNODEID == "" ]] && echo "ERROR missing IPFS Node id !! IPFS is not installed !?" && exit 1
########################################################################
echo '
__ __ ____
__/ // /_______ ______ __________ ___ / __ \
/_ _ __/ ___/ | /| / / __ `/ ___/ __ `__ \/ / / /
/_ _ __(__ )| |/ |/ / /_/ / / / / / / / / /_/ /
/_//_/ /____/ |__/|__/\__,_/_/ /_/ /_/ /_/\____/
EXTEND IPFS SWARM and SHAPE IT FROM (ssb_INIT.sh) FRIENDS
Search "ipfstryme" message type in SSB feed
'
[[ ! $WHOAMI ]] && WHOAMI=$($MY_PATH/tools/timeout.sh -t 3 sbotc whoami | jq -r .id)
########################################################################
# GET /tmp/ssb-friends.txt
sbotc query.read '{"query":[{"$filter":{"value":{"author": "'"$WHOAMI"'", "content":{"type":"contact"}}}}]}' | jq -r '.value?.content?.contact' > /tmp/ssb-friends.txt
# GET /tmp/ssb-NOTfriends.txt
sbotc links "{\"source\": \"${WHOAMI}\", \"rel\": \"contact\", \"values\": true, \"reverse\": true}" | jq -c . | grep 'blocking":true' | jq -r .dest > /tmp/ssb-NOTfriends.txt
count=1
########################################################################
# Let's look if our SSB Friends ARE "IPFS swarm connected"
########################################################################
echo "" > /tmp/This_NOTfriends_are_astroport
echo "" > /tmp/This_friends_connect_astroport
echo "" > /tmp/This_friends_should_install_astroport
### TODO -> send sbotc message (private or zip attached?) with this reports
for SSBFRIEND in $(uniq /tmp/ssb-friends.txt); do
# Force Strict #swarm0 !!
[[ $count == 1 ]] && ipfs bootstrap rm --all
### sbotc $SSBFRIEND name
MYFRIEND=$(sbotc query.read '{"query":[{"$filter":{"value":{"author": "'"$SSBFRIEND"'", "content":{"type":"about", "about": "'"$SSBFRIEND"'"}}}}]}' | jq -r .value?.content?.name | grep -v null | tail -n 1)
### GET SSB "ipfstryme" message type !!! Astroport Node should have publish it during "ssb_INIT.sh"
TRYME=$(sbotc query.read '{"query":[{"$filter":{"value":{"author": "'"$SSBFRIEND"'", "content":{"type":"ipfstryme"}}}}]}' | jq -r .value?.content?.text | tail -n 1)
## !! REMOVE NOTfriends from IPFS swarm
[[ $TRYME ]] && [[ $(grep -Rwl "$SSBFRIEND" /tmp/ssb-NOTfriends.txt) ]] && MES="($count) HUMMMM $MYFRIEND ($SSBFRIEND) IS NOT my friend disconnecting" && ipfs swarm disconnect $TRYME && ipfs bootstrap rm $TRYME && echo $MES >> /tmp/This_NOTfriends_are_astroport && continue
## Ici, on peut décider de demander à faire supprimer la couche astroport à son PAS AMI
## ADD Friend to our IPFS swarm
[[ $TRYME ]] && MES="($count) $MYFRIEND ($SSBFRIEND) connect OK $TRYME" && ipfs swarm connect $TRYME && ipfs bootstrap add $TRYME && echo $MES >> /tmp/This_friends_connect_astroport
## Ce pote est connecté IPFS avec moi
## This_friends_should_install_astroport
[[ ! $TRYME ]] && MES="($count) $MYFRIEND ($SSBFRIEND) is NOT running ASTROPORT !!!" && echo $MES >> /tmp/This_friends_should_install_astroport
### WHAT HAPPENED this loop on my ssb friends
echo $MES
echo "_________________________________________________"
count=$((count+1))
done
echo "__________________________________________
$WHOAMI ipfs peers are:"
ipfs swarm peers

134
zen/ssb_SURVEY_contact.sh Executable file
View File

@ -0,0 +1,134 @@
#!/bin/bash
########################################################################
# Author: Fred (support@qo-op.com)
# Version: 2020.03.24
# License: AGPL-3.0 (https://choosealicense.com/licenses/agpl-3.0/)
########################################################################
MY_PATH="`dirname \"$0\"`" # relative
MY_PATH="`( cd \"$MY_PATH\" && pwd )`" # absolutized and normalized
ME="${0##*/}"
echo '
########################################################################
# \\///
# qo-op
############# '$MY_PATH/$ME'
########################################################################
# ex: ./'$ME'
# SURVEY SSB contact from "invite" is happening in feed
######################################################################## _ _ _ _ _
(_)_ ____ _(_) |_ __ _| |_(_) ___ _ __
| | _ \ \ / / | __/ _| | __| |/ _ \| _ \
| | | | \ V /| | || (_| | |_| | (_) | | | |
|_|_| |_|\_/ |_|\__\__|_|\__|_|\___/|_| |_| contact SURVEY
# New Station is joining ASTROPORT !!
DETECT in SSB feed messages "type": "contact", "autofollow": true
LIKE
https://tube.p2p.legal/videos/watch/ef319fdd-caf1-4e03-ba22-91c456e94f73
{
"key": "%jVQewn0/ey0tfdvYCjYXJqVivaaZ6NpeUL9xK5QeGTk=.sha256",
"value": {
"previous": "%ilrZ+8CvMXpu09LWh75Uq37j7lVJnoxTvipyooRSjpg=.sha256",
"sequence": 3,
"author": "@S2KB1zRQNAuCRs1vW08c+63+0gjI2egDj4pjUUrt+dw=.ed25519",
"timestamp": 1585068288462,
"hash": "sha256",
"content": {
"type": "contact",
"following": true,
"autofollow": true,
"contact": "@t/giTDc0EtzdPQGC7iAAzgzVOkFo++XZRvzOOlqgX1c=.ed25519"
},
"signature": "kXsFqfBGqZXZApf7UANDYlqnwLXuGdWFbMMofljBOp4dNGc4dAv+P2hzK3XV/jPT8a1u7PHIraJASugR1NCLCw==.sig.ed25519"
},
"timestamp": 1585068290213
}
'
# CACHE
[[ ! -d ~/.zen/ssb_contact ]] && mkdir -p ~/.zen/ssb_contact
self=$(sbotc whoami | jq -r .id) || exit 1
g1self=$(echo $self | cut -d '@' -f 2 | cut -d '.' -f 1 | base64 -d | base58)
self_name=$(sbotc query.read '{"query":[{"$filter":{"value":{"author": "'"$self"'", "content":{"type":"about", "about": "'"$self"'"}}}}]}' | jq -r .value?.content?.name | grep -v null | tail -n 1)
messages=$(sbotc query.read '{"query":[{"$filter":{"value":{"content":{"type":"contact", "contact":"'"$self"'", "autofollow":true}}}}]}')
while read -r msg
do
timestamp=$(printf %s "$msg" | jq .value.timestamp)
echo '
_ _ ___ ____
/ / \|\ || /\ / |
\_\_/| \||/--\\_ | FROM NEW STATION'
echo $timestamp
author=$(printf %s "$msg" | jq -r .value.author)
[[ "$author" == "$self" ]] && echo "Message from myself" && continue
g1author=$(printf %s "$msg" | jq -r .value.author | cut -d '@' -f 2 | cut -d '.' -f 1 | base64 -d | base58)
# Crypt, ipfs store, send
if [[ -f ~/.ipfs/swarm.key ]]; then
ipfsnodeid=$(ipfs id -f='<id>\n')
mkdir -p ~/.zen/ipfs/.${ipfsnodeid}/CONTACT/${g1author}
# PUBLISH swarm.key.crypt to IPFS, so PUB can push new swam.key to our CONTACT
file=~/.zen/ipfs/.${ipfsnodeid}/CONTACT/${g1author}/ipfs_swarm.key.crypt
$MY_PATH/tools/natools.py encrypt -p ${g1author} -i ~/.ipfs/swarm.key -o ${file}
# IPFS Node PUBLISH Adresses so Pub can become bootstrap for ${g1author}
ipfs id | jq -r .Addresses[] > ~/.zen/ipfs/.${ipfsnodeid}/Addresses
# IPFS Node PUBLISH AgentVersion & repo.stat
ipfs id | jq -r .AgentVersion > ~/.zen/ipfs/.${ipfsnodeid}/AgentVersion
ipfs repo stat > ~/.zen/ipfs/.${ipfsnodeid}/repo.stat
bootstrap=$(cat ~/.zen/ipfs/.${ipfsnodeid}/Addresses | tail -n 1)
echo "
$author
\|/ \|/ \|/
/|\ /|\ /|\ preparing cypher swarmkey
~/.zen/ipfs/.${ipfsnodeid}/CONTACT/${g1author}/ipfs_swarm.key.crypt
PUBLISH IPFS
http://localhost:8080/ipns/
"
ipfs name publish --quieter /ipfs/$(ipfs add -rHq ~/.zen/ipfs | tail -n 1)
name=${file##*/}
id="$(sbotc blobs.add < "$file")"
type="$(file -b --mime-type "$file")"
size="$(wc -c < "$file")"
echo '
______ _ _ _ ____ __ _ _
/\ (_ ||_)/ \|_)/ \|_)|__(_\ //\ |_)|\/||/|_\_/
/--\__) || \\_/| \_/| \| __)\/\//--\| \| ||\|_ | message send
'
echo "SSB
#astroport-swarmkey
[$name]($id)
TO.SSB_${author}
TO.G1_${g1author}
+++
FROM.SSB_${self_name}
FROM.G1_${g1self}
FROM.IPFS_${ipfsnodeid}
"
sbotc publish '{"type":"post","text":"#astroport-swarmkey = ['"$name"']('"$id"') TO.SSB_'"$author"' TO.G1_'"$g1author"' +++ FROM.SSB_'"$self_name"' FROM.G1_'"$g1self"' FROM.IPFS_'"$ipfsnodeid"'","mentions":[{"link":"'"$id"'","name":"'"$name"'","size":'"$size"',"type":"'"$type"'"}]}'
else
echo "NO swarm.key here."
fi
done < <(printf '%s\n' "$messages")

122
zen/ssb_SURVEY_swarmkey.sh Executable file
View File

@ -0,0 +1,122 @@
#!/bin/bash
########################################################################
# Author: Fred (support@qo-op.com)
# Version: 2020.03.24
# License: AGPL-3.0 (https://choosealicense.com/licenses/agpl-3.0/)
########################################################################
MY_PATH="`dirname \"$0\"`" # relative
MY_PATH="`( cd \"$MY_PATH\" && pwd )`" # absolutized and normalized
ME="${0##*/}"
echo '
########################################################################
# \\///
# qo-op
############# '$MY_PATH/$ME'
########################################################################
# ex: ./'$ME'
# SURVEY received #astroport-swarmkey ipfs_swarm.key.crypt for IPFS
########################################################################
___DESACTIVATED___ TODO testing.
__ __ _ _
(_ (_ |_) _ ._ _ _|_o|
__)__)|_) _>|_||\/(/_\/ | ||(/__>
/
USED ONLY ONCE... Next swarm.key change will accurs in ~/.zen/ipfs-swarm
{
"key": "%ydN2fyzKTKzVZiZJSxiTXbb17GVvu0ZOf7LPY6u3Bc8=.sha256",
"value": {
"previous": "%SM2J1D8RcWzd2/P6I3ATyN4VXHuQEP3sXy7YCtK0djE=.sha256",
"sequence": 18,
"author": "@t/giTDc0EtzdPQGC7iAAzgzVOkFo++XZRvzOOlqgX1c=.ed25519",
"timestamp": 1585194822251,
"hash": "sha256",
"content": {
"type": "post",
"text": "#astroport-swarmkey = [ipfs_swarm.key.crypt](&L9nCidDjJ4c4Jz1LNTtx8Xp0SJW9HPCD9IVsbbAhS/I=.sha256) TO.SSB_${author} TO.G1_${g1author} +++ FROM.SSB_${self_name} FROM.G1_${g1self} FROM.IPFS_${ipfsnodeid}",
"mentions": [
{
"link": "&L9nCidDjJ4c4Jz1LNTtx8Xp0SJW9HPCD9IVsbbAhS/I=.sha256",
"name": "ipfs_swarm.key.crypt",
"size": 144,
"type": "application/octet-stream"
}
]
},
"signature": "DHMTIS17yF450CqFssuP2iwYMMdOd3PzCDTkLYdjprTtvjWZYUEG9vHaXBrGuaFZRhV2gGZ3WSknM7YLevilAQ==.sig.ed25519"
},
"timestamp": 1585194822367
}
'
[[ -f ~/.ipfs/ipfs_swarm.key ]] && echo "SWARM KEY ~/.ipfs/ipfs_swarm.key OK !!!" && exit 0
self=$(sbotc whoami | jq -r .id) || exit 1
g1self=$(echo $self | cut -d '@' -f 2 | cut -d '.' -f 1 | base64 -d | base58)
self_name=$(sbotc query.read '{"query":[{"$filter":{"value":{"author": "'"$self"'", "content":{"type":"about", "about": "'"$self"'"}}}}]}' | jq -r .value?.content?.name | grep -v null | tail -n 1)
ipfsnodeid=$(ipfs id -f='<id>\n')
# SEARCH "#astroport-swarmkey" CMD in message text
# Not working without patchwork (TODO: find bug. installation ok!? activate? ssb-server ssb-backlinks node_modules. HELP !! )
# messages=$(sbotc backlinks.read '{"query":[{"$filter":{"dest":"#astroport-swarmkey","value":{"content":{"type":"post"}}}}]}')
# The backlinks.read command does not publish a message, it queries the database for messages. It comes from the ssb-backlinks plugin. This plugin does not come with ssb-server by default (but it does come with Patchwork) so if you are using plain ssb-server and want to use ssb-backlinks you have to install it additionally. But to publish a message you would use the publish method (or private.publish to publish a private message, and that requires the ssb-private plugin, which is included in Patchwork but must be installed separately for ssb-server).
# SCRIPT RUN BY cron_MINUTE.sh check last hour messages
current_ts=$(date -u +%s%N | cut -b1-13)
last_ts=$((current_ts - 24*3600*1000 - 1)) # timestamp from 24h ago
echo '
_ _
-|-|- _. __|_.__ ._ _ .__|___/ |\/|| \
-|-|-(_|_> |_|(_)|_)(_)| |_ \_| ||_/
|
sbotc messagesByType "post" > $last_ts
'
messages=$(sbotc messagesByType '{"type":"post","gt":'$last_ts'}')
#messages=$(sbotc messagesByType '{"type":"post"}') #DEBUG
while read -r msg
do
author=$(printf %s "$msg" | jq -r .value.author)
attached_file=$(printf %s "$msg" | jq -r .value.content.mentions[].name 2>/dev/null)
if [[ $attached_file == "ipfs_swarm.key.crypt" ]]; then
echo '
__ _ _
(_\ //\ |_)|\/| |/|_\_/ _._ .__|_
__)\/\//--\| \| | |\|_ | de(_|\/|_)|_
/ |
to ~/.ipfs/ipfs_swarm.key
'
mylink=$(printf %s "$msg" | jq -r .value.content.mentions[].link)
mytmp=$(mktemp -d "${TMPDIR:-/tmp}/astroport.swarmkey.XXXXXXXXX")
echo "http://localhost:8989/blobs/get/$mylink"
continue
curl -s "http://localhost:8989/blobs/get/$mylink" > $mytmp/ipfs_swarm.key.crypt
$MY_PATH/tools/natools.py decrypt -f pubsec -k ~/.ssb/secret.dunikey -i $mytmp/ipfs_swarm.key.crypt -o ~/.ipfs/ipfs_swarm.key && \
echo "IPFS SWARM KEY ~/.ipfs/ipfs_swarm.key received from SSB $author ... OK !"
echo '
___ _ _ __
| |_)|_(_ _| _. _ ._ _ _ ._
_|_| | __) (_|(_|(/_| | |(_)| | ... restart ...
'
# TODO!!! Add user in sudo without password like "pi" = Run astroport under pi user IDEA.
sudo systemctl restart ipfs
fi
done < <(printf '%s\n' "$messages")

7
zen/tools/clean_OLD_ipfs.Qm.sh Executable file
View File

@ -0,0 +1,7 @@
#!/bin/bash
## In case OLD IPFSNODEID exists (remove it)
IPFSNODEID=$(ipfs id -f='<id>\n') && [[ $IPFSNODEID == "" ]] && exit 1
for DOTQm in ~/.zen/ipfs/.12D3KooW*; do
Qm=$(echo $DOTQm | cut -d '/' -f 6 | cut -d '.' -f 2)
[[ "$Qm" != "$IPFSNODEID" && "$Qm" != "" ]] && rm -Rf $DOTQm && echo "OLD IPFS ID REMOVED"
done

View File

@ -0,0 +1,52 @@
#!/usr/bin/env python3
# This Python script gets /tmp/secret.dunikey produce with key_create_dunikey.py or from https://Cesium.app
# It create ED25519 ipfs (currently 0.7.0) Identity
#########################################################################
# sudo apt install protobuf-compiler
# pip3 install base58 google protobuf duniterpy
# wget https://github.com/libp2p/go-libp2p-core/raw/master/crypto/pb/crypto.proto
# protoc --python_out=. crypto.proto
#########################################################################
import re, base58, base64, crypto_pb2
import cryptography.hazmat.primitives.asymmetric.ed25519 as ed25519
from cryptography.hazmat.primitives import serialization
# TODO controls
# Capturing keys (from /tmp/secret.dunikey)
dunikey = "/tmp/secret.dunikey"
for line in open(dunikey, "r"):
if re.search("pub", line):
shared_key = line.replace('\n','').split(': ')[1]
elif re.search("sec", line):
secure_key = line.replace('\n','').split(': ')[1]
# Decoding keys
decoded_shared = base58.b58decode(shared_key)
decoded_secure = base58.b58decode(secure_key)
ipfs_shared = ed25519.Ed25519PublicKey.from_public_bytes(decoded_shared)
ipfs_secure = ed25519.Ed25519PrivateKey.from_private_bytes(decoded_secure[:32])
ipfs_shared_bytes = ipfs_shared.public_bytes(encoding=serialization.Encoding.Raw,
format=serialization.PublicFormat.Raw)
ipfs_secure_bytes = ipfs_secure.private_bytes(encoding=serialization.Encoding.Raw,
format=serialization.PrivateFormat.Raw,
encryption_algorithm=serialization.NoEncryption())
# Formulating PeerID
ipfs_pid = base58.b58encode(b'\x00$\x08\x01\x12 ' + ipfs_shared_bytes)
PeerID = ipfs_pid.decode('ascii')
print('PeerID={};'.format(ipfs_pid.decode('ascii')))
# Serializing private key in IPFS-native mode, the private key contains public one
pkey = crypto_pb2.PrivateKey()
#pkey.Type = crypto_pb2.KeyType.Ed25519
pkey.Type = 1
pkey.Data = ipfs_secure_bytes + ipfs_shared_bytes
PrivKey = base64.b64encode(pkey.SerializeToString()).decode('ascii')
print('PrivKEY=' + base64.b64encode(pkey.SerializeToString()).decode('ascii'))
# jq '.Identity.PeerID="$PeerID"' ~/.ipfs/config
# jq '.Identity.PrivKey="$PrivKey"' ~/.ipfs/config

22
zen/tools/crypto.proto Normal file
View File

@ -0,0 +1,22 @@
syntax = "proto2";
package crypto.pb;
option go_package = "github.com/libp2p/go-libp2p-core/crypto/pb";
enum KeyType {
RSA = 0;
Ed25519 = 1;
Secp256k1 = 2;
ECDSA = 3;
}
message PublicKey {
required KeyType Type = 1;
required bytes Data = 2;
}
message PrivateKey {
required KeyType Type = 1;
required bytes Data = 2;
}

163
zen/tools/crypto_pb2.py Normal file
View File

@ -0,0 +1,163 @@
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: crypto.proto
import sys
_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
from google.protobuf.internal import enum_type_wrapper
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
from google.protobuf import descriptor_pb2
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor.FileDescriptor(
name='crypto.proto',
package='crypto.pb',
syntax='proto2',
serialized_pb=_b('\n\x0c\x63rypto.proto\x12\tcrypto.pb\";\n\tPublicKey\x12 \n\x04Type\x18\x01 \x02(\x0e\x32\x12.crypto.pb.KeyType\x12\x0c\n\x04\x44\x61ta\x18\x02 \x02(\x0c\"<\n\nPrivateKey\x12 \n\x04Type\x18\x01 \x02(\x0e\x32\x12.crypto.pb.KeyType\x12\x0c\n\x04\x44\x61ta\x18\x02 \x02(\x0c*9\n\x07KeyType\x12\x07\n\x03RSA\x10\x00\x12\x0b\n\x07\x45\x64\x32\x35\x35\x31\x39\x10\x01\x12\r\n\tSecp256k1\x10\x02\x12\t\n\x05\x45\x43\x44SA\x10\x03\x42,Z*github.com/libp2p/go-libp2p-core/crypto/pb')
)
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
_KEYTYPE = _descriptor.EnumDescriptor(
name='KeyType',
full_name='crypto.pb.KeyType',
filename=None,
file=DESCRIPTOR,
values=[
_descriptor.EnumValueDescriptor(
name='RSA', index=0, number=0,
options=None,
type=None),
_descriptor.EnumValueDescriptor(
name='Ed25519', index=1, number=1,
options=None,
type=None),
_descriptor.EnumValueDescriptor(
name='Secp256k1', index=2, number=2,
options=None,
type=None),
_descriptor.EnumValueDescriptor(
name='ECDSA', index=3, number=3,
options=None,
type=None),
],
containing_type=None,
options=None,
serialized_start=150,
serialized_end=207,
)
_sym_db.RegisterEnumDescriptor(_KEYTYPE)
KeyType = enum_type_wrapper.EnumTypeWrapper(_KEYTYPE)
RSA = 0
Ed25519 = 1
Secp256k1 = 2
ECDSA = 3
_PUBLICKEY = _descriptor.Descriptor(
name='PublicKey',
full_name='crypto.pb.PublicKey',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='Type', full_name='crypto.pb.PublicKey.Type', index=0,
number=1, type=14, cpp_type=8, label=2,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
_descriptor.FieldDescriptor(
name='Data', full_name='crypto.pb.PublicKey.Data', index=1,
number=2, type=12, cpp_type=9, label=2,
has_default_value=False, default_value=_b(""),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
],
extensions=[
],
nested_types=[],
enum_types=[
],
options=None,
is_extendable=False,
syntax='proto2',
extension_ranges=[],
oneofs=[
],
serialized_start=27,
serialized_end=86,
)
_PRIVATEKEY = _descriptor.Descriptor(
name='PrivateKey',
full_name='crypto.pb.PrivateKey',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='Type', full_name='crypto.pb.PrivateKey.Type', index=0,
number=1, type=14, cpp_type=8, label=2,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
_descriptor.FieldDescriptor(
name='Data', full_name='crypto.pb.PrivateKey.Data', index=1,
number=2, type=12, cpp_type=9, label=2,
has_default_value=False, default_value=_b(""),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
],
extensions=[
],
nested_types=[],
enum_types=[
],
options=None,
is_extendable=False,
syntax='proto2',
extension_ranges=[],
oneofs=[
],
serialized_start=88,
serialized_end=148,
)
_PUBLICKEY.fields_by_name['Type'].enum_type = _KEYTYPE
_PRIVATEKEY.fields_by_name['Type'].enum_type = _KEYTYPE
DESCRIPTOR.message_types_by_name['PublicKey'] = _PUBLICKEY
DESCRIPTOR.message_types_by_name['PrivateKey'] = _PRIVATEKEY
DESCRIPTOR.enum_types_by_name['KeyType'] = _KEYTYPE
PublicKey = _reflection.GeneratedProtocolMessageType('PublicKey', (_message.Message,), dict(
DESCRIPTOR = _PUBLICKEY,
__module__ = 'crypto_pb2'
# @@protoc_insertion_point(class_scope:crypto.pb.PublicKey)
))
_sym_db.RegisterMessage(PublicKey)
PrivateKey = _reflection.GeneratedProtocolMessageType('PrivateKey', (_message.Message,), dict(
DESCRIPTOR = _PRIVATEKEY,
__module__ = 'crypto_pb2'
# @@protoc_insertion_point(class_scope:crypto.pb.PrivateKey)
))
_sym_db.RegisterMessage(PrivateKey)
DESCRIPTOR.has_options = True
DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('Z*github.com/libp2p/go-libp2p-core/crypto/pb'))
# @@protoc_insertion_point(module_scope)

162
zen/tools/crypto_pb2.py.old Normal file
View File

@ -0,0 +1,162 @@
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: crypto.proto
import sys
_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
from google.protobuf.internal import enum_type_wrapper
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor.FileDescriptor(
name='crypto.proto',
package='crypto.pb',
syntax='proto2',
serialized_options=_b('Z*github.com/libp2p/go-libp2p-core/crypto/pb'),
serialized_pb=_b('\n\x0c\x63rypto.proto\x12\tcrypto.pb\";\n\tPublicKey\x12 \n\x04Type\x18\x01 \x02(\x0e\x32\x12.crypto.pb.KeyType\x12\x0c\n\x04\x44\x61ta\x18\x02 \x02(\x0c\"<\n\nPrivateKey\x12 \n\x04Type\x18\x01 \x02(\x0e\x32\x12.crypto.pb.KeyType\x12\x0c\n\x04\x44\x61ta\x18\x02 \x02(\x0c*9\n\x07KeyType\x12\x07\n\x03RSA\x10\x00\x12\x0b\n\x07\x45\x64\x32\x35\x35\x31\x39\x10\x01\x12\r\n\tSecp256k1\x10\x02\x12\t\n\x05\x45\x43\x44SA\x10\x03\x42,Z*github.com/libp2p/go-libp2p-core/crypto/pb')
)
_KEYTYPE = _descriptor.EnumDescriptor(
name='KeyType',
full_name='crypto.pb.KeyType',
filename=None,
file=DESCRIPTOR,
values=[
_descriptor.EnumValueDescriptor(
name='RSA', index=0, number=0,
serialized_options=None,
type=None),
_descriptor.EnumValueDescriptor(
name='Ed25519', index=1, number=1,
serialized_options=None,
type=None),
_descriptor.EnumValueDescriptor(
name='Secp256k1', index=2, number=2,
serialized_options=None,
type=None),
_descriptor.EnumValueDescriptor(
name='ECDSA', index=3, number=3,
serialized_options=None,
type=None),
],
containing_type=None,
serialized_options=None,
serialized_start=150,
serialized_end=207,
)
_sym_db.RegisterEnumDescriptor(_KEYTYPE)
KeyType = enum_type_wrapper.EnumTypeWrapper(_KEYTYPE)
RSA = 0
Ed25519 = 1
Secp256k1 = 2
ECDSA = 3
_PUBLICKEY = _descriptor.Descriptor(
name='PublicKey',
full_name='crypto.pb.PublicKey',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='Type', full_name='crypto.pb.PublicKey.Type', index=0,
number=1, type=14, cpp_type=8, label=2,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='Data', full_name='crypto.pb.PublicKey.Data', index=1,
number=2, type=12, cpp_type=9, label=2,
has_default_value=False, default_value=_b(""),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto2',
extension_ranges=[],
oneofs=[
],
serialized_start=27,
serialized_end=86,
)
_PRIVATEKEY = _descriptor.Descriptor(
name='PrivateKey',
full_name='crypto.pb.PrivateKey',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='Type', full_name='crypto.pb.PrivateKey.Type', index=0,
number=1, type=14, cpp_type=8, label=2,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='Data', full_name='crypto.pb.PrivateKey.Data', index=1,
number=2, type=12, cpp_type=9, label=2,
has_default_value=False, default_value=_b(""),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto2',
extension_ranges=[],
oneofs=[
],
serialized_start=88,
serialized_end=148,
)
_PUBLICKEY.fields_by_name['Type'].enum_type = _KEYTYPE
_PRIVATEKEY.fields_by_name['Type'].enum_type = _KEYTYPE
DESCRIPTOR.message_types_by_name['PublicKey'] = _PUBLICKEY
DESCRIPTOR.message_types_by_name['PrivateKey'] = _PRIVATEKEY
DESCRIPTOR.enum_types_by_name['KeyType'] = _KEYTYPE
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
PublicKey = _reflection.GeneratedProtocolMessageType('PublicKey', (_message.Message,), dict(
DESCRIPTOR = _PUBLICKEY,
__module__ = 'crypto_pb2'
# @@protoc_insertion_point(class_scope:crypto.pb.PublicKey)
))
_sym_db.RegisterMessage(PublicKey)
PrivateKey = _reflection.GeneratedProtocolMessageType('PrivateKey', (_message.Message,), dict(
DESCRIPTOR = _PRIVATEKEY,
__module__ = 'crypto_pb2'
# @@protoc_insertion_point(class_scope:crypto.pb.PrivateKey)
))
_sym_db.RegisterMessage(PrivateKey)
DESCRIPTOR._options = None
# @@protoc_insertion_point(module_scope)

File diff suppressed because it is too large Load Diff

33
zen/tools/diceware.sh Executable file
View File

@ -0,0 +1,33 @@
#!/bin/bash
########################################################################
# Author: Fred (support@qo-op.com)
# Version: 2020.03.18
# License: AGPL-3.0 (https://choosealicense.com/licenses/agpl-3.0/)
########################################################################
MY_PATH="`dirname \"$0\"`" # relative
MY_PATH="`( cd \"$MY_PATH\" && pwd )`" # absolutized and normalized
########################################################################
# \\///
# qo-op
#############
##########################
#######################################
####################################################
########################################################################
MOTS=$(echo "$1" | grep -E "^\-?[0-9]+$")
# Default is 6 words passphrase
if [[ "$MOTS" == "" ]]; then MOTS=6; fi
WORDCOUNT=${1-$MOTS}
# Download the wordlist
# wget -nc -O ~/.diceware-wordlist http://world.std.com/%7Ereinhold/diceware.wordlist.asc 2> /dev/null
# print a list of the diceware words
cat $MY_PATH/diceware-wordlist.txt | \
awk '/[1-6][1-6][1-6][1-6][1-6]/{ print $2 }' | \
# randomize the list order
shuf --random-source=/dev/urandom | \
# pick the first n words
head -n ${WORDCOUNT} | \
# pretty print
tr '\n' ' '
echo

42
zen/tools/dunikey2secret.sh Executable file
View File

@ -0,0 +1,42 @@
#!/bin/bash
########################################################################
# Author: Fred (support@qo-op.com)
# Version: 1.0
# License: AGPL-3.0 (https://choosealicense.com/licenses/agpl-3.0/)
########################################################################
# This script convert secret.dunikey into ~/.ssb/secret.ssb
########################################################################
MY_PATH="`dirname \"$0\"`" # relative
MY_PATH="`( cd \"$MY_PATH\" && pwd )`" # absolutized and normalized
########################################################################
# \\///
# qo-op
#############
DUNIKEYFILE="$1"
[[ ! ${DUNIKEYFILE} ]] && DUNIKEYFILE="/tmp/secret.dunikey"
[[ ! ${DUNIKEYFILE} ]] && DUNIKEYFILE="~/.ssb/secret.dunikey"
[[ ! -f ${DUNIKEYFILE} ]] && echo "ERROR secret.dunikey unfound" && exit 1
pub=$(cat ${DUNIKEYFILE} | grep "pub" | cut -d ' ' -f 2)
priv=$(cat ${DUNIKEYFILE} | grep "sec" | cut -d ' ' -f 2)
ssbpub=$(echo $pub | base58 -d | base64)
ssbpriv=$(echo $priv | base58 -d | base64 | tr -d "\n")
cat > /tmp/secret.ssb <<EOF
# This secret generated by duniter2secret.sh
# G1 Wallet ACCOUNT BALANCE:
# silkaj balance $pub
#
# THIS KEY IS YOURS!
# NEVER show this to anyone!!!
{
"curve": "ed25519",
"public": "$ssbpub.ed25519",
"private": "$ssbpriv.ed25519",
"id": "@$ssbpub.ed25519"
}
EOF
echo 'Your key is located in /tmp/secret.ssb'
exit 0

132
zen/tools/duniter_getnode.sh Executable file
View File

@ -0,0 +1,132 @@
#!/bin/bash
################################################################################
# Authors: @jytou (https://git.duniter.org/jytou)
# Modified by Fred (support@qo-op.com)
# Version: 0.1
# License: AGPL-3.0 (https://choosealicense.com/licenses/agpl-3.0/)
################################################################################
# Checks the current block number of $DIR/duniter_nodes.txt (is run in parallel)
# and output random (from last synchronized) node
checkonenode()
{
# Timeout in seconds for https nodes
httpsTimeout=1
# Timeout in seconds for http nodes
httpTimeout=1
node=$1
watched=$2
outfile=$3
# Curl: -m timeout, -k ignore SSL certificate errors
cur=`echo "$( { curl -m $httpsTimeout -k https://$node/blockchain/current; } 2>&1 )"`
n=$node
if [[ "$cur" != *issuersFrameVar* ]]
then
# It failed in https, maybe try http?
cur=`echo "$( { curl -m $httpTimeout http://$node/blockchain/current; } 2>&1 )"`
if [[ "$cur" == *issuersFrameVar* ]]
then
# Indicate that the node is http
n="$n-(http)"
fi
fi
if [[ "$cur" != *issuersFrameVar* ]]
then
# The node didn't respond on time
cur="ERROR"
else
# The node did respond - grab the block number and hash of the block as key
cur="`echo "$cur"|grep '^ "number": '|awk '{print $2}'|awk -F, '{print $1}'`-`echo "$cur"|grep '^ "hash": '|awk '{print $2}'|awk '{print substr($1,2,13)}'`"
fi
if [[ $watched =~ .*#$node#.* ]]
then
# The node is a watched node, add some bold
n="\e[1m$n\e[0m"
fi
# Put the result into the file
echo "$cur $n">$outfile
# Notify that we're done here
touch $outfile.done
}
# Temp dir where results are stored
rm -Rf /tmp/zen/gnodewatch
DIR=/tmp/zen/gnodewatch
export DIR
mkdir -p $DIR/chains
# TODO: REMOVE 777 PATCH, ACTIVATE ramdisk
# sudo mkdir /mnt/ramdisk
# sudo mount -t tmpfs -o size=50m tmpfs /mnt/ramdisk
chmod -R 777 /tmp/zen/
# KEEP /tmp/zen/current.duniter for 5 mn
find /tmp/zen/ -mmin +5 -type f -name "current.duniter" -exec rm -f '{}' \;
[[ -f /tmp/zen/current.duniter ]] && cat /tmp/zen/current.duniter && exit 0
##### $DIR/duniter_nodes.txt REFRESH after 20 minutes #####
find $DIR/ -mmin +20 -type f -name "duniter_*" -exec rm -f '{}' \;
if [[ ! -f $DIR/duniter_nodes.txt ]]; then
# Get New BMAS known Nodes list from shuffle one $DIR/good.nodes.txt
[[ -f $DIR/good.nodes.txt ]] && DUNITER=$(shuf -n 1 $DIR/good.nodes.txt) || DUNITER="duniter-g1.p2p.legal:443"
curl -s https://$DUNITER/network/peers | jq '.peers[] | .endpoints' | grep BMAS | awk '{print $2,$3}' | sed s/\"//g | sed s/\,//g | sed s/\ /:/g | sort -u > $DIR/duniter_nodes.txt
fi
# Grab the nodes we are actively watching - they will be in bold in the final output
watched=`grep -v "#" $DIR/duniter_nodes.txt|egrep "\!$"|awk '{print "#" $1 "#"}'`
# All nodes we are watching
nodes=`grep -v "#" $DIR/duniter_nodes.txt|awk '{print $1}'`
# The index to generate separate file names
index=0
# Wipe out the output directory
rm $DIR/*out $DIR/*done $DIR/chains/* $DIR/NODE.* 2>/dev/null
# Query all nodes in parallel
for node in $nodes
do
checkonenode $node "$watched" $DIR/$index.out &
((index++))
done
# Wait a little for the first files to be created
sleep 1s
# Wait for all the threads to report they are done
while [ `ls $DIR/*done|wc -l` -lt $index ]
do
sleep 1s
done
# Grab all results
curs=`cat $DIR/*out|sort`
# Extract all forks, excluding all errors
chains="`echo "$curs"|grep -v ERROR|awk '{print $1}'|sort -r|uniq`"
# Count the number of chains and output most recent consensus to "good.nodes.txt"
nb=0
for chain in $chains
do
echo "$curs" | egrep "^$chain " | awk '{print $2}' >> $DIR/chains/$nb;
((nb++))
done
longchain=$(ls -S $DIR/chains/ | head -n 1)
# WRITE OUT shuffle Duniter Node Sync with longest chain
cp $DIR/chains/$longchain $DIR/good.nodes.txt
## TEST if server is really running Duniter
Dtest=""; IDtest=""; lastresult=""; loop=0
while [[ $Dtest != "duniter" ]]; do
while [[ $lastresult == $result && $loop -lt 7 ]]; do result=$(shuf -n 1 $DIR/good.nodes.txt); ((loop++)); done
lastresult=$result
Dtest=$(curl -s https://$lastresult | jq -r .duniter.software)
## CHECK if server is not too slow
[[ $Dtest == "duniter" ]] && IDtest=$(silkaj -p $lastresult id Fred)
[[ $IDtest == "" ]] && Dtest=""
[[ $loop -eq 8 ]] && result="duniter-g1.p2p.legal:443" && break
((loop++))
done
echo "$result" > /tmp/zen/current.duniter
echo $result

29
zen/tools/emoji.pl Normal file
View File

@ -0,0 +1,29 @@
# Oona Räisänen 2013
# http://windytan.com
# ssh-keygen -l -f ~/.ssh/id_rsa.pub | perl emoji.pl
@emoji = qw( 🌀 🌂 🌅 🌈 🌙 🌞 🌟 🌠 🌰 🌱 🌲 🌳 🌴 🌵 🌷 🌸
🌹 🌺 🌻 🌼 🌽 🌾 🌿 🍀 🍁 🍂 🍃 🍄 🍅 🍆 🍇 🍈
🍉 🍊 🍋 🍌 🍍 🍎 🍏 🍐 🍑 🍒 🍓 🍔 🍕 🍖 🍗 🍘
🍜 🍝 🍞 🍟 🍠 🍡 🍢 🍣 🍤 🍥 🍦 🍧 🍨 🍩 🍪 🍫
🍬 🍭 🍮 🍯 🍰 🍱 🍲 🍳 🍴 🍵 🍶 🍷 🍸 🍹 🍺 🍻
🍼 🎀 🎁 🎂 🎃 🎄 🎅 🎈 🎉 🎊 🎋 🎌 🎍 🎎 🎏 🎒
🎓 🎠 🎡 🎢 🎣 🎤 🎥 🎦 🎧 🎨 🎩 🎪 🎫 🎬 🎭 🎮
🎯 🎰 🎱 🎲 🎳 🎴 🎵 🎷 🎸 🎹 🎺 🎻 🎽 🎾 🎿 🏀
🏁 🏂 🏃 🏄 🏆 🏇 🏈 🏉 🏊 🐀 🐁 🐂 🐃 🐄 🐅 🐆
🐇 🐈 🐉 🐊 🐋 🐌 🐍 🐎 🐏 🐐 🐑 🐒 🐓 🐔 🐕 🐖
🐗 🐘 🐙 🐚 🐛 🐜 🐝 🐞 🐟 🐠 🐡 🐢 🐣 🐤 🐥 🐦
🐧 🐨 🐩 🐪 🐫 🐬 🐭 🐮 🐯 🐰 🐱 🐲 🐳 🐴 🐵 🐶
🐷 🐸 🐹 🐺 🐻 🐼 🐽 🐾 👀 👂 👃 👄 👅 👆 👇 👈
👉 👊 👋 👌 👍 👎 👏 👐 👑 👒 👓 👔 👕 👖 👗 👘
👙 👚 👛 👜 👝 👞 👟 👠 👡 👢 👣 👤 👥 👦 👧 👨
👩 👪 👮 👯 👺 👻 👼 👽 👾 👿 💀 💁 💂 💃 💄 💅 );
while (<>) {
if (/[a-f0-9:]+:[a-f0-9:]+/) {
($b, $m, $a) = ($`, $&, $');
print $b.join(" ", map { $emoji[$_] } map hex, split /:/, $m)." ".$a;
}
}

View File

@ -0,0 +1,115 @@
#!/bin/bash
{
########################################################################
MY_PATH="`dirname \"$0\"`" # relative
MY_PATH="`( cd \"$MY_PATH\" && pwd )`" # absolutized and normalized
ME="${0##*/}"
[[ -f ~/.zen/secret ]] && echo "Please rm -f ~/.zen/secret* before running $ME" && exit 1
echo '>>>>>>> METAVERSE KEY CREATION <<<<<<<<
__ __ ____
__/ // /_______ ______ __________ ___ / __ \
/_ _ __/ ___/ | /| / / __ `/ ___/ __ `__ \/ / / /
/_ _ __(__ )| |/ |/ / /_/ / / / / / / / / /_/ /
/_//_/ /____/ |__/|__/\__,_/_/ /_/ /_/ /_/\____/
CESIUM KEY
CHOOSE YOU LOGIN (min 8 car. best is more than 6 words!!)...
or LEAVE BLANK and HIT ENTER FOR diceware AUTO GENERATION
'
read salt
[[ $salt == "" ]] && echo "Hit ENTER again to continue" && read salt
[[ $salt != "" ]] && echo "CHOOSE PASSWORD?" && read pepper && [[ $pepper == "" ]] && echo "AARRRRGGG why no pepper? exiting" && exit 1
if [[ "$salt" == "" && "$pepper" == "" ]]; then
echo '
._ _ ._ _ ._ _ _ ._ o _
| | | | | (/_ | | | (_) | | | (_
diceware passphrase generator...'
# INSTALL diceware files ## TODO REPLACE WITH ipfs links
[[ ! -f ~/.zen/astroport/zen/tools/diceware.sh ]] \
&& mkdir -p ~/.zen/astroport/zen/tools/ \
&& curl -s https://git.p2p.legal/axiom-team/astroport/raw/master/zen/tools/diceware.sh -o ~/.zen/astroport/zen/tools/diceware.sh \
&& chmod +x ~/.zen/astroport/zen/tools/diceware.sh
[[ ! -f ~/.zen/astroport/zen/tools/diceware-wordlist.txt ]] \
&& curl -s https://git.p2p.legal/axiom-team/astroport/raw/master/zen/tools/diceware-wordlist.txt -o ~/.zen/astroport/zen/tools/diceware-wordlist.txt
# LOGIN (=SALT)
salt="miz $(~/.zen/astroport/zen/tools/diceware.sh 2 | xargs)"
# PASS (=PEPPER)
pepper="$(~/.zen/astroport/zen/tools/diceware.sh 2 | xargs)"
fi
echo "........."
# CREATE /tmp/secret.dunikey
[[ ! -f ~/.zen/astroport/zen/tools/key_create_dunikey.py ]] \
&& mkdir -p ~/.zen/astroport/zen/tools/ \
&& curl -s https://git.p2p.legal/axiom-team/astroport/raw/master/zen/tools/key_create_dunikey.py -o ~/.zen/astroport/zen/tools/key_create_dunikey.py \
&& chmod +x ~/.zen/astroport/zen/tools/key_create_dunikey.py
python3 ~/.zen/astroport/zen/tools/key_create_dunikey.py "$salt" "$pepper"
sleep 1
[[ ! -f /tmp/secret.dunikey ]] && echo "AARRRRGGG problem happens making your secret.dunikey exiting" && exit 1
[[ -f /tmp/secret.dunikey ]] && cp -f /tmp/secret.dunikey ~/.zen/
echo "ZENID=\"$salt\"
ZENPWD=\"$pepper\"
"
g1pub=$(cat ~/.zen/secret.dunikey | grep "pub" | cut -d ' ' -f 2)
g1priv=$(cat ~/.zen/secret.dunikey | grep "sec" | cut -d ' ' -f 2)
# make ScutlleButt secret key
ssbpub=$(echo $g1pub | base58 -d | base64)
ssbpriv=$(echo $g1priv | base58 -d | base64 | tr -d "\n" )
cat > ~/.zen/secret <<EOF
{
"curve": "ed25519",
"public": "${ssbpub}.ed25519",
"private": "${ssbpriv}.ed25519",
"id": "@${ssbpub}.ed25519"
}
EOF
echo "$salt" > ~/.zen/secret.june
echo "$pepper" >> ~/.zen/secret.june
chmod 400 ~/.zen/secret*
echo "~/.zen/secret(s) are OK !"
# MODIFY ~/.ipfs/config
[[ ! -f ~/.zen/astroport/zen/tools/crypto_pb2.py ]] \
&& mkdir -p ~/.zen/astroport/zen/tools/ \
&& curl -s https://git.p2p.legal/axiom-team/astroport/raw/master/zen/tools/crypto_pb2.py -o ~/.zen/astroport/zen/tools/crypto_pb2.py \
[[ ! -f ~/.zen/astroport/zen/tools/create_ipfsnodeid_from_tmp_secret.dunikey.py ]] \
&& mkdir -p ~/.zen/astroport/zen/tools/ \
&& curl -s https://git.p2p.legal/axiom-team/astroport/raw/master/zen/tools/create_ipfsnodeid_from_tmp_secret.dunikey.py -o ~/.zen/astroport/zen/tools/create_ipfsnodeid_from_tmp_secret.dunikey.py \
&& chmod +x ~/.zen/astroport/zen/tools/create_ipfsnodeid_from_tmp_secret.dunikey.py
ipfs_ID=$(python3 ~/.zen/astroport/zen/tools/create_ipfsnodeid_from_tmp_secret.dunikey.py)
echo $ipfs_ID > ~/.zen/secret.ipfs
source ~/.zen/secret.ipfs
cat ~/.zen/secret.ipfs
echo
echo
echo "########################################################"
echo "Welcome to the G1 DRIVE"
echo "Configure IPFS: copy the lines above in your console"
echo "then run jq commands and make your IPFS NODE https://Cesium.app compatible"
echo " -> Read your Cesium messages to find how to Bootstrap your node"
echo
echo "cp -f ~/.ipfs/config ~/.ipfs/config.old"
echo "jq -r --arg PeerID \"\$PeerID\" '.Identity.PeerID=\$PeerID' ~/.ipfs/config > /tmp/config.tmp"
echo "jq -r --arg PrivKEY \"\$PrivKEY\" '.Identity.PrivKey=\$PrivKEY' /tmp/config.tmp > ~/.ipfs/config"
echo ""
[[ -f /tmp/init_IPFS_with_cesium_loginKEY.sh ]] && cp -f /tmp/init_IPFS_with_cesium_loginKEY.sh ~/.zen/astroport/zen/tools/
rm -f /tmp/secret.dunikey
}

10
zen/tools/ipfs_to_g1.py Executable file
View File

@ -0,0 +1,10 @@
#!/usr/bin/env python3
import sys, base58
ID = sys.argv[1]
hexFmt = base58.b58decode(ID)
noTag = hexFmt[6:]
b58Key = base58.b58encode(noTag).decode()
print(b58Key)

27
zen/tools/key_create_dunikey.py Executable file
View File

@ -0,0 +1,27 @@
#!/usr/bin/env python3
# This Python script gets Duniter creddentials as arguments, and writes a PubSec file that should be compatible with Cesium and Silkaj(DuniterPy) clients.
# launch with :
# python3 key_create_dnuikey.py <id> <mdp>
# depends on duniterpy 0.56
### Licence - WTFPL
# This script was written my Matograine, in the hope that it will be helpful.
# Do What The Fuck you like with it. There is :
# * no guarantee that this will work
# * no support of any kind
#
# If this is helpful, please consider making a donation to the developper's pubkey : 78ZwwgpgdH5uLZLbThUQH7LKwPgjMunYfLiCfUCySkM8
# Have fun
from sys import argv
from duniterpy.key import SigningKey
# path to save to
path = "/tmp/secret.dunikey"
key = SigningKey.from_credentials(argv[1], argv[2], None)
key.save_pubsec_file(path)
print(
key.pubkey,
)

400
zen/tools/make_G1SSB_secret.sh Executable file
View File

@ -0,0 +1,400 @@
#!/bin/bash
{
########################################################################
MY_PATH="`dirname \"$0\"`" # relative
MY_PATH="`( cd \"$MY_PATH\" && pwd )`" # absolutized and normalized
ME="${0##*/}"
#### ARM / X64 NOT USED THERE
MACHINE_TYPE=`uname -m`
[ ${MACHINE_TYPE:0:3} == 'arm' ] && isARM="YES"
if [[ "$1" == "RAZ" ]]; then
echo "~/.SSB_ORIGIN is made for $(whoami)"
[[ -d ~/.ssb_$(whoami) ]] && mv ~/.ssb_$(whoami) ~/.SSB_ORIGIN
rm -Rf ~/.ssb*
else
echo '
########################################################################
# \\///
# qo-op
############# '$MY_PATH/$ME'
########################################################################
# Make Astroport Station Account
#
# You should already be runing ipfs daemon
########################################################################
# - Install silkaj youtube-dl & sbotc
# - Backup any ~/.ssb to ~/.ssb_$USER
# - Creates ~/.ssb_astroport and link it to ~/.ssb
# - Ask for credentials (or auto)
# - CREATE "~/.ssb/secret" & "~/.ssb/secret.dunikey" of you
# !!! KEEP CREDENTIALS IN ~/.zen/secret.astroport.key
########################################################################
# UnInstall and Recover your ~/.ssb_$USER
# cd && rm -Rf ~/.zen && rm ~/.ssb && mv ~/.ssb_$USER ~/.ssb
########################################################################
I encourage you to read any code you download.
This one is not perfect, but will not harm your system...
Install IPFS (compatible with ARM and X64)
curl -s https://git.p2p.legal/axiom-team/astroport/raw/master/.install/ipfs_alone.sh | bash
HIT ENTER TO CONTINUE
'
read letsgo
fi
# "ipfs daemon" MUST be RUNNING
YOU=$(ps auxf --sort=+utime | grep -w ipfs | grep -v -E 'color=auto|grep' | tail -n 1 | cut -d " " -f 1)
[[ "$YOU" == "" ]] && echo "EXIT! PLEASE INSTALL & RUN ipfs daemon WITH curl -s https://git.p2p.legal/axiom-team/astroport/raw/master/.install/ipfs_alone.sh | bash " && exit 1
# ~/.zen is ASTROPORT living place.
[[ ! -d ~/.zen/astroport ]] && mkdir -p ~/.zen/astroport
# IS git THERE ?
[[ ! $(which git) ]] && sudo apt install git -y
[[ ! $(which figlet) ]] && sudo apt install figlet -y
[[ ! $(which lolcat) ]] && sudo apt install lolcat -y
# USE git pull OR git clone
if [[ -f ~/.zen/astroport/install.sh ]]; then
cd ~/.zen/astroport && git pull
else
cd ~/.zen
git clone https://git.p2p.legal/axiom-team/astroport.git
fi
cd ~/.zen/astroport
# LETS GO
# Install nvm
echo '
__ _
____ ____ ____/ /__ (_)____
/ __ \/ __ \/ __ / _ \ / / ___/
/ / / / /_/ / /_/ / __/ / (__ )
/_/ /_/\____/\__,_/\___/ __/ /____/
/___/
' | lolcat
if [[ ! $(which node) ]]; then
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.2/install.sh | bash
source ~/.bashrc
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
source ~/.bashrc
nvm install 12
nvm use 12
fi
echo '
____ ___ _____ _________
/ __ \/ | / ___// _/ ___/
/ / / / /| | \__ \ / / \__ \
/ /_/ / ___ |___/ // / ___/ /
\____/_/ |_/____/___//____/
' | lolcat
nodename=$(curl -s https://git.p2p.legal/axiom-team/astroport/raw/master/zen/tools/nodename | bash)
if [[ ! $(which oasis) ]]; then
echo "INSTALL.... http://$nodename"
# echo "ENTER Station accessible Network name !!! Suggestion : $nodename"
# read nodename
# Install nvm
if [[ ! $(which node) || ! $(which npm) ]]; then
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.2/install.sh | bash
source ~/.bashrc
export NVM_DIR="$HOME/.nvm"
nvm install --lts
fi
npm -g install sodium-native ssb-backlinks ssb-ws ssb-links ssb-query ssb-secret-blob ssb-private
npm -g install fraction/oasis#semver:
npm -g install ssb-server ## ADD SSB-SERVER FOR PRIVATE SSB MESSAGING (TODO: integrate Feedless modules on LOVELand Portal)
else
echo "Stopping OASIS"
ssbD=$(ps auxf --sort=+utime | grep -w oasis | grep -v -E 'color=auto|grep' | awk '{print $2}')
ssbD+=$(ps auxf --sort=+utime | grep -w ssb-server | grep -v -E 'color=auto|grep' | awk '{print $2}')
for tokill in $ssbD; do
kill -9 $tokill
done
fi
# INSTALL Silkaj, CLI for Duniter
echo '**************************************************************
__ ___
(_ | | |/ /\ |
__) _|_ |_ |\ /--\ \_|
#Duniter communication client...
' | lolcat
sudo apt update || true
sudo apt install ssmtp mpack libffi-dev build-essential qrencode jq bc gawk -y
export PATH=$PATH:~/.local/bin
if [[ ! $(which silkaj) ]]; then
libzzz=$(sudo apt-cache search libsodium | awk '{print $1}' | grep libsodium2)
[[ $libzzz == "" ]] && libzzz=$(sudo apt-cache search libsodium | awk '{print $1}' | grep libsodium1)
sudo apt install $libzzz -y
sudo apt install python3-pip python3-setuptools python3-wheel -y
pip3 install base58
pip3 install silkaj --user
echo 'PATH=$PATH:$HOME/.local/bin' >> ~/.bashrc && source ~/.bashrc
fi
# INSTALL sbotc
echo '
__ __
_____/ /_ ____ / /______
/ ___/ __ \/ __ \/ __/ ___/
(__ ) /_/ / /_/ / /_/ /__
/____/_.___/\____/\__/\___/
ScuttleButt communication client...
' | lolcat
if [[ ! $(which sbotc) ]]; then
sudo apt install libsodium-dev build-essential imagemagick -y
cd /tmp/
git clone https://git.scuttlebot.io/%25133ulDgs%2FoC1DXjoK04vDFy6DgVBB%2FZok15YJmuhD5Q%3D.sha256 sbotc
cd sbotc
make
sudo make install
cd ~/.zen/astroport
fi
echo '
__ __
____ ______/ /__________ ____ ____ _____/ /_
/ __ `/ ___/ __/ ___/ __ \/ __ \/ __ \/ ___/ __/
/ /_/ (__ ) /_/ / / /_/ / /_/ / /_/ / / / /_
\__,_/____/\__/_/ \____/ .___/\____/_/ \__/
/_/
ONBOARDING activation... linking ~/.ssb to ~/.ssb_astroport
' | lolcat
# CREATE ~/.ssb_astroport
[[ ! -d ~/.ssb_astroport ]] && mkdir -p ~/.ssb_astroport
# If exists backup ~/.ssb to ~/.ssb_$USER SSB (one time only !)
[[ -d ~/.ssb_$USER ]] && echo "BACKUP already existing... Restore it : rm -Rf ~/.ssb && mv ~/.ssb_$USER ~/.ssb # and Try again..." && exit 1
if [[ -d ~/.ssb ]]; then
[[ -f ~/.ssb/manifest.json ]] && cp -f ~/.ssb/manifest.json ~/.ssb_astroport/
[[ -f ~/.ssb/conn.json ]] && cp -f ~/.ssb/conn.json ~/.ssb_astroport/
[[ -f ~/.ssb/gossip.json ]] && cp -f ~/.ssb/gossip.json ~/.ssb_astroport/
fi
# BACKUP ACTUAL SSB ACCOUNT
[[ -d ~/.ssb ]] && mv ~/.ssb ~/.ssb_$USER
# Symlink ~/.ssb -> ~/.ssb_astroport
[[ -L ~/.ssb ]] && rm ~/.ssb
[[ -d ~/.ssb_astroport ]] && ln -s ~/.ssb_astroport ~/.ssb
cd ~/.ssb/
[[ ! -f ~/.ssb/manifest.json ]] && cp ~/.zen/astroport/.install/templates/ssb/manifest.json ~/.ssb/ && echo "manifest.json OK"
echo '>>>>>>> METAVERSE KEY CREATION <<<<<<<<
__ __ ____
__/ // /_______ ______ __________ ___ / __ \
/_ _ __/ ___/ | /| / / __ `/ ___/ __ `__ \/ / / /
/_ _ __(__ )| |/ |/ / /_/ / / / / / / / / /_/ /
/_//_/ /____/ |__/|__/\__,_/_/ /_/ /_/ /_/\____/
KEY
CHOOSE YOU LOGIN (min 8 car. best is more than 6 words!!)...
or LEAVE BLANK and HIT ENTER FOR diceware AUTO GENERATION
' | lolcat
read salt
[[ $salt != "" ]] && echo "CHOOSE PASSWORD?" && read pepper && [[ $pepper == "" ]] && exit 1
if [[ "$salt" == "" && "$pepper" == "" ]]; then
echo '
._ _ ._ _ ._ _ _ ._ o _
| | | | | (/_ | | | (_) | | | (_
diceware passphrase generator...' | lolcat
# INSTALL diceware files ## TODO REPLACE WITH ipfs links
[[ ! -f ~/.zen/astroport/zen/tools/diceware.sh ]] \
&& mkdir -p ~/.zen/astroport/zen/tools/ \
&& curl -s https://git.p2p.legal/axiom-team/astroport/raw/master/zen/tools/diceware.sh -o ~/.zen/astroport/zen/tools/diceware.sh \
&& chmod +x ~/.zen/astroport/zen/tools/diceware.sh
[[ ! -f ~/.zen/astroport/zen/tools/diceware-wordlist.txt ]] \
&& curl -s https://git.p2p.legal/axiom-team/astroport/raw/master/zen/tools/diceware-wordlist.txt -o ~/.zen/astroport/zen/tools/diceware-wordlist.txt
# LOGIN (=SALT)
salt="$(~/.zen/astroport/zen/tools/diceware.sh 6 | xargs)"
# PASS (=PEPPER)
pepper="$(~/.zen/astroport/zen/tools/diceware.sh 4 | xargs)"
fi
echo "........."
rm -f ~/.zen/secret.astroport.key
echo "#20200606 ASTROPORT METAVERSE #SWARM0 IDENTITY
ZENID=\"$salt\"
ZENPWD=\"$pepper\"" > ~/.zen/secret.astroport.key
sleep 1
# CREATE ~/.ssb/secret.dunikey
python3 ~/.zen/astroport/zen/tools/key_create_dunikey.py "$salt" "$pepper"
sleep 1
[[ ! -f /tmp/secret.dunikey ]] && echo "AARRRRGGG problem happens making your secret.dunikey" && exit 1
[[ -f /tmp/secret.dunikey ]] && rm -f ~/.ssb/secret.dunikey && mv /tmp/secret.dunikey ~/.ssb/secret.dunikey
# CREATE SSB secret
g1pub=$(cat ~/.ssb/secret.dunikey | grep "pub" | cut -d ' ' -f 2)
echo "G1PUB=\"$g1pub\"" >> ~/.zen/secret.astroport.key
g1priv=$(cat ~/.ssb/secret.dunikey | grep "sec" | cut -d ' ' -f 2)
ssbpub=$(echo $g1pub | base58 -d | base64)
ssbpriv=$(echo $g1priv | base58 -d | base64 | tr -d "\n" )
rm -f ~/.ssb/secret
cat > ~/.ssb/secret <<EOF
# THIS KEY IS YOURS! REMIND IT AND KEEP IT SAFE AS A REAL WALLET
{
"curve": "ed25519",
"public": "${ssbpub}.ed25519",
"private": "${ssbpriv}.ed25519",
"id": "@${ssbpub}.ed25519"
}
# WARNING! It's vital that you DO NOT edit OR share your secret name
# ONLY Share your public name : @${ssbpub}.ed25519
# AND Public G1 WALLET : $g1pub
EOF
echo "WHOAMI=\"@$ssbpub.ed25519\"" >> ~/.zen/secret.astroport.key
echo "
_
|__|_ \ / _ o | _.
|_ |_ \/ (_) | | (_|
Your Identity is created !!
REMEMBER TO KEEP your secret files SECRET !!!
Your public name : @${ssbpub}.ed25519
Your G1 WALLET : $g1pub
"
chmod 400 ~/.ssb/secret
chmod 400 ~/.ssb/secret.dunikey
echo '
__
__________/ /_
/ ___/ ___/ __ \
(__ |__ ) /_/ /
/____/____/_.___/
NEW IDENTITY ACTIVATED in ~/.ssb/secret
' | lolcat
echo '
_________
/ ____< /
/ / __ / /
/ /_/ // /
\____//_/
IDENTITY CREATED in ~/.ssb/secret.dunikey
Install https://cesium.app to use it !!
' | lolcat
cat ~/.zen/secret.astroport.key
echo '
Now you are going to join #Swarm0 IPFS Metaverse
ACTIVATE METAVERSE #SWARM0 INIT SEQUENCE...
ALPHA - ALPHA - ALPHA - ALPHA
'
echo "Starting SSB SERVER... wait 10 seconds..."
ssb-server start &
sleep 10
if [[ $isARM ]]; then
echo "Starting OASIS..."
oasis --allow-host $nodename --host $nodename &
sleep 7
else
# Intall Patchwork
if [[ ! $(which ssb-patchwork) ]]; then
wget https://github.com/ssbc/patchwork/releases/download/v3.18.0/ssb-patchwork_3.18.0_amd64.deb -O /tmp/patchwork.deb
sudo dpkg -i /tmp/patchwork.deb
sleep 1
rm /tmp/patchwork.deb
## npm install way
##npm install --global ssb-patchwork
sleep 2
# Start Patchwork
#[[ $(which ssb-patchwork) ]] && ssb-patchwork || echo -e "${c_red}Patchwork is not installed$c_"
fi
fi
~/.zen/astroport/zen/ssb_INIT.sh
~/.zen/astroport/zen/cron_VRFY.sh
echo -e "Finished...
########################################################################
${c_light}IF SOMETHING WENT WRONG REPORT AN ISSUE
https://git.p2p.legal/axiom-team/astroport/issues$c_
########################################################################
MAKE SOME TEST
1. Test IPFS Layer
ipfs id
2. Test SSB Layer
sbotc whoami
3. Test G1 Layer
silkaj balance $g1pub
4. Test #Swarm0 Activation
crontab -l
5. Test OASIS
WARNING: If tour installation is working on Pathwork, Oasis is disabled
http://$nodename:3000
IF EVERYTHING IS OK
ADD oasis TO YOUR system AUTOSTART !!!
oasis --allow-host $nodename --host $nodename
THANK YOU. Now it is time to connect to your friends...
6. ADD ScuttleButt PUB Invitation (With Oasis: http://$nodename:3000/settings)
${c_light}oasis.astroport.com:8008:@UeiA9iqZ0/XTjmYBht230KGr44bsr+Tl5BXSUDFv8vo=.ed25519~xfUSq/J2zLeFwrvvHie4iXI/GAzybUu7Zs9T7/PgZ+w= $c_
"
exit 0
}

182
zen/tools/natools.py Executable file
View File

@ -0,0 +1,182 @@
#!/usr/bin/env python3
"""
CopyLeft 2020 Pascal Engélibert <tuxmain@zettascript.org>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
__version__ = "1.0"
import os, sys, duniterpy.key, libnacl.sign, base58, base64, getpass
def getargv(arg:str, default:str="", n:int=1, args:list=sys.argv) -> str:
if arg in args and len(args) > args.index(arg)+n:
return args[args.index(arg)+n]
else:
return default
def read_data(data_path, b=True):
if data_path == "-":
if b:
return sys.stdin.read().encode()
else:
return sys.stdin.read()
else:
return open(os.path.expanduser(data_path), "rb" if b else "r").read()
def write_data(data, result_path):
if result_path == "-":
os.fdopen(sys.stdout.fileno(), 'wb').write(data)
else:
open(os.path.expanduser(result_path), "wb").write(data)
def encrypt(data, pubkey):
return duniterpy.key.PublicKey(pubkey).encrypt_seal(data)
def decrypt(data, privkey):
return privkey.decrypt_seal(data)
def sign(data, privkey):
return privkey.sign(data)
def verify(data, pubkey):
try:
sys.stderr.write("Signature OK!\n")
return libnacl.sign.Verifier(duniterpy.key.PublicKey(pubkey).hex_pk()).verify(data)
except ValueError:
sys.stderr.write("Bad signature!\n")
exit(1)
def get_privkey(privkey_path, privkey_format):
if privkey_format == "pubsec":
if privkey_path == "*":
privkey_path = "privkey.pubsec"
return duniterpy.key.SigningKey.from_pubsec_file(privkey_path)
elif privkey_format == "cred":
if privkey_path == "*":
privkey_path = "-"
if privkey_path == "-":
return duniterpy.key.SigningKey.from_credentials(getpass.getpass("Password: "), getpass.getpass("Salt: "))
else:
return duniterpy.key.SigningKey.from_credentials_file(privkey_path)
elif privkey_format == "seedh":
if privkey_path == "*":
privkey_path = "authfile.seedhex"
return duniterpy.key.SigningKey.from_seedhex(read_data(privkey_path, False))
elif privkey_format == "wif":
if privkey_path == "*":
privkey_path = "authfile.wif"
return duniterpy.key.SigningKey.from_wif_or_ewif_file(privkey_path)
elif privkey_format == "wifh":
if privkey_path == "*":
privkey_path = "authfile.wif"
return duniterpy.key.SigningKey.from_wif_or_ewif_hex(privkey_path)
elif privkey_format == "ssb":
if privkey_path == "*":
privkey_path = "secret"
return duniterpy.key.SigningKey.from_ssb_file(privkey_path)
elif privkey_format == "key":
if privkey_path == "*":
privkey_path = "authfile.key"
return duniterpy.key.SigningKey.from_private_key(privkey_path)
fmt = {
"raw": lambda data: data,
"16": lambda data: data.hex().encode(),
"32": lambda data: base64.b32encode(data),
"58": lambda data: base58.b58encode(data),
"64": lambda data: base64.b64encode(data),
"64u": lambda data: base64.urlsafe_b64encode(data),
"85": lambda data: base64.b85encode(data),
}
def show_help():
print("""Usage:
python3 natools.py <command> [options]
Commands:
encrypt Encrypt data
decrypt Decrypt data
sign Sign data
verify Verify data
Options:
-f <fmt> Private key format (default: cred)
key cred pubsec seedh ssb wif wifh
-i <path> Input file path (default: -)
-k <path> Privkey file path (* for auto) (default: *)
-p <str> Pubkey (base58)
-o <path> Output file path (default: -)
--noinc Do not include msg after signature
-O <fmt> Output format: raw 16 32 58 64 64u 85 (default: raw)
--help Show help
--version Show version
--debug Debug mode (display full errors)
Note: "-" means stdin or stdout.
""")
if __name__ == "__main__":
if "--help" in sys.argv:
show_help()
exit()
if "--version" in sys.argv:
print(__version__)
exit()
privkey_format = getargv("-f", "auto")
data_path = getargv("-i", "-")
privkey_path = getargv("-k", "*")
pubkey = getargv("-p")
result_path = getargv("-o", "-")
output_format = getargv("-O", "raw")
try:
if sys.argv[1] == "encrypt":
write_data(fmt[output_format](encrypt(read_data(data_path), pubkey)), result_path)
elif sys.argv[1] == "decrypt":
write_data(fmt[output_format](decrypt(read_data(data_path), get_privkey(privkey_path, privkey_format))), result_path)
elif sys.argv[1] == "sign":
data = read_data(data_path)
signed = sign(data, get_privkey(privkey_path, privkey_format))
if "--noinc" in sys.argv:
signed = signed[:len(signed)-len(data)]
write_data(fmt[output_format](signed), result_path)
elif sys.argv[1] == "verify":
write_data(fmt[output_format](verify(read_data(data_path), pubkey)), result_path)
else:
show_help()
except Exception as e:
if "--debug" in sys.argv:
0/0 # DEBUG MODE
sys.stderr.write("Error: {}\n".format(e))
show_help()
exit(1)

Some files were not shown because too many files have changed in this diff Show More