Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

melon-chart-api

Package Overview
Dependencies
Maintainers
1
Versions
6
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

melon-chart-api - npm Package Compare versions

Comparing version 1.1.1 to 1.1.3

.eslintrc.js

26

defaults.js
/**
* Default constants.
*/
* Default constants.
*/
const START_DATE_KEY = 'startDay';

@@ -16,5 +16,7 @@ const END_DATE_KEY = 'endDay';

artistNames: '.wrap_song_info .rank02 span',
albumNames: '.wrap_song_info .rank03 a'
albumNames: '.wrap_song_info .rank03 a',
};
const MESSAGE_FN = function() { console.log('no messageFn is provied') };
const MESSAGE_FN = function MESSAGE_FN() {
console.log('no messageFn is provied');
};

@@ -34,20 +36,6 @@ function populateOptions(options) {

messageFn: options.messageFn || MESSAGE_FN,
date: options.date || new Date()
date: options.date || new Date(),
};
}
/*
3 different options:
Daily: { moved: Y, index: 0|1 }
Weekly: { moved: Y, index: 0|1, startDay: date, endDay: date, isFirstDate: true|false, isLastDate: true|fasle }
Monthly: { moved: Y, index: 0|1, rankMonth: 2017/03, isFirstDate: true|false, isLastDate: true|false }
* There is no option to get daily of another day.
* For "monthly", `isLastDate` will be alwasy set to true.
* The entire part of URL should have not been a default b/c it is NOT a constant?
*/
module.exports = populateOptions;

@@ -1,146 +0,17 @@

const fetch = require('node-fetch');
const cheerio = require('cheerio');
const startOfWeek = require('date-fns/start_of_week');
const endOfWeek = require('date-fns/end_of_week');
const subWeeks = require('date-fns/sub_weeks');
const isThisWeek = require('date-fns/is_this_week');
const isThisMonth = require('date-fns/is_this_month');
const isFuture = require('date-fns/is_future');
const subMonths = require('date-fns/sub_months');
const formatDate = require('date-fns/format');
const parseDate = require('date-fns/parse');
const queryString = require('querystring');
const parse = require('url-parse');
const populateOptions = require('./defaults');
/**
* Date parsing functions.
*/
const dateRange = (function(date) {
const dateObj = parseDate(date);
const format = 'YYYYMMDD';
const {
dateRange,
scrapeMelon,
composeUrl,
} = require('./helpers');
return {
daily: function() {
let startDate = dateObj;
let endDate = dateObj;
if (isFuture(dateObj)) {
startDate = new Date();
endDate = new Date();
};
return {
'start': formatDate(startDate, format),
'end': formatDate(endDate, format)
};
},
weekly: function() {
const option = { weekStartsOn: 1 };
const includedDate = (isThisWeek(dateObj, option)) ? subWeeks(dateObj, 1) : dateObj;
const startDate = startOfWeek(includedDate, option);
const endDate = endOfWeek(includedDate, option);
return {
'start': formatDate(startDate, format),
'end': formatDate(endDate, format)
};
},
monthly: function() {
const monthFormat = 'YYYYMM';
let startDate = dateObj;
let endDate = dateObj;
if (isThisMonth(dateObj) || isFuture(dateObj)) {
const lastMonth = subMonths(new Date(), 1);
startDate = lastMonth;
endDate = lastMonth;
};
return {
'start': formatDate(startDate, monthFormat),
'end': formatDate(endDate, monthFormat)
};
},
}
});
/**
* URL parsing functions.
*/
function makeUrlString(parsed) {
return 'http://' + parsed.hostname + parsed.pathname + '?' + parsed.query;
}
function composeUrl(period, dates, options) {
// Base attributes which all charts need.
let url = options.url;
const decoded = {};
decoded[options.indexKey] = options.cutLine > 50 ? 0 : 1;
decoded[options.movedKey] = 'Y';
if (period === 'week') {
url = options.url.replace('day', 'week');
decoded[options.startDateKey] = dates.start.toString();
decoded[options.endDateKey] = dates.end.toString();
decoded[options.isFirstDateKey] = false;
decoded[options.isLastDateKey] = false;
}
if (period === 'month') {
url = options.url.replace('day', 'month');
decoded[options.rankMonthKey] = dates.start.toString();
}
const parsed = parse(url);
const encoded = queryString.stringify(decoded);
parsed.query = encoded;
return makeUrlString(parsed);
};
/**
* HTML parsing functions.
*/
function extractChart(htmlText, xpath) {
const $ = cheerio.load(htmlText);
function trimText(i, el) {
return $(this).text().trim();
}
const songTitles = $(xpath.songTitles).map(trimText).get();
const artistNames = $(xpath.artistNames).map(trimText).get();
const albumNames = $(xpath.albumNames).map(trimText).get();
return songTitles.map(function(el, i) {
return {
'rank': (i + 1).toString(),
'title': el,
'artist': artistNames[i],
'album': albumNames[i]
}
});
};
function fetchHtmlText(url) {
return fetch(url).then(resp => resp.text());
};
function createMessageData(chartData, cutLine, dates) {
return {
data: chartData.slice(0, cutLine),
dates: dates
};
}
/**
* Melon class.
*/
* Melon class.
*/
function Melon(date, options) {
const opts = populateOptions(options);
const dateManager = dateRange(date);
const cutLine = opts.cutLine;
const xpath = opts.xpath;
const scrapeMelon = function(url, dates) {
return fetchHtmlText(url)
.then(function(htmlText) {
const chartData = extractChart(htmlText, xpath);
return createMessageData(chartData, cutLine, dates);
});
};
return {
daily: function() {
daily() {
// NOTE: Dates are not needed for daily chart

@@ -152,19 +23,19 @@ // as Melon Music Chart does not provide previous daily charts.

const url = composeUrl(period, dates, opts);
return scrapeMelon(url, dates);
return scrapeMelon(url, dates, opts);
},
weekly: function() {
weekly() {
const dates = dateManager.weekly();
const period = 'week';
const url = composeUrl(period, dates, opts);
return scrapeMelon(url, dates);
return scrapeMelon(url, dates, opts);
},
monthly: function() {
monthly() {
const dates = dateManager.monthly();
const period = 'month';
const url = composeUrl(period, dates, opts);
return scrapeMelon(url, dates);
}
}
return scrapeMelon(url, dates, opts);
},
};
}
module.exports = Melon
module.exports = Melon;
{
"name": "melon-chart-api",
"version": "1.1.1",
"version": "1.1.3",
"description": "Melon Music Chart API",
"repository": "https://github.com/hyunchel/melon-chart-api",
"main": "index.js",
"scripts": {
"test": "ava"
"test": "ava",
"lint": "eslint ."
},

@@ -12,3 +14,2 @@ "author": "Hyunchel Kim <hyunchel.inbox@gmail.com> (http://hyunchel.me)",

"dependencies": {
"ava": "^0.19.1",
"cheerio": "^0.22.0",

@@ -19,3 +20,9 @@ "date-fns": "^1.28.3",

"url-parse": "^1.1.8"
},
"devDependencies": {
"ava": "^0.19.1",
"eslint": "^4.6.1",
"eslint-config-airbnb-base": "^12.0.0",
"eslint-plugin-import": "^2.7.0"
}
}

@@ -16,3 +16,3 @@ # Melon Chart API

```js
const Melon from 'melon-chart-api';
const Melon = require('melon-chart-api');
Melon('04/24/2017', { cutLine: 5 }).daily().then(chartData => {

@@ -19,0 +19,0 @@ console.log(chartData);

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc