@vicociv/instaloader 0.3.0 → 0.3.1
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/README.md +10 -1
- package/dist/index.js +53 -98
- package/dist/index.mjs +53 -98
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
# @vicociv/instaloader
|
|
2
2
|
|
|
3
|
-
[](https://www.npmjs.com/package/@vicociv/instaloader)
|
|
4
3
|
[](https://www.npmjs.com/package/@vicociv/instaloader)
|
|
5
4
|
[](https://bundlephobia.com/package/@vicociv/instaloader)
|
|
5
|
+
[](https://bundlephobia.com/package/@vicociv/instaloader)
|
|
6
|
+
[](https://bundlephobia.com/package/@vicociv/instaloader)
|
|
6
7
|
[](https://github.com/star8ks/instaloader.js/actions/workflows/ci.yml)
|
|
7
8
|
[](https://codecov.io/gh/star8ks/instaloader.js)
|
|
8
9
|
[](https://opensource.org/licenses/MIT)
|
|
@@ -390,6 +391,14 @@ import {
|
|
|
390
391
|
} from '@vicociv/instaloader';
|
|
391
392
|
```
|
|
392
393
|
|
|
394
|
+
## TODO
|
|
395
|
+
|
|
396
|
+
- [ ] Download comments
|
|
397
|
+
- [ ] Download IGTV
|
|
398
|
+
- [ ] Download Reels
|
|
399
|
+
- [ ] Location support
|
|
400
|
+
- [ ] CLI tool
|
|
401
|
+
|
|
393
402
|
## License
|
|
394
403
|
|
|
395
404
|
MIT
|
package/dist/index.js
CHANGED
|
@@ -326,7 +326,7 @@ var SimpleCookieStore = class {
|
|
|
326
326
|
}
|
|
327
327
|
};
|
|
328
328
|
|
|
329
|
-
// src/
|
|
329
|
+
// src/instaloader-context.ts
|
|
330
330
|
function defaultUserAgent() {
|
|
331
331
|
return "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36";
|
|
332
332
|
}
|
|
@@ -1174,7 +1174,7 @@ HTTP redirect from ${url} to ${redirectUrl}`);
|
|
|
1174
1174
|
}
|
|
1175
1175
|
};
|
|
1176
1176
|
|
|
1177
|
-
// src/
|
|
1177
|
+
// src/node-iterator.ts
|
|
1178
1178
|
var import_crypto = require("crypto");
|
|
1179
1179
|
var FrozenNodeIterator = class _FrozenNodeIterator {
|
|
1180
1180
|
queryHash;
|
|
@@ -1441,7 +1441,15 @@ var NodeIterator = class _NodeIterator {
|
|
|
1441
1441
|
}
|
|
1442
1442
|
};
|
|
1443
1443
|
async function resumableIteration(options) {
|
|
1444
|
-
const {
|
|
1444
|
+
const {
|
|
1445
|
+
context,
|
|
1446
|
+
iterator,
|
|
1447
|
+
load,
|
|
1448
|
+
save: _save,
|
|
1449
|
+
formatPath,
|
|
1450
|
+
checkBbd = true,
|
|
1451
|
+
enabled = true
|
|
1452
|
+
} = options;
|
|
1445
1453
|
if (!enabled || !(iterator instanceof NodeIterator)) {
|
|
1446
1454
|
return { isResuming: false, startIndex: 0 };
|
|
1447
1455
|
}
|
|
@@ -1480,9 +1488,7 @@ function optionalNormalize(str) {
|
|
|
1480
1488
|
}
|
|
1481
1489
|
function shortcodeToMediaid(code) {
|
|
1482
1490
|
if (code.length > 11) {
|
|
1483
|
-
throw new InvalidArgumentException(
|
|
1484
|
-
`Wrong shortcode "${code}", unable to convert to mediaid.`
|
|
1485
|
-
);
|
|
1491
|
+
throw new InvalidArgumentException(`Wrong shortcode "${code}", unable to convert to mediaid.`);
|
|
1486
1492
|
}
|
|
1487
1493
|
const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
|
|
1488
1494
|
let mediaid = BigInt(0);
|
|
@@ -1610,10 +1616,7 @@ var PostComment = class _PostComment {
|
|
|
1610
1616
|
get owner() {
|
|
1611
1617
|
if ("iphone_struct" in this._node) {
|
|
1612
1618
|
const iphoneStruct = this._node["iphone_struct"];
|
|
1613
|
-
return Profile.fromIphoneStruct(
|
|
1614
|
-
this._context,
|
|
1615
|
-
iphoneStruct["user"]
|
|
1616
|
-
);
|
|
1619
|
+
return Profile.fromIphoneStruct(this._context, iphoneStruct["user"]);
|
|
1617
1620
|
}
|
|
1618
1621
|
return new Profile(this._context, this._node["owner"]);
|
|
1619
1622
|
}
|
|
@@ -1716,9 +1719,9 @@ var Post = class _Post {
|
|
|
1716
1719
|
const carouselMedia = media["carousel_media"];
|
|
1717
1720
|
if (carouselMedia) {
|
|
1718
1721
|
fakeNode["edge_sidecar_to_children"] = {
|
|
1719
|
-
edges: carouselMedia.map(
|
|
1720
|
-
|
|
1721
|
-
)
|
|
1722
|
+
edges: carouselMedia.map((node) => ({
|
|
1723
|
+
node: _Post._convertIphoneCarousel(node, mediaTypes)
|
|
1724
|
+
}))
|
|
1722
1725
|
};
|
|
1723
1726
|
}
|
|
1724
1727
|
} catch {
|
|
@@ -1770,10 +1773,9 @@ var Post = class _Post {
|
|
|
1770
1773
|
}
|
|
1771
1774
|
async _obtainMetadata() {
|
|
1772
1775
|
if (!this._full_metadata_dict) {
|
|
1773
|
-
const result = await this._context.doc_id_graphql_query(
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
);
|
|
1776
|
+
const result = await this._context.doc_id_graphql_query("8845758582119845", {
|
|
1777
|
+
shortcode: this.shortcode
|
|
1778
|
+
});
|
|
1777
1779
|
const data = result["data"];
|
|
1778
1780
|
const picJson = data["xdt_shortcode_media"];
|
|
1779
1781
|
if (picJson === null) {
|
|
@@ -1786,9 +1788,7 @@ var Post = class _Post {
|
|
|
1786
1788
|
};
|
|
1787
1789
|
const typename = picJson["__typename"];
|
|
1788
1790
|
if (!(typename in xdtTypes)) {
|
|
1789
|
-
throw new BadResponseException(
|
|
1790
|
-
`Unknown __typename in metadata: ${typename}.`
|
|
1791
|
-
);
|
|
1791
|
+
throw new BadResponseException(`Unknown __typename in metadata: ${typename}.`);
|
|
1792
1792
|
}
|
|
1793
1793
|
picJson["__typename"] = xdtTypes[typename];
|
|
1794
1794
|
this._full_metadata_dict = picJson;
|
|
@@ -1812,15 +1812,10 @@ var Post = class _Post {
|
|
|
1812
1812
|
throw new IPhoneSupportDisabledException("iPhone support is disabled.");
|
|
1813
1813
|
}
|
|
1814
1814
|
if (!this._context.is_logged_in) {
|
|
1815
|
-
throw new LoginRequiredException(
|
|
1816
|
-
"Login required to access iPhone media info endpoint."
|
|
1817
|
-
);
|
|
1815
|
+
throw new LoginRequiredException("Login required to access iPhone media info endpoint.");
|
|
1818
1816
|
}
|
|
1819
1817
|
if (!this._iphone_struct_) {
|
|
1820
|
-
const data = await this._context.get_iphone_json(
|
|
1821
|
-
`api/v1/media/${this.mediaid}/info/`,
|
|
1822
|
-
{}
|
|
1823
|
-
);
|
|
1818
|
+
const data = await this._context.get_iphone_json(`api/v1/media/${this.mediaid}/info/`, {});
|
|
1824
1819
|
const items = data["items"];
|
|
1825
1820
|
this._iphone_struct_ = items[0];
|
|
1826
1821
|
}
|
|
@@ -1844,9 +1839,7 @@ var Post = class _Post {
|
|
|
1844
1839
|
}
|
|
1845
1840
|
return d;
|
|
1846
1841
|
} catch {
|
|
1847
|
-
throw new Error(
|
|
1848
|
-
`Field ${keys.join(".")} not found. Use async method for full metadata.`
|
|
1849
|
-
);
|
|
1842
|
+
throw new Error(`Field ${keys.join(".")} not found. Use async method for full metadata.`);
|
|
1850
1843
|
}
|
|
1851
1844
|
}
|
|
1852
1845
|
/**
|
|
@@ -1933,10 +1926,7 @@ var Post = class _Post {
|
|
|
1933
1926
|
get mediacount() {
|
|
1934
1927
|
if (this.typename === "GraphSidecar") {
|
|
1935
1928
|
try {
|
|
1936
|
-
const edges = this._field(
|
|
1937
|
-
"edge_sidecar_to_children",
|
|
1938
|
-
"edges"
|
|
1939
|
-
);
|
|
1929
|
+
const edges = this._field("edge_sidecar_to_children", "edges");
|
|
1940
1930
|
return edges.length;
|
|
1941
1931
|
} catch {
|
|
1942
1932
|
return 1;
|
|
@@ -1989,10 +1979,7 @@ var Post = class _Post {
|
|
|
1989
1979
|
/** List of all lowercased users that are tagged in the Post. */
|
|
1990
1980
|
get tagged_users() {
|
|
1991
1981
|
try {
|
|
1992
|
-
const edges = this._field(
|
|
1993
|
-
"edge_media_to_tagged_user",
|
|
1994
|
-
"edges"
|
|
1995
|
-
);
|
|
1982
|
+
const edges = this._field("edge_media_to_tagged_user", "edges");
|
|
1996
1983
|
return edges.map((edge) => {
|
|
1997
1984
|
const e = edge;
|
|
1998
1985
|
const node = e["node"];
|
|
@@ -2082,10 +2069,7 @@ var Post = class _Post {
|
|
|
2082
2069
|
/** Whether Post is a sponsored post. */
|
|
2083
2070
|
get is_sponsored() {
|
|
2084
2071
|
try {
|
|
2085
|
-
const sponsorEdges = this._field(
|
|
2086
|
-
"edge_media_to_sponsor_user",
|
|
2087
|
-
"edges"
|
|
2088
|
-
);
|
|
2072
|
+
const sponsorEdges = this._field("edge_media_to_sponsor_user", "edges");
|
|
2089
2073
|
return sponsorEdges.length > 0;
|
|
2090
2074
|
} catch {
|
|
2091
2075
|
return false;
|
|
@@ -2095,10 +2079,7 @@ var Post = class _Post {
|
|
|
2095
2079
|
getIsVideos() {
|
|
2096
2080
|
if (this.typename === "GraphSidecar") {
|
|
2097
2081
|
try {
|
|
2098
|
-
const edges = this._field(
|
|
2099
|
-
"edge_sidecar_to_children",
|
|
2100
|
-
"edges"
|
|
2101
|
-
);
|
|
2082
|
+
const edges = this._field("edge_sidecar_to_children", "edges");
|
|
2102
2083
|
return edges.map((edge) => {
|
|
2103
2084
|
const e = edge;
|
|
2104
2085
|
const node = e["node"];
|
|
@@ -2116,10 +2097,7 @@ var Post = class _Post {
|
|
|
2116
2097
|
return;
|
|
2117
2098
|
}
|
|
2118
2099
|
try {
|
|
2119
|
-
const edges = this._field(
|
|
2120
|
-
"edge_sidecar_to_children",
|
|
2121
|
-
"edges"
|
|
2122
|
-
);
|
|
2100
|
+
const edges = this._field("edge_sidecar_to_children", "edges");
|
|
2123
2101
|
const actualEnd = end < 0 ? edges.length - 1 : end;
|
|
2124
2102
|
const actualStart = start < 0 ? edges.length - 1 : start;
|
|
2125
2103
|
for (let idx = 0; idx < edges.length; idx++) {
|
|
@@ -2244,9 +2222,7 @@ var Profile = class _Profile {
|
|
|
2244
2222
|
const data = metadata["data"];
|
|
2245
2223
|
const user = data["user"];
|
|
2246
2224
|
if (user === null) {
|
|
2247
|
-
throw new ProfileNotExistsException(
|
|
2248
|
-
`Profile ${this.username} does not exist.`
|
|
2249
|
-
);
|
|
2225
|
+
throw new ProfileNotExistsException(`Profile ${this.username} does not exist.`);
|
|
2250
2226
|
}
|
|
2251
2227
|
this._node = user;
|
|
2252
2228
|
this._has_full_metadata = true;
|
|
@@ -2271,9 +2247,7 @@ var Profile = class _Profile {
|
|
|
2271
2247
|
The most similar profile${plural}: ${profiles.slice(0, 5).join(", ")}.`
|
|
2272
2248
|
);
|
|
2273
2249
|
}
|
|
2274
|
-
throw new ProfileNotExistsException(
|
|
2275
|
-
`Profile ${this.username} does not exist.`
|
|
2276
|
-
);
|
|
2250
|
+
throw new ProfileNotExistsException(`Profile ${this.username} does not exist.`);
|
|
2277
2251
|
}
|
|
2278
2252
|
throw err;
|
|
2279
2253
|
}
|
|
@@ -2418,10 +2392,7 @@ The most similar profile${plural}: ${profiles.slice(0, 5).join(", ")}.`
|
|
|
2418
2392
|
if (this._context.iphoneSupport && this._context.is_logged_in) {
|
|
2419
2393
|
try {
|
|
2420
2394
|
if (!this._iphone_struct_) {
|
|
2421
|
-
const data = await this._context.get_iphone_json(
|
|
2422
|
-
`api/v1/users/${this.userid}/info/`,
|
|
2423
|
-
{}
|
|
2424
|
-
);
|
|
2395
|
+
const data = await this._context.get_iphone_json(`api/v1/users/${this.userid}/info/`, {});
|
|
2425
2396
|
this._iphone_struct_ = data["user"];
|
|
2426
2397
|
}
|
|
2427
2398
|
const hdInfo = this._iphone_struct_["hd_profile_pic_url_info"];
|
|
@@ -2458,7 +2429,9 @@ The most similar profile${plural}: ${profiles.slice(0, 5).join(", ")}.`
|
|
|
2458
2429
|
const edgeData = this._metadata("edge_owner_to_timeline_media");
|
|
2459
2430
|
const countValue = edgeData["count"];
|
|
2460
2431
|
const baseData = {
|
|
2461
|
-
edges: (edgeData["edges"] || []).map((e) => ({
|
|
2432
|
+
edges: (edgeData["edges"] || []).map((e) => ({
|
|
2433
|
+
node: e["node"] || e
|
|
2434
|
+
})),
|
|
2462
2435
|
page_info: edgeData["page_info"] || { has_next_page: false, end_cursor: null }
|
|
2463
2436
|
};
|
|
2464
2437
|
firstData = typeof countValue === "number" ? { ...baseData, count: countValue } : baseData;
|
|
@@ -2559,10 +2532,9 @@ var StoryItem = class _StoryItem {
|
|
|
2559
2532
|
* Create a StoryItem object from a given mediaid.
|
|
2560
2533
|
*/
|
|
2561
2534
|
static async fromMediaid(context, mediaid) {
|
|
2562
|
-
const picJson = await context.graphql_query(
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
);
|
|
2535
|
+
const picJson = await context.graphql_query("2b0673e0dc4580674a88d426fe00ea90", {
|
|
2536
|
+
shortcode: mediaidToShortcode(mediaid)
|
|
2537
|
+
});
|
|
2566
2538
|
const shortcodeMedia = picJson["data"]["shortcode_media"];
|
|
2567
2539
|
if (shortcodeMedia === null) {
|
|
2568
2540
|
throw new BadResponseException("Fetching StoryItem metadata failed.");
|
|
@@ -2587,10 +2559,7 @@ var StoryItem = class _StoryItem {
|
|
|
2587
2559
|
async getOwnerProfile() {
|
|
2588
2560
|
if (!this._owner_profile) {
|
|
2589
2561
|
const owner = this._node["owner"];
|
|
2590
|
-
this._owner_profile = await Profile.fromId(
|
|
2591
|
-
this._context,
|
|
2592
|
-
Number(owner["id"])
|
|
2593
|
-
);
|
|
2562
|
+
this._owner_profile = await Profile.fromId(this._context, Number(owner["id"]));
|
|
2594
2563
|
}
|
|
2595
2564
|
return this._owner_profile;
|
|
2596
2565
|
}
|
|
@@ -2751,10 +2720,7 @@ var Story = class {
|
|
|
2751
2720
|
/** Profile instance of the story owner. */
|
|
2752
2721
|
get owner_profile() {
|
|
2753
2722
|
if (!this._owner_profile) {
|
|
2754
|
-
this._owner_profile = new Profile(
|
|
2755
|
-
this._context,
|
|
2756
|
-
this._node["user"]
|
|
2757
|
-
);
|
|
2723
|
+
this._owner_profile = new Profile(this._context, this._node["user"]);
|
|
2758
2724
|
}
|
|
2759
2725
|
return this._owner_profile;
|
|
2760
2726
|
}
|
|
@@ -2812,10 +2778,7 @@ var Highlight = class extends Story {
|
|
|
2812
2778
|
/** Profile instance of the highlights' owner. */
|
|
2813
2779
|
get owner_profile() {
|
|
2814
2780
|
if (!this._owner_profile) {
|
|
2815
|
-
this._owner_profile = new Profile(
|
|
2816
|
-
this._context,
|
|
2817
|
-
this._node["owner"]
|
|
2818
|
-
);
|
|
2781
|
+
this._owner_profile = new Profile(this._context, this._node["owner"]);
|
|
2819
2782
|
}
|
|
2820
2783
|
return this._owner_profile;
|
|
2821
2784
|
}
|
|
@@ -2835,16 +2798,13 @@ var Highlight = class extends Story {
|
|
|
2835
2798
|
}
|
|
2836
2799
|
async _fetchItems() {
|
|
2837
2800
|
if (!this._items) {
|
|
2838
|
-
const data = await this._context.graphql_query(
|
|
2839
|
-
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
precomposed_overlay: false
|
|
2846
|
-
}
|
|
2847
|
-
);
|
|
2801
|
+
const data = await this._context.graphql_query("45246d3fe16ccc6577e0bd297a5db1ab", {
|
|
2802
|
+
reel_ids: [],
|
|
2803
|
+
tag_names: [],
|
|
2804
|
+
location_ids: [],
|
|
2805
|
+
highlight_reel_ids: [String(this.unique_id)],
|
|
2806
|
+
precomposed_overlay: false
|
|
2807
|
+
});
|
|
2848
2808
|
const dataObj = data["data"];
|
|
2849
2809
|
const reelsMedia = dataObj["reels_media"];
|
|
2850
2810
|
const firstReel = reelsMedia[0];
|
|
@@ -2918,10 +2878,10 @@ var Hashtag = class _Hashtag {
|
|
|
2918
2878
|
return this._node["name"].toLowerCase();
|
|
2919
2879
|
}
|
|
2920
2880
|
async _query(params) {
|
|
2921
|
-
const jsonResponse = await this._context.get_iphone_json(
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
);
|
|
2881
|
+
const jsonResponse = await this._context.get_iphone_json("api/v1/tags/web_info/", {
|
|
2882
|
+
...params,
|
|
2883
|
+
tag_name: this.name
|
|
2884
|
+
});
|
|
2925
2885
|
if ("graphql" in jsonResponse) {
|
|
2926
2886
|
return jsonResponse["graphql"]["hashtag"];
|
|
2927
2887
|
}
|
|
@@ -2999,10 +2959,7 @@ var Hashtag = class _Hashtag {
|
|
|
2999
2959
|
/** Yields the top posts of the hashtag. */
|
|
3000
2960
|
async *getTopPosts() {
|
|
3001
2961
|
try {
|
|
3002
|
-
const edges = await this.getMetadata(
|
|
3003
|
-
"edge_hashtag_to_top_posts",
|
|
3004
|
-
"edges"
|
|
3005
|
-
);
|
|
2962
|
+
const edges = await this.getMetadata("edge_hashtag_to_top_posts", "edges");
|
|
3006
2963
|
for (const edge of edges) {
|
|
3007
2964
|
const e = edge;
|
|
3008
2965
|
yield new Post(this._context, e["node"]);
|
|
@@ -3188,9 +3145,7 @@ function loadStructure(context, jsonStructure) {
|
|
|
3188
3145
|
if ("shortcode" in jsonStructure) {
|
|
3189
3146
|
return new Post(context, jsonStructure);
|
|
3190
3147
|
}
|
|
3191
|
-
throw new InvalidArgumentException(
|
|
3192
|
-
"Passed json structure is not an Instaloader JSON"
|
|
3193
|
-
);
|
|
3148
|
+
throw new InvalidArgumentException("Passed json structure is not an Instaloader JSON");
|
|
3194
3149
|
}
|
|
3195
3150
|
|
|
3196
3151
|
// src/instaloader.ts
|
package/dist/index.mjs
CHANGED
|
@@ -238,7 +238,7 @@ var SimpleCookieStore = class {
|
|
|
238
238
|
}
|
|
239
239
|
};
|
|
240
240
|
|
|
241
|
-
// src/
|
|
241
|
+
// src/instaloader-context.ts
|
|
242
242
|
function defaultUserAgent() {
|
|
243
243
|
return "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36";
|
|
244
244
|
}
|
|
@@ -1086,7 +1086,7 @@ HTTP redirect from ${url} to ${redirectUrl}`);
|
|
|
1086
1086
|
}
|
|
1087
1087
|
};
|
|
1088
1088
|
|
|
1089
|
-
// src/
|
|
1089
|
+
// src/node-iterator.ts
|
|
1090
1090
|
import { createHash } from "crypto";
|
|
1091
1091
|
var FrozenNodeIterator = class _FrozenNodeIterator {
|
|
1092
1092
|
queryHash;
|
|
@@ -1353,7 +1353,15 @@ var NodeIterator = class _NodeIterator {
|
|
|
1353
1353
|
}
|
|
1354
1354
|
};
|
|
1355
1355
|
async function resumableIteration(options) {
|
|
1356
|
-
const {
|
|
1356
|
+
const {
|
|
1357
|
+
context,
|
|
1358
|
+
iterator,
|
|
1359
|
+
load,
|
|
1360
|
+
save: _save,
|
|
1361
|
+
formatPath,
|
|
1362
|
+
checkBbd = true,
|
|
1363
|
+
enabled = true
|
|
1364
|
+
} = options;
|
|
1357
1365
|
if (!enabled || !(iterator instanceof NodeIterator)) {
|
|
1358
1366
|
return { isResuming: false, startIndex: 0 };
|
|
1359
1367
|
}
|
|
@@ -1392,9 +1400,7 @@ function optionalNormalize(str) {
|
|
|
1392
1400
|
}
|
|
1393
1401
|
function shortcodeToMediaid(code) {
|
|
1394
1402
|
if (code.length > 11) {
|
|
1395
|
-
throw new InvalidArgumentException(
|
|
1396
|
-
`Wrong shortcode "${code}", unable to convert to mediaid.`
|
|
1397
|
-
);
|
|
1403
|
+
throw new InvalidArgumentException(`Wrong shortcode "${code}", unable to convert to mediaid.`);
|
|
1398
1404
|
}
|
|
1399
1405
|
const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
|
|
1400
1406
|
let mediaid = BigInt(0);
|
|
@@ -1522,10 +1528,7 @@ var PostComment = class _PostComment {
|
|
|
1522
1528
|
get owner() {
|
|
1523
1529
|
if ("iphone_struct" in this._node) {
|
|
1524
1530
|
const iphoneStruct = this._node["iphone_struct"];
|
|
1525
|
-
return Profile.fromIphoneStruct(
|
|
1526
|
-
this._context,
|
|
1527
|
-
iphoneStruct["user"]
|
|
1528
|
-
);
|
|
1531
|
+
return Profile.fromIphoneStruct(this._context, iphoneStruct["user"]);
|
|
1529
1532
|
}
|
|
1530
1533
|
return new Profile(this._context, this._node["owner"]);
|
|
1531
1534
|
}
|
|
@@ -1628,9 +1631,9 @@ var Post = class _Post {
|
|
|
1628
1631
|
const carouselMedia = media["carousel_media"];
|
|
1629
1632
|
if (carouselMedia) {
|
|
1630
1633
|
fakeNode["edge_sidecar_to_children"] = {
|
|
1631
|
-
edges: carouselMedia.map(
|
|
1632
|
-
|
|
1633
|
-
)
|
|
1634
|
+
edges: carouselMedia.map((node) => ({
|
|
1635
|
+
node: _Post._convertIphoneCarousel(node, mediaTypes)
|
|
1636
|
+
}))
|
|
1634
1637
|
};
|
|
1635
1638
|
}
|
|
1636
1639
|
} catch {
|
|
@@ -1682,10 +1685,9 @@ var Post = class _Post {
|
|
|
1682
1685
|
}
|
|
1683
1686
|
async _obtainMetadata() {
|
|
1684
1687
|
if (!this._full_metadata_dict) {
|
|
1685
|
-
const result = await this._context.doc_id_graphql_query(
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
);
|
|
1688
|
+
const result = await this._context.doc_id_graphql_query("8845758582119845", {
|
|
1689
|
+
shortcode: this.shortcode
|
|
1690
|
+
});
|
|
1689
1691
|
const data = result["data"];
|
|
1690
1692
|
const picJson = data["xdt_shortcode_media"];
|
|
1691
1693
|
if (picJson === null) {
|
|
@@ -1698,9 +1700,7 @@ var Post = class _Post {
|
|
|
1698
1700
|
};
|
|
1699
1701
|
const typename = picJson["__typename"];
|
|
1700
1702
|
if (!(typename in xdtTypes)) {
|
|
1701
|
-
throw new BadResponseException(
|
|
1702
|
-
`Unknown __typename in metadata: ${typename}.`
|
|
1703
|
-
);
|
|
1703
|
+
throw new BadResponseException(`Unknown __typename in metadata: ${typename}.`);
|
|
1704
1704
|
}
|
|
1705
1705
|
picJson["__typename"] = xdtTypes[typename];
|
|
1706
1706
|
this._full_metadata_dict = picJson;
|
|
@@ -1724,15 +1724,10 @@ var Post = class _Post {
|
|
|
1724
1724
|
throw new IPhoneSupportDisabledException("iPhone support is disabled.");
|
|
1725
1725
|
}
|
|
1726
1726
|
if (!this._context.is_logged_in) {
|
|
1727
|
-
throw new LoginRequiredException(
|
|
1728
|
-
"Login required to access iPhone media info endpoint."
|
|
1729
|
-
);
|
|
1727
|
+
throw new LoginRequiredException("Login required to access iPhone media info endpoint.");
|
|
1730
1728
|
}
|
|
1731
1729
|
if (!this._iphone_struct_) {
|
|
1732
|
-
const data = await this._context.get_iphone_json(
|
|
1733
|
-
`api/v1/media/${this.mediaid}/info/`,
|
|
1734
|
-
{}
|
|
1735
|
-
);
|
|
1730
|
+
const data = await this._context.get_iphone_json(`api/v1/media/${this.mediaid}/info/`, {});
|
|
1736
1731
|
const items = data["items"];
|
|
1737
1732
|
this._iphone_struct_ = items[0];
|
|
1738
1733
|
}
|
|
@@ -1756,9 +1751,7 @@ var Post = class _Post {
|
|
|
1756
1751
|
}
|
|
1757
1752
|
return d;
|
|
1758
1753
|
} catch {
|
|
1759
|
-
throw new Error(
|
|
1760
|
-
`Field ${keys.join(".")} not found. Use async method for full metadata.`
|
|
1761
|
-
);
|
|
1754
|
+
throw new Error(`Field ${keys.join(".")} not found. Use async method for full metadata.`);
|
|
1762
1755
|
}
|
|
1763
1756
|
}
|
|
1764
1757
|
/**
|
|
@@ -1845,10 +1838,7 @@ var Post = class _Post {
|
|
|
1845
1838
|
get mediacount() {
|
|
1846
1839
|
if (this.typename === "GraphSidecar") {
|
|
1847
1840
|
try {
|
|
1848
|
-
const edges = this._field(
|
|
1849
|
-
"edge_sidecar_to_children",
|
|
1850
|
-
"edges"
|
|
1851
|
-
);
|
|
1841
|
+
const edges = this._field("edge_sidecar_to_children", "edges");
|
|
1852
1842
|
return edges.length;
|
|
1853
1843
|
} catch {
|
|
1854
1844
|
return 1;
|
|
@@ -1901,10 +1891,7 @@ var Post = class _Post {
|
|
|
1901
1891
|
/** List of all lowercased users that are tagged in the Post. */
|
|
1902
1892
|
get tagged_users() {
|
|
1903
1893
|
try {
|
|
1904
|
-
const edges = this._field(
|
|
1905
|
-
"edge_media_to_tagged_user",
|
|
1906
|
-
"edges"
|
|
1907
|
-
);
|
|
1894
|
+
const edges = this._field("edge_media_to_tagged_user", "edges");
|
|
1908
1895
|
return edges.map((edge) => {
|
|
1909
1896
|
const e = edge;
|
|
1910
1897
|
const node = e["node"];
|
|
@@ -1994,10 +1981,7 @@ var Post = class _Post {
|
|
|
1994
1981
|
/** Whether Post is a sponsored post. */
|
|
1995
1982
|
get is_sponsored() {
|
|
1996
1983
|
try {
|
|
1997
|
-
const sponsorEdges = this._field(
|
|
1998
|
-
"edge_media_to_sponsor_user",
|
|
1999
|
-
"edges"
|
|
2000
|
-
);
|
|
1984
|
+
const sponsorEdges = this._field("edge_media_to_sponsor_user", "edges");
|
|
2001
1985
|
return sponsorEdges.length > 0;
|
|
2002
1986
|
} catch {
|
|
2003
1987
|
return false;
|
|
@@ -2007,10 +1991,7 @@ var Post = class _Post {
|
|
|
2007
1991
|
getIsVideos() {
|
|
2008
1992
|
if (this.typename === "GraphSidecar") {
|
|
2009
1993
|
try {
|
|
2010
|
-
const edges = this._field(
|
|
2011
|
-
"edge_sidecar_to_children",
|
|
2012
|
-
"edges"
|
|
2013
|
-
);
|
|
1994
|
+
const edges = this._field("edge_sidecar_to_children", "edges");
|
|
2014
1995
|
return edges.map((edge) => {
|
|
2015
1996
|
const e = edge;
|
|
2016
1997
|
const node = e["node"];
|
|
@@ -2028,10 +2009,7 @@ var Post = class _Post {
|
|
|
2028
2009
|
return;
|
|
2029
2010
|
}
|
|
2030
2011
|
try {
|
|
2031
|
-
const edges = this._field(
|
|
2032
|
-
"edge_sidecar_to_children",
|
|
2033
|
-
"edges"
|
|
2034
|
-
);
|
|
2012
|
+
const edges = this._field("edge_sidecar_to_children", "edges");
|
|
2035
2013
|
const actualEnd = end < 0 ? edges.length - 1 : end;
|
|
2036
2014
|
const actualStart = start < 0 ? edges.length - 1 : start;
|
|
2037
2015
|
for (let idx = 0; idx < edges.length; idx++) {
|
|
@@ -2156,9 +2134,7 @@ var Profile = class _Profile {
|
|
|
2156
2134
|
const data = metadata["data"];
|
|
2157
2135
|
const user = data["user"];
|
|
2158
2136
|
if (user === null) {
|
|
2159
|
-
throw new ProfileNotExistsException(
|
|
2160
|
-
`Profile ${this.username} does not exist.`
|
|
2161
|
-
);
|
|
2137
|
+
throw new ProfileNotExistsException(`Profile ${this.username} does not exist.`);
|
|
2162
2138
|
}
|
|
2163
2139
|
this._node = user;
|
|
2164
2140
|
this._has_full_metadata = true;
|
|
@@ -2183,9 +2159,7 @@ var Profile = class _Profile {
|
|
|
2183
2159
|
The most similar profile${plural}: ${profiles.slice(0, 5).join(", ")}.`
|
|
2184
2160
|
);
|
|
2185
2161
|
}
|
|
2186
|
-
throw new ProfileNotExistsException(
|
|
2187
|
-
`Profile ${this.username} does not exist.`
|
|
2188
|
-
);
|
|
2162
|
+
throw new ProfileNotExistsException(`Profile ${this.username} does not exist.`);
|
|
2189
2163
|
}
|
|
2190
2164
|
throw err;
|
|
2191
2165
|
}
|
|
@@ -2330,10 +2304,7 @@ The most similar profile${plural}: ${profiles.slice(0, 5).join(", ")}.`
|
|
|
2330
2304
|
if (this._context.iphoneSupport && this._context.is_logged_in) {
|
|
2331
2305
|
try {
|
|
2332
2306
|
if (!this._iphone_struct_) {
|
|
2333
|
-
const data = await this._context.get_iphone_json(
|
|
2334
|
-
`api/v1/users/${this.userid}/info/`,
|
|
2335
|
-
{}
|
|
2336
|
-
);
|
|
2307
|
+
const data = await this._context.get_iphone_json(`api/v1/users/${this.userid}/info/`, {});
|
|
2337
2308
|
this._iphone_struct_ = data["user"];
|
|
2338
2309
|
}
|
|
2339
2310
|
const hdInfo = this._iphone_struct_["hd_profile_pic_url_info"];
|
|
@@ -2370,7 +2341,9 @@ The most similar profile${plural}: ${profiles.slice(0, 5).join(", ")}.`
|
|
|
2370
2341
|
const edgeData = this._metadata("edge_owner_to_timeline_media");
|
|
2371
2342
|
const countValue = edgeData["count"];
|
|
2372
2343
|
const baseData = {
|
|
2373
|
-
edges: (edgeData["edges"] || []).map((e) => ({
|
|
2344
|
+
edges: (edgeData["edges"] || []).map((e) => ({
|
|
2345
|
+
node: e["node"] || e
|
|
2346
|
+
})),
|
|
2374
2347
|
page_info: edgeData["page_info"] || { has_next_page: false, end_cursor: null }
|
|
2375
2348
|
};
|
|
2376
2349
|
firstData = typeof countValue === "number" ? { ...baseData, count: countValue } : baseData;
|
|
@@ -2471,10 +2444,9 @@ var StoryItem = class _StoryItem {
|
|
|
2471
2444
|
* Create a StoryItem object from a given mediaid.
|
|
2472
2445
|
*/
|
|
2473
2446
|
static async fromMediaid(context, mediaid) {
|
|
2474
|
-
const picJson = await context.graphql_query(
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
);
|
|
2447
|
+
const picJson = await context.graphql_query("2b0673e0dc4580674a88d426fe00ea90", {
|
|
2448
|
+
shortcode: mediaidToShortcode(mediaid)
|
|
2449
|
+
});
|
|
2478
2450
|
const shortcodeMedia = picJson["data"]["shortcode_media"];
|
|
2479
2451
|
if (shortcodeMedia === null) {
|
|
2480
2452
|
throw new BadResponseException("Fetching StoryItem metadata failed.");
|
|
@@ -2499,10 +2471,7 @@ var StoryItem = class _StoryItem {
|
|
|
2499
2471
|
async getOwnerProfile() {
|
|
2500
2472
|
if (!this._owner_profile) {
|
|
2501
2473
|
const owner = this._node["owner"];
|
|
2502
|
-
this._owner_profile = await Profile.fromId(
|
|
2503
|
-
this._context,
|
|
2504
|
-
Number(owner["id"])
|
|
2505
|
-
);
|
|
2474
|
+
this._owner_profile = await Profile.fromId(this._context, Number(owner["id"]));
|
|
2506
2475
|
}
|
|
2507
2476
|
return this._owner_profile;
|
|
2508
2477
|
}
|
|
@@ -2663,10 +2632,7 @@ var Story = class {
|
|
|
2663
2632
|
/** Profile instance of the story owner. */
|
|
2664
2633
|
get owner_profile() {
|
|
2665
2634
|
if (!this._owner_profile) {
|
|
2666
|
-
this._owner_profile = new Profile(
|
|
2667
|
-
this._context,
|
|
2668
|
-
this._node["user"]
|
|
2669
|
-
);
|
|
2635
|
+
this._owner_profile = new Profile(this._context, this._node["user"]);
|
|
2670
2636
|
}
|
|
2671
2637
|
return this._owner_profile;
|
|
2672
2638
|
}
|
|
@@ -2724,10 +2690,7 @@ var Highlight = class extends Story {
|
|
|
2724
2690
|
/** Profile instance of the highlights' owner. */
|
|
2725
2691
|
get owner_profile() {
|
|
2726
2692
|
if (!this._owner_profile) {
|
|
2727
|
-
this._owner_profile = new Profile(
|
|
2728
|
-
this._context,
|
|
2729
|
-
this._node["owner"]
|
|
2730
|
-
);
|
|
2693
|
+
this._owner_profile = new Profile(this._context, this._node["owner"]);
|
|
2731
2694
|
}
|
|
2732
2695
|
return this._owner_profile;
|
|
2733
2696
|
}
|
|
@@ -2747,16 +2710,13 @@ var Highlight = class extends Story {
|
|
|
2747
2710
|
}
|
|
2748
2711
|
async _fetchItems() {
|
|
2749
2712
|
if (!this._items) {
|
|
2750
|
-
const data = await this._context.graphql_query(
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
precomposed_overlay: false
|
|
2758
|
-
}
|
|
2759
|
-
);
|
|
2713
|
+
const data = await this._context.graphql_query("45246d3fe16ccc6577e0bd297a5db1ab", {
|
|
2714
|
+
reel_ids: [],
|
|
2715
|
+
tag_names: [],
|
|
2716
|
+
location_ids: [],
|
|
2717
|
+
highlight_reel_ids: [String(this.unique_id)],
|
|
2718
|
+
precomposed_overlay: false
|
|
2719
|
+
});
|
|
2760
2720
|
const dataObj = data["data"];
|
|
2761
2721
|
const reelsMedia = dataObj["reels_media"];
|
|
2762
2722
|
const firstReel = reelsMedia[0];
|
|
@@ -2830,10 +2790,10 @@ var Hashtag = class _Hashtag {
|
|
|
2830
2790
|
return this._node["name"].toLowerCase();
|
|
2831
2791
|
}
|
|
2832
2792
|
async _query(params) {
|
|
2833
|
-
const jsonResponse = await this._context.get_iphone_json(
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
);
|
|
2793
|
+
const jsonResponse = await this._context.get_iphone_json("api/v1/tags/web_info/", {
|
|
2794
|
+
...params,
|
|
2795
|
+
tag_name: this.name
|
|
2796
|
+
});
|
|
2837
2797
|
if ("graphql" in jsonResponse) {
|
|
2838
2798
|
return jsonResponse["graphql"]["hashtag"];
|
|
2839
2799
|
}
|
|
@@ -2911,10 +2871,7 @@ var Hashtag = class _Hashtag {
|
|
|
2911
2871
|
/** Yields the top posts of the hashtag. */
|
|
2912
2872
|
async *getTopPosts() {
|
|
2913
2873
|
try {
|
|
2914
|
-
const edges = await this.getMetadata(
|
|
2915
|
-
"edge_hashtag_to_top_posts",
|
|
2916
|
-
"edges"
|
|
2917
|
-
);
|
|
2874
|
+
const edges = await this.getMetadata("edge_hashtag_to_top_posts", "edges");
|
|
2918
2875
|
for (const edge of edges) {
|
|
2919
2876
|
const e = edge;
|
|
2920
2877
|
yield new Post(this._context, e["node"]);
|
|
@@ -3100,9 +3057,7 @@ function loadStructure(context, jsonStructure) {
|
|
|
3100
3057
|
if ("shortcode" in jsonStructure) {
|
|
3101
3058
|
return new Post(context, jsonStructure);
|
|
3102
3059
|
}
|
|
3103
|
-
throw new InvalidArgumentException(
|
|
3104
|
-
"Passed json structure is not an Instaloader JSON"
|
|
3105
|
-
);
|
|
3060
|
+
throw new InvalidArgumentException("Passed json structure is not an Instaloader JSON");
|
|
3106
3061
|
}
|
|
3107
3062
|
|
|
3108
3063
|
// src/instaloader.ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vicociv/instaloader",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "TypeScript port of instaloader - Download pictures (or videos) along with their captions and other metadata from Instagram.",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|