Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
zstyblik committed Mar 14, 2024
1 parent 2521071 commit 6371859
Show file tree
Hide file tree
Showing 14 changed files with 932 additions and 0 deletions.
31 changes: 31 additions & 0 deletions .github/workflows/ii_wrapper.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: ii-wrapper workflow

on: [push]

jobs:
build:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- name: Set up Python 3.11
uses: actions/setup-python@v1
with:
python-version: 3.11
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements-ci.txt
- name: Reorder Python imports
run: |
./ci/run-reorder-python-imports.sh
- name: Lint with flake8
run: |
./ci/run-flake8.sh
- name: Lint with black
run: |
./ci/run-black.sh check || ( ./ci/run-black.sh diff; exit 1 )
- name: Test with pytest
run: |
python -m pytest .
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*.pyc
__pycache__
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# ii-wrapper

Wrapper and a bot for [ii] IRC client inspired by and based on [iibot] by
[c00kiemon5ter]. Unlike the original, this one is leaning towards Python for
better or worse.

_Why?_ Why not? Bash, cURL, calc - all of these are dependencies in the same way
as Python and friends are.

ii v1.8(newer version not tested, probably compatible as well) required due to
change in log output format.

Features:

* commands
* configuration file in order to support multiple instances of bot
* auto reconnect

## UnLicense

Since the original is [UnLicense]-d, I've decided to follow the suit.

[ii]: https://tools.suckless.org/ii/
[iibot]: https://github.com/c00kiemon5ter/iibot
[c00kiemon5ter]: https://github.com/c00kiemon5ter
[UnLicense]: https://unlicense.org
23 changes: 23 additions & 0 deletions ci/run-black.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/usr/bin/env bash
set -e
set -u


MODE=${1:?Mode must be given.}

if [ "${MODE}" == "check" ]; then
black_arg=" --check"
elif [ "${MODE}" == "diff" ]; then
black_arg=" --diff"
elif [ "${MODE}" == "format" ]; then
black_arg=""
else
printf "Mode '%s' is not supported.\n" "${MODE}" 1>&2
exit 1
fi

python3 \
-m black \
${black_arg} \
-l 80 \
`find . ! -path '*/\.*' -name '*.py'`
13 changes: 13 additions & 0 deletions ci/run-flake8.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/usr/bin/env bash
set -e
set -u

python3 -m flake8 \
. \
--ignore=W503 \
--application-import-names="app,settings" \
--import-order-style=pycharm \
--max-line-length=80 \
--show-source \
--count \
--statistics
5 changes: 5 additions & 0 deletions ci/run-reorder-python-imports.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
set -e
set -u

reorder-python-imports `find . ! -path '*/\.*' -name '*.py'`
157 changes: 157 additions & 0 deletions iibot-ng
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
#!/bin/sh
# Desc: Wrapper for iibot based on script by c00kiemon5ter
#
# Example of .cfg file:
# ~~~
# net:irc.ssh.cz:#chan1 #chan2
# nickname:testme
# ircdir:$HOME/ii/
# ~~~
#
# 2017/Apr/08 @ Zdenek Styblik <[email protected]>
set -e
set -u

monitor()
{
local iipid="${1}"
tail -f -n1 --pid=${iipid} "${ircdir}/${network}/${channel}/out" | \
while read -r nixtime nick msg; do
# if msg is by the system ignore it
if [ "$nick" = '-!-' ]; then
continue
fi
# strip < and >. if msg is by ourself ignore it
nick=$(printf -- "${nick}" | sed -e 's@^<@@' | sed -e 's@>$@@')
if [ "${nick}" = "${nickname}" ]; then
continue
fi

# FIXME: somehow pass credentials for bit.ly
# if msg contains a url, transform to url command
if printf -- "%s" "${msg}" | grep -q -E -e 'https?://' ; then
exec "${ircdir}/iicmd.py" \
--nick "${nick}" \
--message "url ${msg#* }" \
--ircd "${ircdir}" \
--network "${network}" \
--channel "${channel}" \
--self "${nickname}" | fold -w 255 &
continue
fi
# if msg is a command, invoke iicmd
if printf -- "%s" "${msg}" | grep -q -E -e '^!' ; then
exec "${ircdir}/iicmd.py" \
--nick "${nick}" \
--message "${msg#\!}" \
--ircd "${ircdir}" \
--network "${network}" \
--channel "${channel}" \
--self "${nickname}" | fold -w 255 &
continue
fi
done > "${ircdir}/${network}/${channel}/in"
}

monitor_link()
{
local iipid=${1}
IFS='
'
tail -f -n1 --pid=${iipid} "${ircdir}/${network}/out" | \
while read -r response; do
if printf -- "%s" "${response}" | grep -q -i -e 'Closing Link' -E -e "${nickname}.*ping timeout"; then
printf "Killing bot.\n" 1>&2
kill "${iipid}"
break
fi
done
}

remove_lock()
{
if [ -n "${pids}" ]; then
printf -- "${pids}" | xargs kill || true
fi
rmdir "${LOCK_DIR}"
}

IRC_CONFIG=${1:?Supply name of IRC config to use.}
IRC_CONFIG_NAME=$(basename -- "${IRC_CONFIG}")
LOCK_DIR="/tmp/${IRC_CONFIG_NAME}.lock"

if [ ! -r "${IRC_CONFIG}" ]; then
printf "Config file '%s' doesn't exist or is not readable.\n" \
${IRC_CONFIG} 1>&2
exit 2
fi


ircdir=$(grep -e '^ircdir:' "${IRC_CONFIG}" | cut -d ':' -f 2- | head -n 1)
ircdir=${ircdir:-${HOME}/tmp/ii/ii/}
nickname=$(grep -e '^nickname:' "${IRC_CONFIG}" | awk -F':' '{ print $2 }' |\
head -n 1)
nickname=${nickname:-"testme"}
net_conf=$(grep -e '^net:' "${IRC_CONFIG}" | sort | uniq | head -n1)
network=$(printf -- "%s" "${net_conf}" | awk -F: '{ print $2 }')
if [ -z "${net_conf}" ] || [ -z "${network}" ]; then
printf "No network configuration has been found in '%s'.\n" \
"${IRC_CONFIG}" 1>&2
exit 1
fi

mkdir -p "${LOCK_DIR}" || \
( printf "Failed to create lock for '%s'.\n" "${IRC_CONFIG}" 1>&2; exit 1; )
trap remove_lock INT QUIT TERM EXIT

# some privacy please, thanks
chmod 700 "${ircdir}"
chmod 600 "${ircdir}"/*/ident 1> /dev/null 2>&1 || true

pids=""
# cleanup
rm -f "${ircdir}/${network}/in"
# connect to network - password is set through the env var IIPASS
# NOTE: name of env variable MUST BE given as an CLI arg, eg. -k IIPASS,
# therefore this currently doesn't work.
ii -i "${ircdir}" -n "${nickname}" -s "${network}" \
-f "${nickname}" >> "${ircdir}/${network}.log" 2>&1 &
pid="$!"

# wait for the connection
time_slept=0
while ! test -p "${ircdir}/${network}/in"; do
sleep 1
time_slept=$((time_slept + 1))
if [ ${time_slept} -ge 15 ]; then
break
fi
done

monitor_link "$pid" &
pids=$(printf -- "%s %s" "${pids}" $!)

# auth to services
if [ -e "${ircdir}/${network}/ident" ]; then
printf -- "/j nickserv identify %s\n" \
"$(<"${ircdir}/${network}/ident")" > "${ircdir}/${network}/in"
fi
# clean that up - ident passwd is in there
rm -f "${ircdir}/${network}/nickserv/out"

sleep 3
# join channels
for channel in $(printf -- "%s" "${net_conf}" | awk -F':' '{ print $3 }'); do
printf -- "/j %s\n" "${channel}" > "${ircdir}/${network}/in"
if [ ! -e "${ircdir}/${network}/${channel}/out" ]; then
touch "${ircdir}/${network}/${channel}/out"
fi
monitor "${pid}" &
pids=$(printf -- "%s %s" "${pids}" $!)
done

# if connection is lost, die
wait "${pid}"
remove_lock
trap - INT QUIT TERM EXIT
# EOF
Loading

0 comments on commit 6371859

Please sign in to comment.