Skip to content

Commit

Permalink
Add support for instagram sidecars
Browse files Browse the repository at this point in the history
  • Loading branch information
amadejkastelic committed Aug 2, 2023
1 parent bf412ca commit 0d196fa
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 10 deletions.
1 change: 1 addition & 0 deletions Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ playwright = "==1.36.0"
"discord.py" = "==2.3.1"
instaloader = "==4.10"
facebook-scraper = "==0.2.59"
python-magic = "0.4.27"

[dev-packages]
black = "==23.7.0"
Expand Down
16 changes: 12 additions & 4 deletions Pipfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 20 additions & 4 deletions downloader/instagram.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import io
from urllib.parse import urlparse
import typing
from urllib.parse import urlparse, parse_qs

import instaloader

Expand All @@ -12,12 +13,27 @@ class InstagramClient(base.BaseClient):
def __init__(self, url: str):
super(InstagramClient, self).__init__(url=url)
self.client = instaloader.Instaloader()
self.id = urlparse(url).path.strip('/').split('/')[-1]

async def download(self) -> io.BytesIO:
parsed_url = urlparse(url)
self.id = parsed_url.path.strip('/').split('/')[-1]
self.index = int(parse_qs(parsed_url.query).get('img_index', ['1'])[0]) - 1

async def download(self) -> typing.Tuple[str, io.BytesIO]:
post = instaloader.Post.from_shortcode(self.client.context, self.id)

with self.client.context._session.get(post.video_url) as resp:
match post.typename:
case 'GraphImage':
download_url = post.url
case 'GraphVideo':
download_url = post.video_url
case 'GraphSidecar':
node = next(post.get_sidecar_nodes(start=self.index, end=self.index))
if node.is_video:
download_url = node.video_url
else:
download_url = node.display_url

with self.client.context._session.get(download_url) as resp:
return (
self.MESSAGE.format(
url=self.url,
Expand Down
12 changes: 10 additions & 2 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import io
import logging
import mimetypes
import os
import random
import re
import typing

import discord
import magic

from downloader import registry

Expand Down Expand Up @@ -32,15 +35,15 @@ async def on_message(self, message: discord.Message):
new_message = await message.channel.send('🔥 Working on it 🥵')

try:
text, video = await client.download()
text, buffer = await client.download()
except Exception as e:
logging.error(f'Failed downloading {url}: {str(e)}')
await new_message.edit(content=f'Failed downloading {url}. {message.author.mention}')
return

await message.channel.send(
content=f'Here you go {message.author.mention} {random.choice(emoji)}.\n{text}',
file=discord.File(fp=video, filename='video.mp4'),
file=discord.File(fp=buffer, filename=f'file.{self._guess_extension_from_buffer(buffer=buffer)}'),
suppress_embeds=True,
)
await new_message.delete()
Expand All @@ -49,6 +52,11 @@ def _find_first_url(self, string: str) -> typing.Optional[str]:
urls = re.findall(r'(https?://[^\s]+)', string)
return urls[0] if urls else None

def _guess_extension_from_buffer(self, buffer: io.BytesIO) -> str:
extension = mimetypes.guess_extension(type=magic.from_buffer(buffer.read(2048), mime=True))
buffer.seek(0)
return extension


intents = discord.Intents.default()
intents.message_content = True
Expand Down

0 comments on commit 0d196fa

Please sign in to comment.