Skip to content

Commit

Permalink
Add basic support for Mastodon (fix #2739)
Browse files Browse the repository at this point in the history
  • Loading branch information
Bionus committed Jul 13, 2022
1 parent bda40fc commit 3f47e01
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 0 deletions.
3 changes: 3 additions & 0 deletions scripts/windows-setup/setup.iss
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,9 @@ Source: "{#SrcDir}\sites\Gelbooru (0.2)\icon.png"; DestDir: "{app}\sites\Gel
Source: "{#SrcDir}\sites\Gelbooru (0.2)\model.js"; DestDir: "{app}\sites\Gelbooru (0.2)"; Flags: ignoreversion
Source: "{#SrcDir}\sites\Gelbooru (0.2)\sites.txt"; DestDir: "{app}\sites\Gelbooru (0.2)"; Flags: ignoreversion
Source: "{#SrcDir}\sites\Gelbooru (0.2)\gelbooru.com\defaults.ini"; DestDir: "{app}\sites\Gelbooru (0.2)\gelbooru.com"; Flags: ignoreversion
Source: "{#SrcDir}\sites\Mastodon\icon.png"; DestDir: "{app}\sites\Mastodon"; Flags: ignoreversion
Source: "{#SrcDir}\sites\Mastodon\model.js"; DestDir: "{app}\sites\Mastodon"; Flags: ignoreversion
Source: "{#SrcDir}\sites\Mastodon\sites.txt"; DestDir: "{app}\sites\Mastodon"; Flags: ignoreversion
Source: "{#SrcDir}\sites\Moebooru\icon.png"; DestDir: "{app}\sites\Moebooru"; Flags: ignoreversion
Source: "{#SrcDir}\sites\Moebooru\model.js"; DestDir: "{app}\sites\Moebooru"; Flags: ignoreversion
Source: "{#SrcDir}\sites\Moebooru\sites.txt"; DestDir: "{app}\sites\Moebooru"; Flags: ignoreversion
Expand Down
Binary file added src/sites/Mastodon/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
135 changes: 135 additions & 0 deletions src/sites/Mastodon/model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
const map = {
"id": "id",
"created_at": "created_at",
"author": "account.username",
};
function parseImage(raw: any, media?: any): IImage {
const img: IImage = Grabber.mapFields(raw, map);
img.rating = raw["sensitive"] ? "explicit" : "safe";

const medias = media ? [media] : raw["media_attachments"];
if (medias.length >= 1) {
img.file_url = medias[0].remote_url || medias[0].url;
img.preview_url = medias[0].preview_remote_url || medias[0].preview_url;
if (medias[0].meta) {
img.width = medias[0].meta.original.width;
img.height = medias[0].meta.original.height;
img.preview_width = medias[0].meta.small.width;
img.preview_height = medias[0].meta.small.height;
}
}

if (medias.length > 1) {
img.type = "gallery";
img.gallery_count = medias.length;
}

return img;
}

const meta: Record<string, MetaField> = {
user_id: {
type: "input",
},
}

export const source: ISource = {
name: "Mastodon",
modifiers: ["user:"],
forcedTokens: [],
meta,
auth: {
oauth2: {
type: "oauth2",
authType: "authorization_code",
authorizationUrl: "/oauth/authorize",
tokenUrl: "/oauth/token",
scopes: ["read"],
},
},
apis: {
json: {
name: "JSON",
auth: [],
maxLimit: 40,
search: {
url: (query: ISearchQuery, opts: IUrlOptions): string | IError => {
const search = Grabber.parseSearchQuery(query.search, meta);

// Search
if (search.query) {
if (!opts.loggedIn) {
return { error: "You must be logged in to use search" };
}
const userId = search.user_id ? "&account_id=" + search.user_id : "";
return "/api/v2/search?type=statuses&q=" + encodeURIComponent(search.query) + userId + "&limit=" + opts.limit;
}

// User ID
if (search.user_id) {
return "/api/v1/accounts/" + search.user_id + "/statuses?only_media=true&limit=" + opts.limit;
}

// Public timeline
return "/api/v1/timelines/public?only_media=true&limit=" + opts.limit;
},
parse: (src: string): IParsedSearch => {
const data: any[] = JSON.parse(src);
const images = data.map((raw: any) => parseImage(raw));
return {
images,
};
},
},
gallery: {
url: (query: IGalleryQuery): string => {
return "/api/v1/statuses/" + query.id;
},
parse: (src: string): IParsedGallery | IError => {
let data = JSON.parse(src);
if ("statuses" in data) {
data = data["statuses"];
}

const medias = data["media_attachments"];
if (medias.length <= 1) {
return { error: "Not a gallery" };
}

const images = medias.map((media: any) => parseImage(data, media));
return {
images,
imageCount: images.length,
};
},
},
details: {
fullResults: true,
url: (id: string, md5: string): string => {
return "/api/v1/statuses/" + id;
},
parse: (src: string): IImage => {
const data = JSON.parse(src);
const img = parseImage(data);

// For galleries, we should trust the original information from the gallery endpoint, not the new one which is always the first page
if (img.type === "gallery") {
delete img.file_url;
delete img.sample_url;
delete img.preview_url;
}

return img;
},
},
check: {
url: (): string => {
return "/about";
},
parse: (src: string): boolean => {
return src.indexOf("joinmastodon.org") !== -1;
},
},
},
},
};
Empty file added src/sites/Mastodon/sites.txt
Empty file.
Empty file.

0 comments on commit 3f47e01

Please sign in to comment.