This JavaScript code imports various modules and sets constants for a project directory, then defines two functions, getLocations and getLocation, which respectively retrieve a list of locations and extract specific data from each location's webpage. The getLocation function makes a GET request to a URL, extracts XPath expressions for elements containing day names, times, and deals, and then maps the results to an object with dotw, time, and deals properties.
var importer = require('../Core');
var util = require('util');
var request = util.promisify(require('request'));
var {JSDOM} = require('jsdom');
var fs = require('fs');
var path = require('path');
var PROFILE_PATH = process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE;
var project = PROFILE_PATH + '/Collections/flagstaff-happy';
var locations, getAllXPath;
function getLocations() {
if(typeof locations !== 'undefined') {
return Promise.resolve(locations);
}
return request('https://web.archive.org/web/20160322001433/http://keepflaghappy.com/happy-hours/friday/')
.then(r => {
const getAllXPath = importer.import("all elements xpath from string")(r.body);
return getAllXPath([
'//a[contains(@href, "by-location")]/@href',
]);
})
.then(r => {
locations = r
.filter(l => l.match(/by-location\/[^#]+/ig))
.map(l => l.includes('archive.org') ? l : 'https://web.archive.org' + l);
return locations;
});
}
function getLocation(l) {
console.log('Downloading ' + l);
return request(l)
.then(r => {
const getAllXPath = importer.import("all elements xpath from string")(r.body);
return getAllXPath([
'//h3[contains(., "Mon") or contains(., "Tue") or contains(., "Wed") or contains(., "Thu") or contains(., "Fri") or contains(., "Sat") or contains(., "Sun")]',
{
dotw: './text()',
time: './following-sibling::p[count(./preceding-sibling::h3)=$i+1]//text()',
deals: './following-sibling::ul[count(./preceding-sibling::h3)=$i+1]//text()'
}
]);
})
.then(r => {
const happy = r.map(l => {
return {
dotw: l.dotw,
time: l.time,
deals: l.deals.join('\n').trim().split(/\s*\n+\s*/ig)
};
});
const name = l.trim().replace(/\/$/ig, '').split('/').pop().replace(/[^a-z0-9-_]/ig, '_');
fs.writeFileSync(path.join(project, name + '.json'), JSON.stringify(happy, null, 4));
return happy;
})
}
$.async();
getLocations()
.then(r => {
return importer.runAllPromises(r.map(l => resolve => {
return getLocation(l)
.then(r => setTimeout(() => resolve(r), 100))
}));
})
.then(r => $.mime({'text/plain': JSON.stringify(r, null, 4)}))
.catch(e => $.sendError(e))
const { JSDOM } = require('jsdom');
const fs = require('fs');
const path = require('path');
const axios = require('axios');
const { createWriteStream } = require('fs');
const { promisify } = require('util');
const { importAll } = require('../Core');
const { sendError, mime } = require('./util');
const importAllXpath = importAll('all elements xpath from string');
const getLocations = async () => {
try {
const response = await axios.get('https://web.archive.org/web/20160322001433/http://keepflaghappy.com/happy-hours/friday/');
const locations = await getLocationsFromResponse(response.data);
return locations;
} catch (error) {
console.error('Error fetching locations:', error);
throw error;
}
};
const getLocationsFromResponse = async (response) => {
const getAllXPath = importAllXpath(response);
const hrefs = await getAllXPath([
'//a[contains(@href, "by-location")]/@href',
]);
return hrefs
.filter(href => href.match(/by-location\/[^#]+/ig))
.map(href => href.includes('archive.org')? href : 'https://web.archive.org' + href);
};
const getLocation = async (location) => {
try {
console.log('Downloading'+ location);
const response = await axios.get(location);
const allElementsXpath = importAllXpath(response.data);
const data = await allElementsXpath([
'//h3[contains(., "Mon") or contains(., "Tue") or contains(., "Wed") or contains(., "Thu") or contains(., "Fri") or contains(., "Sat") or contains(., "Sun")]',
{
dotw: './text()',
time: './following-sibling::p[count(./preceding-sibling::h3)=$i+1]//text()',
deals: './following-sibling::ul[count(./preceding-sibling::h3)=$i+1]//text()'
}
]);
const happy = data.map((l, i) => {
return {
dotw: l.dotw,
time: l.time,
deals: l.deals.join('\n').trim().split(/\s*\n+\s*/ig)
};
});
const name = location.trim().replace(/\/$/ig, '').split('/').pop().replace(/[^a-z0-9-_]/ig, '_');
const writeStream = createWriteStream(path.join(process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE, 'Collections', 'flagstaff-happy', name + '.json'));
writeStream.write(JSON.stringify(happy, null, 4));
await new Promise(resolve => writeStream.end(resolve));
return happy;
} catch (error) {
console.error('Error fetching location:', error);
throw error;
}
};
const runPromises = async (locations) => {
const promises = locations.map((location, index) => {
return new Promise(resolve => {
getLocation(location)
.then(data => setTimeout(() => resolve(data), 100))
.catch(error => {
console.error(`Error fetching location ${location}:`, error);
resolve(null);
});
});
});
return Promise.all(promises);
};
const main = async () => {
try {
const locations = await getLocations();
const happyHours = await runPromises(locations);
const result = happyHours
.filter(happyHour => happyHour!== null)
.map(happyHour => JSON.stringify(happyHour, null, 4));
return { result };
} catch (error) {
console.error('Error:', error);
throw error;
}
};
main()
.then(result => {
mime({ 'text/plain': result.result.join('\n') });
})
.catch(error => sendError(error));var importer = require('../Core');
var util = require('util');
var request = util.promisify(require('request'));
var {JSDOM} = require('jsdom');
var fs = require('fs');
var path = require('path');
var PROFILE_PATH = process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE;
var project = PROFILE_PATH + '/Collections/flagstaff-happy';
Core module, util, request, jsdom, fs, and path.var locations, getAllXPath;
function getLocations() {
//...
}
function getLocation(l) {
//...
}
getLocations and getLocation.locations variable is declared, but not initialized.function getLocations() {
if(typeof locations!== 'undefined') {
return Promise.resolve(locations);
}
return request('https://web.archive.org/web/20160322001433/http://keepflaghappy.com/happy-hours/friday/')
.then(r => {
const getAllXPath = importer.import('all elements xpath from string')(r.body);
return getAllXPath([
'//a[contains(@href, "by-location")]/@href',
]);
})
.then(r => {
locations = r
.filter(l => l.match(/by-location\/[^#]+/ig))
.map(l => l.includes('archive.org')? l : 'https://web.archive.org' + l);
return locations;
});
}
getLocations function checks if the locations variable is already defined. If it is, it returns a resolved promise with the value of locations.locations is not defined, it makes a GET request to a specific URL, extracts XPath expressions for links containing "by-location" in their href attributes, and then filters and maps the results to an array of URLs.locations variable.function getLocation(l) {
console.log('Downloading'+ l);
return request(l)
.then(r => {
const getAllXPath = importer.import('all elements xpath from string')(r.body);
return getAllXPath([
'//h3[contains(., "Mon") or contains(., "Tue") or contains(., "Wed") or contains(., "Thu") or contains(., "Fri") or contains(., "Sat") or contains(., "Sun")]',
{
dotw: './text()',
time: './following-sibling::p[count(./preceding-sibling::h3)=$i+1]//text()',
deals: './following-sibling::ul[count(./preceding-sibling::h3)=$i+1]//text()'
}
]);
})
.then(r => {
const happy = r.map(l => {
return {
dotw: l.dotw,
time: l.time,
deals: l.deals.join('\n').trim().split(/\s*\n+\s*/ig)
};
});
//...
});
}
getLocation function makes a GET request to a specific URL, extracts XPath expressions for elements containing day names, times, and deals, and then maps the results to an object with dotw, time, and deals properties.happy variable is an array of objects containing the extracted data.