Merge pull request 'Version 2.0.0' (#1) from devel into main

Reviewed-on: inhji/obsidian-microblog#1
This commit is contained in:
inhji 2023-06-10 08:48:48 +02:00
commit b010551363
16 changed files with 145 additions and 42 deletions

View File

@ -1,4 +1,6 @@
# Micro.publish
# Micropub
Forked from https://github.com/otaviocc/obsidian-microblog
Micro.publish is a community maintained plugin for [Obsidian](https://obsidian.md/) to publish notes to a [Micro.blog](https://micro.blog/) blog.

View File

@ -1,10 +1,10 @@
{
"id": "microblog-publish-plugin",
"name": "Micro.publish",
"version": "1.6.0",
"id": "micropub-publish-plugin",
"name": "Micropub",
"version": "2.0.0",
"minAppVersion": "0.15.0",
"description": "Publish notes to Micro.blog",
"author": "Otavio Cordeiro",
"authorUrl": "https://otavio.cc",
"description": "Publish notes to your own site with Micropub",
"author": "Inhji",
"authorUrl": "https://inhji.de",
"isDesktopOnly": false
}
}

View File

@ -1,6 +1,6 @@
{
"name": "microblog-publish-plugin",
"version": "1.6.0",
"version": "2.0.0",
"description": "Publish Note to Micro.blog",
"main": "main.js",
"scripts": {

View File

@ -30,8 +30,8 @@ export default class MicroPlugin extends Plugin {
this.synchronizationService.fetchTags()
this.addCommand({
id: 'microblog-publish-command',
name: 'Post to Micro.blog',
id: 'micropub-publish-command',
name: 'Post with Micropub',
editorCallback: (editor, markdownView) => {
if (editor.getValue().trim().length == 0) {
new ErrorView(
@ -49,7 +49,7 @@ export default class MicroPlugin extends Plugin {
})
this.addCommand({
id: 'microblog-categories-sync-command',
id: 'micropub-categories-sync-command',
name: 'Synchronize Categories',
callback: () => {
this.synchronizationService.fetchTags()

View File

@ -36,9 +36,11 @@ export class MicroPluginContainer implements MicroPluginContainerInterface {
) {
this.settings = settings
this.plugin = plugin
this.networkRequestFactory = new NetworkRequestFactory()
this.networkClient = new NetworkClient(() => {
return this.settings.appToken
})
this.networkRequestFactory = new NetworkRequestFactory(
() => this.settings.micropubEndpoint
)
this.networkClient = new NetworkClient(
() => this.settings.appToken
)
}
}

View File

@ -95,7 +95,7 @@ export class ViewModelFactory implements ViewModelFactoryInterface {
public makeEmptyPostErrorViewModel(): ErrorViewModel {
return new ErrorViewModel(
"Oops",
"Micro.blog doesn't support blank posts. Write something first and try again."
"Micropub doesn't support blank posts. Write something first and try again."
)
}
}

View File

@ -1,4 +1,5 @@
import { NetworkRequest } from '@networking/NetworkRequest'
import { PublishResponse } from './PublishResponse'
export interface NetworkClientInterface {
@ -6,6 +7,7 @@ export interface NetworkClientInterface {
// and returns a Promise. `T` specifies the return type and is used
// by the network client to decode the network payload.
run<T>(request: NetworkRequest): Promise<T>
publish(request: NetworkRequest): Promise<PublishResponse>
}
/*
@ -24,29 +26,62 @@ export class NetworkClient implements NetworkClientInterface {
// Life cycle
constructor(
appToken: () => string
appToken: () => string,
) {
this.appToken = appToken
}
private requestHeaders(): HeadersInit {
return {
'Content-Type': 'application/x-www-form-urlencoded',
'Accept': 'application/json',
'Authorization': 'Bearer ' + this.appToken()
}
}
// Public
public async run<T>(request: NetworkRequest): Promise<T> {
const url = 'https://micro.blog' + request.path + '?' + request.parameters
const url = request.url + '?' + request.parameters
const response = await fetch(url, {
method: request.method,
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Bearer ' + this.appToken()
}
headers: this.requestHeaders(),
body: request.body
})
if (!response.ok) {
throw new Error('Network error: ' + response.status)
throw new Error(
`Network error: ${response.status}`
)
}
return await response.json() as T
}
public async publish(request: NetworkRequest): Promise<PublishResponse> {
const response: Response = await fetch(request.url, {
method: request.method,
headers: this.requestHeaders(),
body: request.body
})
if (!response.ok) {
throw new Error(
`Network error: ${response.status}`
)
}
const postUrl: string | null = response.headers.get("Location") || response.headers.get("location")
if (!postUrl) {
throw new Error(
"Response is missing url of new post."
)
}
return {
url: postUrl
}
}
}

View File

@ -4,7 +4,7 @@
* body sent.
*/
export type NetworkRequest = {
path: string
url: string
parameters: URLSearchParams
method: string
body?: string

View File

@ -30,6 +30,18 @@ export interface NetworkRequestFactoryInterface {
*/
export class NetworkRequestFactory implements NetworkRequestFactoryInterface {
// Properties
private endpointUrl: () => string
// Life cycle
constructor(
endpointUrl: () => string,
) {
this.endpointUrl = endpointUrl
}
// Public
public makePublishRequest(
@ -65,7 +77,7 @@ export class NetworkRequestFactory implements NetworkRequestFactoryInterface {
})
return {
path: '/micropub',
url: this.endpointUrl(),
parameters: parameters,
method: 'POST'
}
@ -73,7 +85,7 @@ export class NetworkRequestFactory implements NetworkRequestFactoryInterface {
public makeConfigRequest(): NetworkRequest {
return {
path: '/micropub',
url: this.endpointUrl(),
parameters: new URLSearchParams([
['q', 'config']
]),
@ -83,7 +95,7 @@ export class NetworkRequestFactory implements NetworkRequestFactoryInterface {
public makeCategoriesRequest(): NetworkRequest {
return {
path: '/micropub',
url: this.endpointUrl(),
parameters: new URLSearchParams([
['q', 'category']
]),

View File

@ -3,6 +3,6 @@
*/
export type PublishResponse = {
url: string
preview: string
edit: string
//preview: string
//edit: string
}

View File

@ -3,6 +3,12 @@
*/
export interface StoredSettings {
// Application url used to access the site
siteUrl: string
// The site's micropub endpoint
micropubEndpoint: string
// Application token used to access Micro.blog.
appToken: string
@ -27,6 +33,8 @@ export interface StoredSettings {
// Default values for the plugin.
export const defaultSettings: StoredSettings = {
siteUrl: '',
micropubEndpoint: '',
appToken: '',
defaultTags: '',
postVisibility: 'draft',

View File

@ -49,7 +49,7 @@ export class MicroPluginSettingsView extends PluginSettingTab implements MicroPl
this.display()
new Notice(
'Micro.blog login succeeded'
'Login succeeded'
)
}
@ -57,7 +57,7 @@ export class MicroPluginSettingsView extends PluginSettingTab implements MicroPl
this.display()
new Notice(
'Micro.blog login failed'
'Login failed'
)
}
@ -87,11 +87,11 @@ export class MicroPluginSettingsView extends PluginSettingTab implements MicroPl
const { containerEl } = this
containerEl.empty()
containerEl.createEl('h2', { text: 'Micro.publish' })
containerEl.createEl('h2', { text: 'Micropub' })
new Setting(containerEl)
.setName('App Token')
.setDesc('Visit Micro.blog\'s Account page to generate one.')
.setDesc('This will be autogenerated in the future.')
.addText(text => text
.setPlaceholder('Enter app token')
.setValue(this.viewModel.appToken)
@ -100,6 +100,28 @@ export class MicroPluginSettingsView extends PluginSettingTab implements MicroPl
})
)
new Setting(containerEl)
.setName('Site URL')
.setDesc('Your site\'s full address, eg. https://example.com.')
.addText(text => text
.setPlaceholder('https://example.com')
.setValue(this.viewModel.siteUrl)
.onChange(value => {
this.viewModel.siteUrl = value
})
)
new Setting(containerEl)
.setName('Micropub Endpoint')
.setDesc('Your site\'s micropub endpoint.')
.addText(text => text
.setPlaceholder('https://example.com/micropub')
.setValue(this.viewModel.micropubEndpoint)
.onChange(value => {
this.viewModel.micropubEndpoint = value
})
)
new Setting(containerEl)
.addButton(button => button
.setButtonText('Log in')
@ -119,7 +141,7 @@ export class MicroPluginSettingsView extends PluginSettingTab implements MicroPl
const { containerEl } = this
containerEl.empty()
containerEl.createEl('h2', { text: 'Micro.publish' })
containerEl.createEl('h2', { text: 'Micropub' })
new Setting(containerEl)
.setName('Blog')

View File

@ -69,6 +69,24 @@ export class MicroPluginSettingsViewModel {
this.plugin.saveSettings()
}
public get siteUrl(): string {
return this.settings.siteUrl
}
public set siteUrl(value: string) {
this.settings.siteUrl = value
this.plugin.saveSettings()
}
public get micropubEndpoint(): string {
return this.settings.micropubEndpoint
}
public set micropubEndpoint(value: string) {
this.settings.micropubEndpoint = value
this.plugin.saveSettings()
}
public get tags(): string {
return this.settings.defaultTags
}

View File

@ -183,10 +183,13 @@ export class PublishView extends Modal implements PublishViewModelDelegate {
contentEl.createEl('h2', { text: 'Published' })
contentEl.createEl('a', { text: 'Open post URL', href: response.url })
/*
contentEl.createEl('br')
contentEl.createEl('a', { text: 'Open post Preview URL', href: response.preview })
contentEl.createEl('br')
contentEl.createEl('a', { text: 'Open post Edit URL', href: response.edit })
*/
}
private makeMessageView(

View File

@ -149,7 +149,7 @@ export class PublishViewModel implements TagSuggestionDelegate {
this.delegate?.publishDidValidateDate()
try {
const response = this.networkRequestFactory.makePublishRequest(
const request = this.networkRequestFactory.makePublishRequest(
this.title,
this.content,
this.tags,
@ -158,11 +158,11 @@ export class PublishViewModel implements TagSuggestionDelegate {
this.formattedScheduledDate()
)
const result = await this.networkClient.run<PublishResponse>(
response
const response: PublishResponse = await this.networkClient.publish(
request
)
this.delegate?.publishDidSucceed(result)
this.delegate?.publishDidSucceed(response)
} catch (error) {
this.delegate?.publishDidFail(error)
}

View File

@ -1,3 +1,4 @@
{
"1.6.0": "0.15.0"
}
"1.6.0": "0.15.0",
"2.0.0": "0.15.0"
}