forked from microlinkhq/metascraper
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdate.js
More file actions
85 lines (75 loc) · 2.79 KB
/
Copy pathdate.js
File metadata and controls
85 lines (75 loc) · 2.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
const isIso = require('is-isodate')
const chrono = require('chrono-node')
/**
* Wrap a rule with validation and formatting logic.
*
* @param {Function} rule
* @return {Function} wrapped
*/
function wrap(rule) {
return ($) => {
let value = rule($)
if (!value) return
// remove whitespace for easier parsing
value = value.trim()
// convert isodates to restringify, because sometimes they are truncated
if (isIso(value)) return new Date(value).toISOString()
// parse number strings as milliseconds
if (/^[0-9]+$/.test(value)) {
const int = parseInt(value, 10)
const date = new Date(int)
return date.toISOString()
}
// try to parse with the built-in date parser
const native = new Date(value)
if (!isNaN(native.getTime())) return native.toISOString()
// try to parse a complex date string
const parsed = chrono.parseDate(value)
if (parsed) return parsed.toISOString()
}
}
/**
* Rules.
*/
module.exports = [
wrap(($) => $('meta[property="article:published_time"]').attr('content')),
wrap(($) => $('meta[name="dc.date"]').attr('content')),
wrap(($) => $('meta[name="DC.date"]').attr('content')),
wrap(($) => $('meta[name="dc.date.issued"]').attr('content')),
wrap(($) => $('meta[name="DC.date.issued"]').attr('content')),
wrap(($) => $('meta[name="dc.date.created"]').attr('content')),
wrap(($) => $('meta[name="DC.date.created"]').attr('content')),
wrap(($) => $('meta[name="DC.Date"]').attr('content')),
wrap(($) => $('meta[name="date"]').attr('content')),
wrap(($) => $('meta[name="dcterms.date"]').attr('content')),
wrap(($) => $('[itemprop="datePublished"]').attr('content')),
wrap(($) => $('time[itemprop*="pubDate"]').attr('datetime')),
wrap(($) => $('time[itemprop*="pubdate"]').attr('datetime')),
wrap(($) => $('[property*="dc:date"]').attr('content')),
wrap(($) => $('[property*="dc:created"]').attr('content')),
wrap(($) => $('time[datetime][pubdate]').attr('datetime')),
wrap(($) => $('meta[name="sailthru.date"]').attr('content')),
wrap(($) => $('meta[property="book:release_date"]').attr('content')),
wrap(($) => $('time[datetime]').attr('datetime')),
wrap(($) => $('[class*="byline"]').text()),
wrap(($) => $('[class*="dateline"]').text()),
wrap(($) => $('[class*="date"]').text()),
wrap(($, url) => {
const regexp = /(\d{4}[\-\/]\d{2}[\-\/]\d{2})/
const match = regexp.exec(url)
if (!match) return
const [ full, string ] = match
const date = new Date(string)
return date.toISOString()
}),
wrap(($) => {
const text = $('[class*="byline"]').text()
if (!text) return
const regexp = /(\w+ \d{2},? \d{4})/
const match = regexp.exec(text)
if (!match) return
const [ full, string ] = match
const date = new Date(string)
return date.toISOString()
}),
]