Last active
November 22, 2022 04:49
-
-
Save omkelderman/037342ca6612140197d0bb6f19328884 to your computer and use it in GitHub Desktop.
osu! api fetch stuff for google scripts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// some sample code, you can change whatever you want starting from here till where it says to not change anything | |
var ACTIVE_SHEET = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("name of sheet here"); | |
// run this function to trigger all the things | |
// this sampe code assumes you have a list of user-ids in A2:A and a list of beatmap ids in H2:H | |
// basically how it works you tell what property of the user or beatmap object you want in which column | |
function RUN_ALL_THE_THINGS() { | |
setUserDataOnSheet(ACTIVE_SHEET, 'A2:A', { | |
username: 'B', | |
pp_rank: 'C', | |
country: 'D', | |
pp_raw: 'E', | |
playcount: 'F', | |
}); | |
setBeatmapDataOnSheet(ACTIVE_SHEET, 'H2:H', { | |
title: 'I', | |
artist: 'J', | |
version: 'K', | |
artist_title: 'L', | |
artist_title_version: 'M', | |
}); | |
} | |
// === set osu! api key here | |
var OSU_API_KEY = 'API KEY HERE'; // replace with ur own api key | |
// ===== DO NOT CHANGE ANYTHING BELOW THIS UNLESS YOU KNOW WHAT YOU'RE DOING!!!!!!!!! ====== | |
var DEFAULT_MAP_SPECIALS = { | |
artist_title: function(obj) { return obj.artist + ' - ' + obj.title; }, | |
artist_title_version: function(obj) { return obj.artist + ' - ' + obj.title + ' [' + obj.version + ']'; }, | |
}; | |
var DEFAULT_USER_SPECIALS = { | |
// havent tought of one yet, not sure if you even could think of one that makes sense | |
}; | |
// helper function to do a http request, expecting an array back (as almost all osu api request do) and returning the first object | |
function JSONArrayRequestGetFirst(url) { | |
var response = UrlFetchApp.fetch(url).getContentText('UTF8'); | |
var json = JSON.parse(response); | |
return json[0]; | |
} | |
// get user by ID | |
function osuApiGetUser(userId) { | |
var url = 'https://osu.ppy.sh/api/get_user?k=' + OSU_API_KEY + '&type=id&u=' + userId; | |
return JSONArrayRequestGetFirst(url); | |
} | |
// get beatmap by ID | |
function osuApiGetBeatmap(beatmapId) { | |
var url = 'https://osu.ppy.sh/api/get_beatmaps?k=' + OSU_API_KEY + '&b=' + beatmapId; | |
return JSONArrayRequestGetFirst(url); | |
} | |
/** | |
* main function for setting user-data on the sheet | |
* params: | |
* - sheet: reference to the sheet (duh) | |
* - userIdRange: a1notation of the input-range containing user-ids (example 'A2:A') | |
* - output: a javascript object containing which user-api-object-property to map to which column, example: | |
* { | |
* 'username': 'B', | |
* 'pp_rank': 'C' | |
* } | |
* this will put the username in column B and the rank in column C. | |
* for available properties, go to https://osu.ppy.sh/api/get_user?k=APIKEY&type=id&u=USERID in ur browser and take a look at what exists | |
*/ | |
function setUserDataOnSheet(sheet, userIdRange, output, specials) { | |
setApiDataOnSheet(sheet, userIdRange, output, Object.assign({}, DEFAULT_USER_SPECIALS, specials), osuApiGetUser); | |
} | |
/** | |
* main function for setting beatmap-data on the sheet | |
* params: | |
* - sheet: reference to the sheet (duh) | |
* - beatmapIdRange: a1notation of the input-range containing beatmap-ids (example 'A2:A') | |
* - output: a javascript object containing which beatmap-api-object-property to map to which column, example: | |
* { | |
* 'title': 'B', | |
* 'artist': 'C', | |
* 'version': 'D' | |
* } | |
* this will put the username in column B and the rank in column C. | |
* for available properties, go to https://osu.ppy.sh/api/get_beatmaps?k=APIKEY&b=BEATMAPID in ur browser and take a look at what exists | |
*/ | |
function setBeatmapDataOnSheet(sheet, beatmapIdRange, output, specials) { | |
setApiDataOnSheet(sheet, beatmapIdRange, output, Object.assign({}, DEFAULT_MAP_SPECIALS, specials), osuApiGetBeatmap); | |
} | |
function getProperyFromObjectOrSpecial(obj, propName, specials) { | |
if(obj) { | |
if(obj[propName]) return obj[propName]; | |
if(specials) { | |
var specialFn = specials[propName]; | |
if(specialFn) return specialFn(obj); | |
} | |
} | |
return undefined; | |
} | |
function setApiDataOnSheet(sheet, inputRange, output, specials, apiGetFunction) { | |
var range = sheet.getRange(inputRange); | |
var inputValues = range.getValues(); | |
var rowStart = range.getRow(); | |
var outputKeys = Object.keys(output); | |
if(outputKeys.length == 0) return; | |
for(var i=0; i<inputValues.length; ++i) { | |
var currentRow = rowStart + i; | |
var inputValue = inputValues[i][0]; | |
var id = inputValue ? parseInt(inputValue, 10) : undefined; | |
if(id) { | |
try { | |
var apiObj = apiGetFunction(id); | |
for(var j=0; j<outputKeys.length; ++j) { | |
var outputKey = outputKeys[j]; | |
var outputCol = output[outputKey]; | |
var outputValue = getProperyFromObjectOrSpecial(apiObj, outputKey, specials); | |
sheet.getRange(outputCol + currentRow).setValue(outputValue || ''); | |
} | |
} catch(e) { | |
// api error :( | |
Logger.log('osu api error:') | |
Logger.log(e); | |
for(var j=0; j<outputKeys.length; ++j) { | |
var outputKey = outputKeys[j]; | |
var outputCol = output[outputKey]; | |
sheet.getRange(outputCol + currentRow).setValue('OSU-API-ERROR'); | |
} | |
} | |
} else { | |
// input was either empty or invalid, lets just empty out the output cells | |
for(var j=0; j<outputKeys.length; ++j) { | |
var outputKey = outputKeys[j]; | |
var outputCol = output[outputKey]; | |
sheet.getRange(outputCol + currentRow).setValue(''); | |
} | |
} | |
} | |
} | |
// Object.assign polyfill | |
if (typeof Object.assign !== 'function') { | |
// Must be writable: true, enumerable: false, configurable: true | |
Object.defineProperty(Object, "assign", { | |
value: function assign(target, varArgs) { // .length of function is 2 | |
'use strict'; | |
if (target === null || target === undefined) { | |
throw new TypeError('Cannot convert undefined or null to object'); | |
} | |
var to = Object(target); | |
for (var index = 1; index < arguments.length; index++) { | |
var nextSource = arguments[index]; | |
if (nextSource !== null && nextSource !== undefined) { | |
for (var nextKey in nextSource) { | |
// Avoid bugs when hasOwnProperty is shadowed | |
if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) { | |
to[nextKey] = nextSource[nextKey]; | |
} | |
} | |
} | |
} | |
return to; | |
}, | |
writable: true, | |
configurable: true | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment