refs #125 Implement sub status methods for misskey

This commit is contained in:
AkiraFukushima 2020-03-02 22:48:52 +09:00
parent d833099b10
commit 027b884227
7 changed files with 185 additions and 27 deletions

View file

@ -689,7 +689,13 @@ export interface MegalodonInterface {
* @param focus Two floating points (x,y), comma-delimited, ranging from -1.0 to 1.0.
* @return Attachment
*/
updateMedia(id: string, file?: any, description?: string | null, focus?: string | null): Promise<Response<Entity.Attachment>>
updateMedia(
id: string,
file?: any,
description?: string | null,
focus?: string | null,
is_sensitive?: boolean | null
): Promise<Response<Entity.Attachment>>
// ======================================
// statuses/polls
// ======================================
@ -707,7 +713,7 @@ export interface MegalodonInterface {
* @param choices Array of own votes containing index for each option (starting from 0).
* @return Poll
*/
votePoll(id: string, choices: Array<number>): Promise<Response<Entity.Poll>>
votePoll(id: string, choices: Array<number>, status_id?: string | null): Promise<Response<Entity.Poll>>
// ======================================
// statuses/scheduled_statuses
// ======================================
@ -1153,6 +1159,24 @@ export class NoImplementedError extends Error {
}
}
export class ArgumentError extends Error {
constructor(err?: string) {
super(err)
this.name = new.target.name
Object.setPrototypeOf(this, new.target.prototype)
}
}
export class UnexpectedError extends Error {
constructor(err?: string) {
super(err)
this.name = new.target.name
Object.setPrototypeOf(this, new.target.prototype)
}
}
type Instance = {
title: string
uri: string

View file

@ -3,7 +3,7 @@ import { DEFAULT_UA } from './default'
import { ProxyConfig } from './proxy_config'
import OAuth from './oauth'
import Response from './response'
import { NoImplementedError } from './megalodon'
import { NoImplementedError, ArgumentError, UnexpectedError } from './megalodon'
export default class Misskey {
public client: MisskeyAPI.Client
@ -1103,4 +1103,119 @@ export default class Misskey {
})
.then(res => ({ ...res, data: MisskeyAPI.Converter.note(res.data) }))
}
// ======================================
// statuses/media
// ======================================
/**
* POST /api/drive/files/create
*/
public async uploadMedia(file: any, _description?: string | null, _focus?: string | null): Promise<Response<Entity.Attachment>> {
const formData = new FormData()
formData.append('file', file)
return this.client
.post<MisskeyAPI.Entity.File>('/api/drive/files/create', formData)
.then(res => ({ ...res, data: MisskeyAPI.Converter.file(res.data) }))
}
/**
* POST /api/drive/files/update
*/
public async updateMedia(
id: string,
_file?: any,
_description?: string | null,
_focus?: string | null,
is_sensitive?: boolean | null
): Promise<Response<Entity.Attachment>> {
let params = {
fileId: id
}
if (is_sensitive !== undefined && is_sensitive !== null) {
params = Object.assign(params, {
isSensitive: is_sensitive
})
}
return this.client
.post<MisskeyAPI.Entity.File>('/api/drive/files/update', params)
.then(res => ({ ...res, data: MisskeyAPI.Converter.file(res.data) }))
}
// ======================================
// statuses/polls
// ======================================
public async getPoll(_id: string): Promise<Response<Entity.Poll>> {
return new Promise((_, reject) => {
const err = new NoImplementedError('misskey does not support')
reject(err)
})
}
/**
* POST /api/notes/polls/vote
*/
public async votePoll(_id: string, choices: Array<number>, status_id?: string | null): Promise<Response<Entity.Poll>> {
if (!status_id) {
return new Promise((_, reject) => {
const err = new ArgumentError('status_id is required')
reject(err)
})
}
const params = {
noteId: status_id,
choice: choices[0]
}
await this.client.post<{}>('/api/notes/polls/vote', params)
const res = await this.client
.post<MisskeyAPI.Entity.Note>('/api/notes/show', {
noteId: status_id
})
.then(res => {
const note = MisskeyAPI.Converter.note(res.data)
return { ...res, data: note.poll }
})
if (!res.data) {
return new Promise((_, reject) => {
const err = new UnexpectedError('poll does not exist')
reject(err)
})
}
return { ...res, data: res.data }
}
// ======================================
// statuses/scheduled_statuses
// ======================================
public async getScheduledStatuses(
_limit?: number | null,
_max_id?: string | null,
_since_id?: string | null,
_min_id?: string | null
): Promise<Response<Array<Entity.ScheduledStatus>>> {
return new Promise((_, reject) => {
const err = new NoImplementedError('misskey does not support')
reject(err)
})
}
public async getScheduledStatus(_id: string): Promise<Response<Entity.ScheduledStatus>> {
return new Promise((_, reject) => {
const err = new NoImplementedError('misskey does not support')
reject(err)
})
}
public async scheduleStatus(_id: string, _scheduled_at?: string | null): Promise<Response<Entity.ScheduledStatus>> {
return new Promise((_, reject) => {
const err = new NoImplementedError('misskey does not support')
reject(err)
})
}
public async cancelScheduledStatus(_id: string): Promise<Response<{}>> {
return new Promise((_, reject) => {
const err = new NoImplementedError('misskey does not support')
reject(err)
})
}
}

View file

@ -1,4 +1,5 @@
import axios, { AxiosResponse, CancelTokenSource, AxiosRequestConfig } from 'axios'
import moment from 'moment'
import { DEFAULT_UA } from '../default'
import proxyAgent, { ProxyConfig } from '../proxy_config'
import Response from '../response'
@ -9,6 +10,7 @@ namespace MisskeyAPI {
export namespace Entity {
export type App = MisskeyEntity.App
export type Blocking = MisskeyEntity.Blocking
export type Choice = MisskeyEntity.Choice
export type CreatedNote = MisskeyEntity.CreatedNote
export type Emoji = MisskeyEntity.Emoji
export type Favorite = MisskeyEntity.Favorite
@ -18,6 +20,7 @@ namespace MisskeyAPI {
export type FollowRequest = MisskeyEntity.FollowRequest
export type Mute = MisskeyEntity.Mute
export type Note = MisskeyEntity.Note
export type Poll = MisskeyEntity.Poll
export type Relation = MisskeyEntity.Relation
export type User = MisskeyEntity.User
export type UserDetail = MisskeyEntity.UserDetail
@ -151,6 +154,28 @@ namespace MisskeyAPI {
}
}
export const choice = (c: Entity.Choice): MegalodonEntity.PollOption => {
return {
title: c.text,
votes_count: c.votes
}
}
export const poll = (p: Entity.Poll): MegalodonEntity.Poll => {
const now = moment()
const expire = moment(p.expiresAt)
const count = p.choices.reduce((sum, choice) => sum + choice.votes, 0)
return {
id: '',
expires_at: p.expiresAt,
expired: now.isAfter(expire),
multiple: p.multiple,
votes_count: count,
options: p.choices.map(c => choice(c)),
voted: p.choices.some(c => c.isVoted)
}
}
export const note = (n: Entity.Note): MegalodonEntity.Status => {
return {
id: n.id,
@ -169,14 +194,14 @@ namespace MisskeyAPI {
reblogged: false,
favourited: false,
muted: false,
sensitive: n.cw ? true : false,
sensitive: n.files ? n.files.some(f => f.isSensitive) : false,
spoiler_text: n.cw ? n.cw : '',
visibility: visibility(n.visibility),
media_attachments: n.files ? n.files.map(f => file(f)) : [],
mentions: [],
tags: [],
card: null,
poll: null,
poll: n.poll ? poll(n.poll) : null,
application: null,
language: null,
pinned: null

View file

@ -1,6 +1,7 @@
/// <reference path="user.ts" />
/// <reference path="emoji.ts" />
/// <reference path="file.ts" />
/// <reference path="poll.ts" />
namespace MisskeyEntity {
export type Note = {
@ -22,5 +23,6 @@ namespace MisskeyEntity {
emojis: Array<Emoji>
fileIds: Array<string>
files: Array<File>
poll?: Poll
}
}

View file

@ -0,0 +1,13 @@
namespace MisskeyEntity {
export type Choice = {
text: string
votes: number
isVoted: boolean
}
export type Poll = {
multiple: boolean
expiresAt: string
choices: Array<Choice>
}
}

View file

@ -9,6 +9,7 @@
/// <reference path="entities/followRequest.ts" />
/// <reference path="entities/mute.ts" />
/// <reference path="entities/note.ts" />
/// <reference path="entities/poll.ts" />
/// <reference path="entities/relation.ts" />
/// <reference path="entities/user.ts" />
/// <reference path="entities/userDetail.ts" />

View file

@ -587,15 +587,6 @@
regexpp "^3.0.0"
tsutils "^3.17.1"
"@typescript-eslint/experimental-utils@2.19.2":
version "2.19.2"
resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-2.19.2.tgz#4611d44cf0f0cb460c26aa7676fc0a787281e233"
integrity sha512-B88QuwT1wMJR750YvTJBNjMZwmiPpbmKYLm1yI7PCc3x0NariqPwqaPsoJRwU9DmUi0cd9dkhz1IqEnwfD+P1A==
dependencies:
"@types/json-schema" "^7.0.3"
"@typescript-eslint/typescript-estree" "2.19.2"
eslint-scope "^5.0.0"
"@typescript-eslint/experimental-utils@2.21.0":
version "2.21.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-2.21.0.tgz#71de390a3ec00b280b69138d80733406e6e86bfa"
@ -615,19 +606,6 @@
"@typescript-eslint/typescript-estree" "2.21.0"
eslint-visitor-keys "^1.1.0"
"@typescript-eslint/typescript-estree@2.19.2":
version "2.19.2"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-2.19.2.tgz#67485b00172f400474d243c6c0be27581a579350"
integrity sha512-Xu/qa0MDk6upQWqE4Qy2X16Xg8Vi32tQS2PR0AvnT/ZYS4YGDvtn2MStOh5y8Zy2mg4NuL06KUHlvCh95j9C6Q==
dependencies:
debug "^4.1.1"
eslint-visitor-keys "^1.1.0"
glob "^7.1.6"
is-glob "^4.0.1"
lodash "^4.17.15"
semver "^6.3.0"
tsutils "^3.17.1"
"@typescript-eslint/typescript-estree@2.21.0":
version "2.21.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-2.21.0.tgz#7e4be29f2e338195a2e8c818949ed0ff727cc943"