Skip to content

Commit 21725f4

Browse files
authored
Merge pull request #512 from lockdown-systems/bluesky-migrate
feature: migrate to Bluesky without X/Twitter login
2 parents e18d49c + fe11f69 commit 21725f4

21 files changed

+619
-253
lines changed

src/account_facebook/facebook_account_controller.ts

Lines changed: 40 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ export class FacebookAccountController {
170170
url TEXT NOT NULL,
171171
name TEXT NOT NULL,
172172
profilePictureFilename TEXT NOT NULL
173-
);`, `CREATE TABLE story (
173+
);`, `CREATE TABLE story (
174174
id INTEGER PRIMARY KEY AUTOINCREMENT,
175175
storyID TEXT NOT NULL UNIQUE,
176176
url TEXT NOT NULL,
@@ -185,19 +185,19 @@ export class FacebookAccountController {
185185
deletedStoryAt DATETIME,
186186
FOREIGN KEY(userID) REFERENCES user(userID),
187187
FOREIGN KEY(attachedStoryID) REFERENCES attached_story(storyID)
188-
);`, `CREATE TABLE attached_story (
188+
);`, `CREATE TABLE attached_story (
189189
id INTEGER PRIMARY KEY AUTOINCREMENT,
190190
storyID TEXT NOT NULL UNIQUE,
191191
text TEXT
192192
);`,
193193
`CREATE TABLE media (
194-
id INTEGER PRIMARY KEY AUTOINCREMENT,
194+
id INTEGER PRIMARY KEY AUTOINCREMENT,
195195
mediaType TEXT NOT NULL, -- "Photo", "Video", "GenericAttachmentMedia"
196196
mediaID TEXT NOT NULL UNIQUE,
197197
filename TEXT,
198198
isPlayable BOOLEAN,
199199
accessibilityCaption TEXT,
200-
title TEXT,
200+
title TEXT,
201201
url TEXT,
202202
needsVideoDownload BOOLEAN DEFAULT 0
203203
);`,
@@ -209,7 +209,7 @@ export class FacebookAccountController {
209209
FOREIGN KEY(mediaID) REFERENCES media(mediaID)
210210
);`,
211211
`CREATE TABLE media_attached_story (
212-
id INTEGER PRIMARY KEY AUTOINCREMENT,
212+
id INTEGER PRIMARY KEY AUTOINCREMENT,
213213
storyID TEXT NOT NULL, -- Foreign key to attached_story.storyID
214214
mediaID TEXT NOT NULL, -- Foreign key to media.mediaID
215215
FOREIGN KEY(storyID) REFERENCES attached_story(storyID),
@@ -291,9 +291,9 @@ export class FacebookAccountController {
291291

292292
// Find lifeEventTitle, for life events (like birthdays)
293293
let lifeEventTitle = null;
294-
if(
295-
data.attachments &&
296-
data.attachments.length > 0 &&
294+
if (
295+
data.attachments &&
296+
data.attachments.length > 0 &&
297297
data.attachments[0].style_type_renderer.__typename == "StoryAttachmentLifeEventStyleRenderer" &&
298298
data.attachments[0].style_type_renderer.attachment.style_infos &&
299299
data.attachments[0].style_type_renderer.attachment.style_infos.length > 0 &&
@@ -313,8 +313,8 @@ export class FacebookAccountController {
313313
if (existingStory) {
314314
// Update existing story
315315
exec(
316-
this.db,
317-
'UPDATE story SET url = ?, createdAt = ?, text = ?, title = ?, lifeEventTitle = ?, userID = ?, attachedStoryID = ?, addedToDatabaseAt = ? WHERE storyID = ?',
316+
this.db,
317+
'UPDATE story SET url = ?, createdAt = ?, text = ?, title = ?, lifeEventTitle = ?, userID = ?, attachedStoryID = ?, addedToDatabaseAt = ? WHERE storyID = ?',
318318
[
319319
data.url, // url
320320
new Date(data.creation_time * 1000), // createdAt
@@ -330,8 +330,8 @@ export class FacebookAccountController {
330330
} else {
331331
// Save the story
332332
exec(
333-
this.db,
334-
'INSERT INTO story (storyID, url, createdAt, text, title, lifeEventTitle, userID, attachedStoryID, addedToDatabaseAt, archivedAt, deletedStoryAt) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)',
333+
this.db,
334+
'INSERT INTO story (storyID, url, createdAt, text, title, lifeEventTitle, userID, attachedStoryID, addedToDatabaseAt, archivedAt, deletedStoryAt) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)',
335335
[
336336
data.id, // storyID
337337
data.url, // url
@@ -350,7 +350,7 @@ export class FacebookAccountController {
350350

351351
if (data.attachments && data.attachments.length > 0) {
352352
log.info("FacebookAccountController.parseNode: parsing attachments", data.id);
353-
for(const attachment of data.attachments) {
353+
for (const attachment of data.attachments) {
354354
await this.parseAttachment(data.id, attachment, 'story');
355355
}
356356
}
@@ -394,15 +394,15 @@ export class FacebookAccountController {
394394
if (existingUser) {
395395
// Update existing user
396396
exec(
397-
this.db,
398-
'UPDATE user SET url = ?, name = ?, profilePictureFilename = ? WHERE userID = ?',
397+
this.db,
398+
'UPDATE user SET url = ?, name = ?, profilePictureFilename = ? WHERE userID = ?',
399399
[url, name, profilePictureFilename, userID]
400400
);
401401
} else {
402402
// Save the user
403403
exec(
404-
this.db,
405-
'INSERT INTO user (userID, url, name, profilePictureFilename) VALUES (?, ?, ?, ?)',
404+
this.db,
405+
'INSERT INTO user (userID, url, name, profilePictureFilename) VALUES (?, ?, ?, ?)',
406406
[userID, url, name, profilePictureFilename]
407407
);
408408
}
@@ -419,22 +419,22 @@ export class FacebookAccountController {
419419
if (existingAttachedStory) {
420420
// Update existing attached story
421421
exec(
422-
this.db,
423-
'UPDATE attached_story SET text = ? WHERE storyID = ?',
422+
this.db,
423+
'UPDATE attached_story SET text = ? WHERE storyID = ?',
424424
[text, storyID]
425425
);
426426
} else {
427427
// Save the attached story
428428
exec(
429-
this.db,
429+
this.db,
430430
'INSERT INTO attached_story (storyID, text) VALUES (?, ?)',
431431
[storyID, text]
432432
);
433433
}
434434

435435
if (attachedStory.attachments && attachedStory.attachments.length > 0) {
436436
log.info("FacebookAccountController.saveAttachedStory: parsing attachments", storyID);
437-
for(const attachment of attachedStory.attachments) {
437+
for (const attachment of attachedStory.attachments) {
438438
await this.parseAttachment(attachedStory.id, attachment, 'attached_story');
439439
}
440440
}
@@ -449,25 +449,25 @@ export class FacebookAccountController {
449449
const mediaID = media.id;
450450

451451
// It seems that GenericAttachmentMedia media does not have a steady mediaID, so we're skipping it to avoid duplicates
452-
if(mediaType == "GenericAttachmentMedia") {
452+
if (mediaType == "GenericAttachmentMedia") {
453453
log.info("FacebookAccountController.saveMedia: GenericAttachmentMedia mediaID is not steady, skipping download");
454454
return null;
455455
}
456456

457457
let needsVideoDownload = mediaType == "Video" ? 1 : 0;
458458

459459
let url: string | null = null;
460-
if(media.image) {
460+
if (media.image) {
461461
url = media.image.uri;
462-
} else if(media.fallback_image) {
462+
} else if (media.fallback_image) {
463463
url = media.fallback_image.uri;
464464
} else {
465465
log.info("FacebookAccountController.parseAttachment: no image found, skipping download");
466466
}
467467

468468
let filename: string | null = null;
469-
if(url) {
470-
if(mediaType == "Video") {
469+
if (url) {
470+
if (mediaType == "Video") {
471471
// Make sure the video directory exists
472472
const videosDir = path.join(this.accountDataPath, 'media', 'videos');
473473
if (!fs.existsSync(videosDir)) {
@@ -555,7 +555,7 @@ export class FacebookAccountController {
555555
const saveJoin = async (mediaID: string, storyType: 'story' | 'attached_story') => {
556556
if (storyType == 'story') {
557557
const existingJoin = exec(this.db, 'SELECT * FROM media_story WHERE storyID = ? AND mediaID = ?', [storyID, mediaID], "get");
558-
if(!existingJoin) {
558+
if (!existingJoin) {
559559
exec(
560560
this.db,
561561
'INSERT INTO media_story (storyID, mediaID) VALUES (?, ?)',
@@ -564,7 +564,7 @@ export class FacebookAccountController {
564564
}
565565
} else {
566566
const existingJoin = exec(this.db, 'SELECT * FROM media_attached_story WHERE storyID = ? AND mediaID = ?', [storyID, mediaID], "get");
567-
if(!existingJoin) {
567+
if (!existingJoin) {
568568
exec(
569569
this.db,
570570
'INSERT INTO media_attached_story (storyID, mediaID) VALUES (?, ?)',
@@ -576,37 +576,37 @@ export class FacebookAccountController {
576576

577577
if (type == "StoryAttachmentPhotoStyleRenderer") {
578578
// Single photo
579-
if(!attachment.style_type_renderer.attachment.media) {
579+
if (!attachment.style_type_renderer.attachment.media) {
580580
log.info("FacebookAccountController.parseAttachment: no media found, skipping");
581581
return;
582582
}
583583
const mediaID = await this.saveMedia(attachment.style_type_renderer.attachment.media, null);
584-
if(mediaID) {
584+
if (mediaID) {
585585
await saveJoin(mediaID, storyType);
586586
}
587587

588588
} else if (type == "StoryAttachmentAlbumStyleRenderer") {
589589
// Multiple photos
590-
if(!attachment.style_type_renderer.attachment.all_subattachments || !attachment.style_type_renderer.attachment.all_subattachments.nodes.length) {
590+
if (!attachment.style_type_renderer.attachment.all_subattachments || !attachment.style_type_renderer.attachment.all_subattachments.nodes.length) {
591591
log.info("FacebookAccountController.parseAttachment: no media found, skipping");
592592
return;
593593
}
594594

595595
for (const mediaItem of attachment.style_type_renderer.attachment.all_subattachments.nodes) {
596596
const mediaID = await this.saveMedia(mediaItem.media, null);
597-
if(mediaID) {
597+
if (mediaID) {
598598
await saveJoin(mediaID, storyType);
599599
}
600600
}
601601

602602
} else if (type == "StoryAttachmentVideoStyleRenderer") {
603603
// Video
604-
if(!attachment.style_type_renderer.attachment.media) {
604+
if (!attachment.style_type_renderer.attachment.media) {
605605
log.info("FacebookAccountController.parseAttachment: no media found, skipping");
606606
return;
607607
}
608608
const mediaID = await this.saveMedia(attachment.style_type_renderer.attachment.media, null);
609-
if(mediaID) {
609+
if (mediaID) {
610610
await saveJoin(mediaID, storyType);
611611
}
612612

@@ -616,10 +616,10 @@ export class FacebookAccountController {
616616

617617
// If there's attached media, save it
618618
let mediaID: string | null = null;
619-
if(attachment.style_type_renderer.attachment.media) {
619+
if (attachment.style_type_renderer.attachment.media) {
620620
const title = attachment.style_type_renderer.attachment.title || null;
621621
mediaID = await this.saveMedia(attachment.style_type_renderer.attachment.media, title);
622-
if(mediaID) {
622+
if (mediaID) {
623623
await saveJoin(mediaID, storyType);
624624
}
625625
}
@@ -697,7 +697,7 @@ export class FacebookAccountController {
697697
for (const [key, value] of params.entries()) {
698698
queryObject[key] = decodeURIComponent(value);
699699
}
700-
if(!queryObject['fb_api_req_friendly_name']) {
700+
if (!queryObject['fb_api_req_friendly_name']) {
701701
log.error("FacebookAccountController.parseAPIResponse: fb_api_req_friendly_name not found in query string");
702702
responseData.processed = true;
703703
return;
@@ -740,15 +740,15 @@ export class FacebookAccountController {
740740
if (isFBAPIResponseProfileCometManagePosts(resp)) {
741741
log.debug("FacebookAccountController.parseAPIResponse: parsing ProfileCometManagePosts response");
742742
let edges;
743-
if(resp.data?.user?.timeline_manage_feed_units?.edges) {
743+
if (resp.data?.user?.timeline_manage_feed_units?.edges) {
744744
edges = resp.data.user.timeline_manage_feed_units.edges;
745745
} else if (resp.data?.node?.timeline_manage_feed_units?.edges) {
746746
edges = resp.data.node.timeline_manage_feed_units.edges;
747747
} else {
748748
log.error("FacebookAccountController.parseAPIResponse: no edges found in response", resp);
749749
continue;
750750
}
751-
751+
752752
for (let i = 0; i < edges.length; i++) {
753753
const edge = edges[i];
754754
if (edge.node) {
@@ -757,7 +757,7 @@ export class FacebookAccountController {
757757
}
758758
} else if (isFBAPIResponseProfileCometManagePosts2(resp)) {
759759
log.debug("FacebookAccountController.parseAPIResponse: parsing ProfileCometManagePosts2 response");
760-
if(resp?.data?.node) {
760+
if (resp?.data?.node) {
761761
await this.parseNode(resp.data.node);
762762
}
763763
} else if (isFBAPIResponseProfileCometManagePostsPageInfo(resp)) {

src/account_x/ipc.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { ipcMain } from 'electron'
2+
import log from 'electron-log/main';
23

34
import { XAccountController } from './x_account_controller';
45

@@ -24,8 +25,10 @@ const controllers: Record<number, XAccountController> = {};
2425

2526
const getXAccountController = (accountID: number): XAccountController => {
2627
if (!controllers[accountID]) {
28+
log.debug("Creating new XAccountController for accountID", accountID);
2729
controllers[accountID] = new XAccountController(accountID, getMITMController(accountID));
2830
}
31+
log.debug("Returning existing XAccountController for accountID", accountID);
2932
controllers[accountID].refreshAccount();
3033
return controllers[accountID];
3134
}
@@ -499,4 +502,13 @@ export const defineIPCX = () => {
499502
throw new Error(packageExceptionForReport(error as Error));
500503
}
501504
});
505+
506+
ipcMain.handle('X:initArchiveOnlyMode', async (_, accountID: number): Promise<void> => {
507+
try {
508+
const controller = getXAccountController(accountID);
509+
await controller.initArchiveOnlyMode();
510+
} catch (error) {
511+
throw new Error(packageExceptionForReport(error as Error));
512+
}
513+
});
502514
};

0 commit comments

Comments
 (0)