mirror of
https://github.com/KazooTTT/kazoottt-blog.git
synced 2025-06-22 18:21:33 +08:00
Update docs and sort content
This commit is contained in:
@ -1,296 +0,0 @@
|
|||||||
---
|
|
||||||
slug: synchronize-profiles-to-remote-and-local-on-a-regular-basis
|
|
||||||
title: 使用github action定时同步obsidian内容到博客仓库
|
|
||||||
date: 2024-11-29
|
|
||||||
author: KazooTTT
|
|
||||||
type: Post
|
|
||||||
status: Published
|
|
||||||
tags:
|
|
||||||
finished: true
|
|
||||||
published: true
|
|
||||||
category:
|
|
||||||
description:
|
|
||||||
---
|
|
||||||
|
|
||||||
## github action
|
|
||||||
|
|
||||||
目标仓库以及具体目录可以根据自己的项目来定
|
|
||||||
|
|
||||||
``` yaml
|
|
||||||
name: Update Docs
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
paths:
|
|
||||||
- "content/**"
|
|
||||||
- "scripts/build_docs.cjs"
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build-and-deploy:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout source repository
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.PAT_TOKEN }}
|
|
||||||
|
|
||||||
- name: Set up Node.js
|
|
||||||
uses: actions/setup-node@v2
|
|
||||||
with:
|
|
||||||
node-version: "20"
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
run: |
|
|
||||||
echo "Installing dependencies in source repository..."
|
|
||||||
npm install
|
|
||||||
echo "Dependencies installed successfully"
|
|
||||||
|
|
||||||
- name: Build docs
|
|
||||||
run: |
|
|
||||||
echo "Starting docs build..."
|
|
||||||
npm run build:docs:server
|
|
||||||
echo "Docs built successfully"
|
|
||||||
|
|
||||||
- name: Checkout target repository
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
repository: kazoottt/kazoottt-blog
|
|
||||||
path: kazoottt-blog
|
|
||||||
token: ${{ secrets.PAT_TOKEN }}
|
|
||||||
|
|
||||||
- name: Copy built docs to target repository
|
|
||||||
run: |
|
|
||||||
echo "Starting copy process..."
|
|
||||||
echo "Content of astroContent before copy:"
|
|
||||||
cp -rv astroContent/* kazoottt-blog/src/content/post/
|
|
||||||
echo "Content of astroContent copy done"
|
|
||||||
|
|
||||||
- name: Setup target repository
|
|
||||||
run: |
|
|
||||||
cd kazoottt-blog
|
|
||||||
echo "Configuring git..."
|
|
||||||
git config --global user.name 'github-actions[bot]'
|
|
||||||
git config --global user.email 'github-actions[bot]@users.noreply.github.com'
|
|
||||||
echo "Installing dependencies in target repository..."
|
|
||||||
npm install
|
|
||||||
echo "Running sort..."
|
|
||||||
npm run sort
|
|
||||||
|
|
||||||
- name: Check for changes and commit
|
|
||||||
run: |
|
|
||||||
cd kazoottt-blog
|
|
||||||
if [[ -n $(git status -s) ]]; then
|
|
||||||
git add .
|
|
||||||
git commit -m "Update docs and sort content"
|
|
||||||
git push
|
|
||||||
else
|
|
||||||
echo "No changes to commit"
|
|
||||||
fi
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.PAT_TOKEN }}
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
PAT_TOKEN申请
|
|
||||||
[Sign in to GitHub · GitHub](https://github.com/settings/tokens)
|
|
||||||
|
|
||||||
需要权限:repo, workflow
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
## obsidian模板
|
|
||||||
|
|
||||||
published是true且notAstro不为true的时候,会被发布到另外一个仓库
|
|
||||||
|
|
||||||
```
|
|
||||||
---
|
|
||||||
title: {{title}}
|
|
||||||
date: {{date}}
|
|
||||||
author: KazooTTT
|
|
||||||
type: Post
|
|
||||||
status: Published
|
|
||||||
tags: []
|
|
||||||
finished: false
|
|
||||||
published: false
|
|
||||||
category:
|
|
||||||
slug:
|
|
||||||
description:
|
|
||||||
notAstro:
|
|
||||||
---
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
## 脚本 scripts/build_docs.cjs
|
|
||||||
|
|
||||||
依赖安装
|
|
||||||
|
|
||||||
```
|
|
||||||
npm install gray-matter
|
|
||||||
```
|
|
||||||
|
|
||||||
可以配置一些不想同步的文件夹
|
|
||||||
|
|
||||||
``` js
|
|
||||||
const fs = require("fs").promises
|
|
||||||
const fsSync = require("fs")
|
|
||||||
const path = require("path")
|
|
||||||
const matter = require("gray-matter")
|
|
||||||
const { execSync } = require("child_process")
|
|
||||||
|
|
||||||
const CONFIG = {
|
|
||||||
outputDir: "astroContent",
|
|
||||||
inputDir: "./content",
|
|
||||||
ignoreList: [
|
|
||||||
".github",
|
|
||||||
".obsidian",
|
|
||||||
"草稿箱",
|
|
||||||
"模板",
|
|
||||||
"attachment",
|
|
||||||
"记录",
|
|
||||||
"导航用",
|
|
||||||
"微信读书",
|
|
||||||
],
|
|
||||||
validExtensions: [".md"],
|
|
||||||
// Local specific config
|
|
||||||
localDestinationRoot: "", // to edit
|
|
||||||
localDestination: "", // to edit
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ensures output directory exists
|
|
||||||
*/
|
|
||||||
function initializeOutputDir() {
|
|
||||||
if (!fsSync.existsSync(CONFIG.outputDir)) {
|
|
||||||
fsSync.mkdirSync(CONFIG.outputDir, { recursive: true })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validates if a file should be processed based on its metadata
|
|
||||||
*/
|
|
||||||
function shouldProcessFile(frontMatter) {
|
|
||||||
return frontMatter.published === true && !frontMatter.notAstro
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Processes a single markdown file
|
|
||||||
*/
|
|
||||||
async function processMarkdownFile(fullPath, outputPath) {
|
|
||||||
try {
|
|
||||||
const fileContent = await fs.readFile(fullPath, "utf8")
|
|
||||||
const { data } = matter(fileContent)
|
|
||||||
|
|
||||||
if (shouldProcessFile(data)) {
|
|
||||||
await fs.copyFile(fullPath, outputPath)
|
|
||||||
console.log(`✓ Copied: ${path.relative(CONFIG.inputDir, fullPath)}`)
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error(`Error processing file ${fullPath}:`, error.message)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Recursively processes directories and files
|
|
||||||
*/
|
|
||||||
async function processDirectory(dir) {
|
|
||||||
try {
|
|
||||||
const files = await fs.readdir(dir)
|
|
||||||
|
|
||||||
await Promise.all(
|
|
||||||
files.map(async (file) => {
|
|
||||||
const fullPath = path.join(dir, file)
|
|
||||||
const relativePath = path.relative(CONFIG.inputDir, fullPath)
|
|
||||||
const outputPath = path.join(CONFIG.outputDir, relativePath)
|
|
||||||
|
|
||||||
const stats = await fs.stat(fullPath)
|
|
||||||
|
|
||||||
if (stats.isDirectory()) {
|
|
||||||
if (CONFIG.ignoreList.includes(file)) return
|
|
||||||
await fs.mkdir(outputPath, { recursive: true })
|
|
||||||
await processDirectory(fullPath)
|
|
||||||
} else if (path.extname(file) === ".md" && file !== "index.md") {
|
|
||||||
await processMarkdownFile(fullPath, outputPath)
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
} catch (error) {
|
|
||||||
console.error(`Error processing directory ${dir}:`, error.message)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copies processed files to final destination and commits changes
|
|
||||||
*/
|
|
||||||
async function copyToLocalDestination() {
|
|
||||||
try {
|
|
||||||
// Remove existing content
|
|
||||||
if (fsSync.existsSync(CONFIG.localDestination)) {
|
|
||||||
await fs.rm(CONFIG.localDestination, { recursive: true })
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create destination directory
|
|
||||||
await fs.mkdir(CONFIG.localDestination, { recursive: true })
|
|
||||||
|
|
||||||
// Copy files
|
|
||||||
const files = await fs.readdir(CONFIG.outputDir)
|
|
||||||
await Promise.all(
|
|
||||||
files.map(async (file) => {
|
|
||||||
const sourcePath = path.join(CONFIG.outputDir, file)
|
|
||||||
const destPath = path.join(CONFIG.localDestination, file)
|
|
||||||
await fs.rename(sourcePath, destPath)
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
|
|
||||||
console.log("Content has been successfully copied to the local destination.")
|
|
||||||
|
|
||||||
// Commit changes
|
|
||||||
execSync(`cd ${path.dirname(CONFIG.localDestination)} && npm run sort`)
|
|
||||||
execSync(`git add ${CONFIG.localDestination} && git commit -m "update content"`)
|
|
||||||
// push changes
|
|
||||||
// execSync(`git push`)
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Error copying to destination:", error.message)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cleans up the temporary output directory
|
|
||||||
*/
|
|
||||||
async function cleanupOutputDir() {
|
|
||||||
try {
|
|
||||||
if (fsSync.existsSync(CONFIG.outputDir)) {
|
|
||||||
await fs.rm(CONFIG.outputDir, { recursive: true })
|
|
||||||
}
|
|
||||||
console.log("Cleaned up temporary directory.")
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Error cleaning up:", error.message)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Main execution
|
|
||||||
*/
|
|
||||||
async function main() {
|
|
||||||
try {
|
|
||||||
const isLocalBuild = process.argv.includes("--local")
|
|
||||||
console.log(`Starting document processing... (${isLocalBuild ? "local" : "server"} build)`)
|
|
||||||
|
|
||||||
initializeOutputDir()
|
|
||||||
await processDirectory(CONFIG.inputDir)
|
|
||||||
|
|
||||||
if (isLocalBuild) {
|
|
||||||
await copyToLocalDestination()
|
|
||||||
await cleanupOutputDir()
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log("Document processing completed successfully!")
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Fatal error:", error.message)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
main()
|
|
||||||
|
|
||||||
```
|
|
@ -1,88 +0,0 @@
|
|||||||
---
|
|
||||||
title: 01 Perplexity系列产品
|
|
||||||
date: 2024-09-04
|
|
||||||
author: KazooTTT
|
|
||||||
type: Post
|
|
||||||
status: Published
|
|
||||||
tags:
|
|
||||||
- AI
|
|
||||||
- 搜索引擎
|
|
||||||
- Perplexity
|
|
||||||
- Playground
|
|
||||||
- 播客
|
|
||||||
finished: true
|
|
||||||
published: true
|
|
||||||
category: 编程-AI
|
|
||||||
slug: perplexity-productions-intro
|
|
||||||
description: 概述Perplexity系列产品,包括搜索引擎、Playground和播客,重点介绍其功能和区别。
|
|
||||||
NotionID-notionnext: ae2fba46-af30-4bd5-b6d0-fe751c162800
|
|
||||||
link-notionnext: https://kazoottt.notion.site/01-Perplexity-ae2fba46af304bd5b6d0fe751c162800
|
|
||||||
---
|
|
||||||
|
|
||||||
# Perplexity系列产品
|
|
||||||
|
|
||||||
## 产品1 Perplexity搜索引擎
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
https://www.perplexity.ai/
|
|
||||||
|
|
||||||
### 普通和Pro的区别
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
### 频繁人工验证怎么办
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
[Perplexity - AI Search - Chrome 应用商店](https://chromewebstore.google.com/detail/perplexity-ai-search/bnaffjbjpgiagpondjlnneblepbdchol)
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
### 同类别产品
|
|
||||||
|
|
||||||
[Devv AI](https://devv.ai/) (编程向)
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
## 产品2 Perplexity Playground
|
|
||||||
|
|
||||||
体验最新大模型
|
|
||||||
|
|
||||||
https://labs.perplexity.ai/
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
[Introducing Llama 3.1: Our most capable models to date](https://ai.meta.com/blog/meta-llama-3-1/)
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
[Changelog - Perplexity](https://docs.perplexity.ai/changelog/changelog#introducing-new-and-improved-sonar-models)
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
## 产品3 Perplexity播客
|
|
||||||
|
|
||||||
[资讯汇总 Discover](https://www.perplexity.ai/discover)
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
Perplexity和eleventlab合作,把Discover的内容转成播客了。
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
很适合练习听力以及了解科技资讯。地址:[Discover Daily by Perplexity](https://discoverdaily.ai/)
|
|
||||||
|
|
||||||
[spotify](https://open.spotify.com/episode/1CaSWrm7uUAOkaKjE9KI47?si=WPbA0x73QkGEPm-DFh4big)
|
|
||||||
|
|
||||||
[pca.st](https://pca.st/03qazv0d)
|
|
||||||
|
|
||||||
支持rss
|
|
||||||
|
|
||||||

|
|
@ -1,60 +0,0 @@
|
|||||||
---
|
|
||||||
title: “git-credential-osxkeychain”想要访问你的钥匙串中的密钥“github.com” 解决方法
|
|
||||||
date: 2024-09-01
|
|
||||||
author: KazooTTT
|
|
||||||
type: Post
|
|
||||||
status: Published
|
|
||||||
tags:
|
|
||||||
- Git
|
|
||||||
- macOS
|
|
||||||
- 解决方案
|
|
||||||
finished: true
|
|
||||||
published: true
|
|
||||||
category: 软件
|
|
||||||
slug: git-credential-osxkeychain-solve-method
|
|
||||||
description: 解决 macOS 弹出 'git-credential-osxkeychain' 访问 GitHub 密钥的问题
|
|
||||||
NotionID-notionnext: 462377ea-6b4a-472c-9f55-ca4965dfe5c4
|
|
||||||
link-notionnext: https://kazoottt.notion.site/git-credential-osxkeychain-github-com-462377ea6b4a472c9f55ca4965dfe5c4
|
|
||||||
---
|
|
||||||
|
|
||||||
# macos 一直弹出 “git-credential-osxkeychain”想要访问你的钥匙串中的密钥“github.com” 解决方法
|
|
||||||
|
|
||||||
现在网络上关于这个问题的解决方案大部分都是打开钥匙串访问,然后删除github的密钥,但是这个方法其实并不奏效。具体的解决方法如下(二选一即可)
|
|
||||||
|
|
||||||
## 方法一 使用GitHub CLI
|
|
||||||
|
|
||||||
首先,使用brew安装GitHub CLI:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
brew install gh
|
|
||||||
```
|
|
||||||
|
|
||||||
然后,使用以下命令来登录:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
gh auth login
|
|
||||||
```
|
|
||||||
|
|
||||||
## 方法二 使用Git Credential Manager
|
|
||||||
|
|
||||||
如果没有git,使用brew安装git:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
brew install git
|
|
||||||
```
|
|
||||||
|
|
||||||
然后,安装git-credential-manager
|
|
||||||
|
|
||||||
```bash
|
|
||||||
brew install --cask git-credential-manager
|
|
||||||
```
|
|
||||||
|
|
||||||
最后,使用以下命令来登录:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git credential-osxkeychain
|
|
||||||
```
|
|
||||||
|
|
||||||
## 参考地址
|
|
||||||
|
|
||||||
[在 Git 中缓存 GitHub 凭据 - GitHub 文档](https://docs.github.com/zh/get-started/getting-started-with-git/caching-your-github-credentials-in-git)
|
|
@ -1,89 +0,0 @@
|
|||||||
---
|
|
||||||
title: 我自己常用的ffmpeg批处理
|
|
||||||
date: 2024-10-14
|
|
||||||
author: KazooTTT
|
|
||||||
type: Post
|
|
||||||
status: Published
|
|
||||||
tags:
|
|
||||||
- 视频处理
|
|
||||||
- ffmpeg
|
|
||||||
finished: false
|
|
||||||
published: true
|
|
||||||
category: 软件
|
|
||||||
slug: >-
|
|
||||||
01-my-own-commonly-used-ffmpeg-batch-processingmy-own-commonly-used-ffmpeg-batching
|
|
||||||
description: 转换FLV格式的视频成HDDP,用于弹幕压制。使用FFmpeg来实现该功能,支持多个操作系统,如Windows和macOS。
|
|
||||||
---
|
|
||||||
|
|
||||||
## 720x1080批量转1920x1080(两边黑屏)
|
|
||||||
|
|
||||||
手机直播的时候录播机录出来的分辨率是720x1080,使用ffmpeg转成横屏的1920x1080。这样xml转ass弹幕的时候,就不需要另外处理了,看起来很更舒服。
|
|
||||||
|
|
||||||
macos的写法:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
input_folder="" # 要转化的录播的文件夹路径
|
|
||||||
output_folder="" # 要输出的文件夹路径
|
|
||||||
|
|
||||||
# Create the output folder if it does not exist
|
|
||||||
mkdir -p "$output_folder"
|
|
||||||
|
|
||||||
for f in "$input_folder"/*.flv; do
|
|
||||||
ffmpeg -i "$f" -vf "scale=720:1080,pad=1920:1080:(ow-iw)/2:(oh-ih)/2" -c:a copy "$output_folder/$(basename "${f%.*}.mp4")"
|
|
||||||
done
|
|
||||||
```
|
|
||||||
|
|
||||||
windows的写法:
|
|
||||||
|
|
||||||
```powershell
|
|
||||||
$input_folder = "Z:\\rec\\48743-hanser\\20240731-又来画画了!" # 要转化的录播的文件夹路径
|
|
||||||
$output_folder = "Z:\\rec\\48743-hanser\\20240731-又来画画了!" # 要输出的文件夹路径
|
|
||||||
|
|
||||||
# Create the output folder if it does not exist
|
|
||||||
If (-Not (Test-Path $output_folder)) {
|
|
||||||
New-Item -ItemType Directory -Path $output_folder | Out-Null
|
|
||||||
}
|
|
||||||
|
|
||||||
Get-ChildItem -Path $input_folder -Filter *.flv | ForEach-Object {
|
|
||||||
$input_file = $_.FullName
|
|
||||||
$output_file = Join-Path $output_folder ($_.BaseName + ".mp4")
|
|
||||||
$ffmpeg_args = @("-i", $input_file, "-vf", "scale=720:1080,pad=1920:1080:(ow-iw)/2:(oh-ih)/2", "-c:a", "copy", $output_file)
|
|
||||||
& ffmpeg $ffmpeg_args
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
效果
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
## 弹幕压制
|
|
||||||
|
|
||||||
### windows版(使用cuda)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
@echo off
|
|
||||||
set input_folder=YourInputFolderPath
|
|
||||||
set output_folder=YourOutputFolderPath
|
|
||||||
|
|
||||||
for %%a in ("%input_folder%\\*.flv") do (
|
|
||||||
ffmpeg -hwaccel cuda -c:v h264_cuvid -i "%%a" -vf subtitles="%%~na.ass" -c:v h264_nvenc -b:v 6000k -c:a copy "%output_folder%\\%%~na_压制.mp4" -y
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
### macOS版
|
|
||||||
|
|
||||||
```bash
|
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
input_folder="/path/to/input" # Replace with your input folder path
|
|
||||||
output_folder="/path/to/output" # Replace with your output folder path
|
|
||||||
|
|
||||||
mkdir -p "$output_folder" # Create the output folder if it doesn't exist
|
|
||||||
|
|
||||||
for f in "$input_folder"/*.mp4; do
|
|
||||||
subtitle_file="${f%.*}.ass" # Assumes subtitle file name is same as video file name but with .ass extension
|
|
||||||
output_file="$output_folder/$(basename "${f%.*}_压制.mp4")" # Output file name with _ass suffix
|
|
||||||
|
|
||||||
ffmpeg -i "$f" -vf "ass=$subtitle_file" "$output_file"
|
|
||||||
done
|
|
||||||
```
|
|
Reference in New Issue
Block a user