diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 604597e..847c656 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -35,9 +35,8 @@ jobs: ${{ runner.os }}-node- - run: npm i + - name: semver plugins - env: - CMC_PRO_API_KEY: ${{secrets.CMC_PRO_API_KEY}} run: | npm install '@semantic-release/changelog' \ '@semantic-release/exec' \ diff --git a/.gitignore b/.gitignore index ef0772c..7ae3f74 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ node_modules build .DS_Store package-lock.json +.env diff --git a/README.md b/README.md index 900f40b..49dca55 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,17 @@ # Number Pull cryptocurrency prices -Pull crypto prices from **coinmarketcap** in Mac os Apple Numbers +Pull crypto prices from **coinmarketcap** in Mac os Apple Numbers #### Tools used -- jxa (javascript for automation) +- jxa (javascript for automation) - Apple Numbers Objective C exposed library - [creat-jxa-app](https://github.com/aheissenberger/macos-jxa-bundler/tree/main/packages/create-jxa-app) ## Usage -- First table in first sheet need to be of the form. +- name your sheet : 'pull-crypto-sheet' +- name table(s): 'pull-crypto-table' +- The table need to be of the form. |CMC coin symbol | price | last refresh | |:--------------:|-------:|-------------:| @@ -24,11 +26,6 @@ In a second part we need to run the jxa script - **Or** download the the js script in Github release and use it from **cli** : `osascript pull-cryptos-prices.js` -## Roadmap - -- [ ] Config in a Numbers table instead of always taking the first -- [ ] Refacto index.js script with more SRP functions - ## Contribution #### To debug : @@ -36,7 +33,7 @@ In a second part we need to run the jxa script ```bash npm run build && npm run run-script ``` -or +or ```bash npm run start &; npm run run-script # on each edit diff --git a/assets/example-crypto-portfolio.numbers b/assets/example-crypto-portfolio.numbers index bc25696..0d16a3b 100755 Binary files a/assets/example-crypto-portfolio.numbers and b/assets/example-crypto-portfolio.numbers differ diff --git a/package.json b/package.json index c6f1eb0..c13b834 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,7 @@ "source": "src/index.js", "dependencies": { "cjxa-scripts": "0.0.13", + "crypto-js": "^4.0.0", "jxabundler": "^1.0.12" }, "scripts": { diff --git a/src/cmcApi.js b/src/cmcApi.js index 93d3e5a..11a4d73 100644 --- a/src/cmcApi.js +++ b/src/cmcApi.js @@ -1,9 +1,9 @@ -import { run, getEnv } from "./utils/shell" +import { run } from "./utils/shell" export default { url: 'pro-api.coinmarketcap.com', headers: { - 'X-CMC_PRO_API_KEY': getEnv('CMC_PRO_API_KEY') + 'X-CMC_PRO_API_KEY': '57c7edd3-62c2-4172-9c9e-1ee3130f52b2' }, defaultsParams: { convert: 'USD', @@ -14,7 +14,7 @@ export default { createUrl (endpoint, params) { let url = `https://${this.url}/${endpoint}?`; - for (const [key, value] of Object.entries({ ...this.defaultsParams, ...params })) { + for (const [key, value] of Object.entries({ ...this.defaultsParams, ...params })) { url += `${key}=${value}&`; } @@ -26,9 +26,13 @@ export default { .join(' '); }, fetch(url, additionalsHeaders = {}) { - return JSON.parse( - run(`curl ${this.createHeaders(additionalsHeaders)} -fsL -G '${url}'`) - ) + try { + return JSON.parse( + run(`curl ${this.createHeaders(additionalsHeaders)} -fsL -G '${url}'`) + ) + } catch(e) { + throw new Error('Error while fetching ' + url) + } }, getQuotes(symbols) { const url = this.createUrl( @@ -40,4 +44,4 @@ export default { return data } -}; \ No newline at end of file +}; diff --git a/src/index.js b/src/index.js index 37c5458..0c89431 100644 --- a/src/index.js +++ b/src/index.js @@ -1,5 +1,6 @@ import cmcApi from './cmcApi'; import { friendlyDate } from './utils/date'; +import NumbersDoc from './model/NumbersDoc'; /** * Only for Macos-x (Less Yosemite) @@ -7,22 +8,23 @@ import { friendlyDate } from './utils/date'; * Needed : * - first sheet with a table of tree columns in the body * Usage : - * - osascript pull-cryptos-prices.js + * - osascript pull-cryptos-prices.js */ (() => { 'use strict'; - const app = Application('Numbers'); - app.includeStandardAdditions = true; - // TODO: use a config table - const table = app.documents()[0].sheets()[0].tables()[0]; + const NbDoc = new NumbersDoc({ + sheetName: 'pull-crypto-sheet', + tableName: 'pull-crypto-table' + }) + const table = NbDoc.findTableByNameWithConfig(); const cellsRange = table.cellRange(); // Simple Helper const testValidValueCell = cell => cell.column().address() === 1 && - cell.row().address() > table.headerRowCount() && - cell.row().address() <= (table.rowCount() - table.footerRowCount()) && - cell.value() != null; + cell.row().address() > table.headerRowCount() && + cell.row().address() <= (table.rowCount() - table.footerRowCount()) && + cell.value() != null; const quotes = cmcApi.getQuotes( cellsRange diff --git a/src/model/NumbersDoc.js b/src/model/NumbersDoc.js new file mode 100644 index 0000000..a73cbc4 --- /dev/null +++ b/src/model/NumbersDoc.js @@ -0,0 +1,28 @@ +export default class NumbersDoc { + constructor(config) { + this.app = Application('Numbers') + this.app.includeStandardAdditions = true + this.config = config + this.document = this.getDocument() + } + + getDocument() { + if (0 in this.app.documents()) { + return this.app.documents()[0] + } else { + throw new Error('No document open') + } + } + + findTableByName({ sheetName, tableName }) { + return this.document + .sheets() + .find(sheet => sheet.name().toLowerCase() === sheetName.toLowerCase()) + .tables() + .find(table => table.name().toLowerCase() === tableName.toLowerCase()) + } + + findTableByNameWithConfig() { + return this.findTableByName(this.config) + } +} diff --git a/src/utils/shell.js b/src/utils/shell.js index 4264400..e0989ec 100644 --- a/src/utils/shell.js +++ b/src/utils/shell.js @@ -5,4 +5,11 @@ export const run = command => { return app.doShellScript(command) } -export const getEnv = key => run(`echo $${key}`) +export const getEnv = key => { + try { + run('source .env') + return run(`echo $${key}`) + } catch(e) { + throw new Error(`impossible to get env ${key}`) + } +}