Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support sm.ms in electron #319

Merged
merged 35 commits into from Mar 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
a7dad70
feat: add events support
terwer Mar 15, 2024
f09fb41
feat: basic picgo flow
terwer Mar 15, 2024
9e4a6bc
feat: add universal picgo store
terwer Mar 15, 2024
07cc413
feat: adapt universal picgo config path
terwer Mar 15, 2024
9c8115e
feat: adapt universal picgo config path
terwer Mar 15, 2024
2367023
feat: adapt universal picgo config path
terwer Mar 15, 2024
066cd00
feat: add localForge support
Mar 16, 2024
952cff9
feat: use ts-localstorage for browser
Mar 16, 2024
c44c32a
feat: finish picgo store ataptor
Mar 16, 2024
7f9db6c
feat: init picgo
Mar 16, 2024
08c41c9
feat: init picgo
Mar 16, 2024
7ca1875
feat: init picgo
Mar 16, 2024
15fa112
feat: init picgo
Mar 16, 2024
796e839
Merge branch 'dev' of github.com:terwer/siyuan-plugin-picgo into dev
terwer Mar 18, 2024
b88113e
chore: ignore script cache
terwer Mar 18, 2024
7a0ee05
feat: rename cfg folder to universal-picgo
terwer Mar 18, 2024
def516b
feat: add partial i18n support
terwer Mar 18, 2024
17da086
feat: support browser i18n
terwer Mar 18, 2024
5c0c623
feat: add plugin db support
terwer Mar 18, 2024
a0717f3
feat: electron write file
terwer Mar 18, 2024
7d38391
feat: db support electron and browser
terwer Mar 19, 2024
dd73797
feat: db support electron and browser
terwer Mar 19, 2024
e27c09f
feat: db support electron and browser
terwer Mar 19, 2024
adfa24e
feat: restructure db
terwer Mar 19, 2024
6789d48
feat: add lifecycle
terwer Mar 19, 2024
5c131a0
feat: add clipboard image support
terwer Mar 19, 2024
7b986ab
feat: save clipboard image
terwer Mar 19, 2024
a570bca
feat: add transformer
terwer Mar 19, 2024
678ad8a
feat: add axios for request
terwer Mar 19, 2024
679625b
feat: add smms plugin
Mar 19, 2024
78deb04
feat: add picgo request
Mar 19, 2024
1a12645
feat: add picgo request
Mar 19, 2024
ed67d2d
feat: lifecycle should throw error
terwer Mar 20, 2024
cce03db
feat: lifecycle should throw error
terwer Mar 20, 2024
7a7cb59
feat: support sm.ms
terwer Mar 20, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Expand Up @@ -39,4 +39,5 @@ yarn-error.log*
.idea
artifacts
cookie.txt
token.txt
token.txt
__pycache__
23 changes: 21 additions & 2 deletions libs/Universal-PicGo-Core/.eslintrc.cjs
@@ -1,4 +1,23 @@
module.exports = {
root: true,
extends: ["./node_modules/@terwer/eslint-config-custom/typescript/index.cjs"],
extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended", "turbo", "prettier"],

parser: "@typescript-eslint/parser",

plugins: ["@typescript-eslint", "prettier"],

rules: {
// Note: you must disable the base rule as it can report incorrect errors
semi: "off",
quotes: "off",
"no-undef": "off",
"@typescript-eslint/no-var-requires": "off",
"@typescript-eslint/no-this-alias": "off",
"@typescript-eslint/no-non-null-assertion": "off",
"@typescript-eslint/no-unused-vars": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-empty-function": "off",
"@typescript-eslint/ban-types": "off",
"turbo/no-undeclared-env-vars": "off",
"prettier/prettier": "error",
},
}
15 changes: 13 additions & 2 deletions libs/Universal-PicGo-Core/README.md
Expand Up @@ -6,12 +6,23 @@ picgo lib for node, browser and electron

```js
// usage
import { UniversalPicGo } from "universal-picgo"

try {
const picgo = new UniversalPicGo()
console.log("picgo =>", picgo)

const result = await picgo.upload()
console.log("upload success =>", result)
} catch (e: any) {
console.error(e)
}
```

## Deps

```
## Congregations! universal-picgo need no deps, it is just pure js code 🎉
├── universal-picgo-store
```

## Dev
Expand All @@ -38,4 +49,4 @@ pnpm test -F universal-picgo

```bash
pnpm publish -F universal-picgo --tag latest
```
```
4 changes: 4 additions & 0 deletions libs/Universal-PicGo-Core/custom.d.ts
@@ -0,0 +1,4 @@
declare module '*.json' {
const value: { [key: string]: any }
export default value
}
8 changes: 7 additions & 1 deletion libs/Universal-PicGo-Core/package.json
@@ -1,6 +1,6 @@
{
"name": "universal-picgo",
"version": "1.5.1",
"version": "1.5.6",
"type": "module",
"description": "picgo lib for node, browser and electron",
"main": "./dist/index.js",
Expand Down Expand Up @@ -30,6 +30,12 @@
"vite-plugin-node-polyfills": "^0.21.0"
},
"dependencies": {
"@picgo/i18n": "^1.0.0",
"axios": "^1.6.8",
"dayjs": "^1.11.10",
"js-yaml": "^4.1.0",
"queue": "^7.0.0",
"universal-picgo-store": "workspace:*",
"zhi-lib-base": "^0.8.0"
},
"publishConfig": {
Expand Down
157 changes: 157 additions & 0 deletions libs/Universal-PicGo-Core/src/core/Lifecycle.ts
@@ -0,0 +1,157 @@
/*
* GNU GENERAL PUBLIC LICENSE
* Version 3, 29 June 2007
*
* Copyright (C) 2024 Terwer, Inc. <https://terwer.space/>
* Everyone is permitted to copy and distribute verbatim copies
* of this license document, but changing it is not allowed.
*/

import { EventEmitter } from "../utils/nodePolyfill"
import { ILifecyclePlugins, IPicGo, IPlugin, Undefinable } from "../types"
import { ILogger } from "zhi-lib-base"
import { createContext } from "../utils/createContext"
import { IBuildInEvent } from "../utils/enums"
import { handleUrlEncode } from "../utils/common"

export class Lifecycle extends EventEmitter {
private readonly ctx: IPicGo
private readonly logger: ILogger

constructor(ctx: IPicGo) {
super()
this.ctx = ctx
this.logger = this.ctx.getLogger("lifecycle")
this.logger.debug("lifecycle is inited")
}

async start(input: any[]): Promise<IPicGo> {
// ensure every upload process has an unique context
const ctx = createContext(this.ctx)
try {
// images input
if (!Array.isArray(input)) {
throw new Error("Input must be an array.")
}
ctx.input = input
ctx.output = []

// lifecycle main
await this.beforeTransform(ctx)
await this.doTransform(ctx)
await this.beforeUpload(ctx)
await this.doUpload(ctx)
await this.afterUpload(ctx)
return ctx
} catch (e: any) {
ctx.log.warn(IBuildInEvent.FAILED)
ctx.emit(IBuildInEvent.UPLOAD_PROGRESS, -1)
ctx.emit(IBuildInEvent.FAILED, e)
ctx.log.error(e)
// if (ctx.getConfig<Undefinable<string>>("debug")) {
// }
// should throw error to stop the process
throw e
// return ctx
}
}

private async beforeTransform(ctx: IPicGo): Promise<IPicGo> {
ctx.emit(IBuildInEvent.UPLOAD_PROGRESS, 0)
ctx.emit(IBuildInEvent.BEFORE_TRANSFORM, ctx)
ctx.log.info("Before transform")
await this.handlePlugins(ctx.helper.beforeTransformPlugins, ctx)
return ctx
}

private async doTransform(ctx: IPicGo): Promise<IPicGo> {
ctx.emit(IBuildInEvent.UPLOAD_PROGRESS, 30)
const type = ctx.getConfig<Undefinable<string>>("picBed.transformer") || "path"
let currentTransformer = type
let transformer = ctx.helper.transformer.get(type)
if (!transformer) {
transformer = ctx.helper.transformer.get("path")
currentTransformer = "path"
ctx.log.warn(`Can't find transformer - ${type}, switch to default transformer - path`)
}
ctx.log.info(`Transforming... Current transformer is [${currentTransformer}]`)
await transformer?.handle(ctx)
return ctx
}

private async beforeUpload(ctx: IPicGo): Promise<IPicGo> {
ctx.emit(IBuildInEvent.UPLOAD_PROGRESS, 60)
ctx.log.info("Before upload")
ctx.emit(IBuildInEvent.BEFORE_UPLOAD, ctx)
await this.handlePlugins(ctx.helper.beforeUploadPlugins, ctx)
return ctx
}

private async doUpload(ctx: IPicGo): Promise<IPicGo> {
let type =
ctx.getConfig<Undefinable<string>>("picBed.uploader") ||
ctx.getConfig<Undefinable<string>>("picBed.current") ||
"smms"
let uploader = ctx.helper.uploader.get(type)
let currentTransformer = type
if (!uploader) {
type = "smms"
currentTransformer = "smms"
uploader = ctx.helper.uploader.get("smms")
ctx.log.warn(`Can't find uploader - ${type}, switch to default uploader - smms`)
}
ctx.log.info(`Uploading... Current uploader is [${currentTransformer}]`)
await uploader?.handle(ctx)
for (const outputImg of ctx.output) {
outputImg.type = type
}
return ctx
}

private async afterUpload(ctx: IPicGo): Promise<IPicGo> {
ctx.emit(IBuildInEvent.AFTER_UPLOAD, ctx)
ctx.emit(IBuildInEvent.UPLOAD_PROGRESS, 100)
await this.handlePlugins(ctx.helper.afterUploadPlugins, ctx)
let msg = ""
const length = ctx.output.length
// notice, now picgo builtin uploader will encodeOutputURL by default
const isEncodeOutputURL = ctx.getConfig<Undefinable<boolean>>("settings.encodeOutputURL") === true
for (let i = 0; i < length; i++) {
if (typeof ctx.output[i].imgUrl !== "undefined") {
msg += isEncodeOutputURL ? handleUrlEncode(ctx.output[i].imgUrl!) : ctx.output[i].imgUrl!
if (i !== length - 1) {
msg += "\n"
}
}
delete ctx.output[i].base64Image
delete ctx.output[i].buffer
}
ctx.emit(IBuildInEvent.FINISHED, ctx)
if (msg === "") {
ctx.log.warn("[after-upload] image upload occured an error, please read log for details")
} else {
ctx.log.info(`[after-upload] upload finishied => \n${msg}`)
}
return ctx
}

// ===================================================================================================================

private async handlePlugins(lifeCyclePlugins: ILifecyclePlugins, ctx: IPicGo): Promise<IPicGo> {
const plugins = lifeCyclePlugins.getList()
const pluginNames = lifeCyclePlugins.getIdList()
const lifeCycleName = lifeCyclePlugins.getName()
await Promise.all(
plugins.map(async (plugin: IPlugin, index: number) => {
try {
ctx.log.info(`${lifeCycleName}: ${pluginNames[index]} running`)
await plugin.handle(ctx)
} catch (e) {
ctx.log.error(`${lifeCycleName}: ${pluginNames[index]} error`)
throw e
}
})
)
return ctx
}
}