@rmdes/indiekit-endpoint-activitypub 0.1.9 → 0.1.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +1 -1
- package/lib/controllers/migrate.js +9 -12
- package/package.json +1 -1
- package/views/activitypub-migrate.njk +29 -7
package/index.js
CHANGED
|
@@ -180,7 +180,7 @@ export default class ActivityPubEndpoint {
|
|
|
180
180
|
router.get("/admin/activities", activitiesController(mp));
|
|
181
181
|
router.get("/admin/migrate", migrateGetController(mp, this.options));
|
|
182
182
|
router.post("/admin/migrate", migratePostController(mp, this.options));
|
|
183
|
-
router.post("/admin/migrate/import",
|
|
183
|
+
router.post("/admin/migrate/import", migrateImportController(mp, this.options));
|
|
184
184
|
|
|
185
185
|
return router;
|
|
186
186
|
}
|
|
@@ -7,8 +7,6 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import {
|
|
10
|
-
parseMastodonFollowingCsv,
|
|
11
|
-
parseMastodonFollowersList,
|
|
12
10
|
bulkImportFollowing,
|
|
13
11
|
bulkImportFollowers,
|
|
14
12
|
} from "../migration.js";
|
|
@@ -56,19 +54,20 @@ export function migratePostController(mountPath, pluginOptions) {
|
|
|
56
54
|
}
|
|
57
55
|
|
|
58
56
|
/**
|
|
59
|
-
* JSON endpoint for
|
|
60
|
-
*
|
|
57
|
+
* JSON endpoint for import — receives { handles, importTypes }.
|
|
58
|
+
* CSV is parsed client-side to extract handles only, keeping the
|
|
59
|
+
* JSON payload small enough for Express's default body parser limit.
|
|
61
60
|
*/
|
|
62
61
|
export function migrateImportController(mountPath, pluginOptions) {
|
|
63
62
|
return async (request, response, next) => {
|
|
64
63
|
try {
|
|
65
64
|
const { application } = request.app.locals;
|
|
66
|
-
const {
|
|
65
|
+
const { handles, importTypes } = request.body;
|
|
67
66
|
|
|
68
|
-
if (!
|
|
67
|
+
if (!Array.isArray(handles) || handles.length === 0) {
|
|
69
68
|
return response.status(400).json({
|
|
70
69
|
type: "error",
|
|
71
|
-
text: "No
|
|
70
|
+
text: "No handles provided.",
|
|
72
71
|
});
|
|
73
72
|
}
|
|
74
73
|
|
|
@@ -84,15 +83,13 @@ export function migrateImportController(mountPath, pluginOptions) {
|
|
|
84
83
|
let followersResult = { imported: 0, failed: 0, errors: [] };
|
|
85
84
|
|
|
86
85
|
if (importFollowing && followingCollection) {
|
|
87
|
-
|
|
88
|
-
console.log(`[ActivityPub] Migration: parsed ${handles.length} following handles from CSV`);
|
|
86
|
+
console.log(`[ActivityPub] Migration: importing ${handles.length} following handles`);
|
|
89
87
|
followingResult = await bulkImportFollowing(handles, followingCollection);
|
|
90
88
|
}
|
|
91
89
|
|
|
92
90
|
if (importFollowers && followersCollection) {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
followersResult = await bulkImportFollowers(entries, followersCollection);
|
|
91
|
+
console.log(`[ActivityPub] Migration: importing ${handles.length} follower entries`);
|
|
92
|
+
followersResult = await bulkImportFollowers(handles, followersCollection);
|
|
96
93
|
}
|
|
97
94
|
|
|
98
95
|
const totalFailed = followingResult.failed + followersResult.failed;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rmdes/indiekit-endpoint-activitypub",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.10",
|
|
4
4
|
"description": "ActivityPub federation endpoint for Indiekit via Fedify. Adds full fediverse support: actor, inbox, outbox, followers, following, syndication, and Mastodon migration.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"indiekit",
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
@change="readFile($event)">
|
|
77
77
|
<template x-if="fileName">
|
|
78
78
|
<p class="hint" style="margin-top: 0.5em">
|
|
79
|
-
<strong x-text="fileName"></strong> — <span x-text="
|
|
79
|
+
<strong x-text="fileName"></strong> — <span x-text="handles.length + ' accounts found'"></span>
|
|
80
80
|
</p>
|
|
81
81
|
</template>
|
|
82
82
|
<template x-if="fileError">
|
|
@@ -85,7 +85,7 @@
|
|
|
85
85
|
</div>
|
|
86
86
|
|
|
87
87
|
<button class="button" type="button"
|
|
88
|
-
:disabled="importing ||
|
|
88
|
+
:disabled="importing || handles.length === 0"
|
|
89
89
|
@click="startImport()">
|
|
90
90
|
<span x-show="!importing">{{ __("activitypub.migrate.importButton") }}</span>
|
|
91
91
|
<span x-show="importing" x-text="statusText"></span>
|
|
@@ -119,7 +119,7 @@
|
|
|
119
119
|
<script>
|
|
120
120
|
function csvImport(mountPath) {
|
|
121
121
|
return {
|
|
122
|
-
|
|
122
|
+
handles: [],
|
|
123
123
|
fileName: '',
|
|
124
124
|
lineCount: 0,
|
|
125
125
|
fileError: '',
|
|
@@ -129,9 +129,14 @@
|
|
|
129
129
|
resultText: '',
|
|
130
130
|
resultErrors: [],
|
|
131
131
|
|
|
132
|
+
/**
|
|
133
|
+
* Parse CSV client-side — extract handles (first column) only.
|
|
134
|
+
* This keeps the JSON payload small (handles only, no raw CSV),
|
|
135
|
+
* avoiding Express's default 100KB body parser limit.
|
|
136
|
+
*/
|
|
132
137
|
readFile(event) {
|
|
133
138
|
var self = this;
|
|
134
|
-
self.
|
|
139
|
+
self.handles = [];
|
|
135
140
|
self.fileName = '';
|
|
136
141
|
self.lineCount = 0;
|
|
137
142
|
self.fileError = '';
|
|
@@ -151,9 +156,19 @@
|
|
|
151
156
|
var reader = new FileReader();
|
|
152
157
|
reader.onload = function(e) {
|
|
153
158
|
var text = e.target.result;
|
|
154
|
-
|
|
159
|
+
var lines = text.split('\n').filter(function(l) { return l.trim(); });
|
|
155
160
|
self.fileName = file.name;
|
|
156
|
-
self.lineCount =
|
|
161
|
+
self.lineCount = lines.length;
|
|
162
|
+
|
|
163
|
+
// Extract handles: skip header, take first CSV column, keep only valid handles
|
|
164
|
+
var parsed = [];
|
|
165
|
+
for (var i = 1; i < lines.length; i++) {
|
|
166
|
+
var handle = lines[i].split(',')[0].trim();
|
|
167
|
+
if (handle && handle.indexOf('@') !== -1) {
|
|
168
|
+
parsed.push(handle);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
self.handles = parsed;
|
|
157
172
|
};
|
|
158
173
|
reader.onerror = function() {
|
|
159
174
|
self.fileError = 'Could not read file';
|
|
@@ -183,12 +198,19 @@
|
|
|
183
198
|
return;
|
|
184
199
|
}
|
|
185
200
|
|
|
201
|
+
if (self.handles.length === 0) {
|
|
202
|
+
self.importing = false;
|
|
203
|
+
self.resultType = 'error';
|
|
204
|
+
self.resultText = 'No valid handles found in the CSV file.';
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
|
|
186
208
|
try {
|
|
187
209
|
var res = await fetch(mountPath + '/admin/migrate/import', {
|
|
188
210
|
method: 'POST',
|
|
189
211
|
headers: { 'Content-Type': 'application/json' },
|
|
190
212
|
body: JSON.stringify({
|
|
191
|
-
|
|
213
|
+
handles: self.handles,
|
|
192
214
|
importTypes: importTypes
|
|
193
215
|
})
|
|
194
216
|
});
|