summaryrefslogtreecommitdiff
path: root/ext/bg
diff options
context:
space:
mode:
authorAlex Yatskov <alex@foosoft.net>2016-10-15 17:30:49 -0700
committerAlex Yatskov <alex@foosoft.net>2016-10-15 17:30:49 -0700
commit6898de4ca65b3313d260a993f0f4e88d043152b6 (patch)
tree3dbef74f23b87de3988637d7346efd8ca896b06e /ext/bg
parent66fe5018cf7a7b905ca30648e94308131a65d5db (diff)
WIP
Diffstat (limited to 'ext/bg')
-rw-r--r--ext/bg/js/ankiweb.js111
1 files changed, 102 insertions, 9 deletions
diff --git a/ext/bg/js/ankiweb.js b/ext/bg/js/ankiweb.js
index aabd3d2a..4b5652cb 100644
--- a/ext/bg/js/ankiweb.js
+++ b/ext/bg/js/ankiweb.js
@@ -17,33 +17,126 @@
*/
class AnkiWeb {
- constructor() {
+ constructor(username, password) {
+ this.username = username;
+ this.password = password;
+ this.noteInfo = null;
+ this.logged = false;
}
addNote(note) {
+ return Promise.resolve(true);
}
canAddNotes(notes) {
+ return Promise.resolve([]);
}
getDeckNames() {
+ return this.retrieve().then(info => info.deckNames);
}
getModelNames() {
+ return this.retrieve().then(info => info.models.map(m => m.name));
}
getModelFieldNames(modelName) {
+ return this.retrieve().then(info => {
+ const model = info.models.find(m => m.name === modelName);
+ return model ? model.fields : [];
+ });
+ }
+
+ retrieve() {
+ if (this.noteInfo !== null) {
+ return Promise.resolve(this.noteInfo);
+ }
+
+ return this.authenticate().then(() => {
+ return AnkiWeb.scrape();
+ }).then(({deckNames, models}) => {
+ this.noteInfo = {deckNames, models};
+ return this.noteInfo;
+ });
+ }
+
+ authenticate() {
+ if (this.logged) {
+ return Promise.resolve(true);
+ }
+
+ return AnkiWeb.logout().then(() => {
+ return AnkiWeb.login(this.username, this.password);
+ }).then(() => {
+ this.logged = true;
+ return true;
+ });
}
getStatus() {
- return this.getVersion().then(version => {
- if (version === null) {
- return 'disconnected';
- } else if (version === this.apiVersion) {
- return 'ready';
- } else {
- return 'mismatch';
- }
+ return 'ready';
+ }
+
+ static scrape() {
+ return new Promise((resolve, reject) => {
+ $.get('https://ankiweb.net/edit/', (data, status) => {
+ if (status !== 'success') {
+ reject('scrape failed');
+ return;
+ }
+
+ const modelsJson = JSON.parse(/editor\.models = (.*}]);/.exec(data)[1]);
+ if (!modelsJson) {
+ reject('failed to scrape model data');
+ return;
+ }
+
+ const decksJson = JSON.parse(/editor\.decks = (.*}});/.exec(data)[1]);
+ if (!decksJson) {
+ reject('failed to scrape deck data');
+ return;
+ }
+
+ const deckNames = Object.keys(decksJson).map(d => decksJson[d].name);
+ const models = [];
+ for (const modelJson of modelsJson) {
+ models.push({
+ name: modelJson.name,
+ id: modelJson.id,
+ fields: modelJson.flds.map(f => f.name)
+ });
+ }
+
+ resolve({deckNames, models});
+ });
+ });
+ }
+
+ static login(username, password) {
+ return new Promise((resolve, reject) => {
+ $.post('https://ankiweb.net/account/login', {username, password, submitted: 1}, (data, status) => {
+ if (status !== 'success') {
+ if (data.includes('class="mitem"')) {
+ resolve();
+ } else {
+ reject('authentication failed');
+ }
+ } else {
+ reject('login failed');
+ }
+ });
+ });
+ }
+
+ static logout() {
+ return new Promise((resolve, reject) => {
+ $.get('https://ankiweb.net/account/logout', (data, status) => {
+ if (status === 'success') {
+ resolve();
+ } else {
+ reject('logout failed');
+ }
+ });
});
}
}