summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--.woodpecker/.alpine.yaml11
-rw-r--r--.woodpecker/.archlinux.yaml11
-rw-r--r--Makefile42
-rw-r--r--README.md23
-rw-r--r--chphoto/Makefile2
-rw-r--r--cieresults/.gitignore3
-rw-r--r--cieresults/LICENSE22
-rw-r--r--cieresults/Makefile7
-rw-r--r--cieresults/README.md36
-rw-r--r--cieresults/cieresults.py126
-rw-r--r--cieresults/requirements.txt3
-rw-r--r--memch/Makefile4
-rw-r--r--ykpsmuttauth/Makefile2
13 files changed, 212 insertions, 80 deletions
diff --git a/.woodpecker/.alpine.yaml b/.woodpecker/.alpine.yaml
deleted file mode 100644
index fbfbc9d..0000000
--- a/.woodpecker/.alpine.yaml
+++ /dev/null
@@ -1,11 +0,0 @@
-skip_clone: false
-
-steps:
- build:
- when:
- branch: []
- event: []
- image: alpine
- commands:
- - apk add --no-cache build-base alpine-sdk gcc go curl-dev openssl-dev ncurses-dev
- - make
diff --git a/.woodpecker/.archlinux.yaml b/.woodpecker/.archlinux.yaml
deleted file mode 100644
index bfa91aa..0000000
--- a/.woodpecker/.archlinux.yaml
+++ /dev/null
@@ -1,11 +0,0 @@
-skip_clone: false
-
-steps:
- build:
- when:
- branch: []
- event: []
- image: archlinux
- commands:
- - pacman --noconfirm -Sy make gcc pkgconf openssl curl ncurses go
- - make
diff --git a/Makefile b/Makefile
deleted file mode 100644
index 34db750..0000000
--- a/Makefile
+++ /dev/null
@@ -1,42 +0,0 @@
-.PHONY: all install sjauth memch chphoto ykpsmuttauth clean uninstall pdfutils
-
-all: sjauth memch chphoto ykpsmuttauth pdfutils
-
-sjauth:
- $(MAKE) -C sjauth
- mkdir -p bin/
- install -c -m 755 sjauth/sjauth bin/
-
-memch:
- mkdir -p bin/
- $(MAKE) -C memch
- install -c -m 755 memch/memch bin/
-
-chphoto:
- mkdir -p bin/
- $(MAKE) -C chphoto
- install -c -m 755 chphoto/chphoto bin/
-
-ykpsmuttauth:
- mkdir -p bin/
- $(MAKE) -C ykpsmuttauth
- install -c -m 755 ykpsmuttauth/ykpsmuttauth bin/
-
-pdfutils:
- mkdir -p bin/
- install -c -m 755 pdfutils/* bin/
-
-install: all
- mkdir -p $${HOME}/.local/bin/
- install -c -m 755 bin/* $${HOME}/.local/bin/
-
-clean:
- $(MAKE) -C sjauth clean
- $(MAKE) -C memch clean
- $(MAKE) -C chphoto clean
- $(MAKE) -C ykpsmuttauth clean
- rm -f bin/*
-
-uninstall:
- rm -f $${HOME}/.local/bin/sjauth $${HOME}/.local/bin/memch $${HOME}/.local/bin/chphoto $${HOME}/.local/bin/ykpsmuttauth $${HOME}/.local/bin/fixpdf $${HOME}/.local/bin/html2pdf $${HOME}/.local/bin/pdf2djvu $${HOME}/.local/bin/pdfclean
-
diff --git a/README.md b/README.md
index a7968fd..6d0e1ff 100644
--- a/README.md
+++ b/README.md
@@ -1,24 +1,23 @@
# Scripts, utilities, and other files related to life at YK Pao School
-Most of these are written in C, Go, shell script, and occasionally prototypes in Python. While I try to make things portable, sometimes I might foget, or sometimes GNU Bash extensions are just too convenient, so there is no guarantee that any of this would run on macOS. They should, however, at least work on Alpine and Fedora, and on most other Linux-based systems too.
-
-[![CI status](https://ci.codeberg.org/api/badges/13559/status.svg)](https://ci.codeberg.org/repos/13559)
+While I try to make things portable, sometimes I might foget, so there is no guarantee that any of this would run on macOS. They should, however, at least work on Alpine and Fedora, and on most other Linux-based systems too.
## Contents
-|Program|Language|Description|
-|--|--|--|
-|`chphoto`|Go|Change Outlook profile photos|
-|`memch`|C|Help memorize classical Chinese texts|
-|`pdfutils`|Shell|Help manipulate PDFs|
-|`sjauth`|C|Log on to [STUWIRELESS](https://ykps.runxiyu.org/wifi)|
-|`ykpsmuttauth`|Go, C|Get XOAUTH2 tokens for mutt/aerc for Outlook|
+| Program |Language| Description |
+|--------------|--------|------------------------------------------------------|
+|`chphoto` |Go |Change Outlook profile photos |
+|`memch` |C |Help memorize classical Chinese texts |
+|`pdfutils` |Shell |Help manipulate PDFs |
+|`sjauth` |C |Log on to [STUWIRELESS](https://ykps.runxiyu.org/wifi)|
+|`ykpsmuttauth`|Go, C |Get XOAUTH2 tokens for mutt/aerc for Outlook |
+|`cieresults` |Python |Poll the IGCSE results page |
## Build
-Only GNU Make is supported. Users on BSD systems should call `gmake` instead of `make`.
+There is a Makefile in each subdirectory that builds the relevant program.
-The top-level makefile simply builds subdirectories. Each subdirectory is a phony target, so you could type `make sjauth` to build `sjauth`. The resulting binary is copied to `bin/sjauth`. The `install` target *additionally* causes the binaries to be copied over to `~/.local/bin/`.
+Only GNU Make is supported. Users on BSD systems should call `gmake` instead of `make`.
## Contributing
diff --git a/chphoto/Makefile b/chphoto/Makefile
index c23c37d..541687f 100644
--- a/chphoto/Makefile
+++ b/chphoto/Makefile
@@ -4,4 +4,4 @@ chphoto: chphoto.go
go build
clean:
- rm chphoto
+ rm -f chphoto
diff --git a/cieresults/.gitignore b/cieresults/.gitignore
new file mode 100644
index 0000000..2f7ba60
--- /dev/null
+++ b/cieresults/.gitignore
@@ -0,0 +1,3 @@
+cieauth.txt
+*.html
+cieresults
diff --git a/cieresults/LICENSE b/cieresults/LICENSE
new file mode 100644
index 0000000..d5dfee8
--- /dev/null
+++ b/cieresults/LICENSE
@@ -0,0 +1,22 @@
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS "AS IS" AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/cieresults/Makefile b/cieresults/Makefile
new file mode 100644
index 0000000..43cd9be
--- /dev/null
+++ b/cieresults/Makefile
@@ -0,0 +1,7 @@
+.PHONY: clean
+
+cieresults: cieresults.py
+ install -T -m755 cieresults.py cieresults
+
+clean:
+ rm -f cieresults
diff --git a/cieresults/README.md b/cieresults/README.md
new file mode 100644
index 0000000..7072982
--- /dev/null
+++ b/cieresults/README.md
@@ -0,0 +1,36 @@
+# cieresults
+
+This is an IRC bot that polls [the CIE results
+page](https://myresults.cie.org.uk/cie-candidate-results/results) and announces
+the prescence of results to an IRC channel.
+
+Available under the 2-clause BSD license.
+
+## Usage
+
+Install dependencies (BeautifulSoup4, miniirc, requests):
+```sh
+python3 -m pip install -r requirements.txt
+```
+
+Add your myresults.cie.org.uk username and password to `cieauth.txt`, separated
+by newlines:
+```
+username
+passwod
+```
+
+Then, modify `cieresuts.py` and modify the `irc_config` dictionary to your
+liking:
+```python
+irc_config = {
+ "nick": "cieresults",
+ "ip": "irc.runxiyu.org",
+ "port": 6697,
+ "channels": ["#chat"],
+ "ssl": True,
+ "ident": "cieresults",
+ "realname": "Bot to poll CIE results",
+ "quit_message": "Leaving",
+}
+```
diff --git a/cieresults/cieresults.py b/cieresults/cieresults.py
new file mode 100644
index 0000000..9143b8c
--- /dev/null
+++ b/cieresults/cieresults.py
@@ -0,0 +1,126 @@
+#!/usr/bin/env python3
+#
+# Poll myresults.cie.org.uk and announce the availability of results to an IRC channel.
+#
+# Written by Runxi Yu <https://runxiyu.org>
+#
+# SPDX-License-Identifier: CC0-1.0
+#
+
+import miniirc # type: ignore
+import requests
+import bs4
+import time
+
+initial_headers = {
+ "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:120.0) Gecko/20100101 Firefox/120.0",
+ "TE": "trailers",
+ "Origin": "https://myresults.cie.org.uk",
+ "Host": "myresults.cie.org.uk",
+ "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8",
+ "Accept-Language": "en-US,en;q=0.5",
+ "Accept-Encoding": "gzip, deflate, br, zstd",
+ "DNT": "1",
+ "Sec-GPC": "1",
+ "Upgrade-Insecure-Requests": "1",
+ "Sec-Fetch-Dest": "document",
+ "Sec-Fetch-Mode": "navigate",
+ "Sec-Fetch-Site": "same-origin",
+ "Sec-Fetch-User": "?1",
+ "Priority": "u=0, i",
+}
+
+ping = "runxiyu, rx"
+
+irc_config = {
+ "nick": "cieresults",
+ "ip": "irc.runxiyu.org",
+ "port": 6697,
+ "channels": ["#chat"],
+ "ssl": True,
+ "ident": "cieresults",
+ "realname": "Bot to poll CIE results",
+ "quit_message": "Leaving",
+}
+
+print("[*] Creating IRC object")
+irc = miniirc.IRC(**irc_config)
+
+def main() -> int:
+ print("[*] Connecting to IRC")
+ irc.connect()
+ return 0
+
+
+@irc.Handler("001", colon=False) # type: ignore
+def handle(irc, hostmask, args) -> None:
+ print("[*] Initialized connection to IRC (001 received)")
+ while True:
+ print("[*] --------------- Polling --------------------")
+ with open("cieauth.txt", "r") as fd:
+ e = fd.readlines()
+ username = e[0].strip()
+ password = e[1].strip()
+
+ s = requests.Session()
+ s.headers.update(initial_headers)
+ r = s.get("https://myresults.cie.org.uk/cie-candidate-results/login")
+ if r.status_code != 200:
+ print("[!] Login page returned status code %d" % r.status_code)
+ continue
+ print("[*] Fetched login page to consume the cookies")
+ r = s.post(
+ "https://myresults.cie.org.uk/cie-candidate-results/j_spring_security_check",
+ data={"j_username": username, "j_password": password},
+ )
+ if r.status_code != 200:
+ print("[!] Results page returned status code %d" % r.status_code)
+ continue
+ print("[*] Fetched results web page")
+
+ soup = bs4.BeautifulSoup(r.text, features="html.parser")
+
+ # soup = bs4.BeautifulSoup(open("bs.html", "r").read())
+
+ div_yourresults = soup.find(id="yourresults")
+ table = div_yourresults.find( # type: ignore
+ "table", summary="Your examination results for June 2024"
+ )
+ tbody = table.find("tbody") # type: ignore
+ rows = tbody.find_all("tr") # type: ignore
+
+ out_subjects = []
+ not_out_subjects = []
+
+ for row in rows:
+ td1, td2, td3 = row.find_all("td")
+ span1, span2 = td1.find_all("span")
+ subject = "%s %s" % (span1.string.strip(), span2.string.strip())
+ results = td3.string.strip()
+
+ if results == "Results to be released":
+ print("[-] %s: %s" % (subject, results))
+ not_out_subjects.append(subject)
+ else:
+ print("[+] %s: %s\a" % (subject, results))
+ out_subjects.append(subject)
+
+
+ if out_subjects:
+ for channel in irc_config["channels"]: # type: ignore
+ irc.msg(
+ channel, "%s: Results out for %s" % (ping, ", ".join(out_subjects))
+ )
+ # if not_out_subjects:
+ # for channel in irc_config["channels"]: # type: ignore
+ # irc.msg(
+ # channel,
+ # "%s: Results NOT out for %s" % (ping, ", ".join(not_out_subjects)),
+ # )
+
+ print("[*] Waiting for 300 seconds before polling again")
+ time.sleep(300)
+
+
+if __name__ == "__main__":
+ exit(main())
diff --git a/cieresults/requirements.txt b/cieresults/requirements.txt
new file mode 100644
index 0000000..efe9637
--- /dev/null
+++ b/cieresults/requirements.txt
@@ -0,0 +1,3 @@
+miniirc
+requests
+beautifulsoup4
diff --git a/memch/Makefile b/memch/Makefile
index e6838b2..4fbbb53 100644
--- a/memch/Makefile
+++ b/memch/Makefile
@@ -1,7 +1,7 @@
.PHONY: clean
memch: memch.c
- $(CC) -D_DEFAULT_SOURCE -std=c99 -o $@ $< $(shell pkg-config --libs --cflags ncursesw)
+ $(CC) -D_DEFAULT_SOURCE -std=c99 -o memch memch.c $(shell pkg-config --libs --cflags ncursesw)
clean:
- rm memch
+ rm -f memch
diff --git a/ykpsmuttauth/Makefile b/ykpsmuttauth/Makefile
index 618bd7d..53e46a3 100644
--- a/ykpsmuttauth/Makefile
+++ b/ykpsmuttauth/Makefile
@@ -4,7 +4,7 @@ ykpsmuttauth: ykpsmuttauth.go
go build
ykpsmuttauth2: ykpsmuttauth2.c
- $(CC) -Wall -Wextra -pedantic -o $@ $< $(shell pkg-config --cflags --libs json-c) $(shell pkg-config --cflags --libs libcurl) $(shell pkg-config --cflags --libs openssl)
+ $(CC) -Wall -Wextra -pedantic -o ykpsmuttauth2 ykpsmuttauth2.c $(shell pkg-config --cflags --libs json-c) $(shell pkg-config --cflags --libs libcurl) $(shell pkg-config --cflags --libs openssl)
clean:
rm -fv ykpsmuttauth ykpsmuttauth2