-
Notifications
You must be signed in to change notification settings - Fork 27
/
build.js
112 lines (84 loc) · 2.71 KB
/
build.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
#!/usr/bin/env node
'use strict';
const fs = require( 'fs' );
const path = require( 'path' );
const axios = require( 'axios' );
const iconv = require( 'iconv-lite' );
const babyparse = require( 'babyparse' );
// https://support.google.com/googleplay/android-developer/answer/6154891?hl=en
// https://support.google.com/googleplay/answer/1727131?hl=en
// On the CSV file, devices are ordered alphabetically (A-Z) by manufacturer name and listed in the following format:
// Retail brand, marketing name, build.os.DEVICE, build.os.MODEL
const SUPPORTED_DEVICES_CSV = 'https://storage.googleapis.com/play_public/supported_devices.csv';
const DEVICES_OUTPUT_FILE = path.join( __dirname, 'devices.json' );
const BRANDS_OUTPUT_FILE = path.join( __dirname, 'brands.json' );
function getCvs () {
console.log( 'Downloading: ' + SUPPORTED_DEVICES_CSV );
axios.get( SUPPORTED_DEVICES_CSV )
.then( buildJSON )
.catch( e => {
console.log( 'Download failed' );
console.log( e );
} );
}
// convert utf-16le to utf8
function decodeRaw ( data ) {
// check file encoding:
// $ file -I supported_devices.csv
// supported_devices.csv: text/plain; charset=utf-16le
let buffer = Buffer.from( data );
return iconv.decode( buffer, 'utf-16le' );
}
function buildJSON ( response ) {
console.log( 'Downloaded', response.status, response.statusText );
console.log( 'File size: ' + response.headers['content-length'] + ' bytes' );
let devices = parseCVS( decodeRaw( response.data ) );
// remove first row: "Retail Branding,Marketing Name,Device,Model"
devices.shift();
console.log( devices.length + ' devices' );
fs.writeFile( DEVICES_OUTPUT_FILE, JSON.stringify( devices, null, 2 ), ( err ) => {
if ( err ) {
throw err;
}
console.log( 'Device list saved to ' + DEVICES_OUTPUT_FILE );
} );
let brands = [];
devices.forEach( device => {
if ( !device.brand ) {
return;
}
if ( brands.indexOf( device.brand ) === -1 ) {
brands.push( device.brand );
}
} );
console.log( brands.length + ' brands' );
fs.writeFile( BRANDS_OUTPUT_FILE, JSON.stringify( brands, null, 2 ), ( err ) => {
if ( err ) {
throw err;
}
console.log( 'Brand list saved to ' + BRANDS_OUTPUT_FILE );
} );
}
function parseCVS ( data ) {
let parsed = babyparse.parse( data );
let out = [];
parsed.data.forEach( parts => {
if ( parts.length === 4 ) {
out.push( {
brand: parts[0],
name: cleanup( parts[1] ),
device: parts[2],
model: cleanup( parts[3] )
} );
}
} );
return out;
}
function cleanup ( str ) {
if ( !str ) {
return str;
}
return str.replace( /\\'/g, '\'' ).replace( /\\t/g, '' ).trim();
}
// start
getCvs();