Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add functions to Import/Clear/Export the WCIF #52

Merged
merged 3 commits into from
Nov 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .env.DEV
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ USE_CDN=
API_KEY='example-application-id'
API_SECRET='example-secret'
COOKIE_SECRET='b8f6959746b617d9c9e90ce4a4b6e0'
WCIF_DATA_FOLDER=wcif_data
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ google-credentials.json
.env.*
!.env.DEV
.wcif_cache
wcif_data

# Logs
logs
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ Node must be installed on your machine.

```
$ npm install
$ ENV=DEV npx nodemon .
$ npm run dev-server
```

`ENV=DEV` uses a dev WCA environment running on the same machine. If you would like to use the production WCA site, you need to:
Running the development server will use uses a dev WCA environment running on the same machine. If you would like to use the production WCA site, you need to:

1. Make an OAuth application [here](https://www.worldcubeassociation.org/oauth/applications). For "Scopes", use `public manage_competitions`; for "Callback Urls" use `http://localhost:3033/auth/oauth_response`.
2. Make a copy of the `.env.DEV` file, such as `.env.PROD`. This file should not be committed; `.gitignore` should automatically ignore it.
Expand Down
1 change: 1 addition & 0 deletions functions/functions.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@ module.exports = {
require('./tuple').functions,
require('./udf').functions,
require('./util').functions,
require('./wcif').functions,
)
}
96 changes: 96 additions & 0 deletions functions/wcif.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
const fs = require('fs')
const fse = require('fs-extra')

const ClearWCIF = {
name: 'ClearWCIF',
docs: 'Remove all childActivities keeping only the main schedule, remove all assignments, cleanup roles, cleanup NatsHelper extension data.',
args: [
{
name: 'clearExternalExtensions',
type: 'Boolean',
docs: 'Also cleanup external tools extensions.',
defaultValue: false,
},
],
outputType: 'Void',
usesContext: true,
mutations: ['schedule', 'persons'],
implementation: (ctx, clearExternalExtensions) => {
const cleanupExtensions = (object) => {
if (clearExternalExtensions) {
object.extensions = []
} else {
object.extensions = object.extensions.filter(({ id }) => !id.startsWith("org.cubingusa.natshelper"))
}
}
cleanupExtensions(competition)
ctx.competition.persons.forEach((person) => {
// Cleanup roles which are user-defined.
const immutableRoles = ['delegate', 'organizer', 'trainee-delegate']
person.roles = person.roles.filter((r) => immutableRoles.includes(r))
person.assignments = []
cleanupExtensions(person)
})
ctx.competition.schedule.venues.forEach((venue) => {
venue.rooms.forEach((room) => {
cleanupExtensions(room)
room.activities.forEach((activity) => {
cleanupExtensions(activity)
activity.childActivities = []
})
})
})
}
}

const ImportWCIF = {
name: 'ImportWCIF',
docs: 'Import the WCIF from a json file',
args: [
{
name: 'filename',
type: 'String',
docs: 'WCIF filename (relative to WCIF_DATA_FOLDER/competitionId)',
},
],
outputType: 'String',
usesContext: true,
implementation: (ctx, filename) => {
var fullPath = `${process.env.WCIF_DATA_FOLDER || '.'}/${ctx.competition.id}/${filename}`
var wcif = JSON.parse(fs.readFileSync(fullPath))
if (wcif.id !== ctx.competition.id) {
throw new Error(`The WCIF is not for the correct competition (expected "${ctx.competition.id}", but got "${wcif.id})"`)
}
ctx.competition = wcif
return `Imported WCIF from '${fullPath}'.`
}
}

const ExportWCIF = {
name: 'ExportWCIF',
docs: 'Export the WCIF to a json file',
args: [
{
name: 'filename',
type: 'String',
docs: 'WCIF filename (emitted in WCIF_DATA_FOLDER/competitionId)',
defaultValue: 'wcif.json',
},
],
outputType: 'String',
usesContext: true,
implementation: (ctx, filename) => {
var folder = `${process.env.WCIF_DATA_FOLDER || '.'}/${ctx.competition.id}`;
var fullPath = `${folder}/${filename}`
fse.ensureDirSync(folder)
fs.writeFileSync(
fullPath,
JSON.stringify(ctx.competition, null, 2)
)
return `WCIF saved to '${fullPath}'.`
}
}

module.exports = {
functions: [ClearWCIF, ExportWCIF, ImportWCIF],
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"version": "1.0.0",
"main": "main.js",
"scripts": {
"dev-server": "ENV=DEV npx nodemon -i wcif_data .",
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
Expand Down
Empty file added wcif_data/.keep
Empty file.