Skip to content

Commit

Permalink
Merge branch 'pr/10'
Browse files Browse the repository at this point in the history
  • Loading branch information
yaleiyale committed Nov 22, 2023
2 parents 9a17365 + 8c9bb22 commit 34e44d2
Show file tree
Hide file tree
Showing 9 changed files with 301 additions and 3 deletions.
Empty file modified README.md
100755 → 100644
Empty file.
Binary file added docs/assets/obsidian-settings-page.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion manifest.json
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@
"authorUrl": "https://lestua.eu.org",
"isDesktopOnly": true,
"fundingUrl": "https://lestua.eu.org/donate/"
}
}
8 changes: 6 additions & 2 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { ImgbbParms, IMGBB_DEFAULT_PARMS } from './parms/parms-imgbb'
import { ImgurParms, IMGUR_DEFAULT_PARMS } from './parms/parms-imgur'
import { ImgurlParms, IMGURL_DEFAULT_PARMS } from './parms/parms-imgurl'
import { SmmsParms, SMMS_DEFAULT_PARMS } from './parms/parms-smms'
import { ALIST_DEFAULT_PARMS, AlistParms } from './parms/parms-alist'

export interface Config { // data from data.json
choice: HostingProvider
Expand All @@ -17,6 +18,7 @@ export interface Config { // data from data.json
imgur_parms: ImgurParms
catbox_parms: CatboxParms
chevereto_parms: CheveretoParms
alist_parms: AlistParms
}

export enum HostingProvider { // target hosting
Expand All @@ -27,7 +29,8 @@ export enum HostingProvider { // target hosting
Smms = 'SM.MS',
ImgURL = 'ImgURL',
Imgbb = 'imgbb',
Chevereto = 'chevereto'
Chevereto = 'chevereto',
Alist = 'alist'
}

export const DEFAULT_SETTINGS: Config = {
Expand All @@ -39,5 +42,6 @@ export const DEFAULT_SETTINGS: Config = {
imgurl_parms: IMGURL_DEFAULT_PARMS,
imgbb_parms: IMGBB_DEFAULT_PARMS,
catbox_parms: CATBOX_DEFAULT_PARMS,
chevereto_parms: CHEVERETO_DEFAULT_PARMS
chevereto_parms: CHEVERETO_DEFAULT_PARMS,
alist_parms: ALIST_DEFAULT_PARMS
}
61 changes: 61 additions & 0 deletions src/fragment/fragment-alist.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { Setting } from 'obsidian'
import Emo from '../main'
import { EmoFragment } from '../base/emo-fragment'
import { HostingProvider } from '../config'
import { t } from '../lang/helpers'

export class AlistFragment extends EmoFragment {
constructor (el: HTMLElement, plugin: Emo) {
super(HostingProvider.Alist, el, plugin)
}

display (el: HTMLElement, plugin: Emo): void {
const parms = plugin.config.alist_parms
el.createEl('h3', { text: 'Alist Settings'})

new Setting(el)
.setName(t('domain'))
.addText((text) => {
text
.setValue(parms.required.domain)
.onChange(async (value) => {
parms.required.domain = value
await plugin.saveSettings()
})
})

new Setting(el)
.setName('username')
.addText((text) => {
text
.setValue(parms.required.username)
.onChange(async (value) => {
parms.required.username = value
await plugin.saveSettings()
})
})

new Setting(el)
.setName('password')
.addText((text) => {
text
.setValue(parms.required.password)
.onChange(async (value) => {
parms.required.password = value
await plugin.saveSettings()
})
})

new Setting(el)
.setName('uploadPath')
.addText((text) => {
text
.setValue(parms.required.uploadPath)
.onChange(async (value) => {
parms.required.uploadPath = value
await plugin.saveSettings()
})
})

}
}
4 changes: 4 additions & 0 deletions src/main.ts
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { ImgbbUploader } from './uploader/uploader-imgbb'
import { ImgurUploader } from './uploader/uploader-imgur'
import { CatboxUploader } from './uploader/uploader-catbox'
import { CheveretoUploader } from './uploader/uploader-chevereto'
import { AlistUploader } from './uploader/uploader-alist'

export default class Emo extends Plugin {
config!: Config
Expand Down Expand Up @@ -83,6 +84,9 @@ export default class Emo extends Plugin {
case HostingProvider.Chevereto:
uploader = new CheveretoUploader(this.config.chevereto_parms)
break
case HostingProvider.Alist:
uploader = new AlistUploader(this.config.alist_parms)
break
default:
console.log(new Notice(t('broken'), 2000))
return
Expand Down
22 changes: 22 additions & 0 deletions src/parms/parms-alist.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { EmoParms } from '../base/emo-parms'

export interface AlistParms extends EmoParms {
required: Required
}

interface Required {
domain: string
username: string
password: string
uploadPath: string
}

export const ALIST_DEFAULT_PARMS: AlistParms = {
required: {
domain: 'https://alist.example.com',
username: '',
password: '',
uploadPath: '上传的相对路径',
}
}

2 changes: 2 additions & 0 deletions src/settings-tab.ts
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { ImgurFragment } from './fragment/fragment-imgur'
import { CatboxFragment } from './fragment/fragment-catbox'
import { IMGUR_ACCESS_TOKEN_LOCALSTORAGE_KEY } from './base/constants'
import { CheveretoFragment } from './fragment/fragment-chevereto'
import { AlistFragment } from './fragment/fragment-alist'

export class EmoUploaderSettingTab extends PluginSettingTab {
private readonly plugin: Emo
Expand Down Expand Up @@ -54,6 +55,7 @@ export class EmoUploaderSettingTab extends PluginSettingTab {
fragmentList.push(new ImgbbFragment(containerEl, this.plugin))
fragmentList.push(new CatboxFragment(containerEl, this.plugin))
fragmentList.push(new CheveretoFragment(containerEl, this.plugin))
fragmentList.push(new AlistFragment(containerEl, this.plugin))

// which one will show at the first time
fragmentList.forEach(element => {
Expand Down
205 changes: 205 additions & 0 deletions src/uploader/uploader-alist.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
// 第一部分
import { request, RequestUrlParam } from 'obsidian'
import { EmoFormData } from '../utils/emo-formdata'
import { EmoUploader } from '../base/emo-uploader'
import { CONTENT_TYPE_FORMDATA } from '../base/constants'
import { AlistParms } from '../parms/parms-alist'
import { sha256 } from 'js-sha256'

export class AlistUploader extends EmoUploader {
parms!: AlistParms
constructor (alistParms: AlistParms) {
super()
this.parms = alistParms
}


async upload (file: File): Promise<string> {
// 获取token
const token = await this.getToken()
// 新建文件夹
const determine = await this.determine(file)
if (determine != 'success') {
await this.mkdirFile(file)
}
// 上传文件
await this.putFile(file)
// 刷新列表
await this.refreshDir(file)
// 重命名文件
let newName = file.name
if (file.name == 'image.png'){
newName = await this.renameFile(file)
}

const extension = await this.getFileExtension(file)
const req: RequestUrlParam = {
url: `${this.parms.required.domain}/api/fs/get`,
method: 'POST',
headers: {
'Authorization': token ,
'Content-Type': 'application/json',
},
body: JSON.stringify({
path: `/${this.parms.required.uploadPath}/${extension}/${newName}`
})
}
// 发送请求并返回结果
return await new Promise((resolve, reject) => {
request(req).then(async res => {
const json = JSON.parse(res)
// 赋给markdownText
const markdownText = `![${newName}](${json.data.raw_url})`
resolve(markdownText)
}).catch(err => {
reject(err)
})
})
}

//第二部分
//获取token
async getToken (): Promise<string> {
const req: RequestUrlParam = {
url: `${this.parms.required.domain}/api/auth/login/hash`,
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
username: this.parms.required.username,
password: sha256(this.parms.required.password + '-https://github.com/alist-org/alist')
})
}
// 发送请求并返回token
return await new Promise((resolve, reject) => {
request(req).then(res => {
const json = JSON.parse(res)
resolve(json.data.token as string)
}).catch(err => {
reject(err)
})
})
}


//文件类型
async getFileExtension(file: File): Promise<string> {
const filename = file.name
const match = filename.match(/\.([^.]+)$/)
return match ? match[1] : ""
}

//判断文件夹是否存在
async determine (file: File): Promise<string> {
const extension = await this.getFileExtension(file)
const req: RequestUrlParam = {
url: `${this.parms.required.domain}/api/fs/get`,
method: 'POST',
headers: {
'Authorization': await this.getToken(),
'Content-Type': 'application/json',
},
body: JSON.stringify({
path: `/${this.parms.required.uploadPath}/${extension}`
})
}
return await new Promise((resolve, reject) => {
request(req).then(res => {
const json = JSON.parse(res)
resolve(json.message as string)
}).catch(err => {
reject(err)
})
})
}

async mkdirFile (file: File): Promise<void> {
const extension = await this.getFileExtension(file)
const req: RequestUrlParam = {
url: `${this.parms.required.domain}/api/fs/mkdir`,
method: 'POST',
headers: {
'Authorization': await this.getToken(),
'Content-Type': 'application/json',
},
body: JSON.stringify({
path: `/${this.parms.required.uploadPath}/${extension}`,
})
}
await request(req) // 发送请求并返回链接
}



// 上传文件
async putFile (file: File): Promise<void> {
const extension = await this.getFileExtension(file)
const formData = new EmoFormData()
await formData.add('file', file)
const req: RequestUrlParam = {
url: `${this.parms.required.domain}/api/fs/form`,
method: 'PUT',
headers: {
'Authorization': await this.getToken(),
'Content-Type': CONTENT_TYPE_FORMDATA,
'File-Path': encodeURIComponent(`/${this.parms.required.uploadPath}/${extension}/${file.name}`),
'As-Task': 'true'
},
body: formData.getBody()
}
await request(req) // 发送请求并返回链接
}

//第三部分
// 刷新目录
async refreshDir (file: File): Promise<void> {
const extension = await this.getFileExtension(file)
const req: RequestUrlParam = {
url: `${this.parms.required.domain}/api/fs/list`,
method: 'POST',
headers: {
'Authorization': await this.getToken(),
'Content-Type': 'application/json',
},
body: JSON.stringify({
path: `/${this.parms.required.uploadPath}/${extension}`,
page: 1,
password: "",
per_page: 0,
refresh: true,
})
}
await request(req)

}

// 重命名文件
async renameFile (file: File): Promise<string> {
const extension = await this.getFileExtension(file)
// 获取当前时间
const now = new Date()
// 格式化时间
const formatTime = (n: number) => n.toString().padStart(2, '0')
// 生成新文件名
const newName = `${now.getFullYear()}${formatTime(now.getMonth() + 1)}${formatTime(now.getDate())}-${formatTime(now.getHours())}:${formatTime(now.getMinutes())}:${formatTime(now.getSeconds())}.${extension}`
// 构造请求参数
const req: RequestUrlParam = {
url: `${this.parms.required.domain}/api/fs/rename`,
method: 'POST',
headers: {
'Authorization': await this.getToken(),
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: newName,
path: `/${this.parms.required.uploadPath}/${extension}/${file.name}`
})
}
// 发送请求
await request(req)
return newName
}

}

0 comments on commit 34e44d2

Please sign in to comment.