Skip to content
This repository has been archived by the owner on Jun 2, 2024. It is now read-only.

Commit

Permalink
Merge branch 'release/0.4.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
edward-ly committed Jan 1, 2022
2 parents e107323 + e2137ad commit 7780f34
Show file tree
Hide file tree
Showing 13 changed files with 2,815 additions and 1,826 deletions.
10 changes: 3 additions & 7 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,6 @@ on:
branches:
- develop

env:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_REGION: ${{ secrets.AWS_REGION }}

jobs:
build:
runs-on: ${{ matrix.os }}
Expand All @@ -32,12 +26,14 @@ jobs:
- name: Setup Node
uses: actions/setup-node@v2
with:
node-version: 14.x
node-version: lts/*
- name: Install dependencies
run: yarn --frozen-lockfile
- name: Build app
if: github.ref != 'refs/heads/master'
run: yarn build
- name: Build & deploy app
if: github.ref == 'refs/heads/master'
env:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
run: yarn release
33 changes: 24 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,24 @@ A cross-platform utility app for [StepMania](https://github.com/stepmania/stepma

Made with [Electron](https://www.electronjs.org/) and [Vue.js](https://vuejs.org/) via the [Quasar](https://quasar.dev/) framework.

## Available Songs

Current list of downloadable packs (officially supported and maintained by me):

- [DanceDanceRevolution (Arcade)](https://p.eagate.573.jp/game/ddr/ddra20/p/index.html) - Aims to replicate the DDR arcade experience with a song list that mirrors that of the DDR A20 PLUS song list (meaning that future updates will include both song additions and song removals).
- [The Complete led_light Collection](https://zenius-i-vanisher.com/v5.2/viewsimfilecategory.php?categoryid=821) - A continuously growing collection of DDR-style simfiles made by me!
Recommended for beginners with a wide variety of popular songs!
- [led_light's Tech Experiments](https://zenius-i-vanisher.com/v5.2/viewsimfilecategory.php?categoryid=821) - A separate collection of ITG-style simfiles made by me.
Not recommended for beginners.

## Donate

This is a one-man job, so if you like the app, please consider donating, which will help pay for the costs of hosting and downloading simfiles online.

[![PayPal](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.paypal.com/donate?hosted_button_id=R3F883NUQFLP2)

[![Ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/Z8Z42UJNY)

## Development

```bash
Expand All @@ -23,6 +41,12 @@ yarn lint
yarn build
```

If using [git-flow](https://github.com/petervanderdoes/gitflow-avh), configure release branches:

```bash
git config --local gitflow.release.finish.notag false
```

### Contributing

Want to help make the app better?
Expand Down Expand Up @@ -130,15 +154,6 @@ Feel free to change `128MB` to whatever size you want, but make sure it is large
aws s3 sync </path/to/packs> s3://<bucket-name> --delete --profile <any-profile-name>
```

## Donate

Like the app?
Please consider donating, which will help pay for the costs of hosting and downloading simfiles online.

[![PayPal](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.paypal.com/donate?hosted_button_id=R3F883NUQFLP2)

[![Ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/Z8Z42UJNY)

## License

See [LICENSE](./LICENSE) for details.
36 changes: 22 additions & 14 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "stepmania-song-manager",
"version": "0.3.1",
"version": "0.4.0",
"description": "Download and update song packs for StepMania",
"productName": "StepMania Song Manager",
"author": {
Expand All @@ -20,35 +20,43 @@
"release": "genversion --es6 version.js && quasar build -m electron -P onTagOrDraft"
},
"dependencies": {
"@auth0/s3": "^1.0.0",
"@quasar/extras": "^1.10.7",
"@aws-sdk/client-s3": "^3.45.0",
"@quasar/extras": "^1.12.2",
"auto-launch": "^5.0.5",
"axios": "^0.21.1",
"core-js": "^3.6.5",
"axios": "^0.24.0",
"core-js": "^3.20.1",
"electron-updater": "^4.6.1",
"md5-file": "^5.0.0",
"quasar": "^2.4.2",
"vue-i18n": "^9.0.0-beta.0"
},
"resolutions": {
"ansi-regex": "^5.0.1",
"css-what": "^5.0.1",
"dns-packet": "^1.3.4",
"electron-updater": "^4.3.8",
"glob-parent": "^5.1.2",
"hosted-git-info": "^3.0.8",
"is-svg": "^4.2.2",
"normalize-url": "^4.5.1",
"nth-check": "^2.0.1",
"path-parse": "^1.0.7",
"postcss": "^8.3.0",
"quasar": "^2.0.0",
"vue-i18n": "^9.0.0-beta.0",
"ws": "^7.5.0",
"xmldom": "0.5.0"
"xmldom": "^0.6.0",
"yargs-parser": "^20.2.9"
},
"devDependencies": {
"@quasar/app": "^3.0.0",
"@quasar/app": "^3.2.6",
"babel-eslint": "^10.0.1",
"electron": "^11.3.0",
"electron-builder": "^22.4.0",
"electron-packager": "^14.1.1",
"electron": "^16.0.5",
"electron-builder": "^22.14.5",
"electron-packager": "^15.4.0",
"eslint": "^7.14.0",
"eslint-config-prettier": "^6.15.0",
"eslint-plugin-vue": "^7.0.0",
"eslint-webpack-plugin": "^2.4.0",
"genversion": "^2.3.1",
"prettier": "2.2.1"
"prettier": "2.5.1"
},
"browserslist": [
"last 10 Chrome versions",
Expand Down
8 changes: 8 additions & 0 deletions quasar.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,14 @@ module.exports = configure(function (/* ctx */) {
{
target: 'nsis',
arch: [ 'x64', 'arm64', 'ia32' ]
},
{
target: 'nsis-web',
arch: [ 'x64', 'arm64', 'ia32' ]
},
{
target: 'portable',
arch: [ 'x64', 'arm64', 'ia32' ]
}
]
},
Expand Down
118 changes: 118 additions & 0 deletions src-electron/components/aws-s3.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import path from 'path'
import fs from 'fs-extra'
import _ from 'lodash'
import md5File from 'md5-file'
import EventEmitter from 'events'
import {
S3Client,
ListObjectsV2Command,
GetObjectCommand,
} from '@aws-sdk/client-s3'
import readDirRecursive from '../helpers/readDirRecursive'

async function listBucket (s3Client, bucket, songListOnly) {
let continuationToken = undefined
let contents = []

do {
const listCommand = new ListObjectsV2Command({
Bucket: bucket.name,
ContinuationToken: continuationToken,
})

const res = await s3Client.send(listCommand)
let newContents = res.Contents
if (songListOnly) newContents = newContents.filter(item => {
const ext = path.extname(item.Key)
return _.includes(['.sm', '.ssc', '.ini'], ext)
})
contents = contents.concat(newContents)
continuationToken = res.NextContinuationToken
} while (continuationToken)

return contents.map(item => {
const localPath = path.join(bucket.localPath, item.Key)
return {...item, LocalPath: localPath}
})
}

export default async function s3Download (event, bucket, credentials, songListOnly) {
const ee = new EventEmitter()
ee.on('error', (err) => event.reply('sync-error', err))
ee.on('progress', (progress) => event.reply('sync-progress', progress))
ee.on('end', () => event.reply('sync-end'))

let progressAmount = 0
let progressTotal = 0
ee.emit('progress', NaN)

const bucketName = bucket.name
const downloadPath = bucket.localPath

let s3Params = {
region: bucket.region || 'us-west-2',
credentials: {
accessKeyId: credentials.AccessKeyId,
secretAccessKey: credentials.SecretAccessKey,
},
}
if (bucket.endpoint) s3Params.endpoint = bucket.endpoint
if (credentials.SessionToken) s3Params.sessionToken = credentials.SessionToken
const s3Client = new S3Client(s3Params)


try {
await fs.ensureDir(downloadPath)
let localContents = readDirRecursive(downloadPath)
let s3Contents = await listBucket(s3Client, bucket, songListOnly)
const newContents = s3Contents.filter(item => !localContents.includes(item.LocalPath))
_.pullAll(s3Contents, newContents)
progressTotal = localContents.length + newContents.length
ee.emit('progress', progressAmount / progressTotal)

while (localContents.length) {
const localFile = localContents.shift()
const contentIndex = s3Contents.findIndex(item => item.LocalPath === localFile)

if (contentIndex > -1) {
const content = _.head(s3Contents.splice(contentIndex, 1))
const localHash = await md5File(localFile)

if (!content.ETag.includes(localHash)) {
const getCommand = new GetObjectCommand({
Bucket: bucketName,
Key: content.Key,
})

const res = await s3Client.send(getCommand)
res.Body.pipe(fs.createWriteStream(localFile))
}
}
else {
await fs.rm(localFile)
}

progressAmount++
ee.emit('progress', progressAmount / progressTotal)
}

for (let content of newContents) {
const getCommand = new GetObjectCommand({
Bucket: bucketName,
Key: content.Key,
})

const res = await s3Client.send(getCommand)
const localPath = content.LocalPath
await fs.ensureFile(localPath)
res.Body.pipe(fs.createWriteStream(localPath))

progressAmount++
ee.emit('progress', progressAmount / progressTotal)
}

ee.emit('end')
} catch (err) {
ee.emit('error', err)
}
}
Loading

0 comments on commit 7780f34

Please sign in to comment.