Last active
February 16, 2021 22:32
-
-
Save htammen/0b4ae0e7e747b1ac669b9b7f31f9d5a3 to your computer and use it in GitHub Desktop.
A script to get a list of (open) project offers
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
// This script reads open projects and outputs them to the console. | |
// This is quite messy cause I created it at a sunday evening. | |
// Will hopefully find time in the future to make it a bit more production ready | |
import { | |
decode as base64Decode, | |
encode as base64Encode, | |
} from 'https://deno.land/[email protected]/encoding/base64.ts'; | |
import { ld } from 'https://x.nest.land/[email protected]/mod.ts' | |
import { parse } from "https://deno.land/std/flags/mod.ts" | |
import { format } from "https://deno.land/[email protected]/datetime/mod.ts"; | |
/** | |
* returns a command line argument by name from the args array | |
*/ | |
const getArg = function(argName: string, args: any[]): string { | |
//@ts-ignore | |
const arg = ld.find(args, (arg: string[]) => arg[0] === argName) | |
return arg ? arg[1]: null | |
} | |
/** | |
* check the status of Bitwarden. this script only works with bitwarden. It pulls | |
* the credentials for the server that is given at command line from the bitwarden | |
* password safe. | |
* @returns true if bitwarden is unlocked | |
*/ | |
const checkBWStatus= async function(): Promise<boolean> { | |
const cmd = Deno.run({ | |
cmd: ['bw', 'status'], | |
stdout: "piped", | |
stderr: "piped" | |
}); | |
const output = await cmd.output() // "piped" must be set | |
const outStr = new TextDecoder('utf-8').decode(output); | |
// this is a hack cause TextDecoder returns a string beginning with 'Failed to decrypt' WHY??? We cut off this prefix | |
const str = outStr.substr(outStr.indexOf("{")) | |
log(str) | |
const status = JSON.parse(str) | |
cmd.close() | |
return status.status === "unlocked" | |
} | |
/** | |
* Helper method that logs a msg if debug flag is set | |
*/ | |
const log=function(msg: any) { | |
if(bDebug) { | |
console.log(msg) | |
} | |
} | |
/** | |
* Returns the startDate to start the project search with. | |
* if commandline parameter fromdate is given it is used. | |
* if commandline parameter is not given the last 14 days will be used for search | |
*/ | |
const getBeginDate = function(): string { | |
// check if start date is set. If not select projects for the last 14 days. | |
let startDateMillis = new Date().getTime() | |
if(startDateStr) { | |
startDateMillis = new Date(startDateStr).getTime() | |
} else { | |
let curDate = new Date() | |
// go 14 days back | |
const t=curDate.getTime()-(14*24*60*60*1000) | |
curDate.setTime(t) | |
startDateMillis = curDate.getTime() | |
} | |
return format(new Date(startDateMillis), "yyyy-MM-ddThh:mm:ss") | |
} | |
//console.log(parse(Deno.args)) | |
// parse the args array into an array of 2-dimensionals array. | |
// Each array element is an array with 2 members: 0-argument, 1-argument value | |
const args = ld.toPairs(parse(Deno.args)) | |
//console.log(args) | |
// save the command line parameters in variables. | |
const server = getArg('server', args) | |
const authurl = getArg('authurl', args) | |
const titleFilter = getArg('title', args) | |
const startDateStr = getArg('fromdate', args) | |
const bHelp = getArg('help', args) | |
const bDebug = getArg('debug', args) | |
log(args) | |
/** holds the status of bitwarden. true=unlocked */ | |
const bwStatus = await checkBWStatus() | |
if(!bwStatus) { | |
console.error('Please login to Bitwarden to retrieve your server credentials') | |
Deno.exit(0) | |
} | |
// Show help screen if --help command line parameter was set | |
if(bHelp) { | |
console.log('PRJCRAWLER') | |
console.log('call this program with following options') | |
console.log(` | |
--server: name of the server to contact | |
--authurl: authentication url to use for retrieving the oAuth token | |
--title: search string used for querying projects | |
--fromdate: date to start the query with, default: last 14 days, format: 2020-12-24T00:00:00 (/w or w/o time part) | |
--help: show this help screen | |
--debug: output debug infos. | |
`) | |
Deno.exit(0); | |
} | |
const beginDateStr = getBeginDate() | |
// log the input data | |
console.log(`server: ${server}`) | |
console.log(`titleFilter: ${titleFilter}`) | |
console.log(`startDate: ${beginDateStr}`) | |
const getBitwardenField = async (fieldName:string, credEntry: string): Promise<string> => { | |
const cmd = Deno.run({ | |
cmd: ['bw', 'get', fieldName, credEntry], | |
stdout: "piped", | |
stderr: "piped" | |
}); | |
const output = await cmd.output() // "piped" must be set | |
const outStr = new TextDecoder().decode(output); | |
cmd.close() | |
return outStr | |
} | |
//console.log(server) | |
const username = await getBitwardenField('username', server) | |
const password = await getBitwardenField('password', server) | |
log(username) | |
const auth = base64Encode(`${username}:${password}`) | |
log(`base64encoded auth string: ${auth}`) | |
const authResponse = await fetch(authurl, {method: 'GET', headers: {'Authorization': 'Basic ' + auth}}) | |
const authToken = await authResponse.text() | |
log(`authtoken: ${authToken}`) | |
let sFilter = `OriginalPublicationDate%20ge%20datetime'${beginDateStr}'` | |
if(titleFilter) { | |
sFilter += `%20and%20substringof(%27${titleFilter}%27,Title)` | |
} | |
log(sFilter) | |
const prjOffersUrl=`https://${server}/project-offer-backend/Data.svc/ProjectOffers?$skip=0&$top=30&$orderby=OriginalPublicationDate%20desc&$filter=${sFilter}` | |
log(prjOffersUrl) | |
const prjResult = await fetch(prjOffersUrl, {method: 'GET', headers: {'Authorization': 'Bearer ' + authToken, 'Accept': 'application/json'}}) | |
log(prjResult) | |
const prjJSON = await prjResult.json() | |
if(bDebug) { | |
console.table(prjJSON.d.results, ["Title", "Location", "AgencyOrganization", "Url"]) | |
} | |
const arrProjects:string[] = prjJSON.d.results.map((x:any) => { | |
return `${x.Title}\t>${x.Location}<\t>${x.AgencyOrganization}<\n${x.Url}\n---------------------------------------------------------------------------------------------------` | |
}) | |
const arrPrefix = [ | |
'------------------------------------------------------------------------------------------------------------------------', | |
'R E S U L T S', | |
'------------------------------------------------------------------------------------------------------------------------', | |
] | |
//@ts-ignore | |
const arrOutput = ld.concat(arrPrefix, arrProjects) | |
console.log(arrOutput.join('\n')) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment