forked from axiom-team/astrXbian
Astroport layer for Xbian
This commit is contained in:
parent
08c50eb478
commit
d56393af34
|
@ -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
|
@ -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 |
|
@ -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
|
|
@ -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"
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||||
|
}
|
||||||
|
|
||||||
|
$@
|
|
@ -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.
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||||
|
```
|
|
@ -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_"
|
|
@ -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
|
|
@ -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',
|
||||||
|
);
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
#/bin/bash
|
||||||
|
|
||||||
|
sudo -u www-data php /var/www/nextcloud/occ $@
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
|
|
@ -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]\.";
|
|
@ -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
|
|
@ -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;
|
|
@ -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;
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
$@
|
|
@ -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
|
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"plugins": {
|
||||||
|
"ssb-private": true,
|
||||||
|
"ssb-backlinks": true,
|
||||||
|
"patchfoo": true
|
||||||
|
}
|
||||||
|
}
|
|
@ -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"
|
|
@ -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;
|
||||||
|
}
|
|
@ -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
|
|
@ -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
|
|
@ -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"
|
||||||
|
}
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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"
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||||
|
|
||||||
|
}
|
|
@ -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
|
||||||
|
```
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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 -
|
|
@ -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...
|
|
@ -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 ;)
|
||||||
|
"
|
||||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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` où `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
|
||||||
|
```
|
|
@ -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.
|
@ -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
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
|
@ -0,0 +1,6 @@
|
||||||
|
wheel
|
||||||
|
base58
|
||||||
|
pybase64
|
||||||
|
duniterpy
|
||||||
|
termcolor
|
||||||
|
python-dotenv
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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.
|
@ -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
|
|
@ -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
|
|
@ -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")
|
|
@ -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")
|
|
@ -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
|
|
@ -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
|
|
@ -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")
|
|
@ -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")
|
||||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||||
|
}
|
|
@ -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)
|
|
@ -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
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
||||||
|
}
|
|
@ -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)
|
|
@ -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,
|
||||||
|
)
|
|
@ -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
|
||||||
|
}
|
|
@ -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
Loading…
Reference in New Issue