-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathwp-xml-reader.js
More file actions
158 lines (137 loc) · 4.1 KB
/
wp-xml-reader.js
File metadata and controls
158 lines (137 loc) · 4.1 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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
// external libs
const fs = require("fs")
const path = require("path")
const xml2js = require("xml2js").parseString
const when = require("when")
// internal libs
const helpers = require("./helpers")
class WPXMLReader {
constructor(file) {
this.file = file
// original parsed contents
this.original_contents = null
// final contents
this.contents = this.get_file()
// final parsed contents (keep original structure)
this.mutable_contents = null
}
query(options = {}) {
return when.promise((resolve, reject) => {
this.parse_xml()
.then(data => {
let result = this.extract(data, options)
resolve(result)
})
.catch(reject)
})
}
get_file() {
let file_path = path.join(process.cwd(), this.file)
return fs.readFileSync(file_path, { encoding: "utf-8" })
}
parse_xml() {
return when.promise((resolve, reject) => {
xml2js(this.contents, { trim: true }, (err, result) => {
return err ? reject(err) : resolve(result)
})
})
}
extract_item(item, options) {
// conditions
if (options.conditions.length) {
let result = this.extract_item_conditions(item, options)
this.push_to_mutable_contents_if_possible(result, item)
return result
}
// attributes
if (options.attributes.length) {
let result = this.extract_item_attributes(item, options)
this.push_to_mutable_contents_if_possible(result, item)
return result
}
// default item value
return {}
}
push_to_mutable_contents_if_possible(response, original_item) {
if (Object.keys(response).length > 0) {
// keep only one original reference
this.mutable_contents.rss.channel[0].item.push(original_item)
}
}
extract_item_conditions(item, options) {
let result = {}
options.conditions.forEach(condition => {
const type = helpers.get_condition_type_for_key(condition.name)
let value = helpers[`get_result_from_${type}_condition`](item, condition)
if (value !== null) {
// attributes filters
if (condition.attributes && condition.attributes.length) {
result = this.extract_item_attributes(value, condition)
} else {
result = value
}
}
})
return result
}
extract_item_attributes(item, options) {
let result = {}
options.attributes.forEach(attribute => {
const attribute_type = helpers.get_attribute_type_for_key(attribute)
result[attribute] = helpers[`get_${attribute_type}_value_from_key`](
item,
attribute,
options
)
})
return result
}
extract(data, options) {
// default options
options = Object.assign(
{},
{ row_index: null, attributes: [], conditions: [] },
options
)
// immutable snapshot of original parsed contents
this.original_contents = JSON.parse(JSON.stringify(data))
// mutable snapshot of original parsed contents
this.mutable_contents = JSON.parse(JSON.stringify(data))
// cleanup all items to keep only root elements
this.mutable_contents.rss.channel[0].item = []
// take care of first channel only
const channel = data.rss.channel[0]
let response = []
// item row index position
if (options.row_index !== null) {
// response with row_index
response = this.extract_item(channel.item[options.row_index], options)
return [response]
}
// extract all items
channel.item.forEach(item => {
response.push(this.extract_item(item, options))
})
// response
response = response.filter(r => {
return Object.keys(r).length > 0
})
// write response
if (options.write_response_logs === true) {
this.write(response, options.output_filename)
}
return response
}
write(response, filename = "response") {
let output_path_file = path.join(
"datas",
"output",
[filename, "json"].join(".")
)
fs.writeFile(output_path_file, JSON.stringify(response, null, 2), err => {
if (err) throw err
console.log("The file has been saved!")
})
}
}
module.exports = WPXMLReader