Last active
May 17, 2022 04:09
-
-
Save taichunmin/3e854e9e118785a7985ec24905ee16ce to your computer and use it in GitHub Desktop.
從微程式的 Portal 系統中下載通訊錄,需先安裝 Greasemonkey 或 Tampermonkey 才能執行! 下方連結是安裝網址。 https://gist.github.com/taichunmin/3e854e9e118785a7985ec24905ee16ce/raw/mp-contacts.user.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name 微程式通訊錄 | |
// @namespace https://ef.program.com.tw:8443/contacts | |
// @version 0.24 | |
// @description 從微程式的 Portal 系統中下載通訊錄 | |
// @author taichunmin <taichunmin@gmail.com> | |
// @website https://gist.github.com/taichunmin/3e854e9e118785a7985ec24905ee16ce/ | |
// @updateURL https://gist.github.com/taichunmin/3e854e9e118785a7985ec24905ee16ce/raw/contacts.user.js | |
// @downloadURL https://gist.github.com/taichunmin/3e854e9e118785a7985ec24905ee16ce/raw/contacts.user.js | |
// @match https://ef.program.com.tw:8443/* | |
// @run-at document-start | |
// @grant none | |
// @require https://apis.google.com/js/api.js | |
// @require https://cdn.jsdelivr.net/npm/axios@0/dist/axios.min.js | |
// @require https://cdn.jsdelivr.net/npm/jquery@1/dist/jquery.min.js | |
// @require https://cdn.jsdelivr.net/npm/lodash@4/lodash.min.js | |
// @require https://cdn.jsdelivr.net/npm/papaparse@5/papaparse.min.js | |
// @require https://cdn.jsdelivr.net/npm/sweetalert2@11/dist/sweetalert2.all.min.js | |
// ==/UserScript== | |
/* global jQuery, axios */ | |
(function ($) { | |
'use strict' | |
const sleep = t => new Promise(resolve => setTimeout(resolve, t)) | |
async function getCsv (url, cachetime = 3e4) { | |
const csv = _.trim(_.get(await axios.get(url, { | |
params: { cachebust: _.floor(Date.now() / cachetime) }, | |
}), 'data')) | |
return _.get(Papa.parse(csv, { | |
encoding: 'utf8', | |
header: true, | |
}), 'data', []) | |
} | |
async function fetchPortalPageEmployees (cur) { | |
const html = _.get(await axios.get(`https://ef.program.com.tw:8443/web/12701/5?p_p_id=11&p_p_lifecycle=0&p_p_state=maximized&p_p_mode=view&_11_struts_action=%2Fdirectory%2Fview&_11_tabs1=users&_11_keywords=&_11_advancedSearch=false&_11_andOperator=true&_11_status=0&_11_emailAddress=&_11_firstName=&_11_lastName=&_11_middleName=&_11_organizationId=0&_11_roleId=0&_11_screenName=&_11_userGroupId=0&_11_orderByCol=last-name&_11_orderByType=asc&_11_resetCur=false&_11_delta=200&cur=${cur ?? 1}`, { responseType: 'document' }), 'data') | |
console.log({ cur, html }) | |
const rows = [] | |
$('table.taglib-search-iterator', html).find('tr:has(td)').each(function () { | |
const row = [] | |
$(this).find('td').each(function () { | |
row.push(_.trim($(this).text())) | |
}) | |
if (_.endsWith(row[2], '@program.com.tw')) rows.push({ | |
name: row[1], | |
email: row[2], | |
mobile: row[3].replace(/\D/g, ''), | |
mpid: row[4], | |
}) | |
}) | |
return rows | |
} | |
async function fetchPortalEmployees () { | |
const employees = [] | |
let cur = 1 | |
while (true) { | |
const pageEmployees = await fetchPortalPageEmployees(cur++) | |
if (!pageEmployees.length) break | |
employees.push(...pageEmployees) | |
await sleep(50) | |
} | |
return _.keyBy(employees, 'name') | |
} | |
async function fetchContacts() { | |
return await getCsv('https://us-central1-mp-parking-lot.cloudfunctions.net/gcf-microprogram-contacts/export-csv') | |
} | |
function splitName(fullname) { | |
if (/^[\w\s,.]+$/.test(fullname)) { | |
return _.split(fullname, ' ', 2) | |
} else { | |
return [fullname.substr(1), fullname.substr(0, 1)] | |
} | |
} | |
async function downloadGoogleCsv() { | |
let [employees, contacts] = await Promise.all([ | |
fetchPortalEmployees(), | |
fetchContacts(), | |
]) | |
console.log({ employees, contacts }) | |
contacts = _.filter(_.map(contacts, contact => { | |
const nameSplited = splitName(contact.name) | |
const employee = _.get(employees, contact.name) | |
if (!employee) return | |
return { | |
'E-mail 1 - Type': '* Work', | |
'E-mail 1 - Value': employee.email, | |
'Family Name': nameSplited[1], | |
'Given Name': nameSplited[0], | |
'Phone 1 - Type': employee.mobile ? 'Mobile' : '', | |
'Phone 1 - Value': employee.mobile, | |
mpid: employee.mpid, | |
Name: contact.name, | |
} | |
})) | |
let csv = Papa.unparse(contacts, { header: true }) | |
// console.log(csv) | |
let blob = new Blob([csv], { type: 'text/csv' }) | |
let url = URL.createObjectURL(blob) | |
let download = $.parseHTML(`<a style="display: none" href="${url}" download="google.csv"></a>`)[0] | |
document.body.appendChild(download) | |
download.click() | |
URL.revokeObjectURL(url) | |
} | |
function repairConsole() { | |
// <iframe> element | |
var iframe = document.createElement("iframe"); | |
// Hide it somewhere | |
iframe.style.position="fixed"; | |
iframe.style.height = iframe.style.width = "1px"; | |
iframe.style.top = iframe.style.left = "-5px"; | |
// No src to prevent loading some data | |
iframe.src = "about: blank"; | |
// Needs append to work | |
document.body.appendChild(iframe); | |
// Get the inner console | |
window.console = iframe.contentWindow.console; | |
} | |
$(function () { // on jQuery ready event | |
repairConsole() // 恢復 console | |
// 下載通訊錄按鈕 | |
$($.parseHTML('<li><a class="the-firstlayer">匯出通訊錄</a></li>')).appendTo('ul#navigation-ul').click(downloadGoogleCsv) | |
}) | |
})(jQuery.noConflict(true)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment