Skip to content

Commit

Permalink
Merge pull request #108 from mediumroast/v0.7.0_competitive_insight
Browse files Browse the repository at this point in the history
V0.7.0 competitive insight
  • Loading branch information
miha42-github authored Aug 3, 2024
2 parents 8a81fcb + 9117c8f commit 2ae428a
Show file tree
Hide file tree
Showing 14 changed files with 1,055 additions and 158 deletions.
89 changes: 89 additions & 0 deletions cli/mrcli-actions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
#!/usr/bin/env node

/**
* A CLI utility used for accessing and reporting on mediumroast.io user objects
* @author Michael Hay <michael.hay@mediumroast.io>
* @file actions.js
* @copyright 2024 Mediumroast, Inc. All rights reserved.
* @license Apache-2.0
* @verstion 1.0.0
*/

// Import required modules
import { Billings } from '../src/api/gitHubServer.js'
import Environmentals from '../src/cli/env.js'
import CLIOutput from '../src/cli/output.js'

// Related object type
const objectType = 'Actions'

// Environmentals object
const environment = new Environmentals(
'2.0',
`${objectType}`,
`Command line interface to report on and update actions.`,
objectType
)

/*
-----------------------------------------------------------------------
FUNCTIONS - Key functions needed for MAIN
-----------------------------------------------------------------------
*/


/*
-----------------------------------------------------------------------
MAIN - Steps below represent the main function of the program
-----------------------------------------------------------------------
*/

// Create the environmental settings
let myProgram = environment.parseCLIArgs(true)

// Remove command line options for reset_by_type, delete, update, and add_wizard by calling the removeArgByName method in the environmentals class
myProgram = environment.removeArgByName(myProgram, '--delete')
myProgram = environment.removeArgByName(myProgram, '--add_wizard')
myProgram = environment.removeArgByName(myProgram, '--reset_by_type')
myProgram = environment.removeArgByName(myProgram, '--report')
myProgram = environment.removeArgByName(myProgram, '--find_by_name')
myProgram = environment.removeArgByName(myProgram, '--find_by_x')
myProgram = environment.removeArgByName(myProgram, '--find_by_id')
myProgram = environment.removeArgByName(myProgram, '--report')
myProgram = environment.removeArgByName(myProgram, '--package')
myProgram = environment.removeArgByName(myProgram, '--splash')

// Parse the command line arguments into myArgs and obtain the options
let myArgs = myProgram.parse(process.argv)
myArgs = myArgs.opts()

const myConfig = environment.readConfig(myArgs.conf_file)
let myEnv = environment.getEnv(myArgs, myConfig)
const accessToken = await environment.verifyAccessToken()
const processName = 'mrcli-actions'

// Output object
const output = new CLIOutput(myEnv, objectType)

// Construct the controller objects
const actionsCtl = new Billings(accessToken, myEnv.gitHubOrg, processName)

// Predefine the results variable
let [success, stat, results] = [null, null, null]

if (myArgs.update) {
[success, stat, results] = await billingsCtl.getActionsBilling()
const myUserOutput = new CLIOutput(myEnv, 'ActionsBilling')
myUserOutput.outputCLI([results], myArgs.output)
process.exit()
} else {
[success, stat, results] = await billingsCtl.getAll()
const myUserOutput = new CLIOutput(myEnv, 'AllBilling')
myUserOutput.outputCLI(results, myArgs.output)
process.exit()
}

3 changes: 0 additions & 3 deletions cli/mrcli-billing.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import { Billings } from '../src/api/gitHubServer.js'
import Environmentals from '../src/cli/env.js'
import CLIOutput from '../src/cli/output.js'
import chalk from 'chalk'

// Related object type
const objectType = 'Billings'
Expand Down Expand Up @@ -58,8 +57,6 @@ myProgram = environment.removeArgByName(myProgram, '--report')
myProgram = environment.removeArgByName(myProgram, '--find_by_name')
myProgram = environment.removeArgByName(myProgram, '--find_by_x')
myProgram = environment.removeArgByName(myProgram, '--find_by_id')
myProgram = environment.removeArgByName(myProgram, '--update')
myProgram = environment.removeArgByName(myProgram, '--delete')
myProgram = environment.removeArgByName(myProgram, '--report')
myProgram = environment.removeArgByName(myProgram, '--package')
myProgram = environment.removeArgByName(myProgram, '--splash')
Expand Down
22 changes: 8 additions & 14 deletions cli/mrcli-interaction.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
* A CLI utility used for accessing and reporting on mediumroast.io interaction objects
* @author Michael Hay <michael.hay@mediumroast.io>
* @file interactions.js
* @copyright 2022 Mediumroast, Inc. All rights reserved.
* @copyright 2024 Mediumroast, Inc. All rights reserved.
* @license Apache-2.0
* @version 3.0.0
* @version 3.1.0
*/


Expand Down Expand Up @@ -57,7 +57,7 @@ const objectType = 'Interactions'

// Environmentals object
const environment = new Environmentals(
'3.0.0',
'3.1.0',
`${objectType}`,
`Command line interface for mediumroast.io ${objectType} objects.`,
objectType
Expand Down Expand Up @@ -94,12 +94,10 @@ let results = Array() || []

// Process the cli options
if (myArgs.report) {
console.error('ERROR (%d): Report not implemented.', -1)
process.exit(-1)
// Retrive the interaction by Id
const [int_success, int_stat, int_results] = await interactionCtl.findById(myArgs.report)
// Retrive the company by Name
const [int_success, int_stat, int_results] = await interactionCtl.findByName(myArgs.report)
const companyName = Object.keys(int_results[0].linked_companies)[0]
// Retrive the company by Name
const [comp_success, comp_stat, comp_results] = await companyCtl.findByName(companyName)
// Set the root name to be used for file and directory names in case of packaging
const baseName = int_results[0].name.replace(/ /g,"_")
Expand All @@ -112,8 +110,9 @@ if (myArgs.report) {
const docController = new InteractionStandalone(
int_results[0], // Interaction to report on
comp_results[0], // The company associated to the interaction
'mediumroast.io barrista robot', // The author
'Mediumroast, Inc.' // The authoring company/org
'Mediumroast for GitHub robot', // The author
'Mediumroast, Inc.', // The authoring company/org
myEnv // The environment settings
)

if(myArgs.package) {
Expand Down Expand Up @@ -168,11 +167,6 @@ if (myArgs.report) {
process.exit(-1)
}

} else if (myArgs.find_by_id) {
console.error('ERROR (%d): Find by name not implemented.', -1)
process.exit(-1)
// Retrive the interaction by Id
[success, stat, results] = await interactionCtl.findById(myArgs.find_by_id)
} else if (myArgs.find_by_name) {
// Retrive the interaction by Name
[success, stat, results] = await interactionCtl.findByName(myArgs.find_by_name)
Expand Down
1 change: 0 additions & 1 deletion cli/mrcli-user.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import { Users } from '../src/api/gitHubServer.js'
import Environmentals from '../src/cli/env.js'
import CLIOutput from '../src/cli/output.js'
import chalk from 'chalk'

// Related object type
const objectType = 'Users'
Expand Down
3 changes: 2 additions & 1 deletion cli/mrcli.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,14 @@ import program from 'commander'

program
.name('mrcli')
.version('0.6.4')
.version('0.7.0')
.description('mediumroast.io command line interface')
.command('setup', 'setup the mediumroast.io system via the command line').alias('f')
.command('interaction', 'manage and report on mediumroast.io interaction objects').alias('i')
.command('company', 'manage and report on mediumroast.io company objects').alias('c')
.command('study', 'manage and report on mediumroast.io study objects').alias('s')
.command('user', 'report on mediumroast.io users in GitHub').alias('u')
.command('billing', 'report on GitHub actions and storage units consumed').alias('b')
.command('actions', 'report on and update GitHub actions').alias('a')

program.parse(process.argv)
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "mediumroast_js",
"version": "0.6.4",
"version": "0.7.0",
"description": "A Command Line Interface (CLI) and Javascript SDK to interact with mediumroast.io.",
"main": "cli/mrcli.js",
"scripts": {
Expand Down
50 changes: 50 additions & 0 deletions src/api/gitHubServer.js
Original file line number Diff line number Diff line change
Expand Up @@ -474,5 +474,55 @@ class Interactions extends baseObjects {
}
}

class Actions extends baseObjects {
/**
* @constructor
* @classdesc A subclass of baseObjects that construct the interaction objects
* @param {String} token - the token for the GitHub application
* @param {String} org - the organization for the GitHub application
* @param {String} processName - the process name for the GitHub application
*/
constructor (token, org, processName) {
super(token, org, processName, 'Interactions')
}

async updateObj(objToUpdate, dontWrite=false, system=false) {
// Destructure objToUpdate
const { name, key, value } = objToUpdate
// Define the attributes that can be updated by the user
const whiteList = [
'status', 'content_type', 'file_size', 'reading_time', 'word_count', 'page_count', 'description', 'abstract',

'region', 'country', 'city', 'state_province', 'zip_postal', 'street_address', 'latitude', 'longitude',

'public', 'groups'
]
return await super.updateObj(name, key, value, dontWrite, system, whiteList)
}

async getAll() {
const storageBillingsResp = await this.serverCtl.getStorageBillings()
const actionsBillingsResp = await this.serverCtl.getActionsBillings()
const allBillings = [
{
resourceType: 'Storage',
includedUnits: Math.abs(
storageBillingsResp[2].estimated_paid_storage_for_month -
storageBillingsResp[2].estimated_storage_for_month
) + ' GiB',
paidUnitsUsed: storageBillingsResp[2].estimated_paid_storage_for_month + ' GiB',
totalUnitsUsed: storageBillingsResp[2].estimated_storage_for_month + ' GiB'
},
{
resourceType: 'Actions',
includedUnits: actionsBillingsResp[2].total_minutes_used + ' min',
paidUnitsUsed: actionsBillingsResp[2].total_paid_minutes_used + ' min',
totalUnitsUsed: actionsBillingsResp[2].total_minutes_used + actionsBillingsResp[2].total_paid_minutes_used + ' min'
}
]
return [true, {status_code: 200, status_msg: `found all billings`}, allBillings]
}
}

// Export classes for consumers
export { Studies, Companies, Interactions, Users, Billings }
63 changes: 63 additions & 0 deletions src/api/github.js
Original file line number Diff line number Diff line change
Expand Up @@ -903,6 +903,69 @@ class GitHubFunctions {
// Return success with number of objects written
return [true, {status_code: 200, status_msg: `Released [${repoMetadata.containers.length}] containers.`}, null]
}

// Use fs to read all the files in the actions directory recursively
generateActionsManifest(dir, filelist) {
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename)
dir = dir || path.resolve(path.join(__dirname, './actions') )
const files = fs.readdirSync(dir)
filelist = filelist || []
files.forEach((file) => {
// Skip .DS_Store files and node_modules directories
if (file === '.DS_Store' || file === 'node_modules') {
return
}
if (fs.statSync(path.join(dir, file)).isDirectory()) {
filelist = generateActionsManifest(path.join(dir, file), filelist)
}
else {
// Substitute .github for the first part of the path, in the variable dir
// Log dir to the console including if there are any special characters
if (dir.includes('./')) {
dir = dir.replace('./', '')
}
// This will be the repository name
let dotGitHub = dir.replace(/.*(workflows|actions)/, '.github/$1')

filelist.push({
fileName: file,
containerName: dotGitHub,
srcURL: new URL(path.join(dir, file), import.meta.url)
})
}
})
return filelist
}

async installActions() {
let actionsManifest = this.generateActionsManifest()
// Loop through the actionsManifest and install each action
await actionsManifest.forEach(async (action) => {
let status = false
let blobData
try {
// Read in the blob file
blobData = fs.readFileSync(action.srcURL, 'base64')
status = true
} catch (err) {
return [false, 'Unable to read file [' + action.fileName + '] because: ' + err, null]
}
if(status) {
// Install the action
const installResp = await this.writeBlob(
action.containerName,
action.fileName,
blobData,
'main'
)
} else {
return [false, 'Failed to read item [' + action.fileName + ']', null]
}
})
return [true, 'All actions installed', null]
}

}

export default GitHubFunctions
2 changes: 1 addition & 1 deletion src/cli/interactionTypes.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"Book": {
"Book": {
"author": {"consoleString": "Book's author", "value": "Unknown"},
"year": {"consoleString": "Book's published year", "value": "Unknown"},
"month": {"consoleString": "Book's published month", "value": "Unknown"},
Expand Down
Loading

0 comments on commit 2ae428a

Please sign in to comment.