Add more variables (#3852)

This commit is contained in:
the1812 2024-07-17 19:48:00 +08:00
parent 560d651d35
commit d33a10513d
4 changed files with 118 additions and 28 deletions

View File

@ -13,7 +13,7 @@ import { getComponentSettings } from '@/core/settings'
import { Toast } from '@/core/toast'
import { retrieveImageUrl } from '@/core/utils'
import { logError } from '@/core/utils/log'
import { formatTitle } from '@/core/utils/title'
import { formatTitle, getTitleVariablesFromDate } from '@/core/utils/title'
import { DefaultWidget } from '@/ui'
export default Vue.extend({
@ -31,25 +31,45 @@ export default Vue.extend({
const toast = Toast.info('下载中...', '导出图片')
this.busy = true
try {
const publishDate = getTitleVariablesFromDate(
new Date(
// eslint-disable-next-line no-underscore-dangle
(unsafeWindow.__INITIAL_STATE__?.readInfo?.publish_time ?? 0) * 1000,
),
)
const variables = {
cv: document.URL.match(/read\/cv(\d+)/)?.at(1),
publishYear: publishDate.year,
publishMonth: publishDate.month,
publishDay: publishDate.day,
publishHour: publishDate.hour,
publishMinute: publishDate.minute,
publishSecond: publishDate.second,
publishMillisecond: publishDate.millisecond,
}
const images: { name: string; extension: string; url: string }[] = []
const bannerElement = dq('.banner-image .card-image__image') as HTMLDivElement
const bannerUrl = retrieveImageUrl(bannerElement)
if (bannerUrl) {
images.push({
...bannerUrl,
name: `${formatTitle(columnFormat, false, { n: '1' })}${bannerUrl.extension}`,
name: `${formatTitle(columnFormat, false, { n: '1', ...variables })}${
bannerUrl.extension
}`,
})
console.log(bannerElement, bannerUrl, images)
}
const articleImages = dqa('.article-content .img-box img:not([class*="cut-off-"])')
const articleImages = dqa('.article-content :is(img.normal-img, .normal-img img)')
articleImages.forEach((image: HTMLElement) => {
const url = retrieveImageUrl(image)
if (url) {
images.push({
...url,
name: `${formatTitle(columnFormat, false, { n: (images.length + 1).toString() })}${
url.extension
}`,
name: `${formatTitle(columnFormat, false, {
n: (images.length + 1).toString(),
...variables,
})}${url.extension}`,
})
}
})
@ -68,7 +88,8 @@ export default Vue.extend({
)
const pack = new DownloadPackage()
imageBlobs.forEach((blob, index) => pack.add(images[index].name, blob))
await pack.emit(`${formatTitle(columnFormat, false, { n: '' })}.zip`)
await pack.emit(`${formatTitle(columnFormat, false, { n: '', ...variables })}.zip`)
} catch (error) {
logError(error)
} finally {

View File

@ -3,8 +3,8 @@ import { ComponentEntry } from '@/components/types'
import { getBlob } from '@/core/ajax'
import { DownloadPackage } from '@/core/download'
import { Toast } from '@/core/toast'
import { matchUrlPattern, retrieveImageUrl } from '@/core/utils'
import { formatTitle } from '@/core/utils/title'
import { getVue2Data, matchUrlPattern, retrieveImageUrl } from '@/core/utils'
import { formatTitle, getTitleVariablesFromDate } from '@/core/utils/title'
import { feedsUrls } from '@/core/utils/urls'
import { Options } from '.'
@ -36,6 +36,38 @@ export const setupFeedImageExporter: ComponentEntry<Options> = async ({
}
const toast = Toast.info('下载中...', '导出图片')
let downloadedCount = 0
const vueData = getVue2Data(card.element)
const authorModule = lodash.get(vueData, 'data.modules.module_author', {})
const repostAuthorModule = lodash.get(vueData, 'data.orig.modules.module_author', {})
const date = getTitleVariablesFromDate(new Date(authorModule.pub_ts * 1000))
const repostDate = getTitleVariablesFromDate(
new Date((repostAuthorModule.pub_ts ?? authorModule.pub_ts) * 1000),
)
const variables = {
id: card.id,
user: card.username,
userID: authorModule.mid?.toString(),
originalUser: (card as RepostFeedsCard).repostUsername ?? card.username,
originalUserID: repostAuthorModule.mid?.toString() ?? authorModule.mid?.toString(),
originalID: lodash.get(vueData, 'data.orig.id_str', card.id),
publishYear: date.year,
publishMonth: date.month,
publishDay: date.day,
publishHour: date.hour,
publishMinute: date.minute,
publishSecond: date.second,
publishMillisecond: date.millisecond,
originalPublishYear: repostDate.year,
originalPublishMonth: repostDate.month,
originalPublishDay: repostDate.day,
originalPublishHour: repostDate.hour,
originalPublishMinute: repostDate.minute,
originalPublishSecond: repostDate.second,
originalPublishMillisecond: repostDate.millisecond,
}
const imageBlobs = await Promise.all(
imageUrls.map(async ({ url }) => {
const blob = await getBlob(url)
@ -48,10 +80,8 @@ export const setupFeedImageExporter: ComponentEntry<Options> = async ({
const { feedFormat } = options
imageBlobs.forEach((blob, index) => {
const titleData = {
user: card.username,
id: card.id,
originalUser: (card as RepostFeedsCard).repostUsername ?? card.username,
n: (index + 1).toString(),
...variables,
}
pack.add(
`${formatTitle(feedFormat, false, titleData)}${imageUrls[index].extension}`,
@ -60,10 +90,8 @@ export const setupFeedImageExporter: ComponentEntry<Options> = async ({
})
toast.close()
const packTitleData = {
user: card.username,
id: card.id,
originalUser: (card as RepostFeedsCard).repostUsername ?? card.username,
n: '',
...variables,
}
await pack.emit(`${formatTitle(feedFormat, false, packTitleData)}.zip`)
},

View File

@ -1,11 +1,40 @@
可以批量导出某个地方的图片, 目前支持动态和专栏.
动态文件名变量:
- `user`: 用户名
- `originalUser`: 被转发用户名, 如果不是转发类型的动态则等于 `user`
- `id`: 动态 ID
- `n`: 第 n 张图
- `id`: 动态 ID
- `user`: 用户名
- `userID`: 用户 ID
- 动态发布时间:
- `publishYear`
- `publishMonth`
- `publishDay`
- `publishHour`
- `publishMinute`
- `publishSecond`
- `publishMillisecond`
- 被转发的数据 (如果不是转发类型的动态, 则和上面的对应变量相同):
- `originalID`: 被转发的动态 ID
- `originalUser`: 被转发的用户名
- `originalUserID`: 被转发用户 ID
- 被转发的动态发布时间:
- `originalPublishYear`
- `originalPublishMonth`
- `originalPublishDay`
- `originalPublishHour`
- `originalPublishMinute`
- `originalPublishSecond`
- `originalPublishMillisecond`
专栏文件名变量:
- `n`: 第 n 张图
- `title`: 专栏标题
- `n`: 第 n 张图
- `cv`: 专栏 cv 号
- 专栏发布时间:
- `publishYear`
- `publishMonth`
- `publishDay`
- `publishHour`
- `publishMinute`
- `publishSecond`
- `publishMillisecond`

View File

@ -31,12 +31,24 @@ const tokenSplit = (format: string) => {
}
return tokens.filter(it => it !== '')
}
export const getTitleVariablesFromDate = (date: Date, padStartLength = 2) => {
return {
year: date.getFullYear().toString(),
month: (date.getMonth() + 1).toString().padStart(padStartLength, '0'),
day: date.getDate().toString().padStart(padStartLength, '0'),
hour: date.getHours().toString().padStart(padStartLength, '0'),
minute: date.getMinutes().toString().padStart(padStartLength, '0'),
second: date.getSeconds().toString().padStart(padStartLength, '0'),
millisecond: date.getMilliseconds().toString().substring(0, 3),
}
}
export const formatTitle = (
format: string,
includesPageTitle = true,
extraVariables: StringMap = {},
) => {
const now = new Date()
const getLegacyTitle = () => {
return (
document.title
@ -55,6 +67,7 @@ export const formatTitle = (
.trim()
)
}
const dateVariables = getTitleVariablesFromDate(new Date())
const builtInVariables: StringMap = {
title: (() => {
const videoPageTitle = dq('.video-info-container .video-title')
@ -95,14 +108,13 @@ export const formatTitle = (
bvid: unsafeWindow.bvid,
cid: unsafeWindow.cid,
lid: document.URL.replace(/https:\/\/live\.bilibili\.com\/(blanc\/)?([\d]+)/, '$2'),
// 年月日这方法名真够乱的
y: now.getFullYear().toString(),
M: (now.getMonth() + 1).toString().padStart(2, '0'), // zero-based
d: now.getDate().toString().padStart(2, '0'),
h: now.getHours().toString().padStart(2, '0'),
m: now.getMinutes().toString().padStart(2, '0'),
s: now.getSeconds().toString().padStart(2, '0'),
ms: now.getMilliseconds().toString().substring(0, 3),
y: dateVariables.year,
M: dateVariables.month,
d: dateVariables.day,
h: dateVariables.hour,
m: dateVariables.minute,
s: dateVariables.second,
ms: dateVariables.millisecond,
}
const variables = {
...builtInVariables,