use unified chrome instance to handle open-site-with-boss-cookie - for handleLaunchBossSite and handleViewJobOnlineButtonClick in ui

This commit is contained in:
geekgeekrun
2024-11-23 13:28:41 +08:00
parent c0dc8d30fd
commit 20bef0c97f
4 changed files with 112 additions and 45 deletions
@@ -16,6 +16,8 @@ import path from 'node:path'
import url from 'url' import url from 'url'
import packageJson from '@geekgeekrun/launch-bosszhipin-login-page-with-preload-extension/package.json' assert { type: 'json' } import packageJson from '@geekgeekrun/launch-bosszhipin-login-page-with-preload-extension/package.json' assert { type: 'json' }
import { Target } from 'puppeteer' import { Target } from 'puppeteer'
import { pipeWriteRegardlessError } from '../utils/pipe'
import * as JSONStream from 'JSONStream'
const __dirname = url.fileURLToPath(new URL('.', import.meta.url)) const __dirname = url.fileURLToPath(new URL('.', import.meta.url))
const isRunFromUi = Boolean(process.env.MAIN_BOSSGEEKGO_UI_RUN_MODE) const isRunFromUi = Boolean(process.env.MAIN_BOSSGEEKGO_UI_RUN_MODE)
@@ -125,6 +127,35 @@ export async function launchBossSite() {
const localStoragePageUrl = `https://www.zhipin.com/desktop/` const localStoragePageUrl = `https://www.zhipin.com/desktop/`
await setDomainLocalStorage(browser, localStoragePageUrl, bossLocalStorage) await setDomainLocalStorage(browser, localStoragePageUrl, bossLocalStorage)
//#region pipe
let pipeForWrite: null | fs.WriteStream = null
let pipeForRead: null | fs.ReadStream = null
try {
pipeForWrite = fs.createWriteStream(null, { fd: 3 })
} catch {
console.warn('pipeForWrite is not available')
}
try {
pipeForRead = fs.createReadStream(null, { fd: 3 })
} catch {
console.warn('pipeForRead is not available')
}
pipeForRead?.pipe(JSONStream.parse())?.on('data', async function handler(data) {
if (data.type !== 'NEW_WINDOW') {
return
}
const page = await browser.newPage()
await page.goto(data.url)
})
pipeWriteRegardlessError(
pipeForWrite,
JSON.stringify({
type: 'SUB_PROCESS_OF_OPEN_BOSS_SITE_READY'
})
)
//#endregion
browser.on('targetcreated', (target) => { browser.on('targetcreated', (target) => {
attachRequestsListener(target) attachRequestsListener(target)
}) })
@@ -135,11 +166,16 @@ export async function launchBossSite() {
} }
const cp = browser.process() const cp = browser.process()
cp.kill() cp.kill()
pipeWriteRegardlessError(
pipeForWrite,
JSON.stringify({
type: 'SUB_PROCESS_OF_OPEN_BOSS_SITE_CAN_BE_KILLED'
})
)
process.exit(0) process.exit(0)
}) })
const newPage = await await browser.newPage() const tempPage = await browser.newPage()
await page.close() await page.close()
page = newPage page = tempPage
await page.goto('https://www.zhipin.com/web/user/')
} }
@@ -24,6 +24,8 @@ import {
getJobLibrary getJobLibrary
} from '../utils/db/index' } from '../utils/db/index'
import { PageReq } from '../../../../common/types/pagination' import { PageReq } from '../../../../common/types/pagination'
import { pipeWriteRegardlessError } from '../../utils/pipe'
import { WriteStream } from 'node:fs'
export default function initIpc() { export default function initIpc() {
ipcMain.on('open-external-link', (_, link) => { ipcMain.on('open-external-link', (_, link) => {
@@ -286,31 +288,16 @@ export default function initIpc() {
return a return a
}) })
let subProcessOfOpenBossSite: ChildProcess | undefined let subProcessOfOpenBossSiteDefer: null | PromiseWithResolvers<ChildProcess> = null
let subProcessOfOpenBossSiteLaunching = false let subProcessOfOpenBossSite: null | ChildProcess = null
ipcMain.handle('open-boss-site', async () => { ipcMain.handle('open-site-with-boss-cookie', async (_, data) => {
if (subProcessOfOpenBossSiteLaunching) { const url = data.url
return if (
} !subProcessOfOpenBossSiteDefer ||
subProcessOfOpenBossSiteLaunching = true !subProcessOfOpenBossSite ||
const defer = Promise.withResolvers() subProcessOfOpenBossSite.killed
if (subProcessOfOpenBossSite) { ) {
subProcessOfOpenBossSite.once('exit', defer.resolve) subProcessOfOpenBossSiteDefer = Promise.withResolvers()
subProcessOfOpenBossSite.once('error', console.error)
try {
process.kill(subProcessOfOpenBossSite.pid!)
await sleep(500)
process.kill(subProcessOfOpenBossSite.pid!, 'SIGKILL')
} catch {
defer.resolve(undefined)
}
} else {
defer.resolve(undefined)
}
defer.promise.then(() => {
subProcessOfOpenBossSite = undefined
})
await defer.promise
const puppeteerExecutable = await getAnyAvailablePuppeteerExecutable() const puppeteerExecutable = await getAnyAvailablePuppeteerExecutable()
const subProcessEnv = { const subProcessEnv = {
...process.env, ...process.env,
@@ -319,9 +306,47 @@ export default function initIpc() {
} }
subProcessOfOpenBossSite = childProcess.spawn(process.argv[0], process.argv.slice(1), { subProcessOfOpenBossSite = childProcess.spawn(process.argv[0], process.argv.slice(1), {
env: subProcessEnv, env: subProcessEnv,
stdio: [null, null, null] stdio: [null, null, null, 'pipe']
}) })
subProcessOfOpenBossSiteLaunching = false subProcessOfOpenBossSite.once('exit', () => {
subProcessOfOpenBossSiteDefer = null
})
subProcessOfOpenBossSite.stdio[3]!.pipe(JSONStream.parse()).on(
'data',
async function handler(data) {
switch (data?.type) {
case 'SUB_PROCESS_OF_OPEN_BOSS_SITE_READY': {
subProcessOfOpenBossSiteDefer!.resolve(subProcessOfOpenBossSite as ChildProcess)
break
}
case 'SUB_PROCESS_OF_OPEN_BOSS_SITE_CAN_BE_KILLED': {
try {
subProcessOfOpenBossSite &&
!subProcessOfOpenBossSite.killed &&
subProcessOfOpenBossSite.pid &&
process.kill(subProcessOfOpenBossSite.pid)
} catch {
//
} finally {
subProcessOfOpenBossSiteDefer = null
subProcessOfOpenBossSite = null
}
break
}
}
}
)
}
await subProcessOfOpenBossSiteDefer.promise
pipeWriteRegardlessError(
subProcessOfOpenBossSite!.stdio[3]! as WriteStream,
JSON.stringify({
type: 'NEW_WINDOW',
url: url ?? 'about:blank'
})
)
}) })
ipcMain.handle('exit-app-immediately', () => { ipcMain.handle('exit-app-immediately', () => {
@@ -137,11 +137,10 @@ onMounted(() => {
}) })
}) })
function handleViewJobOnlineButtonClick(encryptJobId: string) { async function handleViewJobOnlineButtonClick(encryptJobId: string) {
electron.ipcRenderer.send( return await electron.ipcRenderer.invoke('open-site-with-boss-cookie', {
'open-external-link', url: `https://www.zhipin.com/job_detail/${encryptJobId}.html`
`https://www.zhipin.com/job_detail/${encryptJobId}.html` })
)
} }
const drawVisibleModelValue = ref(false) const drawVisibleModelValue = ref(false)
@@ -36,6 +36,7 @@ import { useRouter } from 'vue-router'
import { ElIcon } from 'element-plus' import { ElIcon } from 'element-plus'
import { TopRight } from '@element-plus/icons-vue' import { TopRight } from '@element-plus/icons-vue'
import useBuildInfo from '@renderer/hooks/useBuildInfo' import useBuildInfo from '@renderer/hooks/useBuildInfo'
import { debounce } from 'lodash-es'
const router = useRouter() const router = useRouter()
const unmountedCbs: Array<InstanceType<typeof Function>> = [] const unmountedCbs: Array<InstanceType<typeof Function>> = []
onUnmounted(() => { onUnmounted(() => {
@@ -94,9 +95,15 @@ const handleGotoProjectPageClick = () => {
electron.ipcRenderer.send('open-external-link', 'https://github.com/geekgeekrun/geekgeekrun') electron.ipcRenderer.send('open-external-link', 'https://github.com/geekgeekrun/geekgeekrun')
} }
const handleLaunchBossSite = async () => { const handleLaunchBossSite = debounce(
await electron.ipcRenderer.invoke('open-boss-site') async () => {
} return await electron.ipcRenderer.invoke('open-site-with-boss-cookie', {
url: `https://www.zhipin.com/`
})
},
1000,
{ leading: true, trailing: false }
)
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>