aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbin/currencies.sh32
-rwxr-xr-xbin/gab357
-rwxr-xr-xcgi/gb.cgi47
-rwxr-xr-xcgi/rgb.cgi10
-rwxr-xr-xcgi/weather24
-rwxr-xr-xcgi/weather.sh7
6 files changed, 477 insertions, 0 deletions
diff --git a/bin/currencies.sh b/bin/currencies.sh
new file mode 100755
index 0000000..0bb684d
--- /dev/null
+++ b/bin/currencies.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+
+fiatentry() {
+ printf "## %s\n" "$1" >> "$3"
+ code=$(/usr/bin/curl -o /tmp/ratesx-resp.txt -s -w "%{http_code}" rub.rate.sx/$2)
+ if [[ $code == 200 ]]; then
+ cat /tmp/ratesx-resp.txt >> "$3"
+ else
+ printf "rate.sx вернул $code :(\n" >> "$3"
+ fi
+ printf "%s\n" '---' >> "$3"
+}
+
+echo "# Курсы криптовалют" > /opt/gemini/crypto.gmi
+echo "(обновление раз в 10 минут с rate.sx)" >> /opt/gemini/crypto.gmi
+echo "udp $(date +"%Y-%m-%d %H:%M") GMT+3" >> /opt/gemini/cryptfiato.gmi
+echo '```' >> /opt/gemini/crypto.gmi
+/usr/bin/curl rate.sx/?qTF | tail -n +6>> /opt/gemini/crypto.gmi
+echo '```' >> /opt/gemini/crypto.gmi
+
+echo "# Курсы фиатных валют к рублю" > /opt/gemini/fiat.gmi
+echo "(обновление раз в 10 минут с rate.sx)" >> /opt/gemini/fiat.gmi
+echo "udp $(date +"%Y-%m-%d %H:%M") GMT+3" >> /opt/gemini/fiat.gmi
+
+fiatentry "Доллар США" 1USD /opt/gemini/fiat.gmi
+fiatentry "Евро" 1EUR /opt/gemini/fiat.gmi
+fiatentry "Юань" 1CNY /opt/gemini/fiat.gmi
+fiatentry "Иена" 1JPY /opt/gemini/fiat.gmi
+fiatentry "Турецкая лира" 1TRY /opt/gemini/fiat.gmi
+fiatentry "Швейцарский франк" 1CHF /opt/gemini/fiat.gmi
+fiatentry "Британский фунт" 1GBP /opt/gemini/fiat.gmi
+
diff --git a/bin/gab b/bin/gab
new file mode 100755
index 0000000..46d5fc7
--- /dev/null
+++ b/bin/gab
@@ -0,0 +1,357 @@
+#!/usr/bin/env python3
+import os
+import sys
+import time
+from datetime import datetime
+import subprocess as sp
+from subprocess import call
+import tempfile
+
+LIST_MESSAGES_LIMIT = "30"
+
+chan_dir = ".config/gab/channels" ## not used yet. todo: move all gab channel logs to this dir
+current_user = os.environ.get('USER')
+log = {}
+
+help_text = """
+GAB - A simple chat interface
+
+syntax: gab [flag] [value]
+
+flag value
+-------------------- ---------------
+-h, --help, help
+-m, --msg, msg Quoted text with the msg being added to chat
+-l, --list, list An integer representing the number of rows you'd like
+ to view, default 5
+-b, --block, block A username to block/ignore
+-u, --unblock, unblock A username to unblock/unignore
+-c, --channel, channel Name of the channel you would like to join or create.
+ An empty value lists the available channels.
+-n, --new, new Check for new, unread messages.
+-N, --new-verbose, new-verbose Check for new, unread messages, creating output
+ even when no new messages exist.
+
+Channels names ending in ! are private. They can be joined by anyone that
+knows they exist, but will not be listed in the channel listings. To return
+to the main/default channel, simply switch channels to 'gab':
+ gab channel gab
+
+Examples:
+ gab msg "Good afternoon!"
+ gab list 20
+ gab block annoyingperson
+ gab channel my-secret-channel!
+ gab channel a-public-channel
+ gab unblock somedude
+"""
+
+title = "\033[1mGAB v2.2\033[0m"
+
+def get_chan():
+ fp = "/home/{}/.gab_chan".format(current_user)
+
+ if not os.path.isfile(fp):
+ return ""
+
+ with open(fp, 'r') as chanfile:
+ channel = chanfile.read().split("\n")[0].strip()
+ if channel:
+ channel = "-" + channel
+ return channel
+
+def blocked_users():
+ fp = "/home/{}/.gab_block".format(current_user)
+
+ if not os.path.isfile(fp):
+ return []
+
+ with open(fp, 'r') as blockfile:
+ return blockfile.read().split("\n")
+
+def get_files(channel):
+ return [[x, "/home/{}/.gab{}".format(x, channel)] for x in os.listdir("/home/") if x not in blocked_users() and os.access("/home/"+x, os.R_OK)]
+
+
+def get_user_channels(user_dir):
+ chans = {"gab"}
+ for y in os.listdir(user_dir):
+ if len(y) > 5 and y[:5] == ".gab-" and y[-1] != "!":
+ chans.add(y[5:])
+ return chans
+
+
+def get_chan_list():
+ chans = {"gab"}
+ for x in os.listdir("/home/"):
+ if not os.access("/home/" + x, os.R_OK):
+ continue
+ for y in os.listdir("/home/" + x):
+ if len(y) > 5 and y[:5] == ".gab-" and y[-1] != "!":
+ chans.add(y[5:])
+ return chans
+
+
+def list_channels():
+ chans = get_chan_list()
+ chan = get_chan()
+ print(title)
+ print("\n\033[1mAvailable channels\033[0m:")
+ for x in chans:
+ if chan[1:] == x:
+ x = x + " *"
+ elif chan == "" and x == "gab":
+ x = x + " *"
+ print(x)
+
+
+def read_file(user, path, num_lines):
+ global log
+ if os.path.isfile(path) and os.access(path, os.R_OK):
+ if "/home/" + current_user + "/" in path:
+ os.utime(path, None) ## update file's timestamp on each read
+ with open(path, "r") as f:
+ for line in range(num_lines):
+ msg = f.readline().split("|", 1)
+ dt = msg[0].strip()
+ if len(msg) == 2 and float(dt) < time.time():
+ msg = msg[1].strip()
+ if msg[:3] == "/me":
+ log[dt] = "\033[7m * * * \033[0m \033[3m{}\033[0m".format(msg.replace("/me", user))
+ else:
+ log[dt] = "\033[7m {} \033[0m {}\033[0m".format(user, msg)
+
+
+def list_messages(count=LIST_MESSAGES_LIMIT):
+ global log
+ chan = get_chan()
+ files = get_files(chan)
+
+ try:
+ count = int(count)
+ except ValueError:
+ print("Error parsing list number, using default: 5")
+ count = 5
+
+ for x in files:
+ read_file(x[0], x[1], count)
+
+ sorted_keys = list(log.keys())
+ if len(sorted_keys) > 0:
+ sorted_keys.sort(reverse=True)
+ last_time = float(sorted_keys[0])
+ sorted_keys = sorted_keys[:min(len(sorted_keys), count)]
+ sorted_keys.sort(reverse=False)
+ print(title)
+ print("Current channel: \033[1m{}\033[0m".format(chan[1:] if chan else "gab"))
+ print("Last message: {}".format(diff_time_from_now(last_time)))
+ print("\n- - -")
+ for key in range(min(count, len(sorted_keys))):
+ print(log[sorted_keys[key]])
+ print("- - -")
+ else:
+ print(title)
+ print("Current channel: \033[1m{}\033[0m".format(chan[1:] if chan else "gab"))
+ print()
+ print("There are no messages to display")
+
+
+def diff_time_from_now(t, n=time.time()):
+ diff = n - t
+ diff = int(diff)
+ out = ""
+
+ # Days
+ if diff // (3600 * 24) > 0:
+ days = diff // (3600 * 24)
+ out += "{}d ".format(days)
+ diff = diff - (days * 3600 * 24)
+
+ # Hours
+ if diff // 3600 > 0:
+ out += "{}h ".format(diff // 3600)
+ diff = diff - (diff // 3600 * 3600)
+
+ # Minutes
+ if diff // 60 > 0:
+ out += "{}m ".format(diff // 60)
+ diff = diff - (diff // 60 * 60)
+
+ # Seconds
+ out += "{}s ago".format(diff)
+
+ return out
+
+
+def add_message(msg):
+ timestamp = str(time.time())
+ output = "{}|{}\n".format(timestamp, msg.strip())
+ fp = "/home/{}/.gab{}".format(current_user, get_chan())
+ try:
+ with open(fp, 'r') as original:
+ data = original.read(12000)
+ with open(fp, 'w') as modified:
+ modified.write(output)
+ modified.write(data)
+ except FileNotFoundError:
+ with open(fp, 'a') as modified:
+ modified.write(output)
+ except:
+ print("Error adding text to chatlog")
+ return
+
+ print("Successfully added text to chatlog")
+
+ try:
+ os.chmod(fp, 0o644)
+ except PermissionError:
+ print("You do not have permission to modify the chatlog")
+ except FileNotFoundError:
+ print("The chatlog does not exist")
+
+
+def block_user(user_to_block):
+ fp = "/home/{}/.gab_block".format(current_user)
+ block_fp = "/home/{}/".format(user_to_block)
+ if not os.path.isdir(block_fp):
+ print("User '{}' does not exist, no action taken".format(user_to_block))
+ return
+
+ with open(fp, 'a') as blockfile:
+ blockfile.write(user_to_block)
+ blockfile.write("\n")
+
+ print("User '{}' has been blocked, you will not see their messages".format(user_to_block))
+ return
+
+
+def unblock_user(user_to_unblock):
+ fp = "/home/{}/.gab_block".format(current_user)
+ unblock_fp = "/home/{}/".format(user_to_unblock)
+
+ if not os.path.isfile(fp):
+ print("You do not have any users on your block list, no action taken")
+ return
+
+ if not os.path.isdir(unblock_fp):
+ print("User '{}' does not exist, no action taken".format(user_to_unblock))
+ return
+
+ blocked_users_list = [x for x in blocked_users() if x != user_to_unblock]
+
+ with open(fp, 'w') as blocked:
+ blocked.write("\n".join(blocked_users_list))
+
+ print("User '{}' has been removed from your block list".format(user_to_unblock))
+
+
+def switch_channel(newchan):
+ chan = newchan
+ if newchan == "gab":
+ newchan = ""
+
+ fp = "/home/{}/.gab_chan".format(current_user)
+
+ with open(fp, 'w') as chanfile:
+ chanfile.write(newchan)
+
+ print("You are now viewing the '{}' channel.".format(chan))
+ list_messages()
+
+
+def new_scan(silent=True):
+ unread_chans = []
+ chans = get_user_channels("/home/" + current_user)
+
+ for c in chans:
+ my_timestamp = chan_timestamp = 0.0
+ if c == "gab":
+ files = get_files("")
+ else:
+ files = get_files("-" + c)
+
+ for f in files:
+ if os.path.isfile(f[1]):
+ try:
+ with open(f[1]) as fh:
+ timestamp = float(fh.readline().split("|")[0])
+ if timestamp > float(chan_timestamp):
+ chan_timestamp = timestamp
+ if f[0] == current_user:
+ atime= time.ctime(os.stat(f[1]).st_atime)
+ my_timestamp = time.mktime(datetime.strptime(atime, "%a %b %d %H:%M:%S %Y").timetuple())
+ except:
+ continue
+ if my_timestamp - chan_timestamp < 0:
+ unread_chans.append(c)
+
+ if len(unread_chans):
+ print("New gab messages in: " + ", ".join(unread_chans))
+ else:
+ if silent == False:
+ print("gab: no unread messages.")
+ exit(1)
+
+
+def parse_command():
+ args = sys.argv[1:]
+ if not len(args):
+ list_messages()
+ elif args[0] in ["-h", "--help", "help"]:
+ print(help_text)
+ elif args[0] in ["list", "--list", "-l"]:
+ if len(args) == 2:
+ list_messages(args[1])
+ else:
+ print("Invalid command input to 'list'")
+ elif args[0] in ["new", "--new", "-n"]:
+ new_scan()
+ elif args[0] in ["new-verbose", "--new-verbose", "-N"]:
+ new_scan(silent=False)
+ elif args[0] in ["-m", "--msg", "msg"]:
+ if len(args) < 2:
+ # code from https://stackoverflow.com/a/6309753
+ EDITOR = os.environ.get('EDITOR') if os.environ.get('EDITOR') else 'vi'
+ with tempfile.NamedTemporaryFile(suffix=".tmp") as tf:
+ tf.flush()
+ call([EDITOR, tf.name])
+ tf.seek(0)
+ edited_message = tf.read()
+ lines = edited_message.decode("utf-8").split("\n")
+ for line in lines:
+ if len(line.split()):
+ add_message(line)
+
+ elif len(args) > 2:
+ print("Expected a message, but received too many arguments. Did you put your message in quotes?")
+ else:
+ add_message(args[1])
+ elif args[0] in ["-b", "--block", "block"]:
+ if len(args) < 2:
+ print("Expected a user to block, but one was not received")
+ elif len(args) > 2:
+ print("Expected a user to block, but received too many arguments")
+ else:
+ block_user(args[1])
+ elif args[0] in ["-u", "--unblock", "unblock"]:
+ if len(args) < 2:
+ print("Expected a user to unblock, but one was not received")
+ elif len(args) > 2:
+ print("Expected a user to unblock, but received too many arguments")
+ else:
+ unblock_user(args[1])
+ elif args[0] in ["-c", "--channel", "channel"]:
+ if len(args) < 2:
+ # print("Returning to default channel.")
+ # switch_channel("gab")
+ list_channels()
+ elif len(args) > 2:
+ print("Expected a channel to join, but received too many arguments")
+ else:
+ switch_channel(args[1])
+ else:
+ print("Unknown command: {}".format(args[0]))
+
+
+if __name__ == '__main__':
+ parse_command()
diff --git a/cgi/gb.cgi b/cgi/gb.cgi
new file mode 100755
index 0000000..cf14ab8
--- /dev/null
+++ b/cgi/gb.cgi
@@ -0,0 +1,47 @@
+#!/usr/bin/python3
+
+import os
+import subprocess
+import sys
+import urllib.parse
+
+import datetime
+from datetime import date
+
+query = os.environ["QUERY_STRING"]
+if not query:
+ print("10 Напишите сообщение и нажмите \"Enter\".")
+ sys.exit()
+
+text = urllib.parse.unquote(query)
+
+print("20 text/gemini")
+
+#print (text)
+
+#today = date.today()
+file1 = open("/opt/gemini/gb.gmi", "a") # append mode
+file1.write('%s.\n' % (datetime.datetime.now()))
+file1.write(" ")
+file1.write(text)
+file1.write("\n\n")
+file1.close()
+
+
+try:
+ proc = subprocess.run(
+ ["/usr/bin/cat","/opt/gemini/gb.gmi"],
+# input="/var/gemini/gb.gmi",
+ capture_output=True,
+ check=True,
+ text=True,
+ )
+except:
+ print("42 Unexpected Error")
+else:
+# print("20 text/plain")
+ print(proc.stdout)
+
+#print("=> /cgi-bin/rgb.cgi Читать гостевую")
+print("=> gemini://gemini.phreedom.club:1968/cgi-bin/gb.cgi Писать в гостевую")
+print("=> gemini://gemini.phreedom.club:1968/index.gmi Выйти из гостевой")
diff --git a/cgi/rgb.cgi b/cgi/rgb.cgi
new file mode 100755
index 0000000..84fce1f
--- /dev/null
+++ b/cgi/rgb.cgi
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+#printf "20 text/plain\r\n"
+printf "20 text/gemini\r\n"
+/usr/bin/cat /srv/gemini/gb.gmi
+echo ""
+#echo "=>/cgi-bin/rgb.cgi Читать гостевую"
+echo "=> gemini://phreedom.club/cgi-bin/gb.cgi Писать в гостевую"
+echo "=> gemini://phreedom.club/~tolstoevsky/index.gmi На капсулу Tolstoevsky"
+echo "=> gemini://phreedom.club/index.gmi На капсулу Phreedom"
diff --git a/cgi/weather b/cgi/weather
new file mode 100755
index 0000000..5590e83
--- /dev/null
+++ b/cgi/weather
@@ -0,0 +1,24 @@
+#!/usr/bin/python3
+
+import os
+import subprocess
+import sys
+import urllib.parse
+
+import datetime
+from datetime import date
+
+query = os.environ["QUERY_STRING"]
+if not query:
+ print("10 Введите поисковый запрос и нажмите \"Enter\".")
+ sys.exit()
+
+text = urllib.parse.unquote(query)
+
+print("20 text/gemini")
+
+#print("````")
+#print (text)
+
+print(subprocess.Popen(["ansiweather", "-F", "-u", "metric", "-a", "false", "-w", "true", "-p", "true", "-d", "true", "-s", "false", "-l" , text ], stdout=subprocess.PIPE).stdout.read())
+#print("````")
diff --git a/cgi/weather.sh b/cgi/weather.sh
new file mode 100755
index 0000000..791417c
--- /dev/null
+++ b/cgi/weather.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+if [[ -n ${QUERY_STRING} && ${QUERY_STRING} =~ ${re} ]] ; then
+ printf "20 text/gemini\r\n $(ansiweather -F -u metric -a false -w true -p true -d true -s true -l ${QUERY_STRING}| sed 's/-/\n/g' | sed 's/=/\n/g' )\r\n --- \r\n Источник - OpenWeatherMap"
+
+else
+ printf "10 введите город (латиницей)"
+fi