Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
K
koishi-plugin-pics
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
3rdeye
koishi-plugin-pics
Commits
67646c15
Commit
67646c15
authored
Apr 20, 2022
by
nanahira
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add middleware framework
parent
e6233815
Pipeline
#11792
canceled with stage
Changes
5
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
172 additions
and
20 deletions
+172
-20
src/config.ts
src/config.ts
+17
-0
src/index.ts
src/index.ts
+86
-20
src/middleware.ts
src/middleware.ts
+37
-0
src/middlewares/assets.ts
src/middlewares/assets.ts
+18
-0
src/middlewares/download.ts
src/middlewares/download.ts
+14
-0
No files found.
src/config.ts
View file @
67646c15
// import 'source-map-support/register';
import
{
DefineSchema
,
RegisterSchema
,
SchemaClass
}
from
'
koishi-thirdeye
'
;
import
{
Quester
}
from
'
koishi
'
;
import
{
PicMiddleware
}
from
'
./index
'
;
@
RegisterSchema
()
export
class
PicsPluginConfig
{
...
...
@@ -58,3 +59,19 @@ export class PicSourceConfig implements PicSourceInfo {
}
export
const
PicSourceSchema
=
SchemaClass
(
PicSourceConfig
);
export
interface
PicMiddlewareInfo
{
name
?:
string
;
prepend
?:
boolean
;
}
export
class
PicMiddlewareConfig
{
constructor
(
config
:
PicMiddlewareInfo
)
{}
name
:
string
;
prepend
:
boolean
;
applyTo
(
target
:
PicMiddleware
)
{
target
.
name
=
this
.
name
;
target
.
prepend
=
this
.
prepend
;
}
}
src/index.ts
View file @
67646c15
// import 'source-map-support/register';
import
{
Context
,
Assets
,
Awaitable
,
Random
,
Logger
,
Bot
}
from
'
koishi
'
;
import
{
PicSourceInfo
,
PicsPluginConfig
}
from
'
./config
'
;
import
{
Context
,
Assets
,
Awaitable
,
Random
,
Logger
,
Bot
,
remove
,
}
from
'
koishi
'
;
import
{
PicMiddlewareConfig
,
PicMiddlewareInfo
,
PicSourceInfo
,
PicsPluginConfig
,
}
from
'
./config
'
;
import
_
from
'
lodash
'
;
import
{
segment
,
Quester
}
from
'
koishi
'
;
import
{
BasePlugin
,
Caller
,
ClassType
,
DefinePlugin
,
Inject
,
InjectLogger
,
LifecycleEvents
,
Provide
,
}
from
'
koishi-thirdeye
'
;
import
{
AxiosRequestConfig
}
from
'
axios
'
;
import
{
PicAssetsTransformMiddleware
}
from
'
./middlewares/assets
'
;
import
{
PicDownloaderMiddleware
}
from
'
./middlewares/download
'
;
import
{
PicMiddleware
,
PicNext
}
from
'
./middleware
'
;
export
*
from
'
./config
'
;
export
*
from
'
./middleware
'
;
declare
module
'
koishi
'
{
// eslint-disable-next-line @typescript-eslint/no-namespace
...
...
@@ -65,6 +84,7 @@ export default class PicsContainer
implements
LifecycleEvents
{
private
sources
=
new
Map
<
PicSource
,
()
=>
boolean
>
();
private
picMiddlewares
:
PicMiddleware
[]
=
[];
@
Caller
()
private
caller
:
Context
;
...
...
@@ -72,9 +92,6 @@ export default class PicsContainer
@
InjectLogger
()
private
logger
:
Logger
;
@
Inject
()
private
assets
:
Assets
;
@
Inject
(
true
)
private
http
:
Quester
;
...
...
@@ -108,6 +125,24 @@ export default class PicsContainer
return
Array
.
from
(
this
.
sources
.
keys
());
}
middleware
(
mid
:
PicMiddleware
,
targetCtx
?:
Context
)
{
const
processingCtx
:
Context
=
targetCtx
||
this
.
caller
;
mid
.
name
||=
processingCtx
.
state
?.
plugin
?.
name
;
const
disposable
=
processingCtx
.
on
(
'
dispose
'
,
()
=>
{
disposable
();
this
.
removeMiddlware
(
mid
);
});
if
(
mid
.
prepend
)
{
this
.
picMiddlewares
.
unshift
(
mid
);
}
else
{
this
.
picMiddlewares
.
push
(
mid
);
}
}
removeMiddlware
(
mid
:
PicMiddleware
)
{
remove
(
this
.
picMiddlewares
,
mid
);
}
pickAvailableSources
(
sourceTags
:
string
[]
=
[],
includeNonDefault
=
false
)
{
let
sources
=
this
.
allSources
();
if
(
sourceTags
.
length
)
{
...
...
@@ -188,32 +223,63 @@ export default class PicsContainer
);
}
async
getSegment
(
url
:
string
,
bot
?:
Bot
)
{
let
useFileHeader
=
false
;
async
download
(
url
:
string
,
extraConfig
:
AxiosRequestConfig
=
{})
{
if
(
url
.
startsWith
(
'
base64://
'
))
{
return
url
;
}
const
buf
=
await
this
.
_http
.
get
(
url
,
{
responseType
:
'
arraybuffer
'
,
...
extraConfig
,
});
return
`base64://
${
buf
.
toString
(
'
base64
'
)}
`
;
}
async
resolveUrl
(
url
:
string
,
middlwares
=
this
.
picMiddlewares
)
{
if
(
!
middlwares
.
length
)
{
return
url
;
}
const
next
:
PicNext
=
async
(
nextUrl
)
=>
{
nextUrl
||=
url
;
const
nextResult
=
await
this
.
resolveUrl
(
nextUrl
,
middlwares
.
slice
(
1
));
return
nextResult
||
nextUrl
;
};
try
{
if
(
this
.
config
.
useAssets
&&
this
.
assets
)
{
const
uploadedUrl
=
await
this
.
assets
.
upload
(
url
,
undefined
);
url
=
uploadedUrl
;
}
else
if
(
this
.
config
.
useBase64
&&
url
.
startsWith
(
'
http
'
))
{
const
buf
=
await
this
.
_http
.
get
(
url
,
{
responseType
:
'
arraybuffer
'
,
});
url
=
`base64://
${
buf
.
toString
(
'
base64
'
)}
`
;
useFileHeader
=
true
;
let
result
=
await
middlwares
[
0
].
use
(
url
,
next
);
if
(
!
result
)
{
this
.
logger
.
warn
(
`Got empty result from middleware
${
middlwares
[
0
].
name
||
'
???
'
}
`
,
);
result
=
url
;
}
return
result
;
}
catch
(
e
)
{
this
.
logger
.
warn
(
`Download image
${
url
}
failed:
${
e
.
toString
()}
`
);
this
.
logger
.
warn
(
`Resolve url
${
url
}
failed:
${
e
.
toString
()}
`
);
return
url
;
}
const
isOneBotBot
=
this
.
isOneBotBot
(
bot
);
}
async
getSegment
(
url
:
string
,
bot
?:
Bot
)
{
url
=
await
this
.
resolveUrl
(
url
);
const
picData
:
segment
.
Data
=
{
[
isOneBotBot
&&
useFileHeader
?
'
file
'
:
'
url
'
]:
url
,
[
url
.
startsWith
(
'
base64://
'
)
&&
this
.
isOneBotBot
(
bot
)
?
'
file
'
:
'
url
'
]:
url
,
cache
:
true
,
};
return
segment
(
'
image
'
,
picData
);
}
async
onApply
()
{
private
installDefaultMiddlewares
()
{
if
(
this
.
config
.
useAssets
)
{
this
.
ctx
.
plugin
(
PicAssetsTransformMiddleware
);
}
if
(
this
.
config
.
useBase64
)
{
this
.
ctx
.
plugin
(
PicDownloaderMiddleware
);
}
}
onApply
()
{
this
.
_http
=
this
.
http
.
extend
(
this
.
config
.
httpConfig
);
this
.
installDefaultMiddlewares
();
const
ctx
=
this
.
ctx
;
ctx
.
i18n
.
define
(
'
zh
'
,
`commands.
${
this
.
config
.
commandName
}
`
,
{
description
:
'
获取随机图片
'
,
...
...
src/middleware.ts
0 → 100644
View file @
67646c15
import
{
Awaitable
,
Logger
}
from
'
koishi
'
;
import
{
PicMiddlewareConfig
,
PicMiddlewareInfo
}
from
'
./config
'
;
import
{
BasePlugin
,
Inject
,
InjectLogger
,
LifecycleEvents
,
}
from
'
koishi-thirdeye
'
;
import
PicsContainer
from
'
./index
'
;
export
type
PicNext
=
(
url
?:
string
)
=>
Awaitable
<
string
>
;
export
interface
PicMiddleware
extends
PicMiddlewareInfo
{
use
(
url
:
string
,
next
:
PicNext
):
Awaitable
<
string
>
;
}
export
class
PicMiddlewareBase
<
C
extends
PicMiddlewareConfig
=
PicMiddlewareConfig
,
>
extends
BasePlugin
<
C
>
implements
PicMiddleware
,
LifecycleEvents
{
@
Inject
(
true
)
protected
pics
:
PicsContainer
;
@
InjectLogger
()
protected
logger
:
Logger
;
onApply
()
{
this
.
config
.
applyTo
(
this
);
this
.
pics
.
middleware
(
this
);
}
use
(
url
:
string
,
next
:
PicNext
):
Awaitable
<
string
>
{
return
next
(
url
);
}
}
src/middlewares/assets.ts
0 → 100644
View file @
67646c15
import
{
DefinePlugin
,
Inject
}
from
'
koishi-thirdeye
'
;
import
{
Assets
}
from
'
koishi
'
;
import
{
PicMiddlewareBase
,
PicNext
}
from
'
../middleware
'
;
import
{
PicMiddlewareConfig
}
from
'
../config
'
;
@
DefinePlugin
({
schema
:
PicMiddlewareConfig
})
export
class
PicAssetsTransformMiddleware
extends
PicMiddlewareBase
{
@
Inject
()
private
assets
:
Assets
;
override
async
use
(
url
:
string
,
next
:
PicNext
)
{
if
(
!
this
.
assets
)
{
return
next
();
}
const
transformed
=
await
this
.
assets
.
upload
(
url
,
undefined
);
return
next
(
transformed
);
}
}
src/middlewares/download.ts
0 → 100644
View file @
67646c15
import
{
DefinePlugin
}
from
'
koishi-thirdeye
'
;
import
{
PicMiddlewareBase
,
PicNext
}
from
'
../middleware
'
;
import
{
PicMiddlewareConfig
}
from
'
../config
'
;
@
DefinePlugin
({
schema
:
PicMiddlewareConfig
})
export
class
PicDownloaderMiddleware
extends
PicMiddlewareBase
{
override
async
use
(
url
:
string
,
next
:
PicNext
)
{
if
(
url
.
startsWith
(
'
base64://
'
))
{
return
next
();
}
const
downloadedUrl
=
await
this
.
pics
.
download
(
url
);
return
next
(
downloadedUrl
);
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment