flowerpicker 0.1.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -12
- package/convert.js +36 -0
- package/index.js +16 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@ Currently only Jubeat is supported as far as games go.
|
|
|
9
9
|
|
|
10
10
|
Below is some example code with their explanations to get started:
|
|
11
11
|
```js
|
|
12
|
-
import FlowerPicker from "
|
|
12
|
+
import FlowerPicker, { convert } from "flowerpicker";
|
|
13
13
|
|
|
14
14
|
// The constructor has 2 parameters: The url to the server dashboard, and your cookie to said dashboard
|
|
15
15
|
const SESSION_COOKIE = "abc123";
|
|
@@ -25,6 +25,11 @@ await picker.setupJubeatScoreLog();
|
|
|
25
25
|
// This is an example of how to export the score log from the package to a text file
|
|
26
26
|
// Temporarily incredibly scuffed as I get the basic functionality up and running
|
|
27
27
|
fs.writeFileSync(`./data/data-${Date.now()}-${picker._gameScoreLogs.jubeat.length}.json`, JSON.stringify(picker._gameScoreLogs.jubeat, null, 2) , 'utf-8');
|
|
28
|
+
|
|
29
|
+
// To convert an export to a tachi-compatible JSON, you can use the convert module
|
|
30
|
+
// The first parameter is the JSON file, the second what you want the service to show up as imported from
|
|
31
|
+
const convertedJubeat = await picker.convert.jubeatToTachiCompat(JSON.parse(fs.readFileSync(fileName, 'utf-8')), "FlowerPicker-FLO");
|
|
32
|
+
fs.writeFileSync('converted.json', JSON.stringify(convertedJubeat, null, 2), 'utf-8');
|
|
28
33
|
```
|
|
29
34
|
|
|
30
35
|
## Supported data (Accessible via the package)
|
|
@@ -40,17 +45,17 @@ The following account information is accessible via this package:
|
|
|
40
45
|
|
|
41
46
|
The following games may not be updated by me, PRs may be reviewed and accepted
|
|
42
47
|
|
|
43
|
-
| Game | Profile Information[^1] | Score Log | Game Specific Data |
|
|
44
|
-
| :------------------------------ | :---------------------: | :-------: | :----------------: |
|
|
45
|
-
| beatmania IIDX | ❌ | ❌ | ❌ |
|
|
46
|
-
| DanceDanceRevolution | ❌ | ❌ | ❌ |
|
|
47
|
-
| GITADORA | ❌ | ❌ | ❌ |
|
|
48
|
-
| Jubeat | ⚠️[^2] | ✅ | ❌[^3] |
|
|
49
|
-
| NOSTALGIA | ❌ | ❌ | ❌ |
|
|
50
|
-
| pop'n music | ❌ | ❌ | ❌ |
|
|
51
|
-
| REFLEC BEAT | ❌ | ❌ | ❌ |
|
|
52
|
-
| Sound Voltex | ❌ | ❌ | ❌ |
|
|
53
|
-
| PASELI Charging Machine (Soon™️) | ❌ | ❌ | ❌ |
|
|
48
|
+
| Game | Profile Information[^1] | Score Log | Game Specific Data | Tachi Export |
|
|
49
|
+
| :------------------------------ | :---------------------: | :-------: | :----------------: | :----------: |
|
|
50
|
+
| beatmania IIDX | ❌ | ❌ | ❌ | ❌ |
|
|
51
|
+
| DanceDanceRevolution | ❌ | ❌ | ❌ | ❌ |
|
|
52
|
+
| GITADORA | ❌ | ❌ | ❌ | ❌ |
|
|
53
|
+
| Jubeat | ⚠️[^2] | ✅ | ❌[^3] | ✅ |
|
|
54
|
+
| NOSTALGIA | ❌ | ❌ | ❌ | ❌ |
|
|
55
|
+
| pop'n music | ❌ | ❌ | ❌ | ❌ |
|
|
56
|
+
| REFLEC BEAT | ❌ | ❌ | ❌ | ❌ |
|
|
57
|
+
| Sound Voltex | ❌ | ❌ | ❌ | ❌ |
|
|
58
|
+
| PASELI Charging Machine (Soon™️) | ❌ | ❌ | ❌ | ❌ |
|
|
54
59
|
|
|
55
60
|
[^1]: Profile information includes profile id(s) on the site, game display name, and unlock statuses
|
|
56
61
|
|
package/convert.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export function jubeatToTachiCompat(jubeatDataJSON, service) {
|
|
2
|
+
// Thank you to https://gist.github.com/Meta-link/d01c15fc56a277becc7d67a7c1dccfa2 for the tachi structure
|
|
3
|
+
let tachiCompJson = {
|
|
4
|
+
meta: {
|
|
5
|
+
"game": "jubeat",
|
|
6
|
+
"playtype": "Single",
|
|
7
|
+
"service": service ? service : "FlowerPicker",
|
|
8
|
+
},
|
|
9
|
+
scores: []
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
jubeatDataJSON.forEach((item) => {
|
|
13
|
+
tachiCompJson.scores.push({
|
|
14
|
+
"score": Number(item.songNumberScore),
|
|
15
|
+
"lamp": item.songClearStatus.toUpperCase(), // Values returned by the scraper are the same, just not in uppercase
|
|
16
|
+
"musicRate": Number(item.songMusicRate.replace('%', '')), // Jubeat specific field :)
|
|
17
|
+
"matchType": "inGameID",
|
|
18
|
+
"identifier": item.songID,
|
|
19
|
+
"difficulty": (item.songIsHardPlay ? "HARD " : "") + item.songChart.split(' ')[0], // Returns "ABC 1.1", so this shouldn't be a problem
|
|
20
|
+
"timeAchieved": Math.floor(new Date(item.songTimestampString).getTime()),
|
|
21
|
+
"judgements": {
|
|
22
|
+
"perfect": Number(item.scoreData.perfects),
|
|
23
|
+
"great": Number(item.scoreData.greats),
|
|
24
|
+
"good": Number(item.scoreData.goods),
|
|
25
|
+
"poor": Number(item.scoreData.poors),
|
|
26
|
+
"miss": Number(item.scoreData.misses)
|
|
27
|
+
},
|
|
28
|
+
"optional": {
|
|
29
|
+
"maxCombo": Number(item.songMaxCombo),
|
|
30
|
+
"musicBar": item.judgeBar
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
return tachiCompJson;
|
|
36
|
+
}
|
package/index.js
CHANGED
|
@@ -94,17 +94,17 @@ class FlowerPicker {
|
|
|
94
94
|
poors: this._trimToNumber($(songTrDiv).find("div:contains('Poors')").text()),
|
|
95
95
|
misses: this._trimToNumber($(songTrDiv).find("div:contains('Misses')").text()),
|
|
96
96
|
};
|
|
97
|
+
let judgeBar = $(songTrDiv).find(".jubeat-bars").attr("data-jubeat-judge").split(" ").map(Number);
|
|
97
98
|
let onPage = i;
|
|
98
99
|
|
|
99
100
|
scoreArray.push({
|
|
100
101
|
playID, songTitle, songID, songDifficultyID, songIsHardPlay, songChart,
|
|
101
102
|
songLetterScore, songNumberScore, songMusicRate, songJubility,
|
|
102
103
|
songClearStatus, songMaxCombo, songTimestampString,
|
|
103
|
-
arcadePlayedAtString, arcadePlayedAtID, machinePlayedWithString, scoreData, onPage
|
|
104
|
+
arcadePlayedAtString, arcadePlayedAtID, machinePlayedWithString, scoreData, judgeBar, onPage
|
|
104
105
|
});
|
|
105
106
|
});
|
|
106
107
|
|
|
107
|
-
scoreArray.reverse();
|
|
108
108
|
this._gameScoreLogs.jubeat.push(...scoreArray); // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
|
|
109
109
|
})
|
|
110
110
|
// FIXME: This one as well
|
|
@@ -113,6 +113,17 @@ class FlowerPicker {
|
|
|
113
113
|
});
|
|
114
114
|
}
|
|
115
115
|
|
|
116
|
+
async getProfileId(game, id) {
|
|
117
|
+
const res = await this._fetchWithCookie(`${this._baseURL}/game/${game}/profile/${id}`);
|
|
118
|
+
const html = await res.text();
|
|
119
|
+
const $ = cheerio.load(html);
|
|
120
|
+
|
|
121
|
+
const href = $("small > a").first().attr("href");
|
|
122
|
+
if (!href) return null;
|
|
123
|
+
|
|
124
|
+
return href.split("/")[4] ?? null;
|
|
125
|
+
}
|
|
126
|
+
|
|
116
127
|
async _fetchWithCookie(url) {
|
|
117
128
|
return fetch(url, {
|
|
118
129
|
headers: {
|
|
@@ -201,7 +212,7 @@ class FlowerPicker {
|
|
|
201
212
|
let walletID = theElement.attr('href')?.split('/').pop();
|
|
202
213
|
let walletBalance = this._trimToNumber(theElement.children('.list-group-item-text').text());
|
|
203
214
|
|
|
204
|
-
walletIDs.push({arcadeName, walletID, walletBalance});
|
|
215
|
+
walletIDs.push({ arcadeName, walletID, walletBalance });
|
|
205
216
|
});
|
|
206
217
|
|
|
207
218
|
return walletIDs;
|
|
@@ -213,4 +224,5 @@ class FlowerPicker {
|
|
|
213
224
|
}
|
|
214
225
|
}
|
|
215
226
|
|
|
216
|
-
export default FlowerPicker;
|
|
227
|
+
export default FlowerPicker;
|
|
228
|
+
export * as convert from "./convert.js";
|