Compare commits
11 commits
202db44593
...
a80737ee62
Author | SHA1 | Date | |
---|---|---|---|
a80737ee62 | |||
b9e35dfe09 | |||
3604ff197f | |||
df28a6e11b | |||
bcf8fba4f0 | |||
92a303401b | |||
e2024eaa34 | |||
de87f5a926 | |||
17af5069b3 | |||
82d909693d | |||
95fe298ae1 |
12 changed files with 2260 additions and 1 deletions
65
.forgejo/workflows/push.yaml
Normal file
65
.forgejo/workflows/push.yaml
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
name: On_Push
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- 'main'
|
||||||
|
paths:
|
||||||
|
- flake.*
|
||||||
|
- src/**/*
|
||||||
|
- Cargo.*
|
||||||
|
- .forgejo/**/*
|
||||||
|
- rust-toolchain.toml
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
# rust code must be formatted for standardisation
|
||||||
|
lint_fmt:
|
||||||
|
# build it using teh base nixos system, helps with caching
|
||||||
|
runs-on: nix
|
||||||
|
steps:
|
||||||
|
# get the repo first
|
||||||
|
- uses: https://code.forgejo.org/actions/checkout@v4
|
||||||
|
- run: nix build .#fmt --verbose
|
||||||
|
|
||||||
|
# clippy is incredibly useful for making yer code better
|
||||||
|
lint_clippy:
|
||||||
|
# build it using teh base nixos system, helps with caching
|
||||||
|
runs-on: nix
|
||||||
|
permissions:
|
||||||
|
checks: write
|
||||||
|
steps:
|
||||||
|
# get the repo first
|
||||||
|
- uses: https://code.forgejo.org/actions/checkout@v4
|
||||||
|
- run: nix build .#clippy --verbose
|
||||||
|
|
||||||
|
test:
|
||||||
|
# build it using teh base nixos system, helps with caching
|
||||||
|
runs-on: nix
|
||||||
|
permissions:
|
||||||
|
checks: write
|
||||||
|
steps:
|
||||||
|
# get the repo first
|
||||||
|
- uses: https://code.forgejo.org/actions/checkout@v4
|
||||||
|
- run: nix build .#test --verbose
|
||||||
|
|
||||||
|
build:
|
||||||
|
# build it using teh base nixos system, helps with caching
|
||||||
|
runs-on: nix
|
||||||
|
needs: [ lint_fmt, lint_clippy, test ]
|
||||||
|
steps:
|
||||||
|
# get the repo first
|
||||||
|
- uses: https://code.forgejo.org/actions/checkout@v4
|
||||||
|
- name: "Build it locally"
|
||||||
|
run: nix build --verbose
|
||||||
|
|
||||||
|
# # deploy it upstream
|
||||||
|
# deploy:
|
||||||
|
# # runs on teh default docker container
|
||||||
|
# runs-on: docker
|
||||||
|
# needs: [ build ]
|
||||||
|
# steps:
|
||||||
|
# - name: "Deploy to Skynet"
|
||||||
|
# uses: https://forgejo.skynet.ie/Skynet/actions-deploy-to-skynet@v2
|
||||||
|
# with:
|
||||||
|
# input: 'skynet_discord_bot'
|
||||||
|
# token: ${{ secrets.API_TOKEN_FORGEJO }}
|
37
.gitattributes
vendored
Normal file
37
.gitattributes
vendored
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
# Git config here
|
||||||
|
* text eol=lf
|
||||||
|
|
||||||
|
#############################################
|
||||||
|
# Git lfs stuff
|
||||||
|
# Documents
|
||||||
|
*.pdf filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.doc filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.docx filter=lfs diff=lfs merge=lfs -text
|
||||||
|
# Excel
|
||||||
|
*.xls filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.xlsx filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.xlsm filter=lfs diff=lfs merge=lfs -text
|
||||||
|
# Powerpoints
|
||||||
|
*.ppt filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.pptx filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.ppsx filter=lfs diff=lfs merge=lfs -text
|
||||||
|
# Images
|
||||||
|
*.png filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.jpg filter=lfs diff=lfs merge=lfs -text
|
||||||
|
# Video
|
||||||
|
*.mkv filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.mp4 filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.wmv filter=lfs diff=lfs merge=lfs -text
|
||||||
|
# Misc
|
||||||
|
*.zip filter=lfs diff=lfs merge=lfs -text
|
||||||
|
# ET4011
|
||||||
|
*.cbe filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.pbs filter=lfs diff=lfs merge=lfs -text
|
||||||
|
# Open/Libre office
|
||||||
|
# from https://www.libreoffice.org/discover/what-is-opendocument/
|
||||||
|
*.odt filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.ods filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.odp filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.odg filter=lfs diff=lfs merge=lfs -text
|
||||||
|
# QT
|
||||||
|
*.ui filter=lfs diff=lfs merge=lfs -text
|
15
.gitignore
vendored
Normal file
15
.gitignore
vendored
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
/target
|
||||||
|
/.idea
|
||||||
|
|
||||||
|
.env
|
||||||
|
*.env
|
||||||
|
|
||||||
|
result
|
||||||
|
/result
|
||||||
|
|
||||||
|
*.db
|
||||||
|
*.db.*
|
||||||
|
|
||||||
|
tmp/
|
||||||
|
tmp.*
|
||||||
|
*.csv
|
9
.rustfmt.toml
Normal file
9
.rustfmt.toml
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
max_width = 150
|
||||||
|
single_line_if_else_max_width = 100
|
||||||
|
chain_width = 100
|
||||||
|
fn_params_layout = "Compressed"
|
||||||
|
#control_brace_style = "ClosingNextLine"
|
||||||
|
#brace_style = "PreferSameLine"
|
||||||
|
struct_lit_width = 0
|
||||||
|
tab_spaces = 2
|
||||||
|
use_small_heuristics = "Max"
|
1504
Cargo.lock
generated
Normal file
1504
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
20
Cargo.toml
Normal file
20
Cargo.toml
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
[package]
|
||||||
|
name = "wolves-oxidised"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
# this is for anythign in dev and not finalised yet
|
||||||
|
unstable = []
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
# for making teh requests
|
||||||
|
reqwest = { version = "0.12", features = ["json"] }
|
||||||
|
|
||||||
|
# for testing async stuff
|
||||||
|
tokio-test = "0.4"
|
||||||
|
|
||||||
|
|
||||||
|
# parsing teh results
|
||||||
|
serde_json = { version = "1.0", features = ["raw_value"] }
|
||||||
|
serde = { version = "1.0.215", features = ["derive"] }
|
|
@ -1,3 +1,11 @@
|
||||||
# wolves-oxidised
|
# wolves-oxidised
|
||||||
|
|
||||||
Rust library to interact with the UL Wolves API
|
Rust library to interact with the UL Wolves API
|
||||||
|
|
||||||
|
## Mockoon
|
||||||
|
Mockoon is a tool that is able to mock an api.
|
||||||
|
The responses from Woles are mocked using this tool and are stored in ``mocking``.
|
||||||
|
|
||||||
|
``nix-shell -p mockoon``
|
||||||
|
|
||||||
|
Then load up teh config in ``mocking``
|
93
flake.lock
Normal file
93
flake.lock
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"naersk": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1721727458,
|
||||||
|
"narHash": "sha256-r/xppY958gmZ4oTfLiHN0ZGuQ+RSTijDblVgVLFi1mw=",
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "naersk",
|
||||||
|
"rev": "3fb418eaf352498f6b6c30592e3beb63df42ef11",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "naersk",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1731890469,
|
||||||
|
"narHash": "sha256-D1FNZ70NmQEwNxpSSdTXCSklBH1z2isPR84J6DQrJGs=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "5083ec887760adfe12af64830a66807423a859a7",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"id": "nixpkgs",
|
||||||
|
"type": "indirect"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs_2": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1732014248,
|
||||||
|
"narHash": "sha256-y/MEyuJ5oBWrWAic/14LaIr/u5E0wRVzyYsouYY3W6w=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "23e89b7da85c3640bbc2173fe04f4bd114342367",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"id": "nixpkgs",
|
||||||
|
"ref": "nixos-unstable",
|
||||||
|
"type": "indirect"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"naersk": "naersk",
|
||||||
|
"nixpkgs": "nixpkgs_2",
|
||||||
|
"utils": "utils"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"systems": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1681028828,
|
||||||
|
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"utils": {
|
||||||
|
"inputs": {
|
||||||
|
"systems": "systems"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1731533236,
|
||||||
|
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
66
flake.nix
Normal file
66
flake.nix
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
{
|
||||||
|
description = "UL Wolves API Library";
|
||||||
|
|
||||||
|
inputs = {
|
||||||
|
nixpkgs.url = "nixpkgs/nixos-unstable";
|
||||||
|
naersk.url = "github:nix-community/naersk";
|
||||||
|
utils.url = "github:numtide/flake-utils";
|
||||||
|
};
|
||||||
|
|
||||||
|
nixConfig = {
|
||||||
|
extra-substituters = "https://nix-cache.skynet.ie/skynet-cache";
|
||||||
|
extra-trusted-public-keys = "skynet-cache:zMFLzcRZPhUpjXUy8SF8Cf7KGAZwo98SKrzeXvdWABo=";
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs = {
|
||||||
|
self,
|
||||||
|
nixpkgs,
|
||||||
|
utils,
|
||||||
|
naersk,
|
||||||
|
}:
|
||||||
|
utils.lib.eachDefaultSystem (
|
||||||
|
system: let
|
||||||
|
pkgs = (import nixpkgs) {inherit system;};
|
||||||
|
naersk' = pkgs.callPackage naersk {};
|
||||||
|
package_name = "wolves_api";
|
||||||
|
buildInputs = with pkgs; [
|
||||||
|
openssl
|
||||||
|
pkg-config
|
||||||
|
rustfmt
|
||||||
|
];
|
||||||
|
in rec {
|
||||||
|
packages = {
|
||||||
|
# For `nix build` & `nix run`:
|
||||||
|
default = naersk'.buildPackage {
|
||||||
|
pname = "${package_name}";
|
||||||
|
src = ./.;
|
||||||
|
buildInputs = buildInputs;
|
||||||
|
};
|
||||||
|
# Run `nix build .#fmt` to run tests
|
||||||
|
fmt = naersk'.buildPackage {
|
||||||
|
src = ./.;
|
||||||
|
mode = "fmt";
|
||||||
|
buildInputs = buildInputs;
|
||||||
|
};
|
||||||
|
# Run `nix build .#clippy` to lint code
|
||||||
|
clippy = naersk'.buildPackage {
|
||||||
|
src = ./.;
|
||||||
|
mode = "clippy";
|
||||||
|
buildInputs = buildInputs;
|
||||||
|
};
|
||||||
|
test = naersk'.buildPackage {
|
||||||
|
src = ./.;
|
||||||
|
mode = "test";
|
||||||
|
buildInputs = buildInputs;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# `nix develop`
|
||||||
|
devShell = pkgs.mkShell {
|
||||||
|
nativeBuildInputs = (
|
||||||
|
with pkgs; [rustc cargo]
|
||||||
|
) ++ buildInputs;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
187
mocking/wolves_api.json
Normal file
187
mocking/wolves_api.json
Normal file
|
@ -0,0 +1,187 @@
|
||||||
|
{
|
||||||
|
"uuid": "5b065de8-1360-4d55-aba4-c0f919f3669e",
|
||||||
|
"lastMigration": 32,
|
||||||
|
"name": "Wolves API",
|
||||||
|
"endpointPrefix": "",
|
||||||
|
"latency": 0,
|
||||||
|
"port": 3001,
|
||||||
|
"hostname": "",
|
||||||
|
"folders": [],
|
||||||
|
"routes": [
|
||||||
|
{
|
||||||
|
"uuid": "b8a7a9df-6d18-46ca-9f55-87385b1654cd",
|
||||||
|
"type": "http",
|
||||||
|
"documentation": "",
|
||||||
|
"method": "post",
|
||||||
|
"endpoint": "get_cns",
|
||||||
|
"responses": [
|
||||||
|
{
|
||||||
|
"uuid": "55d1e82e-ea35-4929-b8ce-2b1fe6e2f962",
|
||||||
|
"body": "{\n \"success\": 1,\n \"result\": {{data 'WolvesCommittees'}}\n}",
|
||||||
|
"latency": 0,
|
||||||
|
"statusCode": 200,
|
||||||
|
"label": "",
|
||||||
|
"headers": [],
|
||||||
|
"bodyType": "INLINE",
|
||||||
|
"filePath": "",
|
||||||
|
"databucketID": "pwev",
|
||||||
|
"sendFileAsBody": false,
|
||||||
|
"rules": [],
|
||||||
|
"rulesOperator": "OR",
|
||||||
|
"disableTemplating": false,
|
||||||
|
"fallbackTo404": false,
|
||||||
|
"default": true,
|
||||||
|
"crudKey": "id",
|
||||||
|
"callbacks": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responseMode": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uuid": "3d598a24-8088-43b4-a221-2296a7d7dc0b",
|
||||||
|
"type": "http",
|
||||||
|
"documentation": "",
|
||||||
|
"method": "post",
|
||||||
|
"endpoint": "get_members",
|
||||||
|
"responses": [
|
||||||
|
{
|
||||||
|
"uuid": "808c8312-66f6-4498-ac60-9fcf15211a6a",
|
||||||
|
"body": "{\n \"success\": 1,\n \"result\": {{data 'WolvesMembers'}}\n}",
|
||||||
|
"latency": 0,
|
||||||
|
"statusCode": 200,
|
||||||
|
"label": "",
|
||||||
|
"headers": [],
|
||||||
|
"bodyType": "INLINE",
|
||||||
|
"filePath": "",
|
||||||
|
"databucketID": "",
|
||||||
|
"sendFileAsBody": false,
|
||||||
|
"rules": [],
|
||||||
|
"rulesOperator": "OR",
|
||||||
|
"disableTemplating": false,
|
||||||
|
"fallbackTo404": false,
|
||||||
|
"default": true,
|
||||||
|
"crudKey": "id",
|
||||||
|
"callbacks": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responseMode": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uuid": "18a929f9-e616-4cf6-a67e-0950e1248ce8",
|
||||||
|
"type": "http",
|
||||||
|
"documentation": "",
|
||||||
|
"method": "post",
|
||||||
|
"endpoint": "get_member",
|
||||||
|
"responses": [
|
||||||
|
{
|
||||||
|
"uuid": "f4b77b66-4e4b-4429-b5ca-7bd3cd06cd04",
|
||||||
|
"body": "{\n \"success\": 1,\n \"result\": {{data 'WolvesMember'}}\n}",
|
||||||
|
"latency": 0,
|
||||||
|
"statusCode": 200,
|
||||||
|
"label": "",
|
||||||
|
"headers": [],
|
||||||
|
"bodyType": "INLINE",
|
||||||
|
"filePath": "",
|
||||||
|
"databucketID": "",
|
||||||
|
"sendFileAsBody": false,
|
||||||
|
"rules": [],
|
||||||
|
"rulesOperator": "OR",
|
||||||
|
"disableTemplating": false,
|
||||||
|
"fallbackTo404": false,
|
||||||
|
"default": true,
|
||||||
|
"crudKey": "id",
|
||||||
|
"callbacks": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uuid": "84af1b80-9b7c-48e9-a555-ed22f4652e75",
|
||||||
|
"body": "{\n \"success\": 1,\n \"result\": null\n}",
|
||||||
|
"latency": 0,
|
||||||
|
"statusCode": 200,
|
||||||
|
"label": "",
|
||||||
|
"headers": [],
|
||||||
|
"bodyType": "INLINE",
|
||||||
|
"filePath": "",
|
||||||
|
"databucketID": "",
|
||||||
|
"sendFileAsBody": false,
|
||||||
|
"rules": [],
|
||||||
|
"rulesOperator": "OR",
|
||||||
|
"disableTemplating": false,
|
||||||
|
"fallbackTo404": false,
|
||||||
|
"default": false,
|
||||||
|
"crudKey": "id",
|
||||||
|
"callbacks": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responseMode": "RANDOM"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"rootChildren": [
|
||||||
|
{
|
||||||
|
"type": "route",
|
||||||
|
"uuid": "b8a7a9df-6d18-46ca-9f55-87385b1654cd"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "route",
|
||||||
|
"uuid": "3d598a24-8088-43b4-a221-2296a7d7dc0b"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "route",
|
||||||
|
"uuid": "18a929f9-e616-4cf6-a67e-0950e1248ce8"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"proxyMode": false,
|
||||||
|
"proxyHost": "",
|
||||||
|
"proxyRemovePrefix": false,
|
||||||
|
"tlsOptions": {
|
||||||
|
"enabled": false,
|
||||||
|
"type": "CERT",
|
||||||
|
"pfxPath": "",
|
||||||
|
"certPath": "",
|
||||||
|
"keyPath": "",
|
||||||
|
"caPath": "",
|
||||||
|
"passphrase": ""
|
||||||
|
},
|
||||||
|
"cors": true,
|
||||||
|
"headers": [
|
||||||
|
{
|
||||||
|
"key": "Content-Type",
|
||||||
|
"value": "application/json"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"proxyReqHeaders": [
|
||||||
|
{
|
||||||
|
"key": "",
|
||||||
|
"value": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"proxyResHeaders": [
|
||||||
|
{
|
||||||
|
"key": "",
|
||||||
|
"value": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"uuid": "44f1e367-1b0c-4008-bb76-2f2547adeea2",
|
||||||
|
"id": "pwev",
|
||||||
|
"name": "WolvesCommittees",
|
||||||
|
"documentation": "",
|
||||||
|
"value": "[\n {{#repeat 1 20}}\n {{setVar 'name' (faker 'internet.userName')}}\n {\n \"id\": \"{{int 100 500}}\",\n \"name\": \"{{@name}}\",\n \"link\": \"https://ulwolves.ie/society/{{@name}}\",\n \"committee\": [\n {{#repeat 1 10}}\n \"{{int 1000 5000}}\",\n {{/repeat}}\n ]\n }\n {{/repeat}}\n]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uuid": "58843751-e03b-49e0-96d5-c9449deae514",
|
||||||
|
"id": "nejb",
|
||||||
|
"name": "WolvesMembers",
|
||||||
|
"documentation": "",
|
||||||
|
"value": "\n[\n \n {{#repeat 1 20}} \n {\n {{! Name of the Club/Soc}}\n \"committee\": \"Computer\",\n \"member_id\": \"{{int 100 500}}\",\n \"first_name\": \"{{firstName}}\",\n \"last_name\": \"{{lastName}}\",\n \"contact_email\": \"{{email}}\",\n \"opt_in_email\": \"{{oneOf (array '0' '1')}}\",\n \"student_id\": {{{oneOf (array 'null' '\"24123456\"' )}}},\n \"note\": {{{oneOf (array 'null' '\"note\"')}}},\n \"expiry\": \"{{date '2020-11-20' '2026-11-25' 'yyyy-MM-dd HH:mm:ss'}}\",\n \"requested\": \"{{date '2020-11-20' '2026-11-25' 'yyyy-MM-dd HH:mm:ss'}}\",\n \"approved\": \"{{date '2020-11-20' '2026-11-25' 'yyyy-MM-dd HH:mm:ss'}}\",\n \"sitename\":\"UL Wolves\",\n \"domain\":\"ulwolves.ie\"\n }\n {{/repeat}}\n]\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uuid": "208bfc7f-ef60-4fdd-be8d-44bcfe48d264",
|
||||||
|
"id": "ef36",
|
||||||
|
"name": "WolvesMember",
|
||||||
|
"documentation": "",
|
||||||
|
"value": "{\n \"member_id\": \"{{int 100 500}}\",\n \"contact_email\": \"{{email}}\"\n}\n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"callbacks": []
|
||||||
|
}
|
2
rust-toolchain.toml
Normal file
2
rust-toolchain.toml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[toolchain]
|
||||||
|
channel = "1.82"
|
253
src/lib.rs
Normal file
253
src/lib.rs
Normal file
|
@ -0,0 +1,253 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
// This is what Wolves returns to us
|
||||||
|
// success will always be 1?
|
||||||
|
#[derive(Deserialize, Serialize, Debug)]
|
||||||
|
struct WolvesResult<T> {
|
||||||
|
success: i8,
|
||||||
|
result: Vec<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize, Debug)]
|
||||||
|
struct WolvesResultSingle<T> {
|
||||||
|
success: i8,
|
||||||
|
result: T,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Data returned for a member of a club/soc
|
||||||
|
#[derive(Deserialize, Serialize, Debug)]
|
||||||
|
pub struct WolvesUser {
|
||||||
|
// TODO: Might be worth trying to get this replaced with the club/soc ID?
|
||||||
|
/// Club/Soc the user is a member of
|
||||||
|
pub committee: String,
|
||||||
|
/// ID which uniquely identifies them on teh site
|
||||||
|
pub member_id: String,
|
||||||
|
/// First Name
|
||||||
|
pub first_name: String,
|
||||||
|
/// Last Name
|
||||||
|
pub last_name: String,
|
||||||
|
/// Email that they have set in their profile: <https://ulwolves.ie/memberships/profile>
|
||||||
|
///
|
||||||
|
/// Note: This does not indicate if they wish to be contacted via this address.
|
||||||
|
pub contact_email: String,
|
||||||
|
/// Denotes if a user has opted into being emailed: ``0`` or ``1``
|
||||||
|
pub opt_in_email: String,
|
||||||
|
/// if the member is/was a student this is their ID
|
||||||
|
pub student_id: Option<String>,
|
||||||
|
/// Optional note set by Committee
|
||||||
|
pub note: Option<String>,
|
||||||
|
/// When their membership will expire: ``yyyy-MM-dd HH:mm:ss``
|
||||||
|
pub expiry: String,
|
||||||
|
/// When member requested membership: ``yyyy-MM-dd HH:mm:ss``
|
||||||
|
pub requested: String,
|
||||||
|
/// When the member was approved: ``yyyy-MM-dd HH:mm:ss``
|
||||||
|
pub approved: String,
|
||||||
|
/// Name of the site the user is a member of:``UL Wolves``
|
||||||
|
pub sitename: String,
|
||||||
|
/// Domain of the site they are a member of: ``ulwolves.ie``
|
||||||
|
pub domain: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "unstable")]
|
||||||
|
/// Information on an individual club/soc
|
||||||
|
#[derive(Deserialize, Serialize, Debug)]
|
||||||
|
pub struct WolvesCNS {
|
||||||
|
/// ID of teh club/Society
|
||||||
|
pub id: String,
|
||||||
|
/// Name of the Club/Society
|
||||||
|
pub name: String,
|
||||||
|
/// Link to their page such as <https://ulwolves.ie/society/computer>
|
||||||
|
pub link: String,
|
||||||
|
/// Array of Committee members ``member_id````'s
|
||||||
|
pub committee: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
enum WolvesUserExists {
|
||||||
|
B(bool),
|
||||||
|
S(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Client {
|
||||||
|
base_wolves: String,
|
||||||
|
base_key: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Client {
|
||||||
|
/// Create a new client for teh Wolves API
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
/// * `base_wolves` - Base URL for the requests, for example: ``https://cp.ulwolves.ie/api``
|
||||||
|
/// * `base_key` - An instance API Key for running higher level privilege tasks
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use wolves_oxidised::Client;
|
||||||
|
/// let client = Client::new("https://cp.ulwolves.ie/api", None);
|
||||||
|
/// ```
|
||||||
|
/// ```rust
|
||||||
|
/// use wolves_oxidised::Client;
|
||||||
|
/// let client = Client::new("https://cp.ulwolves.ie/api", Some("api_key"));
|
||||||
|
/// ```
|
||||||
|
pub fn new(base_wolves: &str, base_key: Option<&str>) -> Self {
|
||||||
|
Self {
|
||||||
|
base_wolves: base_wolves.to_string(),
|
||||||
|
base_key: base_key.map(|x| x.to_string()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// General method to get endpoints which return an array
|
||||||
|
async fn get_bulk<T: serde::de::DeserializeOwned>(&self, wolves_endpoint: &str, api_key: &str) -> Vec<T> {
|
||||||
|
if self.base_wolves.is_empty() {
|
||||||
|
return vec![];
|
||||||
|
}
|
||||||
|
|
||||||
|
let url = format!("{}/{}", &self.base_wolves, wolves_endpoint);
|
||||||
|
|
||||||
|
// get wolves data
|
||||||
|
match reqwest::Client::new().post(&url).header("X-AM-Identity", api_key).send().await {
|
||||||
|
Ok(x) => {
|
||||||
|
if let Ok(WolvesResult {
|
||||||
|
success,
|
||||||
|
result,
|
||||||
|
}) = x.json::<WolvesResult<T>>().await
|
||||||
|
{
|
||||||
|
if success != 1 {
|
||||||
|
return vec![];
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
dbg!(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vec![]
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the members of a Club?Society based on teh API key inputted
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
/// * `api_key` - API key scoped to teh specific club/soc
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// # tokio_test::block_on(async {
|
||||||
|
/// use wolves_oxidised::{Client, WolvesUser};
|
||||||
|
/// let client = Client::new("https://cp.ulwolves.ie/api", None);
|
||||||
|
/// let result: Vec<WolvesUser> = client.get_members("api_key_club_1").await;
|
||||||
|
/// # })
|
||||||
|
/// ```
|
||||||
|
pub async fn get_members(&self, api_key: &str) -> Vec<WolvesUser> {
|
||||||
|
self.get_bulk::<WolvesUser>("get_members", api_key).await
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "unstable")]
|
||||||
|
/// Get information about teh Club/Soc, including committee members
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
/// No instance API key set
|
||||||
|
/// ```rust
|
||||||
|
/// # tokio_test::block_on(async {
|
||||||
|
/// use wolves_oxidised::{Client, WolvesCNS};
|
||||||
|
/// let client = Client::new("https://cp.ulwolves.ie/api", None);
|
||||||
|
/// let result: Vec<WolvesCNS> = client.get_committees().await;
|
||||||
|
/// assert_eq!(result.len(), 0);
|
||||||
|
/// # })
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// Instance API key set, will return details if there are no other errors
|
||||||
|
/// ```rust
|
||||||
|
/// # tokio_test::block_on(async {
|
||||||
|
/// use wolves_oxidised::{Client, WolvesCNS};
|
||||||
|
/// let client = Client::new("https://cp.ulwolves.ie/api", Some("api_key_instance"));
|
||||||
|
/// let result: Vec<WolvesCNS> = client.get_committees().await;
|
||||||
|
/// # })
|
||||||
|
/// ```
|
||||||
|
pub async fn get_committees(&self) -> Vec<WolvesCNS> {
|
||||||
|
if let Some(api_key) = &self.base_key {
|
||||||
|
self.get_bulk::<WolvesCNS>("get_cns", api_key).await
|
||||||
|
} else {
|
||||||
|
vec![]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the ``member_id`` for a specific email if it exists.
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
/// * `api_key` - API key scoped to teh specific club/soc
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
/// No instance API key set
|
||||||
|
/// ```rust
|
||||||
|
/// # tokio_test::block_on(async {
|
||||||
|
/// use wolves_oxidised::Client;
|
||||||
|
/// let client = Client::new("https://cp.ulwolves.ie/api", None);
|
||||||
|
/// let result: Option<i64> = client.get_member("example@example.ie").await;
|
||||||
|
/// assert!(result.is_none());
|
||||||
|
/// # })
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// Instance API key set, will return details if there are no other errors
|
||||||
|
/// ```rust
|
||||||
|
/// # tokio_test::block_on(async {
|
||||||
|
/// use wolves_oxidised::Client;
|
||||||
|
/// let client = Client::new("https://cp.ulwolves.ie/api", Some("api_key_instance"));
|
||||||
|
/// let result: Option<i64> = client.get_member("example@example.ie").await;
|
||||||
|
/// # })
|
||||||
|
/// ```
|
||||||
|
pub async fn get_member(self, email: &str) -> Option<i64> {
|
||||||
|
// if the key isnt set then we cant do anything.
|
||||||
|
let api_key = match &self.base_key {
|
||||||
|
None => {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
Some(key) => key,
|
||||||
|
};
|
||||||
|
|
||||||
|
let url = format!("{}/get_id_from_email", &self.base_wolves);
|
||||||
|
|
||||||
|
match reqwest::Client::new()
|
||||||
|
.post(&url)
|
||||||
|
.form(&[("email", email)])
|
||||||
|
.header("X-AM-Identity", api_key)
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(x) => {
|
||||||
|
if let Ok(y) = x.json::<WolvesResultSingle<WolvesUserExists>>().await {
|
||||||
|
// this is the only time we will get a positive response, the None at the end catches everything else
|
||||||
|
if let WolvesUserExists::S(z) = y.result {
|
||||||
|
if let Ok(id) = z.parse::<i64>() {
|
||||||
|
return Some(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
dbg!(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// pub fn add(left: u64, right: u64) -> u64 {
|
||||||
|
// left + right
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// #[cfg(test)]
|
||||||
|
// mod tests {
|
||||||
|
// use super::*;
|
||||||
|
//
|
||||||
|
// #[test]
|
||||||
|
// fn it_works() {
|
||||||
|
// let result = add(2, 2);
|
||||||
|
// assert_eq!(result, 4);
|
||||||
|
// }
|
||||||
|
// }
|
Loading…
Reference in a new issue