UNPKG

eksi-sozluk

Version:
251 lines (223 loc) 5.17 kB
const axios = require('axios') const setCookie = require('set-cookie-parser') const qs = require('querystring') const { URLS } = require('../constants') /** * Draft entry. */ class DraftEntry { /** * Entry author. * * @type {string} */ author /** * Author URL. * * @type {string} */ authorUrl /** * Entry content. * * @type {string} */ content /** * Entry title. * * @type {string} */ title /** * Title ID. * * @type {number} */ titleId /** * Title slug. * * @type {number} */ titleSlug /** * Entry title endpoint. * * @type {string} */ titleEndpoint /** * Entry title URL. * * @type {string} */ titleUrl /** * Create draft entry. * * @param {object} request Axios client. * @param {string} title Title. * @param {string} cookies Cookie string. */ constructor (request, title, cookies) { this.title = title this._request = request this._cookies = cookies this._isRetrieved = false } /** * Parse properties with given document. * * @param {object} $ Cheerio document. * @ignore */ serialize ($) { const username = $('div.mobile-notification-icons ul li a').attr('title') this.titleId = $('#title').data('id') this.titleUrl = URLS.BASE + $('h1#title a').attr('href') this.titleSlug = $('#title').data('slug') this.titleEndpoint = $('#title').data('slug') + '--' + this.titleId this.author = username this.authorUrl = URLS.USER + username this.content = $('#draft-content').text() // mark as retrieved this._isRetrieved = true } /** * Retrieve the draft entry. * * @returns {Promise} Promise. */ retrieve () { return new Promise((resolve, reject) => { const requestOptions = { endpoint: `/?q=${this.title}`, cookie: this._cookies } this._request(requestOptions, $ => { this.serialize($) resolve() }) }) } /** * Publish the draft entry. * * @returns {Promise} Promise. */ publish () { return new Promise((resolve, reject) => { if (!this._isRetrieved) { return reject(new Error('Retrieve first.')) } axios .get(`${URLS.BASE}/${this.titleEndpoint}`, { headers: { Cookie: this._cookies } }) .then(res => { // parse csrf token and cookies const csrfRegex = new RegExp( '(?<=input name="__RequestVerificationToken" type="hidden" value=")(.*)(?=" />)', 'u' ) const csrfToken = csrfRegex.exec(res.data)[0] const cookies = setCookie.parse(res.headers['set-cookie'], { map: true }) const csrfTokenInCookies = cookies.__RequestVerificationToken.value return { csrfToken, csrfTokenInCookies } }) .then(async ({ csrfToken, csrfTokenInCookies }) => { // create entry const _res = await axios({ url: URLS.ENTRY_CREATE, method: 'POST', headers: { Cookie: `__RequestVerificationToken=${csrfTokenInCookies}; ${this._cookies}` }, data: qs.stringify({ __RequestVerificationToken: csrfToken, Title: this.title, Content: this.content }) }) return _res }) .then(res => { resolve() }) }) } /** * Change the draft entry content. * * @param {string} content Draft entry content. * @returns {Promise} Promise. */ change (content) { return new Promise((resolve, reject) => { if (!this._isRetrieved) { return reject(new Error('Retrieve first.')) } const requestBody = { title: this.title, content } const config = { headers: { 'x-requested-with': 'XMLHttpRequest', cookie: this._cookies } } axios .post( `${URLS.BASE}/${this.titleEndpoint}/savedraft`, qs.stringify(requestBody), config ) .then(res => { if (res.data.Success) { this.content = res.data.SavedDraftContent resolve() } else { reject(new Error('An unknown error occurred.')) } }) }) } /** * Dismiss the draft entry. * * @returns {Promise} Promise. */ dismiss () { return new Promise((resolve, reject) => { if (!this._isRetrieved) { return reject(new Error('Retrieve first.')) } const requestBody = { title: this.title } const config = { headers: { 'x-requested-with': 'XMLHttpRequest', cookie: this._cookies } } axios .post( `${URLS.BASE}/${this.titleEndpoint}/deletedraft`, qs.stringify(requestBody), config ) .then(res => { resolve() }) }) } } module.exports = DraftEntry