Skip to content

Commit 3e06297

Browse files
committed
chrome.download + fix fb_storySaver
1 parent 00a244e commit 3e06297

File tree

9 files changed

+98
-64
lines changed

9 files changed

+98
-64
lines changed

scripts/content-scripts/ufs_global.js

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,12 @@ function runInContentScript(fnPath, params) {
143143
});
144144
}
145145
function runInBackground(fnPath, params) {
146+
if (typeof chrome?.runtime?.sendMessage == "function") {
147+
return chrome.runtime.sendMessage({
148+
action: "ufs-runInBackground",
149+
data: { fnPath, params },
150+
});
151+
}
146152
return sendToContentScript("ufs-runInBackground", {
147153
fnPath,
148154
params,
@@ -165,15 +171,31 @@ async function fetchByPassOrigin(url, options = {}) {
165171
function getURL(filePath) {
166172
return runInContentScript("chrome.runtime.getURL", [filePath]);
167173
}
168-
function download(options) {
169-
return runInBackground("chrome.downloads.download", [options]);
170-
}
171174
function trackEvent(scriptId) {
172175
return runInBackground("trackEvent", [scriptId]);
173176
}
174177
function waitForTabToLoad(tabId) {
175178
return runInBackground("utils.waitForTabToLoad", [tabId]);
176179
}
180+
181+
// https://developer.chrome.com/docs/extensions/reference/api/downloads#type-DownloadOptions
182+
/**
183+
* A function to trigger a download using chrome.downloads API.
184+
*
185+
* @param {Object} options - The options for the download operation.
186+
* @param {string} options.url - The URL to download.
187+
* @param {string} [options.body] - Post body.
188+
* @param {{name: string, value: string}[]} [options.headers] - Extra HTTP headers to send with the request if the URL uses the HTTP[s] protocol. Each header is represented as a dictionary containing the keys name and either value or binaryValue, restricted to those allowed by XMLHttpRequest.
189+
* @param {'GET'|'POST'} [options.method] - The HTTP method to use for the download.
190+
* @param {string} [options.filename] - A file path relative to the Downloads directory to contain the downloaded file, possibly containing subdirectories.
191+
* @param {string} [options.saveAs] - Use a file-chooser to allow the user to select a filename regardless of whether filename is set or already exists.
192+
* @param {'uniquify'|'overwrite'|'prompt'} [options.conflictAction] - The action to take if filename already exists.
193+
* @return {Promise<number>} - A promise that resolves to the ID of the created download.
194+
*/
195+
function download(options) {
196+
return runInBackground("chrome.downloads.download", [options]);
197+
}
198+
177199
// #endregion
178200

179201
// #region DOM
@@ -1834,9 +1856,7 @@ function downloadBlob(blob, filename) {
18341856
a.href = blobUrl;
18351857
a.download = filename;
18361858
a.style.display = "none";
1837-
document.body.appendChild(a);
18381859
a.click();
1839-
document.body.removeChild(a);
18401860
URL.revokeObjectURL(blobUrl);
18411861
}
18421862
// https://stackoverflow.com/a/15832662/11898496
@@ -1846,9 +1866,7 @@ function downloadURL(url, name) {
18461866
link.target = "_blank";
18471867
link.download = name;
18481868
link.href = url;
1849-
document.body.appendChild(link);
18501869
link.click();
1851-
document.body.removeChild(link);
18521870
}
18531871
function downloadData(data, filename, type = "text/plain") {
18541872
let file = new Blob([data], { type: type });

scripts/douyin_downloadWachingVideo.js

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { UfsGlobal } from "./content-scripts/ufs_global.js";
2+
13
export default {
24
icon: "https://www.douyin.com/favicon.ico",
35
name: {
@@ -12,18 +14,10 @@ export default {
1214

1315
popupScript: {
1416
onClick: async function () {
15-
const { UfsGlobal } = await import("./content-scripts/ufs_global.js");
1617
const { runScriptInCurrentTab, showLoading } = await import(
1718
"./helpers/utils.js"
1819
);
1920

20-
// const {
21-
// downloadURL,
22-
// downloadBlob,
23-
// getBlobFromUrlWithProgress,
24-
// formatSize,
25-
// } = UfsGlobal.Utils;
26-
2721
const { closeLoading, setLoadingText } = showLoading(
2822
"Đang tìm video url..."
2923
);
@@ -36,21 +30,7 @@ export default {
3630
alert("Không tìm thấy video nào.");
3731
} else {
3832
setLoadingText("Đang tải video...");
39-
// downloadURL(src, "douyin_video.mp4");
4033
window.open(src);
41-
// const blob = await getBlobFromUrlWithProgress(
42-
// src,
43-
// ({ loaded, total, speed }) => {
44-
// const percent = ((loaded / total) * 100) | 0;
45-
// setLoadingText(
46-
// `Đang tải video...<br/>` +
47-
// `Vui lòng không tắt popup <br/>` +
48-
// `${formatSize(loaded)}/${formatSize(total)} (${percent}%)` +
49-
// ` - ${formatSize(speed)}/s`
50-
// );
51-
// }
52-
// );
53-
// await downloadBlob(blob, "douyin_video.mp4");
5434
}
5535
closeLoading();
5636
},

scripts/fb_downloadWatchingVideo.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,25 @@ export default {
2929
);
3030
try {
3131
let listVideoId = await shared.getListVideoIdInWebsite();
32-
if (!listVideoId?.length > 0) throw Error("Không tìm thấy video");
32+
if (!listVideoId?.length > 0) throw Error("Không tìm thấy video nào");
3333

3434
setLoadingText("Đang lấy token dtsg...");
3535
let dtsg = await fb_videoDownloader.getDtsg();
3636

37+
let downloaded = 0;
3738
for (let videoId of listVideoId) {
3839
setLoadingText("Đang tìm video url...");
3940
let videoUrl = await fb_videoDownloader.getLinkFbVideo(videoId, dtsg);
40-
if (videoUrl) UfsGlobal.Utils.downloadURL(videoUrl, "fb_video.mp4");
41+
if (videoUrl) {
42+
downloaded++;
43+
UfsGlobal.Extension.download({
44+
url: videoUrl,
45+
filename: "fb_video.mp4",
46+
});
47+
}
48+
}
49+
if (downloaded === 0) {
50+
alert("Không tìm thấy link video");
4151
}
4252
} catch (e) {
4353
alert("ERROR: " + e);

scripts/fb_storySaver.js

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export default {
1111
vi: "Tải facebook story / video bình luận bạn đang xem",
1212
},
1313

14-
contentScript: {
14+
pageScript: {
1515
onClick: function () {
1616
// Source code extracted from: https://chrome.google.com/webstore/detail/story-saver/mafcolokinicfdmlidhaebadidhdehpk
1717

@@ -22,45 +22,55 @@ export default {
2222
if (videos[i].offsetHeight === 0) continue;
2323
let reactKey = "";
2424
let keys = Object.keys(videos[i]);
25-
for (let key of keys) {
26-
if (key.indexOf("__reactFiber") != -1) {
27-
reactKey = key.split("__reactFiber")[1];
25+
for (let j = 0; j < keys.length; j++) {
26+
if (keys[j].indexOf("__reactFiber") != -1) {
27+
reactKey = keys[j].split("__reactFiber")[1];
2828
break;
2929
}
3030
}
3131
let storyUrl;
3232
try {
33-
//prettier-ignore
34-
storyUrl = videos[i].parentElement.parentElement.parentElement.parentElement['__reactProps' + reactKey].children[0].props.children.props.implementations[1].data.hdSrc;
33+
storyUrl =
34+
videos[i].parentElement.parentElement.parentElement.parentElement[
35+
"__reactProps" + reactKey
36+
].children[0].props.children.props.implementations[1].data.hdSrc;
3537
} catch (e) {}
3638
if (storyUrl == null) {
3739
try {
38-
//prettier-ignore
39-
storyUrl = videos[i].parentElement.parentElement.parentElement.parentElement['__reactProps' + reactKey].children[0].props.children.props.implementations[1].data.sdSrc;
40+
storyUrl =
41+
videos[i].parentElement.parentElement.parentElement.parentElement[
42+
"__reactProps" + reactKey
43+
].children[0].props.children.props.implementations[1].data.sdSrc;
4044
} catch (e) {}
4145
}
4246
if (storyUrl == null) {
4347
try {
44-
//prettier-ignore
45-
storyUrl = videos[i].parentElement.parentElement.parentElement.parentElement['__reactProps' + reactKey].children.props.children.props.implementations[1].data.hdSrc;
48+
storyUrl =
49+
videos[i].parentElement.parentElement.parentElement.parentElement[
50+
"__reactProps" + reactKey
51+
].children.props.children.props.implementations[1].data.hdSrc;
4652
} catch (e) {}
4753
}
4854
if (storyUrl == null) {
4955
try {
50-
//prettier-ignore
51-
storyUrl = videos[i].parentElement.parentElement.parentElement.parentElement['__reactProps' + reactKey].children.props.children.props.implementations[1].data.sdSrc;
56+
storyUrl =
57+
videos[i].parentElement.parentElement.parentElement.parentElement[
58+
"__reactProps" + reactKey
59+
].children.props.children.props.implementations[1].data.sdSrc;
5260
} catch (e) {}
5361
}
5462
if (storyUrl == null) {
5563
try {
56-
//prettier-ignore
57-
storyUrl = videos[i]['__reactFiber' + reactKey].return.stateNode.props.videoData.$1.hd_src;
64+
storyUrl =
65+
videos[i]["__reactFiber" + reactKey].return.stateNode.props
66+
.videoData.$1.hd_src;
5867
} catch (e) {}
5968
}
6069
if (storyUrl == null) {
6170
try {
62-
//prettier-ignore
63-
storyUrl = videos[i]['__reactFiber' + reactKey].return.stateNode.props.videoData.$1.sd_src;
71+
storyUrl =
72+
videos[i]["__reactFiber" + reactKey].return.stateNode.props
73+
.videoData.$1.sd_src;
6474
} catch (e) {}
6575
}
6676
if (storyUrl != null) {
@@ -69,16 +79,24 @@ export default {
6979
}
7080

7181
let storyImgUrl = Array.from(
72-
document.querySelectorAll('div[data-id] img[draggable="false"]')
82+
document.querySelectorAll('img[draggable="false"]')
7383
).find((_) => _.alt)?.src;
7484
if (storyImgUrl) {
7585
listUrls.push({ url: storyImgUrl, type: "img" });
7686
}
7787

88+
let profile_pic = document.querySelector(
89+
"a[role=link][tabindex='0'][href*='https://www.facebook']>img"
90+
);
91+
let username = profile_pic?.alt || "fb_story";
92+
7893
if (!listUrls.length) {
7994
alert("Không tìm thấy facebook story nào trong trang web.");
8095
} else if (listUrls.length === 1) {
81-
UfsGlobal.Utils.downloadURL(listUrls[0].url, "fb_story_video.mp4");
96+
UfsGlobal.Extension.download({
97+
url: listUrls[0].url,
98+
filename: username + (listUrls[0].type === "img" ? ".jpg" : ".mp4"),
99+
});
82100
} else {
83101
let w = window.open("", "", "width=500,height=700");
84102
w.document.write(

scripts/screenshotFullPage.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,10 @@ export default {
4545
console.log(img);
4646

4747
setLoadingText("Đang lưu ảnh...");
48-
UfsGlobal.Utils.downloadURL(
49-
"data:image/png;base64," + img.data,
50-
"fullpage.png"
51-
);
48+
UfsGlobal.Extension.download({
49+
url: "data:image/png;base64," + img.data,
50+
filename: "fullpage.png",
51+
});
5252
}
5353
await detachDebugger(tab);
5454
} catch (e) {

scripts/screenshotVisiblePage.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,10 @@ export default {
7272
console.log(img);
7373

7474
setLoadingText("Đang lưu ảnh...");
75-
UfsGlobal.Utils.downloadURL(
76-
"data:image/png;base64," + img.data,
77-
"webpage.png"
78-
);
75+
UfsGlobal.Extension.download({
76+
url: "data:image/png;base64," + img.data,
77+
filename: "webpage.png",
78+
});
7979

8080
await detachDebugger(tab);
8181
} catch (e) {

scripts/tiktok_downloadWatchingVideo.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,15 @@ export default {
8484
setLoadingText(
8585
t({ vi: `Đang tải video ${title}...`, en: `Downloading ${title}...` })
8686
);
87-
const { formatSize, downloadBlob } = UfsGlobal.Utils;
88-
const blob = await UfsGlobal.Utils.getBlobFromUrlWithProgress(
87+
88+
// UfsGlobal.Extension.download({
89+
// url: link,
90+
// filename: title + ".mp4",
91+
// });
92+
93+
const { formatSize, downloadBlob, getBlobFromUrlWithProgress } =
94+
UfsGlobal.Utils;
95+
const blob = await getBlobFromUrlWithProgress(
8996
link,
9097
({ loaded, total, speed }) => {
9198
let desc =

scripts/webToPDF.js

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,10 @@ export default {
3333
});
3434
await detachDebugger(tab);
3535

36-
// https://stackoverflow.com/a/59352848/11898496
37-
UfsGlobal.Utils.downloadURL(
38-
"data:application/pdf;base64," + res.data,
39-
"web.pdf"
40-
);
36+
UfsGlobal.Extension.download({
37+
url: "data:application/pdf;base64," + res.data,
38+
filename: "web.pdf",
39+
});
4140
} catch (e) {
4241
if (
4342
confirm(

working_note.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
## 01/07/2024 - ?
44

5+
- [ ] hotfix - use chrome.downloads instead of library
6+
57
- [x] get fb profile pic <https://www.facebook.com/profile/pic.php?cuid={}&square_px=1000> -> dont know now cuid was generated
68

79
- [x] find fb account using phone or email <https://www.facebook.com/login/web/?email={phone_or_email}> -> too hard, fb not always show user's avatar/name

0 commit comments

Comments
 (0)