Skip to content

Commit

Permalink
Better config (#62)
Browse files Browse the repository at this point in the history
* configurable bucket name

* more tests

* adding BUCKET_NAME to CircleCI config
  • Loading branch information
eebbesen authored Nov 30, 2023
1 parent b2d8e64 commit 7343d99
Show file tree
Hide file tree
Showing 15 changed files with 101 additions and 34 deletions.
4 changes: 3 additions & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,7 @@ jobs:
- node/install-packages:
pkg-manager: npm
- run:
command: npm run test
command: |
BUCKET_NAME="eulagy"
npm run test
name: Run tests
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ EULAgy is a utility that can be plugged into an application that will stream an

And (shhhh, don't tell) EULAgy will work for _any_ text file, not just EULAs :).


* EULAgy uses Amazon Polly to create an mp3 from EULA text
* EULAgy uses Amazon Comprehend to create a csv from EULA text
* EULAgy is designed to work on AWS Lambda, but can also be run from the command line
Expand All @@ -20,13 +19,16 @@ And (shhhh, don't tell) EULAgy will work for _any_ text file, not just EULAs :).
*In particular, code changes are required to remove hard-coded `eulagy` bucket name throughout the application!*

## Using
### Environment variables
EULAgy requires a populated `BUCKET_NAME` environment variable for tests and production

### AWS Lambda
See Deploy below. Place txt files in the root S3 bucket -- output will appear in the `uploaded` folder of the S3 bucket.

## Develop
1. [Install npm](https://www.npmjs.com/get-npm)
1. `npm install`
1. `npm test` to validate setup!
1. `npm test` to validate setup!
1. `npm run liveTest` to run tests that actually hit S3
* requires configured AWS CLI setup on box running tests -- (You'll need to have AWS credentials created, e.g., https://docs.aws.amazon.com/sdkref/latest/guide/file-format.html)
* will incur AWS charges (up to several cents per full suite run in the cheapest AWS region)
Expand Down
46 changes: 34 additions & 12 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "eulagy",
"version": "3.2.1",
"version": "3.2.2",
"description": "EULAgy takes a text file, converts it to an mp3 and generates a csv based on the Amazon Comprehend findings",
"main": "src/app.ts",
"scripts": {
Expand Down Expand Up @@ -30,6 +30,7 @@
"@aws-sdk/client-polly": ">=3.454.0",
"@aws-sdk/client-s3": ">=3.456.0",
"@types/aws-lambda": ">=8.10.129",
"@types/node": "^20.10.1",
"debug": "4.3.4",
"minimatch": ">=3.12",
"ms": "2.1.2",
Expand All @@ -49,4 +50,4 @@
"url": "https://github.com/eebbesen/eulagy/issues"
},
"homepage": "https://github.com/eebbesen/eulagy#readme"
}
}
6 changes: 3 additions & 3 deletions scripts/package.sh
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
#!/bin/bash

set -e
setopt localoptions rmstarsilent
# setopt localoptions rmstarsilent # not bash, but you need to run if you zsh

echo 'removing node_modules'
rm -rf node_modules/*
rm -rf node_modules/*
echo 'done clearing node_modules'

echo 'npm install --omit=dev'
npm install --omit=dev
npm install --omit=dev

echo 'running tsc to generate .js files for prod only'
rm -rf distProd/*
Expand Down
4 changes: 3 additions & 1 deletion src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ import { type StartSpeechSynthesisTaskCommandOutput } from '@aws-sdk/client-poll
import { type DeleteObjectCommandOutput, type GetObjectCommandOutput, type PutObjectCommandOutput } from '@aws-sdk/client-s3'
import { type DetectKeyPhrasesCommandOutput } from '@aws-sdk/client-comprehend'
import { type S3Event } from 'aws-lambda'

import { log4TSProvider } from './config/LogConfig'

const log = log4TSProvider.getLogger('App')

export async function handler (event: S3Event): Promise<StartSpeechSynthesisTaskCommandOutput> {
log.info('incoming event', JSON.stringify(event))

Utils.bucketProperty() // check early since program need this

const rec: S3Event['Records'] = event.Records
const fileName: string = rec[0].s3.object.key
log.info('processing file', fileName)
Expand Down
11 changes: 6 additions & 5 deletions src/bucketUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
PutObjectCommand,
type PutObjectCommandOutput
} from '@aws-sdk/client-s3'
import * as Utils from './utils'
import { log4TSProvider } from './config/LogConfig'

const log = log4TSProvider.getLogger('BucketUtils')
Expand All @@ -22,7 +23,7 @@ export async function listBuckets (): Promise<ListBucketsCommandOutput> {
};

export function createBucket (name: string): void {
const bucketName = (name.length > 0) ? name : 'eulagy'
const bucketName = (name.length > 0) ? name : Utils.bucketProperty()

listBuckets()
.then(bs => {
Expand All @@ -47,24 +48,24 @@ export function createBucket (name: string): void {

// lists files in S3 bucket
export async function listBucketFiles (name: string): Promise<ListObjectsCommandOutput> {
const bucketName = (name.length > 0) ? name : 'eulagy'
const bucketName = (name.length > 0) ? name : Utils.bucketProperty()
const listObjectsCommand = new ListObjectsCommand({ Bucket: bucketName })
return await client.send(listObjectsCommand)
};

export async function downloadFile (name: string): Promise<GetObjectCommandOutput> {
const getObjectCommand = new GetObjectCommand({ Bucket: 'eulagy', Key: name, RequestPayer: 'requester' })
const getObjectCommand = new GetObjectCommand({ Bucket: Utils.bucketProperty(), Key: name, RequestPayer: 'requester' })
return await client.send(getObjectCommand)
}

export async function deleteFile (name: string): Promise<DeleteObjectCommandOutput> {
const deleteObjectCommand = new DeleteObjectCommand({ Bucket: 'eulagy', Key: name })
const deleteObjectCommand = new DeleteObjectCommand({ Bucket: Utils.bucketProperty(), Key: name })
return await client.send(deleteObjectCommand)
};

// uploads one file to S3 bucket
export async function uploadFile (name: string, data: string): Promise<PutObjectCommandOutput> {
log.debug(`file ${name} size is ${data.length}`)
const putObjectCommand = new PutObjectCommand({ Bucket: 'eulagy', Key: name, Body: data, ContentLength: data.length })
const putObjectCommand = new PutObjectCommand({ Bucket: Utils.bucketProperty(), Key: name, Body: data, ContentLength: data.length })
return await client.send(putObjectCommand)
}
3 changes: 2 additions & 1 deletion src/pollyUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
StartSpeechSynthesisTaskCommand,
type StartSpeechSynthesisTaskCommandOutput
} from '@aws-sdk/client-polly'
import * as Utils from './utils'

const pollyClient = new PollyClient({})

Expand All @@ -28,7 +29,7 @@ export async function startSynthesizeSpeech (text: RegExpMatchArray): Promise<St
OutputFormat: 'mp3',
Text: text[0],
VoiceId: 'Kimberly',
OutputS3BucketName: 'eulagy',
OutputS3BucketName: Utils.bucketProperty(),
OutputS3KeyPrefix: `uploaded/eulagy-${Date.now()}`
})
return await pollyClient.send(command)
Expand Down
8 changes: 8 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,11 @@ export function chunkText (text: string | undefined, limit: number): RegExpMatch

return ret
}

export function bucketProperty(): string {
if (process.env.BUCKET_NAME === undefined ||
process.env.BUCKET_NAME?.trim().length < 1 ) {
throw new Error('No bucket name specified. BUCKET_NAME environment variable required.')
}
return process.env.BUCKET_NAME
}
Loading

0 comments on commit 7343d99

Please sign in to comment.