From 8bedd4e113d2c46e7a334620a785acf5bd449c5e Mon Sep 17 00:00:00 2001 From: Michael DiCarlo Date: Tue, 15 Jun 2021 07:22:44 -0400 Subject: [PATCH 1/4] Start v3.0.35 --- electron-app/package.json | 2 +- package.json | 2 +- ui/package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/electron-app/package.json b/electron-app/package.json index 883565f9..c89d3bb3 100644 --- a/electron-app/package.json +++ b/electron-app/package.json @@ -1,6 +1,6 @@ { "name": "postybirb-plus", - "version": "3.0.34", + "version": "3.0.35", "description": "(ClientServer) PostyBirb is an application that helps artists post art and other multimedia to multiple websites more quickly.", "main": "dist/main.js", "author": "Michael DiCarlo", diff --git a/package.json b/package.json index 60621b36..3b8166fc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postybirb-plus", - "version": "3.0.34", + "version": "3.0.35", "description": "PostyBirb is an application that helps artists post art and other multimedia to multiple websites more quickly..", "main": "index.js", "scripts": { diff --git a/ui/package.json b/ui/package.json index 17b7e132..483201dc 100644 --- a/ui/package.json +++ b/ui/package.json @@ -1,6 +1,6 @@ { "name": "postybirb-plus-ui", - "version": "3.0.34", + "version": "3.0.35", "license": "BSD-3-Clause", "private": true, "Author": "Michael DiCarlo", From 65e85fdeb901502a79dcb973701badc4fe8d4079 Mon Sep 17 00:00:00 2001 From: Michael DiCarlo Date: Tue, 15 Jun 2021 07:28:36 -0400 Subject: [PATCH 2/4] DeviantArt: Fix folders to respect new api structure --- .../deviant-art/deviant-art.service.ts | 35 +++++++++++++++++-- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/electron-app/src/server/websites/deviant-art/deviant-art.service.ts b/electron-app/src/server/websites/deviant-art/deviant-art.service.ts index 0f2318e5..2cfab5c7 100644 --- a/electron-app/src/server/websites/deviant-art/deviant-art.service.ts +++ b/electron-app/src/server/websites/deviant-art/deviant-art.service.ts @@ -30,6 +30,15 @@ import { LoginResponse } from '../interfaces/login-response.interface'; import { ScalingOptions } from '../interfaces/scaling-options.interface'; import { Website } from '../website.base'; +interface DeviantArtFolder { + description: string; + folderid: string; + has_subfolders: boolean; + name: string; + parent?: string; + subfolders: DeviantArtFolder[]; +} + @Injectable() export class DeviantArt extends Website { readonly BASE_URL = 'https://www.deviantart.com'; @@ -104,9 +113,24 @@ export class DeviantArt extends Website { return renewed; } + private flattenFolders(folder: DeviantArtFolder): DeviantArtFolder[] { + const folders = [folder]; + + if (!folder) { + return []; + } + + if (!folder.has_subfolders) { + return folders; + } + + folder.subfolders.forEach((sf) => folders.push(...this.flattenFolders(sf))); + return folders; + } + private async getFolders(profileId: string, token: string) { const res = await Http.get<{ - results: Array<{ folderid: string; name: string; parent: string }>; + results: Array; }>( `${this.BASE_URL}/api/v1/oauth2/gallery/folders?calculate_size=false&limit=50&access_token=${token}`, undefined, @@ -115,9 +139,14 @@ export class DeviantArt extends Website { const folders: Folder[] = []; const results = res.body.results || []; - results.forEach((folder) => { + const flattenedFolders: DeviantArtFolder[] = []; + results.forEach((r: DeviantArtFolder) => + flattenedFolders.push(...this.flattenFolders(r)), + ); + + flattenedFolders.forEach((folder) => { const parent = folder.parent - ? results.find((f) => f.folderid === folder.parent && f.name !== 'Featured') + ? flattenedFolders.find((f) => f.folderid === folder.parent && f.name !== 'Featured') : undefined; folders.push({ value: folder.folderid, From b0f878fca996bb665e34cc9cfe7c57ff47328b33 Mon Sep 17 00:00:00 2001 From: Michael DiCarlo Date: Tue, 15 Jun 2021 07:32:17 -0400 Subject: [PATCH 3/4] FurryNetwork: Filter . in tags --- .../src/server/websites/furry-network/furry-network.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/electron-app/src/server/websites/furry-network/furry-network.service.ts b/electron-app/src/server/websites/furry-network/furry-network.service.ts index 6c80080e..cd7c372a 100644 --- a/electron-app/src/server/websites/furry-network/furry-network.service.ts +++ b/electron-app/src/server/websites/furry-network/furry-network.service.ts @@ -382,7 +382,7 @@ export class FurryNetwork extends Website { .formatTags(tags, { spaceReplacer: '-', maxLength: 30, minLength: 3 }) .map(tag => tag - .replace(/(\(|\)|:|#|;|\]|\[|')/g, '') + .replace(/(\(|\)|:|#|;|\]|\[|\.|')/g, '') .replace(/(\\|\/)/g, '-') .replace(/\?/g, 'unknown'), ) From 79c9dc0b503c86187cea7d5b3ad5c7f131ef21de Mon Sep 17 00:00:00 2001 From: Michael DiCarlo Date: Tue, 15 Jun 2021 08:38:55 -0400 Subject: [PATCH 4/4] Telegram: Login check should be more stable + Expanded supported uploaded file types (unbound) + Store username for display --- .../websites/telegram/telegram.service.ts | 89 +++++++++++-------- 1 file changed, 51 insertions(+), 38 deletions(-) diff --git a/electron-app/src/server/websites/telegram/telegram.service.ts b/electron-app/src/server/websites/telegram/telegram.service.ts index c6fa2d31..c8068ff7 100644 --- a/electron-app/src/server/websites/telegram/telegram.service.ts +++ b/electron-app/src/server/websites/telegram/telegram.service.ts @@ -36,18 +36,20 @@ import FormContent from 'src/server/utils/form-content.util'; export class Telegram extends Website { readonly BASE_URL: string; readonly defaultDescriptionParser = PlaintextParser.parse; - readonly acceptsFiles: string[] = ['jpg', 'gif', 'png']; // TODO expand functionality here + readonly acceptsFiles: string[] = []; private readonly instances: Record = {}; private authData: Record = {}; public acceptsAdditionalFiles = true; public waitBetweenPostsInterval = 30_000; private lastCall: number; + private DEFAULT_WAIT: number = 3000; + private usernameMap: Record = {}; private async callApi(appId: string, protocol: string, data: any): Promise { if (this.lastCall) { const now = Date.now(); - if (now - this.lastCall <= 2000) { - await WaitUtil.wait(Math.max(2000 - (now - this.lastCall), 1000)); + if (now - this.lastCall <= this.DEFAULT_WAIT) { + await WaitUtil.wait(Math.max(this.DEFAULT_WAIT - (now - this.lastCall), 1000)); } } @@ -59,7 +61,8 @@ export class Telegram extends Website { this.lastCall = Date.now(); // Cautious set in case anything unexpected happens res = await this.instances[appId].call(protocol, data); } catch (err) { - if (err.error_message.startsWith('FLOOD_WAIT')) { + this.logger.error(err); + if (err?.error_message?.startsWith('FLOOD_WAIT')) { const wait = Number(err.error_message.split('_').pop()); if (wait > 60) { // Too long of a wait @@ -84,19 +87,19 @@ export class Telegram extends Website { return resErr ? Promise.reject(resErr) : (res as T); } - public authenticate(data: { appId: string; code: string }) { - return this.callApi(data.appId, 'auth.signIn', { - phone_number: this.authData[data.appId].phone_number, - phone_code: data.code, - phone_code_hash: this.authData[data.appId].phone_code_hash, - }) - .then(() => { - result: true; - }) - .catch((err) => { - this.logger.error(err); - return { result: false, message: err.error_message }; + public async authenticate(data: { appId: string; code: string }) { + try { + const signIn: any = await this.callApi(data.appId, 'auth.signIn', { + phone_number: this.authData[data.appId].phone_number, + phone_code: data.code, + phone_code_hash: this.authData[data.appId].phone_code_hash, }); + this.usernameMap[data.appId] = signIn?.user?.username; + return { result: true }; + } catch (err) { + this.logger.error(err); + return { result: false, message: err.error_message }; + } } public async startAuthentication(data: TelegramAccountData) { @@ -154,7 +157,13 @@ export class Telegram extends Website { await this.loadChannels(data._id, appId); status.loggedIn = true; - status.username = ''; + status.username = data.data.username || this.usernameMap[appId] || ''; + // Roundabout way to set username and save it after authentication + if (this.usernameMap[appId]) { + status.data = { + username: this.usernameMap[appId], + }; + } return status; } @@ -206,6 +215,28 @@ export class Telegram extends Website { private async upload(appId: string, file: PostFileRecord) { const parts = _.chunk(file.file.value, 512000); // 512KB const file_id = Date.now(); + const props: { + _: 'inputMediaUploadedDocument' | 'inputMediaUploadedPhoto'; + mime_type?: string; + nosound_video?: boolean; + attributes?: any[]; + } = { + _: 'inputMediaUploadedDocument', + }; + if ( + file.file.options.contentType === 'image/png' || + file.file.options.contentType === 'image/jpg' || + file.file.options.contentType === 'image/jpeg' + ) { + props._ = 'inputMediaUploadedPhoto'; + } else { + props.attributes = []; + props.mime_type = file.file.options.contentType; + if (props.mime_type === 'image/gif') { + props.nosound_video = true; + } + } + if (file.file.value.length >= FileSize.MBtoBytes(10)) { // Big file path for (let i = 0; i < parts.length; i++) { @@ -220,7 +251,7 @@ export class Telegram extends Website { } return { - _: 'inputMediaUploadedPhoto', + ...props, file: { _: 'inputFileBig', id: file_id, @@ -240,7 +271,7 @@ export class Telegram extends Website { } return { - _: 'inputMediaUploadedPhoto', + ...props, file: { _: 'inputFile', id: file_id, @@ -378,31 +409,13 @@ export class Telegram extends Website { ); submissionPart.data.channels.forEach((f) => { if (!WebsiteValidator.folderIdExists(f, folders)) { - problems.push(`Folder (${f}) not found.`); + problems.push(`Channel (${f}) not found.`); } }); } else { problems.push('No channel(s) selected.'); } - const files = [ - submission.primary, - ...(submission.additional || []).filter( - (f) => !f.ignoredAccounts!.includes(submissionPart.accountId), - ), - ]; - - let hasAddedProblem = false; - files.forEach((file) => { - if (hasAddedProblem) { - return; - } - if (!WebsiteValidator.supportsFileType(file, this.acceptsFiles)) { - problems.push(`Currently supported file formats: ${this.acceptsFiles.join(', ')}`); - hasAddedProblem = true; - } - }); - const description = this.defaultDescriptionParser( FormContent.getDescription(defaultPart.data.description, submissionPart.data.description), );