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"] }
|
10
README.md
10
README.md
|
@ -1,3 +1,11 @@
|
|||
# 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