Skip to content

Commit

Permalink
Merge branch 'develop' into enhance/antennaservice
Browse files Browse the repository at this point in the history
  • Loading branch information
kozakura913 authored Dec 20, 2024
2 parents f40045c + 81106eb commit f0c307f
Show file tree
Hide file tree
Showing 64 changed files with 436 additions and 278 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG_YOJO.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,27 @@
## 1.2.0
Cherrypick 4.13.0
Misskey 2024.10.1

### Release Date
2024-12-20

### General
- Change: nodeinfoでyojo-artを名乗る [#565](https://github.com/yojo-art/cherrypick/pull/565)
- Fix: ノートを編集する時に検索許可範囲を記憶する [#558](https://github.com/yojo-art/cherrypick/pull/558)

### Client
- Fix: 絵文字情報表示でローカルのものに絵文字URLが表示されない [#562](https://github.com/yojo-art/cherrypick/pull/562)
- Enhance: 表示中のタグTLをお気に入り登録するボタンを追加 [#561](https://github.com/yojo-art/cherrypick/pull/561)

### Server
- Fix: `api/ap/fetch-outbox`が正しく動作しないのを修正[#560](https://github.com/yojo-art/cherrypick/pull/560)
- Fix: PersonのserchableByが正しく連合できていないのを修正[#556](https://github.com/yojo-art/cherrypick/pull/556)
- Fix: SerchableByが未設定の時にプライバシーを更新できないことがある[#567](https://github.com/yojo-art/cherrypick/pull/567)
- Enhance: `/users/${id}``Accept: application/ld+json`ではないリクエストが来たとき`/@${username}`にリダイレクトするように [#554](https://github.com/yojo-art/cherrypick/pull/554)

## 1.1.0
Cherrypick 4.11.1
Misskey 2024.8.0

### Release Date
2024-11-08
Expand Down Expand Up @@ -113,6 +122,7 @@ docker環境でノートレコードが多数(数百万件)ある場合**一時

## 1.0.1
Cherrypick 4.11.1
Misskey 2024.8.0

### Release Date
2024-09-06
Expand All @@ -129,6 +139,7 @@ Cherrypick 4.11.1

## 1.0.0
Cherrypick 4.11.1
Misskey 2024.8.0

### Release Date
2024-09-05
Expand Down
86 changes: 48 additions & 38 deletions locales/index.d.ts

Large diffs are not rendered by default.

77 changes: 40 additions & 37 deletions locales/ja-JP.yml

Large diffs are not rendered by default.

7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
{
"name": "cherrypick",
"version": "4.13.0-yojo1.2.0",
"name": "yojo-art",
"version": "1.2.0",
"basedMisskeyVersion": "2024.10.1",
"basedCherrypickVersion": "4.13.0",
"codename": "nasubi",
"repository": {
"type": "git",
"url": "https://github.com/kokonect-link/cherrypick.git"
"url": "https://github.com/yojo-art/cherrypick.git"
},
"packageManager": "pnpm@9.6.0",
"workspaces": [
Expand Down
23 changes: 12 additions & 11 deletions packages/backend/src/boot/master.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,26 +31,27 @@ const themeColor = chalk.hex('#ffa9c3');

function greet() {
if (!envOption.quiet) {
//#region CherryPick logo
//#region yojo-art logo
const v = `v${meta.version}`;
console.log(chalk.hex('#ffa9c3').bold(' _________ .__ ') + chalk.hex('#95e3e8').bold('__________.__ __ '));
console.log(chalk.hex('#ffa9c3').bold(' \\_ ___ \\| |__ __________________ ___.__.') + chalk.hex('#95e3e8').bold('\\______ \\__| ____ | | __'));
console.log(chalk.hex('#ffa9c3').bold(' / \\ \\/| | \\_/ __ \\_ __ \\_ __ < | |') + chalk.hex('#95e3e8').bold(' | ___/ |/ ___\\| |/ /'));
console.log(chalk.hex('#ffa9c3').bold(' \\ \\___| Y \\ ___/| | \\/| | \\/\\___ |') + chalk.hex('#95e3e8').bold(' | | | \\ \\___| < '));
console.log(chalk.hex('#ffa9c3').bold(' \\______ /___| /\\___ >__| |__| / ____|') + chalk.hex('#95e3e8').bold(' |____| |__|\\___ >__|_ \\'));
console.log(chalk.hex('#ffa9c3').bold(' \\/ \\/ \\/ \\/ ') + chalk.hex('#95e3e8').bold(' \\/ \\/'));
console.log(chalk.hex('#ffa9c3').bold(' _ ') + chalk.hex('#95e3e8').bold(' _ '));
console.log(chalk.hex('#ffa9c3').bold(' _ _ ___ (_) ___ ') + chalk.hex('#95e3e8').bold(' __ _ _ __| |_ '));
console.log(chalk.hex('#ffa9c3').bold('| | | |/ _ \\| |/ _ \\ ') + chalk.hex('#95e3e8').bold('_____ / _` | \'__| __|'));
console.log(chalk.hex('#ffa9c3').bold('| |_| | (_) | | (_) |') + chalk.hex('#95e3e8').bold('_____| (_| | | | |_ '));
console.log(chalk.hex('#ffa9c3').bold(' \\__, |\\___// |\\___/ ') + chalk.hex('#95e3e8').bold(' \\__,_|_| \\__|'));
console.log(chalk.hex('#ffa9c3').bold(' |___/ |__/ ') + chalk.hex('#95e3e8').bold(' '));
//#endregion

console.log(chalk.hex('#ffa9c3').bold(' Cherry') + chalk.hex('#95e3e8').bold('Pick') + (' is an open-source decentralized microblogging platform based from') + (chalk.hex('#9ec23f').bold(' Misskey') + ('.')));
console.log(chalk.hex('#ffbb00')(' If you like ') + chalk.hex('#ffa9c3').bold('Cherry') + chalk.hex('#95e3e8').bold('Pick') + chalk.hex('#ffbb00')(', please donate to support development. https://www.patreon.com/noridev & https://www.paypal.me/noridev & https://toss.me/noridev'));
console.log(chalk.hex('#ffa9c3').bold(' yojo') + chalk.hex('#98e2cf').bold('-') + chalk.hex('#95e3e8').bold('art') + (' is an open-source decentralized microblogging platform based from') + (chalk.hex('#9ec23f').bold(' Misskey') + (' and') + chalk.hex('#ffa9c3').bold(' Cherry') + chalk.hex('#95e3e8').bold('Pick') + '.'));
console.log(chalk.hex('#ffbb00')(' If you like ') + chalk.hex('#ffa9c3').bold(' yojo') + chalk.hex('#98e2cf').bold('-') + chalk.hex('#95e3e8').bold('art') + chalk.hex('#ffbb00')(', please donate to support development. https://yojo-art.fanbox.cc/'));
// console.log(chalk.hex('#ffa9c3').bold(' KOKO') + chalk.hex('#95e3e8').bold('NECT') + chalk.hex('#ffa9c3')(' with') + chalk.hex('#95e3e8').bold(' NoriDev.'));

console.log('');
console.log(chalkTemplate`--- ${os.hostname()} {gray (PID: ${process.pid.toString()})} ---`);
}

bootLogger.info('Welcome to CherryPick!');
bootLogger.info(`CherryPick v${meta.version}`, null, true);
bootLogger.info('Welcome to yojo-art!');
bootLogger.info(`yojo-art v${meta.version}`, null, true);
bootLogger.info(`Based on Cherrypick v${meta.basedCherrypickVersion}`, null, true);
bootLogger.info(`Based on Misskey v${meta.basedMisskeyVersion}`, null, true);
}

Expand Down
3 changes: 3 additions & 0 deletions packages/backend/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ export type Config = {

version: string;
basedMisskeyVersion: string;
basedCherrypickVersion: string;
publishTarballInsteadOfProvideRepositoryUrl: boolean;
setupPassword: string | undefined;
host: string;
Expand Down Expand Up @@ -261,6 +262,7 @@ export function loadConfig(): Config {
const url = tryCreateUrl(config.url ?? process.env.CHERRYPICK_URL ?? '');
const version = meta.version;
const basedMisskeyVersion = meta.basedMisskeyVersion;
const basedCherrypickVersion = meta.basedCherrypickVersion;
const host = url.host;
const hostname = url.hostname;
const scheme = url.protocol.replace(/:$/, '');
Expand All @@ -284,6 +286,7 @@ export function loadConfig(): Config {
return {
version,
basedMisskeyVersion,
basedCherrypickVersion,
publishTarballInsteadOfProvideRepositoryUrl: !!config.publishTarballInsteadOfProvideRepositoryUrl,
setupPassword: config.setupPassword,
url: url.origin,
Expand Down
1 change: 1 addition & 0 deletions packages/backend/src/core/FetchInstanceMetadataService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ type NodeInfo = {
name?: unknown;
version?: unknown;
basedMisskeyVersion?: unknown;
basedCherrypickVersion?: unknown;
};
metadata?: {
name?: unknown;
Expand Down
15 changes: 14 additions & 1 deletion packages/backend/src/core/activitypub/ApResolverService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { UtilityService } from '@/core/UtilityService.js';
import { bindThis } from '@/decorators.js';
import { LoggerService } from '@/core/LoggerService.js';
import type Logger from '@/logger.js';
import { isCollectionOrOrderedCollection, isIOrderedCollectionPage } from './type.js';
import { isCollectionOrOrderedCollection, isIOrderedCollectionPage, isOrderedCollection } from './type.js';
import { ApDbResolverService } from './ApDbResolverService.js';
import { ApRendererService } from './ApRendererService.js';
import { ApRequestService } from './ApRequestService.js';
Expand Down Expand Up @@ -65,6 +65,19 @@ export class Resolver {
}
}

@bindThis
public async resolveOrderedCollection(value: string | IObject): Promise<IOrderedCollection> {
const collection = typeof value === 'string'
? await this.resolve(value)
: value;

if (isOrderedCollection(collection)) {
return collection;
} else {
throw new Error(`unrecognized collection type: ${collection.type}`);
}
}

@bindThis
public async resolveOrderedCollectionPage(value: string | IObject): Promise<IOrderedCollectionPage> {
const collection = typeof value === 'string'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { NoteEntityService } from '@/core/entities/NoteEntityService.js';
import { NoteCreateService } from '@/core/NoteCreateService.js';
import { IdentifiableError } from '@/misc/identifiable-error.js';
import { ApDbResolverService } from '@/core/activitypub/ApDbResolverService.js';
import { isIOrderedCollectionPage, isCreate, IOrderedCollectionPage, isNote } from '../type.js';
import { isCreate, IOrderedCollectionPage, isNote } from '../type.js';
import { ApAudienceService } from '../ApAudienceService.js';
import type { OnModuleInit } from '@nestjs/common';
import type { ApNoteService } from './ApNoteService.js';
Expand Down Expand Up @@ -83,55 +83,42 @@ export class ApOutboxFetchService implements OnModuleInit {
this.logger.info(`Fetcing the Outbox: ${outboxUrl}`);
const Resolver = resolver ?? this.apResolverService.createResolver();
const cache = await this.redisClient.get(`${outboxUrl}--next`);
// Resolve to (Ordered)Collection Object
const outbox = cache ? await Resolver.resolveOrderedCollectionPage(cache) : await Resolver.resolveCollection(outboxUrl);
let next: string | IOrderedCollectionPage;

if (!cache && outbox.type !== 'OrderedCollection') throw new IdentifiableError('0be2f5a1-2345-46d8-b8c3-430b111c68d3', 'outbox type is not OrderedCollection');
if (!cache && !outbox.first) throw new IdentifiableError('a723c2df-0250-4091-b5fc-e3a7b36c7b61', 'outbox first page not exist');
if (!cache) {
// Resolve to (Ordered)Collection Object
const outbox = await Resolver.resolveOrderedCollection(outboxUrl);
if (!outbox.first) throw new IdentifiableError('a723c2df-0250-4091-b5fc-e3a7b36c7b61', 'outbox first page not exist');
next = outbox.first;
} else next = cache;

let nextUrl = cache ? (outbox as IOrderedCollectionPage).next : outbox.first;
let page = 0;
let created = 0;
if (typeof(nextUrl) !== 'string') {
const first = (nextUrl as any);
if (first.partOf !== user.outbox) throw new IdentifiableError('6603433f-99db-4134-980c-48705ae57ab8', 'outbox part is invalid');

const activityes = first.orderedItems ?? first.items;
await this.fetchObjects(user, activityes, includeAnnounce, created);
for (let page = 0; page < pagelimit; page++) {
const collection = (typeof(next) === 'string' ? await Resolver.resolveOrderedCollectionPage(next) : next);
if (collection.partOf !== user.outbox) throw new IdentifiableError('6603433f-99db-4134-980c-48705ae57ab8', 'outbox part is invalid');

page = 1;
if (!first.next) return;
}

for (; page < pagelimit; page++) {
this.logger.info(nextUrl as string);
const collectionPage = (typeof(nextUrl) === 'string' ? await Resolver.resolveOrderedCollectionPage(nextUrl) : nextUrl) as IOrderedCollectionPage;
if (!isIOrderedCollectionPage(collectionPage)) throw new IdentifiableError('2a05bb06-f38c-4854-af6f-7fd5e87c98ee', 'Object is not collectionPage');
if (collectionPage.partOf !== user.outbox) throw new IdentifiableError('6603433f-99db-4134-980c-48705ae57ab8', 'outbox part is invalid');

const activityes = (collectionPage.orderedItems ?? collectionPage.items);
nextUrl = collectionPage.next;
if (!activityes) continue;
const activityes = (collection.orderedItems ?? collection.items);
if (!activityes) throw new IdentifiableError('2a05bb06-f38c-4854-af6f-7fd5e87c98ee', 'item is unavailable');

created = await this.fetchObjects(user, activityes, includeAnnounce, created);
if (createLimit <= created) break;//次ページ見て一件だけしか取れないのは微妙
if (!nextUrl) {
break;
}
if (!collection.next) break;

await this.redisClient.set(`${outboxUrl}--next`, `${nextUrl}`, 'EX', 60 * 15);//15min
next = collection.next;
await this.redisClient.set(`${outboxUrl}--next`, `${next}`, 'EX', 60 * 15);//15min
}
this.logger.succ(`Outbox Fetced: ${outboxUrl}`);
//this.logger.info(`Outbox Fetced last: ${nextUrl}`);
}

@bindThis
private async fetchObjects(user: MiRemoteUser, activityes: any[], includeAnnounce:boolean, created: number): Promise<number> {
for (const activity of activityes) {
if (createLimit < created) return created;
try {
if (includeAnnounce && activity.type === 'Announce') {
const object = await this.apDbResolverService.getNoteFromApId(activity.id);
if (activity.actor !== user.uri) throw new IdentifiableError('bde7c204-5441-4a87-9b7e-f81e8d05788a');
if (activity.type === 'Announce' && includeAnnounce) {
const object = await this.apNoteService.fetchNote(activity.id);

if (object) continue;

Expand Down Expand Up @@ -188,18 +175,22 @@ export class ApOutboxFetchService implements OnModuleInit {
} finally {
unlock();
}
} else if (isCreate(activity) && typeof(activity.object) !== 'string' && isNote(activity.object)) {
const object = await this.apDbResolverService.getNoteFromApId(activity.object);
if (object) continue;
} else if (isCreate(activity)) {
if (typeof(activity.object) !== 'string') {
if (!isNote(activity)) continue;
}
const fetch = await this.apNoteService.fetchNote(activity.object);
if (fetch) continue;
await this.apNoteService.createNote(activity.object, undefined, true);
}
} catch (err) {
if (err instanceof AbortError) {
this.logger.warn(`Aborted note: ${activity.id}`);
//リモートのリモートが落ちてるなどで止まるとほかが見れなくなってしまうので再スローしない
if (err instanceof IdentifiableError) {
if (err.id === 'bde7c204-5441-4a87-9b7e-f81e8d05788a') this.logger.error(`fetchErrorInvalidActor:${activity.id}`);
} else {
this.logger.warn(JSON.stringify(err));
this.logger.warn(JSON.stringify(activity));
throw err;
this.logger.error(`fetchError:${activity.id}`);
this.logger.error(`${err}`);
continue;
}
}
created ++;
Expand Down
3 changes: 1 addition & 2 deletions packages/backend/src/core/activitypub/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,15 +112,14 @@ export interface IOrderedCollection extends IObject {
type: 'OrderedCollection';
totalItems?: number;
orderedItems?: ApObject;
first?: IObject | string;
first?: IOrderedCollectionPage | string;
last?: IObject | string;
}

export interface IOrderedCollectionPage extends IObject {
type: 'OrderedCollectionPage';
partOf: string;
totalItems?: number;
first?: IObject | string;
orderedItems?: IObject[];
items?: IObject[];
prev: string;
Expand Down
1 change: 1 addition & 0 deletions packages/backend/src/core/entities/MetaEntityService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ export class MetaEntityService {

version: this.config.version,
basedMisskeyVersion: this.config.basedMisskeyVersion,
basedCherrypickVersion: this.config.basedCherrypickVersion,
providesTarball: this.config.publishTarballInsteadOfProvideRepositoryUrl,

name: instance.name,
Expand Down
4 changes: 2 additions & 2 deletions packages/backend/src/models/Meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -414,14 +414,14 @@ export class MiMeta {

@Column('varchar', {
length: 1024,
default: 'https://github.com/kokonect-link/cherrypick',
default: 'https://github.com/yojo-art/cherrypick',
nullable: true,
})
public repositoryUrl: string | null;

@Column('varchar', {
length: 1024,
default: 'https://github.com/kokonect-link/cherrypick/issues/new',
default: 'https://github.com/yojo-art/cherrypick/issues/new',
nullable: true,
})
public feedbackUrl: string | null;
Expand Down
8 changes: 6 additions & 2 deletions packages/backend/src/models/json-schema/meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ export const packedMetaLiteSchema = {
type: 'string',
optional: false, nullable: false,
},
basedCherrypickVersion: {
type: 'string',
optional: false, nullable: false,
},
providesTarball: {
type: 'boolean',
optional: false, nullable: false,
Expand Down Expand Up @@ -60,12 +64,12 @@ export const packedMetaLiteSchema = {
repositoryUrl: {
type: 'string',
optional: false, nullable: true,
default: 'https://github.com/kokonect-link/cherrypick',
default: 'https://github.com/yojo-art/cherrypick',
},
feedbackUrl: {
type: 'string',
optional: false, nullable: true,
default: 'https://github.com/kokonect-link/cherrypick/issues/new',
default: 'https://github.com/yojo-art/cherrypick/issues/new',
},
statusUrl: {
type: 'string',
Expand Down
3 changes: 2 additions & 1 deletion packages/backend/src/server/NodeinfoServerService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,10 @@ export class NodeinfoServerService {
* ソフトウェアの名前を変更すると、一部の独自機能が使用できなくなったり、CherryPickとして認識されないなどの不利益が発生する場合があります。
* フォーク開発者はこの点に注意して修正を行ってください。
*/
name: 'cherrypick',
name: 'yojo-art',
version: this.config.version,
basedMisskeyVersion: this.config.basedMisskeyVersion,
basedCherrypickVersion: this.config.basedCherrypickVersion,
homepage: nodeinfo_homepage,
repository: meta.repositoryUrl,
},
Expand Down
1 change: 1 addition & 0 deletions packages/backend/src/server/api/endpoints/admin/meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -660,6 +660,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
maintainerEmail: instance.maintainerEmail,
version: this.config.version,
basedMisskeyVersion: this.config.basedMisskeyVersion,
basedCherrypickVersion: this.config.basedCherrypickVersion,
name: instance.name,
shortName: instance.shortName,
uri: this.config.url,
Expand Down
16 changes: 12 additions & 4 deletions packages/backend/src/server/api/endpoints/ap/fetch-outbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,16 @@ export const meta = {
code: 'OUTBOX_FIRST_PAGE_UNDEFINED_THIS_USER',
id: 'e1f29e66-86a9-4fdc-9be6-63d4587dc350',
},
invalidPart: {
message: 'outbox part is invalid',
code: 'OUTBOX_PART_IS_INVALID',
id: 'c3e584df-068a-4b1d-967e-54f2f30f7cba',
},
itemIsUnavailable: {
message: 'outbox item is unavailable',
code: 'OUTBOX_ITEM_IS_UNAVAILABLE',
id: 'a07b05af-5f66-4203-918c-ebff9e9384bf',
},
},
} as const;

Expand Down Expand Up @@ -83,11 +93,9 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
if (err.id === '3fc5a089-cab4-48db-b9f3-f220574b3c0a') throw new ApiError(meta.errors.noSuchUser);
if (err.id === '67070303-177c-4600-af93-b26a7ab889c6') throw new ApiError(meta.errors.isLocalUser);
if (err.id === 'e7a2e510-a8ce-40e9-b1e6-c007bacdc89f') throw new ApiError(meta.errors.outboxUndefined);
//if (err.id === 'b27090c8-8a68-4189-a445-14591c32a89c')
//if (err.id === '0be2f5a1-2345-46d8-b8c3-430b111c68d3')
if (err.id === 'a723c2df-0250-4091-b5fc-e3a7b36c7b61') throw new ApiError(meta.errors.outboxFirstPageUndefined);
//if (err.id === '6603433f-99db-4134-980c-48705ae57ab8')
//if (err.id === '2a05bb06-f38c-4854-af6f-7fd5e87c98ee')
if (err.id === '6603433f-99db-4134-980c-48705ae57ab8') throw new ApiError(meta.errors.invalidPart);
if (err.id === '2a05bb06-f38c-4854-af6f-7fd5e87c98ee') throw new ApiError(meta.errors.itemIsUnavailable);
}
throw (err);
}
Expand Down
Loading

0 comments on commit f0c307f

Please sign in to comment.