Skip to content

Commit

Permalink
Merge pull request #1 from zstyblik/initial
Browse files Browse the repository at this point in the history
Initial commit
  • Loading branch information
zstyblik authored Mar 16, 2024
2 parents 2521071 + 000c628 commit 295e178
Show file tree
Hide file tree
Showing 14 changed files with 940 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__
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# 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 or newer(probably) is 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'`
166 changes: 166 additions & 0 deletions iibot-ng
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
#!/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/
# bitly_api_token:api_token
# bitly_group_id:group_id
# ~~~
#
# 2017/Apr/08 @ Zdenek Styblik <[email protected]>
set -e
set -u

monitor()
{
local iipid="${1}"
tail -f -n1 --pid=${iipid} "${ircdir}/${network}/${channel}/out" | \
# NOTE: format of output changed in v1.8
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

# if msg contains a url, transform to url command
if printf -- "%s" "${msg}" | grep -q -E -e 'https?://' ; then
export IICMD_BITLY_GROUP_ID="${bitly_group_id}"
export IICMD_BITLY_API_TOKEN="${bitly_api_token}"
exec "${ircdir}/iicmd.py" \
--nick "${nick}" \
--message "url ${msg#* }" \
--ircd "${ircdir}" \
--network "${network}" \
--channel "${channel}" \
--self "${nickname}" | fold -w 255 &
continue
fi
# NOTE: commands MUST start with _!_ and that's why nothing might be
# happening.
#
# 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 }')
bitly_api_token=$(grep -e '^bitly_api_token:' "${IRC_CONFIG}" | sort | uniq | head -n1)
bitly_group_id=$(grep -e '^bitly_group_id:' "${IRC_CONFIG}" | sort | uniq | head -n1)
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 295e178

Please sign in to comment.