├── sample_apps └── rso_sample_apps │ ├── nodejs │ ├── .nvmrc │ ├── README.md │ ├── package.json │ ├── index.js │ └── package-lock.json │ ├── go │ ├── go.mod │ ├── go.sum │ ├── README.md │ └── main.go │ ├── rust │ ├── mock │ │ ├── Cargo.toml │ │ ├── .gitignore │ │ ├── src │ │ │ └── lib.rs │ │ └── Cargo.lock │ ├── rust-toolchain.toml │ ├── .gitignore │ ├── grcov.yml │ ├── templates │ │ ├── oauth.html │ │ ├── default.html │ │ └── data.html │ ├── Cargo.toml │ ├── Makefile │ ├── config │ │ └── example-config.yml │ ├── src │ │ ├── handlers │ │ │ ├── mod.rs │ │ │ ├── default.rs │ │ │ ├── oauth.rs │ │ │ └── data.rs │ │ ├── main.rs │ │ ├── service.rs │ │ └── config.rs │ └── README.md │ ├── python │ ├── README.md │ ├── pyproject.toml │ ├── main.py │ └── poetry.lock │ └── README.md ├── .gitignore ├── .github ├── pull_request_template.md ├── ISSUE_TEMPLATE │ ├── account_issue.md │ └── bug_report.md └── workflows │ └── rso_sample_apps.yml └── README.md /sample_apps/rso_sample_apps/nodejs/.nvmrc: -------------------------------------------------------------------------------- 1 | 18.9.0 2 | -------------------------------------------------------------------------------- /sample_apps/rso_sample_apps/go/go.mod: -------------------------------------------------------------------------------- 1 | module sample 2 | 3 | go 1.19 4 | 5 | require github.com/joho/godotenv v1.4.0 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # MacOS 2 | .DS_Store 3 | .idea 4 | # NodeJS 5 | node_modules 6 | 7 | # Python 8 | __pycache__/ 9 | *.py[cod] 10 | *$py.class 11 | -------------------------------------------------------------------------------- /sample_apps/rso_sample_apps/rust/mock/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "mock" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | httpmock = "0.7.0" 8 | -------------------------------------------------------------------------------- /sample_apps/rso_sample_apps/go/go.sum: -------------------------------------------------------------------------------- 1 | github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg= 2 | github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= 3 | -------------------------------------------------------------------------------- /sample_apps/rso_sample_apps/nodejs/README.md: -------------------------------------------------------------------------------- 1 | # NodeJS Sample app 2 | 3 | ## Requirements 4 | 1. You need node installed in your machine 5 | 1. `npm install` 6 | 7 | ## Run 8 | Just execute: 9 | ``` 10 | node index.js 11 | ``` 12 | -------------------------------------------------------------------------------- /sample_apps/rso_sample_apps/python/README.md: -------------------------------------------------------------------------------- 1 | # Go Sample app 2 | 3 | ## Requirements 4 | 1. You need `python` 5 | 1. You need `poetry` 6 | 1. Run `poetry install` 7 | 8 | ## Run 9 | Just execute: 10 | ``` 11 | poetry run main.py 12 | ``` 13 | -------------------------------------------------------------------------------- /sample_apps/rso_sample_apps/rust/rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | # The default profile includes rustc, rust-std, cargo, rust-docs, rustfmt and clippy. 3 | # https://rust-lang.github.io/rustup/concepts/profiles.html 4 | profile = "default" 5 | channel = "1.78.0" -------------------------------------------------------------------------------- /sample_apps/rso_sample_apps/rust/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled files 2 | /target 3 | 4 | # Configuration file 5 | /config.yml 6 | 7 | # TLS files 8 | *.cert 9 | *.key 10 | 11 | # Ignore IDE related files 12 | *.idea 13 | *.vscode 14 | 15 | # Ignore .DS_Store on macOS 16 | .DS_Store 17 | -------------------------------------------------------------------------------- /sample_apps/rso_sample_apps/rust/mock/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled files 2 | /target 3 | 4 | # Configuration file 5 | /config.yml 6 | 7 | # TLS files 8 | *.cert 9 | *.key 10 | 11 | # Ignore IDE related files 12 | *.idea 13 | *.vscode 14 | 15 | # Ignore .DS_Store on macOS 16 | .DS_Store 17 | docs -------------------------------------------------------------------------------- /sample_apps/rso_sample_apps/go/README.md: -------------------------------------------------------------------------------- 1 | # Go Sample app 2 | 3 | ## Requirements 4 | 1. Make sure you have your `.env` in the root of the project: `sample_apps/rso_sample_apps/.env` 5 | 1. You need golang installed in your machine 6 | 1. `go mod tidy` 7 | 8 | ## Run 9 | Just execute: 10 | ``` 11 | go run main.go 12 | ``` 13 | -------------------------------------------------------------------------------- /sample_apps/rso_sample_apps/rust/grcov.yml: -------------------------------------------------------------------------------- 1 | branch: false 2 | ignore-not-existing: true 3 | llvm: true 4 | filter: covered 5 | output-type: lcov 6 | ignore: 7 | - "*.cargo/*" 8 | excl-start: "grcov-excl-start" 9 | excl-stop: "grcov-excl-stop" 10 | excl-line: "grcov-excl-line|#\\[derive\\(|ensure!\\(|assert!\\(|/!|///" 11 | -------------------------------------------------------------------------------- /sample_apps/rso_sample_apps/rust/templates/oauth.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 |{{account_data}}
54 || Key | 58 |Value | 59 |
|---|---|
| PUUID | 64 |{{account.puuid}} | 65 |
| Game Name | 68 |{{account.game_name}} | 69 |
| Tag Line | 72 |{{account.tag_line}} | 73 |
{{champion_rotation_data}}
85 || Key | 89 |Value | 90 |
|---|---|
| Free Champion IDs | 95 |{{format!("{:?}", self.champion_rotation.free_champion_ids)}} | 96 |
| Free Champion IDs for New Players | 99 |{{format!("{:?}", self.champion_rotation.free_champion_ids)}} | 100 |
| Max New Player Level | 103 |{{format!("{:?}", self.champion_rotation.max_new_player_level)}} | 104 |
${json2table(account_data)}
70 | ` 71 | 72 | var champion_rotation_data = await get_champion_rotation_data(CONFIG.RGAPI_TOKEN); 73 | var champion_rotation_html = ` 74 |${json2table(champion_rotation_data)}
76 | ` 77 | res.send(` 78 | ${account_html} 79 | ${champion_rotation_html} 80 | `) 81 | }); 82 | 83 | async function get_champion_rotation_data(token) { 84 | const response = await fetch('https://na1.api.riotgames.com/lol/platform/v3/champion-rotations', 85 | { 86 | method: "GET", 87 | headers: { 88 | "X-Riot-Token": token 89 | } 90 | 91 | }); 92 | const data = await response.json(); 93 | return data; 94 | } 95 | 96 | async function get_account_data(access_token) { 97 | const response = await fetch('https://americas.api.riotgames.com/riot/account/v1/accounts/me', 98 | { 99 | method: "GET", 100 | headers: { 101 | Authorization: `Bearer ${access_token}` 102 | } 103 | 104 | }); 105 | const data = await response.json(); 106 | return data; 107 | } 108 | 109 | function json2table(json) { 110 | const style = ` 111 | `; 119 | 120 | var html = ` 121 || key | 125 |value | 126 |
|---|---|
| ${key} | 135 |${value} |
136 |
| key | 87 |value | 88 |
|---|---|
| {key} | 97 |{value} |
98 |
{json2table(json=account_data)}
117 | """ 118 | 119 | champion_rotation_data = get_champion_rotation_data(CONFIG["RGAPI_TOKEN"]) 120 | champion_rotation_html = f""" 121 |{json2table(json=champion_rotation_data)}
123 | """ 124 | 125 | return f""" 126 | {account_html} 127 | {champion_rotation_html} 128 | """ 129 | 130 | 131 | def get_account_data(access_token): 132 | resp = requests.get( 133 | "https://americas.api.riotgames.com/riot/account/v1/accounts/me", 134 | headers={ 135 | "Authorization": f"Bearer {access_token}" 136 | }, 137 | timeout=TIMEOUT 138 | ) 139 | return resp.json() 140 | 141 | 142 | def get_champion_rotation_data(token: str): 143 | resp = requests.get( 144 | "https://na1.api.riotgames.com/lol/platform/v3/champion-rotations", 145 | headers={ 146 | "X-Riot-Token": token 147 | }, 148 | timeout=TIMEOUT 149 | ) 150 | return resp.json() 151 | 152 | 153 | if __name__ == "__main__": 154 | uvicorn.run("main:app", 155 | host="localhost", 156 | port=3000, 157 | log_level="debug", 158 | reload=True 159 | ) 160 | -------------------------------------------------------------------------------- /sample_apps/rso_sample_apps/rust/src/service.rs: -------------------------------------------------------------------------------- 1 | use crate::config::Configuration; 2 | use crate::{config, handlers}; 3 | use axum::{routing::get, Router}; 4 | use axum_server::tls_rustls::RustlsConfig; 5 | use log::{debug, info}; 6 | 7 | /// Creates an instance of `Router` configured with routes and application state. 8 | /// 9 | /// This function sets up the application's routes by associating URL paths with their respective handler functions. 10 | /// It also attaches the application configuration to the state of the router, making it accessible to the handlers. 11 | /// 12 | /// # Arguments 13 | /// * `cfg` - A reference to the application's configuration. 14 | /// 15 | /// # Returns 16 | /// 17 | /// Returns an instance of `Router` configured with the application's routes and state. 18 | fn create_app(cfg: &Configuration) -> Router { 19 | Router::new() 20 | .route("/data", get(handlers::data::handle)) 21 | .route("/oauth", get(handlers::oauth::handle)) 22 | .route("/", get(handlers::default::handle)) 23 | .with_state(cfg.clone()) 24 | } 25 | 26 | /// Starts the web service with the provided configuration. 27 | /// 28 | /// This asynchronous function attempts to parse the server address from the configuration and start the server. 29 | /// If TLS configuration is provided, it starts a TLS server; otherwise, it starts a regular HTTP server. 30 | /// It logs the server's start-up and panics if the server address is invalid or if there are issues starting the server. 31 | /// 32 | /// # Arguments 33 | /// * `cfg` - A reference to the configuration to use for the service. 34 | /// 35 | /// # Panics 36 | /// 37 | /// Panics if the host address is invalid or if there are issues starting the server. 38 | pub(crate) async fn listen(cfg: &config::Configuration) { 39 | match cfg.server.addr.parse::%v
", 111 | accountData) 112 | 113 | championRotationData := getChampionRotationData(CONFIG["RGAPI_TOKEN"]) 114 | championRotationHTML := fmt.Sprintf( 115 | "%v
", 116 | championRotationData) 117 | 118 | html := fmt.Sprintf("%s %s", accountHTML, championRotationHTML) 119 | w.Header().Set("Content-Type", "text/html; charset=utf-8") 120 | w.Write([]byte(html)) 121 | } 122 | 123 | func getAccountData(accessToken string) string { 124 | type AccountData struct { 125 | Puuid string `html:"l=Puuid,e=span,c=puuid"` 126 | GameName string `html:"l=GameName,e=span,c=gamename"` 127 | TagLine string `html:"l=TagLine,e=span,c=tagline"` 128 | } 129 | 130 | req, _ := http.NewRequest( 131 | "GET", 132 | "https://americas.api.riotgames.com/riot/account/v1/accounts/me", 133 | nil, 134 | ) 135 | req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", accessToken)) 136 | res, _ := http.DefaultClient.Do(req) 137 | defer res.Body.Close() 138 | 139 | body, _ := ioutil.ReadAll(res.Body) 140 | 141 | var accountData AccountData 142 | json.Unmarshal(body, &accountData) 143 | 144 | html, _ := structToHTML(map[string]string{ 145 | "puuid": fmt.Sprint(accountData.Puuid), 146 | "gameName": fmt.Sprint(accountData.GameName), 147 | "tagLine": fmt.Sprint(accountData.TagLine), 148 | }) 149 | 150 | return html 151 | } 152 | 153 | func getChampionRotationData(token string) string { 154 | type ChampionRotationData struct { 155 | FreeChampionIds []int 156 | FreeChampionIdsForNewPlayers []int 157 | MaxNewPlayerLevel int 158 | } 159 | 160 | req, _ := http.NewRequest( 161 | "GET", 162 | "https://na1.api.riotgames.com/lol/platform/v3/champion-rotations", 163 | nil, 164 | ) 165 | req.Header.Add("X-Riot-Token", token) 166 | res, _ := http.DefaultClient.Do(req) 167 | defer res.Body.Close() 168 | 169 | body, _ := ioutil.ReadAll(res.Body) 170 | 171 | var championRotationData ChampionRotationData 172 | json.Unmarshal(body, &championRotationData) 173 | 174 | html, _ := structToHTML(map[string]string{ 175 | "freeChampionIds": fmt.Sprint(championRotationData.FreeChampionIds), 176 | "freeChampionIdsForNewPlayers": fmt.Sprint(championRotationData.FreeChampionIdsForNewPlayers), 177 | "maxNewPlayerLevel": fmt.Sprint(championRotationData.MaxNewPlayerLevel), 178 | }) 179 | 180 | return html 181 | } 182 | 183 | func structToHTML(data map[string]string) (string, error) { 184 | style := ` 185 | ` 193 | html := ` 194 || key | 198 |value | 199 |
|---|---|
| %s | 208 |%s |
209 |