-
Notifications
You must be signed in to change notification settings - Fork 0
/
liquid-earth.js
219 lines (181 loc) · 6.44 KB
/
liquid-earth.js
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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
/**
* @fileoverview Liquid Earth: location survey of relevant Liquid Vote agenda items.
*
* Usage:
* // Default behavior
* node liquid-earth.js
*
*/
require('chromedriver');
const fetch = require('node-fetch');
const _ = require('lodash');
const addStreetAddressLocations = require("./src/addStreetAddressLocations.js");
const addProperNameLocations = require("./src/addProperNameLocations.js");
const {
Builder,
By,
until
} = require('selenium-webdriver');
const {
closeIntroScript,
openPanel,
selectInput,
toggleAll,
fly,
topResult,
clickTopResult,
hideSearch,
clearSearch,
toggleDimension
} = require("./src/webcomponent-selectors.js");
//Empty array for output
const locationData = [];
const pauseTime = 10000;
const startupTime = 30000;
//Set up driver
var driver = new Builder()
.forBrowser('chrome')
.build();
//Initial get, wait for load, exit intro, and toggleAll feature layers
driver.get('https://earth.google.com/web/')
.then(driver.sleep(10000))
.then( _ => {
driver.executeScript(closeIntroScript);
driver.executeScript(toggleAll);
});
//Collect urls for app linking
function getEarthUrl(fullAddress, index, collection) {
//we're done, store the data
//if(locationData.length === collection.length){
//TODO: Put the data in a useful place
//return;
//}
//store the data
driver.getCurrentUrl().then((url) => {
//this is the initial search url
locationData[index] = {
address: fullAddress,
earthSearchUrl: url
}
})
//after a 1 second sleep
//We're able to get the search result url
driver.sleep(1000);
driver.getCurrentUrl().then((url) => {
locationData[index] = Object.assign({
earthFoundUrl: url
},
locationData[index])
})
//console.log("get earth url");
//console.log(locationData);
}
function collectGoogleEarthUrl(bill, index, collection){
if(!bill.properNamelocation && !bill.streetAddresses.length){
return null;
}
let city = ', San Francisco'
let address = bill.properNameLocation || bill.streetAddresses[0];
console.log(bill.properNameLocation, bill.streetAddresses);
let fullAddress = address + city;
return new Promise((accept, reject) => {
//clear search, open panel, make sure search is clear, as user could edit
driver.executeScript(clearSearch)
.then( _ => driver.executeScript(openPanel) )
.then( _ => {
let activeElement = driver.switchTo().activeElement();
if (!activeElement.getText() === "") {
console.log('active element text');
console.log(activeElement.getText());
activeElement.clear();
}
})
.then( _ => driver.switchTo().activeElement().sendKeys(fullAddress, '\uE006'))
.then( _ => console.log(`Navigating to ${fullAddress} - ${bill.title} - ${bill.date} - ${bill.streetAddresses}`))
//collect url after we've zoomed in
//add to bill, and return bill
.then(driver.sleep(pauseTime - 1000))
.then(_ => driver.getCurrentUrl())
.then(url => bill.googleEarthUrl = {location: fullAddress, url:url})
.then(url => accept(bill));
})
}
//Navigate to each location
function navigate(bill, index, collection) {
let city = ', San Francisco'
let address = bill.properNameLocation || bill.streetAddresses[0];
let fullAddress = address + city;
//clear search, open panel, make sure search is clear, as user could edit
driver.executeScript(clearSearch)
.then( _ => driver.executeScript(openPanel) )
.then( _ => {
let activeElement = driver.switchTo().activeElement();
if (!activeElement.getText() === "") {
console.log('active element text');
console.log(activeElement.getText());
activeElement.clear();
}
})
//collect url after we've zoomed in
//add to bill, and return bill
return driver.switchTo().activeElement().sendKeys(fullAddress, '\uE006')
.then(driver.sleep(pauseTime - 1000))
.then(_ => driver.getCurrentUrl())
.then(url => bill[googleEarthUrlurl] = url);
//this chain is more for visual survey rather than collection
//It gracefully highlights searches that reveal 2 locations
//And it loops infinitely
//If multiple search items, select first, hide, toggle 3d
driver.executeScript('return ' + topResult)
.then((result) => {
console.log(`navigating to ${fullAddress}`)
console.log(bill.title)
console.log('checking if multiple items');
if (result) {
console.log('selecting first result, hiding and clearing...')
driver.executeScript(clickTopResult);
driver.executeScript(hideSearch);
driver.sleep(5000).then(() => {
driver.executeScript(toggleDimension)
});
}
//Loop infinitely; meditate on the city
if (index === collection.length - 1) {
driver.sleep(pauseTime).then(() => {
console.log('starting to loop infinite')
collection.forEach((bill, index, collection) => {
navigate(bill, index, collection)
});
})
}
})
//grab url, pause before next navigation
driver.sleep(pauseTime);
}
function latestDate(bill) {
return bill.date === "2017-04-25" || bill.date === "2017-04-18";
}
function hasLocation(bill) {
let location = bill.streetAddresses || bill.properNameLocation;
return location;
}
fetch("https://api.liquid.vote/bills")
.then( response => response.json() )
.then( bills => addStreetAddressLocations(bills) )
.then( bills => addProperNameLocations(bills) )
//.then( bills => bills.filter(latestDate) )
//.then( bills => bills.filter(hasLocation) )
//.then( bills => _.uniqBy(bills, bill => location = bill.properNameLocation || bill.streetAddresses[0]))
.then( bills => _.sortBy(bills, bill => new Date(bill.date).getDate() ))
.then( bills => driver.sleep(startupTime).then( _ => bills) )
.then( bills => {
return bills
.map((bill, index, collection) => {
//console.log(bill.streetAddresses, bill.properNameLocation, bill.date);
return collectGoogleEarthUrl(bill, index, collection)
})
})
.then( bills => Promise.all(bills)
.then(bills => {
console.log(bills)
}));