Skip to content

Commit 8f5ff04

Browse files
committed
Fix matrix image uploads
1 parent 9b04d04 commit 8f5ff04

File tree

5 files changed

+92
-7
lines changed

5 files changed

+92
-7
lines changed

.github/workflows/daily-update.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,16 @@ jobs:
1111
runs-on: ubuntu-latest
1212

1313
steps:
14+
- run: |
15+
# Setup Cloudflare WARP
16+
curl -fsSL https://pkg.cloudflareclient.com/pubkey.gpg | sudo gpg --yes --dearmor --output /usr/share/keyrings/cloudflare-warp-archive-keyring.gpg
17+
# Add this repo to your apt repositories
18+
echo "deb [signed-by=/usr/share/keyrings/cloudflare-warp-archive-keyring.gpg] https://pkg.cloudflareclient.com/ $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/cloudflare-client.list
19+
# Install
20+
sudo apt-get update && sudo apt-get install cloudflare-warp
21+
warp-cli --accept-tos register
22+
warp-cli --accept-tos connect
23+
curl https://www.cloudflare.com/cdn-cgi/trace/
1424
- uses: actions/checkout@v2
1525
- name: Set up Python 3.9
1626
uses: actions/setup-python@v1

.github/workflows/weekly-update.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,16 @@ jobs:
1111
runs-on: ubuntu-latest
1212

1313
steps:
14+
- run: |
15+
# Setup Cloudflare WARP
16+
curl -fsSL https://pkg.cloudflareclient.com/pubkey.gpg | sudo gpg --yes --dearmor --output /usr/share/keyrings/cloudflare-warp-archive-keyring.gpg
17+
# Add this repo to your apt repositories
18+
echo "deb [signed-by=/usr/share/keyrings/cloudflare-warp-archive-keyring.gpg] https://pkg.cloudflareclient.com/ $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/cloudflare-client.list
19+
# Install
20+
sudo apt-get update && sudo apt-get install cloudflare-warp
21+
warp-cli --accept-tos register
22+
warp-cli --accept-tos connect
23+
curl https://www.cloudflare.com/cdn-cgi/trace/
1424
- uses: actions/checkout@v2
1525
- name: Set up Python 3.9
1626
uses: actions/setup-python@v1

main.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,20 @@
44

55
import asyncio
66
import logging
7+
import mimetypes
78
import os
89
import sys
10+
import tempfile
911
from multiprocessing import JoinableQueue, Process
1012
from time import sleep
1113

14+
import aiofiles
1215
import discord
1316
import simplematrixbotlib as botlib
1417
import telegram
1518
from discord.ext import commands
1619
from dotenv import load_dotenv
20+
from nio.responses import UploadResponse
1721
from praw import Reddit
1822

1923
import feeds
@@ -28,6 +32,7 @@
2832
create_reddit_matrix_post,
2933
create_reddit_telegram_post)
3034
from util.load_config import load_config
35+
from util.requests import fetch_image_to_file
3136

3237
logging.basicConfig(level=logging.INFO)
3338

@@ -220,6 +225,26 @@ def run_matrix_bot(queue: JoinableQueue):
220225
password=os.getenv('MATRIX_PASSWORD'))
221226
bot = botlib.Bot(creds)
222227

228+
async def get_matrix_content_uri(image_url: str):
229+
image_filepath = os.path.join(tempfile.gettempdir(), os.path.basename(image_url))
230+
if not fetch_image_to_file(image_url, image_filepath):
231+
return None
232+
mime_type = mimetypes.guess_type(image_filepath)[0]
233+
234+
file_stat = await aiofiles.os.stat(image_filepath)
235+
async with aiofiles.open(image_filepath, "r+b") as file:
236+
resp, _ = await bot.api.async_client.upload(
237+
file,
238+
content_type=mime_type,
239+
filename=os.path.basename(image_filepath),
240+
filesize=file_stat.st_size,
241+
encrypt=False,
242+
)
243+
if not isinstance(resp, UploadResponse):
244+
logging.error("Failed Upload Response: %s", resp)
245+
return None
246+
return resp.content_uri
247+
223248
@bot.listener.on_startup
224249
async def on_startup(room_id: str):
225250
if room_id != matrix_space:
@@ -232,11 +257,21 @@ async def on_startup(room_id: str):
232257
source, channel, post = message
233258
if source == 'reddit':
234259
matrix_post = create_reddit_matrix_post(channel, post)
260+
if matrix_post.image_url:
261+
matrix_content_uri = await get_matrix_content_uri(matrix_post.image_url)
262+
if matrix_content_uri:
263+
matrix_post.markdown = matrix_post.markdown.replace(
264+
matrix_post.image_url, matrix_content_uri)
235265
await bot.api.send_markdown_message(
236266
room_id=matrix_rooms['reddit'][channel['category']],
237267
message=matrix_post.markdown)
238268
elif source == 'blog':
239269
matrix_post = create_blog_matrix_post(post)
270+
if matrix_post.image_url:
271+
matrix_content_uri = await get_matrix_content_uri(matrix_post.image_url)
272+
if matrix_content_uri:
273+
matrix_post.markdown = matrix_post.markdown.replace(
274+
matrix_post.image_url, matrix_content_uri)
240275
await bot.api.send_markdown_message(
241276
room_id=matrix_rooms['blog'][channel],
242277
message=matrix_post.markdown)

util/embed_utils.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,7 @@ class MatrixPost:
327327
Matrix post
328328
'''
329329
markdown: str
330+
image_url: str = None
330331

331332

332333
def create_forum_matrix_post(forum, post):
@@ -335,7 +336,7 @@ def create_forum_matrix_post(forum, post):
335336
'''
336337
config = load_config('forums.json')[forum]
337338

338-
message = f'💬 {config["publisher"]}'
339+
message = f'***\n\n💬 {config["publisher"]}'
339340
message += f'\n\n**[{post["title"]}]({post["url"]})**'
340341
if post["description"]:
341342
if len(post["description"]) > 1000:
@@ -356,11 +357,11 @@ def create_blog_matrix_post(post):
356357
'''
357358
Create blog post embed from JSON
358359
'''
359-
message = f'📰 {post["publisher"]}'
360+
message = f'***\n\n📰 {post["publisher"]}'
360361
message += f'\n\n**[{post["title"]}]({post["url"]})**'
361362
image_url = post["image"] if 'image' in post and len(post['image']) > 0 else ''
362363
if image_url:
363-
message += f'\n\n![{post["title"]}]({image_url})'
364+
message += f'\n\n![]({image_url})'
364365
if post["description"]:
365366
if len(post["description"]) > 1000:
366367
post["description"] = post["description"][:1000] + '...'
@@ -370,25 +371,27 @@ def create_blog_matrix_post(post):
370371
message = message.replace('\n\n\n', '\n\n')
371372

372373
return MatrixPost(
373-
markdown=message
374+
markdown=message,
375+
image_url=image_url
374376
)
375377

376378

377379
def create_reddit_matrix_post(subreddit, post):
378380
'''
379381
Create reddit post embed from subreddit JSON
380382
'''
381-
message = f'💬 r/{subreddit["subreddit"]}'
383+
message = f'***\n\n💬 r/{subreddit["subreddit"]}'
382384
message += f'\n\n**[{post["title"]}]({post["url"]})**'
383385
image_url = post["media"]["url"] if 'media' in post and 'url' in post['media'] else ''
384386
if image_url:
385-
message += f'\n\n![{post["title"]}]({image_url})'
387+
message += f'\n\n![]({image_url})'
386388
if post["selftext"]:
387389
if len(post["selftext"]) > 1000:
388390
post["selftext"] = post["selftext"][:1000] + '...'
389391
message += f'\n\n{post["selftext"].strip()}'
390392
message += '\n‎'
391393

392394
return MatrixPost(
393-
markdown=message
395+
markdown=message,
396+
image_url=image_url
394397
)

util/requests.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,30 @@ def fetch_from_server(url: str):
3434
except Exception as exception: # pylint: disable=broad-except
3535
logging.error('Cannot connect to %s - %s', url, str(exception)[:30])
3636
return None
37+
38+
39+
def fetch_image_to_file(url: str, filename: str):
40+
'''
41+
Fetch image from server and save to file
42+
'''
43+
try:
44+
response = requests.get(
45+
url,
46+
headers={
47+
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)'
48+
'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36'
49+
},
50+
timeout=25,
51+
verify=False
52+
)
53+
if response.status_code == 200:
54+
with open(filename, 'wb') as file:
55+
file.write(response.content)
56+
return True
57+
logging.error(
58+
'Request to %s failed - %d: %s', url, response.status_code, response.reason
59+
)
60+
return False
61+
except Exception as exception: # pylint: disable=broad-except
62+
logging.error('Cannot connect to %s - %s', url, str(exception)[:30])
63+
return False

0 commit comments

Comments
 (0)