Last active
May 4, 2019 11:04
-
-
Save probil/95ebb56abf37eb4fc56c5b693021477b to your computer and use it in GitHub Desktop.
Habitica: Import as TODO
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// This scipts allows to import Egghead course as TODO to Habitica | |
// | |
// Step 1: Replace `apiKey` and `userId` with yours (check profile settings on Habitica) | |
// Step 2: Type resource name (egghead/vuemaster/frontendmaster/pluralsight/freecodecamp) in last line of the script | |
// Step 3: Open desired course in browser | |
// Step 4: Open DevTool and execute script in console | |
// Step 5: Check Habitica: new ToDo should be there :) | |
const credentials = { | |
apiKey: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx', | |
userId: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx', | |
}; | |
const nodeListToChecklistItems = nodeList => { | |
return [...nodeList] | |
.map(item => item.innerText) | |
.filter(item => !!item) | |
}; | |
const vueMasteryStrategy = () => { | |
const getText = doc => doc.querySelector('h2.title').innerText; | |
const getChecklistItems = (doc) => { | |
const selectors = doc.querySelectorAll('.lessons-list .list-item-title'); | |
return nodeListToChecklistItems(selectors); | |
}; | |
return { getText, getChecklistItems } | |
}; | |
const eggHeadStrategy = () => { | |
const getText = doc => doc.querySelector('h1').innerText; | |
const getChecklistItems = (doc) => { | |
const selectors = doc.querySelectorAll('.black.ma0.mb1.no-underline.db.pl0.tl.f4.fw5.sans-serif.pointer.lh-text.relative'); | |
return nodeListToChecklistItems(selectors); | |
}; | |
return { getText, getChecklistItems } | |
}; | |
const freeCodeCampStrategy = () => { | |
const getText = doc => doc.title; | |
const getChecklistItems = doc => { | |
const selectors = doc.querySelectorAll('.intro-toc > a > span.list-group-item'); | |
return nodeListToChecklistItems(selectors); | |
}; | |
return { getText, getChecklistItems } | |
}; | |
const frontendMastersStrategy = () => { | |
const getText = doc => doc.querySelector('h1').innerText; | |
const getChecklistItems = doc => { | |
const selectors = doc.querySelectorAll('h3'); | |
return nodeListToChecklistItems(selectors); | |
}; | |
return { getText, getChecklistItems } | |
}; | |
const pluralsightStrategy = () => { | |
const getText = doc => doc.querySelector('h1').innerText + ' ' +doc.querySelector('.course-hero__byline').innerText; | |
const getChecklistItems = (doc) => { | |
const selectors = doc.querySelectorAll('.l-course-page__content a[target="psplayer"]'); | |
return nodeListToChecklistItems(selectors); | |
}; | |
return { getText, getChecklistItems } | |
}; | |
const createStrategy = (strategy) => { | |
const getDesc = (window) => window.location.href; | |
return { getDesc, ...strategy() }; | |
}; | |
const getStrategyByName = name => { | |
const nameToStrategy = { | |
'vuemastery': createStrategy(vueMasteryStrategy), | |
'egghead': createStrategy(eggHeadStrategy), | |
'freecodecamp': createStrategy(freeCodeCampStrategy), | |
'frontendmasters': createStrategy(frontendMastersStrategy), | |
'pluralsight': createStrategy(pluralsightStrategy) | |
}; | |
return nameToStrategy[name]; | |
}; | |
const createTaskOnHabitica = credentials => task => { | |
return fetch('https://habitica.com/api/v3/tasks/user', { | |
method: 'POST', | |
headers: { | |
Accept: 'application/json', | |
'Content-Type': 'application/json', | |
'X-Api-Key': credentials.apiKey, | |
'X-Api-User': credentials.userId, | |
}, | |
body: JSON.stringify(task), | |
}); | |
}; | |
const guid = () => { | |
const s4 = () => Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1); | |
return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4(); | |
}; | |
const makeChecklistItem = text => ({ | |
text, | |
id: guid(), | |
completed: false | |
}); | |
const makeTaskItem = ({ text, notes, checklist, type = 'todo' }) => ({ | |
type, | |
text, | |
notes, | |
checklist, | |
collapseChecklist: true, | |
}); | |
const startImport = async (credentials, strategyName) => { | |
const createTaskForUser = createTaskOnHabitica(credentials); | |
const { getText, getDesc, getChecklistItems } = getStrategyByName(strategyName); | |
const preparedTask = makeTaskItem({ | |
text: getText(document), | |
notes: getDesc(window), | |
checklist: getChecklistItems(document).map(makeChecklistItem), | |
}); | |
return await createTaskForUser(preparedTask); | |
}; | |
startImport(credentials, 'pluralsight'); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment