- +
diff --git a/lang/de-de/index.html b/lang/de-de/index.html index 8a6d6aa..63645a0 100644 --- a/lang/de-de/index.html +++ b/lang/de-de/index.html @@ -94,7 +94,7 @@- +
diff --git a/lang/en-us/index.html b/lang/en-us/index.html index 54d094f..33c4706 100644 --- a/lang/en-us/index.html +++ b/lang/en-us/index.html @@ -94,7 +94,7 @@- +
diff --git a/lang/es-ar/index.html b/lang/es-ar/index.html index d3d1c6e..0561f20 100644 --- a/lang/es-ar/index.html +++ b/lang/es-ar/index.html @@ -94,7 +94,7 @@- +
diff --git a/lang/pt-br/index.html b/lang/pt-br/index.html index 08d7ce2..6c17c0a 100644 --- a/lang/pt-br/index.html +++ b/lang/pt-br/index.html @@ -94,7 +94,7 @@- +
diff --git a/package.json b/package.json index d805bf8..e753c48 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "instantgram", - "version": "10.1.1", + "version": "10.1.2", "description": "A bookmarklet for download photos in Instagram", "author": "Matheus Falcão and from 4.0.0 Sascha Heim", "homepage": "https://thinkbig-company.github.io/instantgram/", diff --git a/src/_langs/partials/button.html b/src/_langs/partials/button.html index c7b4e93..02538db 100644 --- a/src/_langs/partials/button.html +++ b/src/_langs/partials/button.html @@ -1 +1 @@ -[instantgram 10.1.1] \ No newline at end of file +[instantgram 10.1.2] \ No newline at end of file diff --git a/src/helpers/getBlobVideoUrl.ts b/src/helpers/getBlobVideoUrl.ts index a0e079f..ca6afe5 100644 --- a/src/helpers/getBlobVideoUrl.ts +++ b/src/helpers/getBlobVideoUrl.ts @@ -2,105 +2,84 @@ import getDataFromUrl from './getDataFromUrl' async function getBlobVideoUrl(el: HTMLVideoElement, article: any, pos: number, callback: any) { - if (Object.keys(el).length > 0) { - const instanceKey = Object.keys(el).find(key => key.includes('Instance')); + /* Will be used only for single video posts */ + let isMultiVideo = (pos != null) ? true : false; + if (!isMultiVideo) { + let posterRegex = /poster\=\"([\s\S]*)\" preload/gm; + let posterRegexMatch = posterRegex.exec(el.outerHTML.replace(/(\r\n|\n|\r)/gm, '')); + let videoPosterUrl = null; + if (posterRegexMatch) { + // HACK + let div = document.createElement('textarea'); + div.innerHTML = posterRegexMatch[1]; + let decoded = div.firstChild.nodeValue; + videoPosterUrl = decoded; + } + var videoPosterFilename = videoPosterUrl.split('/').pop().split('#')[0].split('?')[0]; + } + + if(article != null && article.length > 0) { + /* Step 1 */ + /* Fetch user id from element */ + let userId = null; + let userProfileUrl = (article[0].querySelectorAll('header > div > div > div > div > span > a')[0] as HTMLLinkElement).href; + + let userProfileUrlResponseData = await getDataFromUrl(userProfileUrl); + if (userProfileUrlResponseData) { + userProfileUrlResponseData = userProfileUrlResponseData.replace(/(\r\n|\n|\r)/gm, ''); - if (typeof instanceKey !== 'undefined') { - const reactVideoEl = el[instanceKey]; + let m; + let regex = /profilePage_([0-9]+)/gm; + while ((m = regex.exec(userProfileUrlResponseData)) !== null) { + /* This is necessary to avoid infinite loops with zero-width matches */ + if (m.index === regex.lastIndex) { + regex.lastIndex++; + } - if (typeof reactVideoEl !== 'undefined') { - const videoUrl = reactVideoEl.return.memoizedProps.fallbackSrc; + /* The result can be accessed through the `m`-variable. */ + m.forEach((match) => { + userId = match; + }) + } + } - if (typeof videoUrl !== 'undefined') { - callback(videoUrl.length > 0 ? videoUrl : false); - } else { - /* Will be used only for single video posts */ - let isMultiVideo = (pos != null) ? true : false; - if (!isMultiVideo) { - let posterRegex = /poster\=\"([\s\S]*)\" preload/gm; - let posterRegexMatch = posterRegex.exec(el.outerHTML.replace(/(\r\n|\n|\r)/gm, '')); - let videoPosterUrl = null; - if (posterRegexMatch) { - // HACK - let div = document.createElement('textarea'); - div.innerHTML = posterRegexMatch[1]; - let decoded = div.firstChild.nodeValue; - videoPosterUrl = decoded; - } - var videoPosterFilename = videoPosterUrl.split('/').pop().split('#')[0].split('?')[0]; - } + /* Step 2 */ + /* Fetch the user data until the file name is found */ + let videoUrl = null; + if (userId) { + let userMediaFeedResponseData = await getDataFromUrl('https://www.instagram.com/graphql/query/?query_hash=003056d32c2554def87228bc3fd9668a&variables={"id":' + userId + ',"first":100}'); + if (userMediaFeedResponseData) { + let json = JSON.parse(userMediaFeedResponseData); - /* Step 1 */ - /* Fetch user id from element */ - let userId = null; - let userProfileUrl = (article.querySelectorAll('header > div > div > div > span > a')[0] as HTMLLinkElement).href; - let userProfileUrlResponseData = await getDataFromUrl(userProfileUrl); + for (let _fI = 0; _fI < json.data.user.edge_owner_to_timeline_media.edges.length; _fI++) { + if (!isMultiVideo) { + if (json.data.user.edge_owner_to_timeline_media.edges[_fI].node.__typename == 'GraphVideo') { + let GraphVideoNode = json.data.user.edge_owner_to_timeline_media.edges[_fI].node; + if (videoPosterFilename == GraphVideoNode.display_url.split('/').pop().split('#')[0].split('?')[0]) { + videoUrl = GraphVideoNode.video_url; - if (userProfileUrlResponseData) { - userProfileUrlResponseData = userProfileUrlResponseData.replace(/(\r\n|\n|\r)/gm, ''); + /* There exists only one node so break it no need to further analyze */ + break; + } + } + /* Multi Post which can have a video */ + } else { + if (json.data.user.edge_owner_to_timeline_media.edges[_fI].node.__typename == 'GraphSidecar') { + if (json.data.user.edge_owner_to_timeline_media.edges[_fI].node.hasOwnProperty('edge_sidecar_to_children')) { + let GraphSidecarNode = json.data.user.edge_owner_to_timeline_media.edges[_fI].node.edge_sidecar_to_children.edges[pos].node; + videoUrl = GraphSidecarNode.video_url; - let m; - let regex = /profilePage_([0-9]+)/gm; - while ((m = regex.exec(userProfileUrlResponseData)) !== null) { - // This is necessary to avoid infinite loops with zero-width matches - if (m.index === regex.lastIndex) { - regex.lastIndex++; - } - - // The result can be accessed through the `m`-variable. - m.forEach((match) => { - userId = match; - }) - } - } - - /* Step 2 */ - /* Fetch the user data until the file name is found */ - let videoUrl = null; - if (userId) { - let userMediaFeedResponseData = await getDataFromUrl('https://www.instagram.com/graphql/query/?query_hash=003056d32c2554def87228bc3fd9668a&variables={"id":' + userId + ',"first":100}'); - if (userMediaFeedResponseData) { - let json = JSON.parse(userMediaFeedResponseData); - - for (let _fI = 0; _fI < json.data.user.edge_owner_to_timeline_media.edges.length; _fI++) { - // Handle different instagram post types - // Single Video - if (!isMultiVideo) { - if (json.data.user.edge_owner_to_timeline_media.edges[_fI].node.__typename == 'GraphVideo') { - let GraphVideoNode = json.data.user.edge_owner_to_timeline_media.edges[_fI].node; - if (videoPosterFilename == GraphVideoNode.display_url.split('/').pop().split('#')[0].split('?')[0]) { - videoUrl = GraphVideoNode.video_url; - - // There exists only one node so break it no need to further analyze - break; - } - } - // Multi Post which can have a video - } else { - if (json.data.user.edge_owner_to_timeline_media.edges[_fI].node.__typename == 'GraphSidecar') { - if (json.data.user.edge_owner_to_timeline_media.edges[_fI].node.hasOwnProperty('edge_sidecar_to_children')) { - let GraphSidecarNode = json.data.user.edge_owner_to_timeline_media.edges[_fI].node.edge_sidecar_to_children.edges[pos].node; - videoUrl = GraphSidecarNode.video_url; - - break; - } - } - } - } - } - } - - callback(videoUrl ? videoUrl : false); - } - } else { - callback(false); - } - } else { - callback(false); - } - } else { - callback(false); - } + break; + } + } + } + } + } + } + + callback(videoUrl ? videoUrl : false); + } else { + callback(false); + } } - export default getBlobVideoUrl; \ No newline at end of file diff --git a/src/modules/MediaScanner.ts b/src/modules/MediaScanner.ts index 29fd070..c2fd23d 100644 --- a/src/modules/MediaScanner.ts +++ b/src/modules/MediaScanner.ts @@ -258,11 +258,9 @@ export class MediaScanner implements Module { } } /* - * For single image + * For single image/video */ } else { - let $article: Element | NodeListOf