Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial commit #1

Merged
merged 1 commit into from
Mar 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading