Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🎉 #14

Merged
merged 13 commits into from
May 14, 2024
Merged

🎉 #14

Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions .github/workflows/preview.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: Create Preview

on:
pull_request_target:
branches: [main]
types: [opened, synchronize, reopened]

jobs:
preview:
name: Preview
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- name: Checkout
uses: actions/checkout@v3

- name: Get changed files in posts folder
id: get_changed_files
uses: tj-actions/changed-files@v44
with:
files: posts/**
json: "true"

- name: get published files cache
if: steps.get_changed_files.outputs.any_changed == 'true'
run: |
git fetch origin processed_files:processed_files
git checkout processed_files -- processed_files.json

- name: Set up Python
if: steps.get_changed_files.outputs.any_changed == 'true'
uses: actions/setup-python@v3
with:
python-version: 3.9

- name: Install dependencies
if: steps.get_changed_files.outputs.any_changed == 'true'
run: |
python -m pip install --upgrade pip
python -m pip install -r requirements.txt

- name: Run script to create preview
if: steps.get_changed_files.outputs.any_changed == 'true'
env:
CHANGED_FILES: ${{ steps.get_changed_files.outputs.all_changed_files }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_NUMBER: ${{ github.event.number }}
run: python -u lib/galaxy-social.py preview
65 changes: 65 additions & 0 deletions .github/workflows/publish_content.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
name: Publish Content

on:
pull_request_target:
branches: [main]
types: [closed]

jobs:
publish:
if: github.event.pull_request.merged == true
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- name: Checkout
uses: actions/checkout@v3

- name: Get changed files in posts folder
id: get_changed_files
uses: tj-actions/changed-files@v44
with:
files: posts/**
json: "true"

- name: get published files cache
if: steps.get_changed_files.outputs.any_changed == 'true'
run: |
git fetch origin processed_files:processed_files
git checkout processed_files -- processed_files.json

- name: Set up Python
if: steps.get_changed_files.outputs.any_changed == 'true'
uses: actions/setup-python@v3
with:
python-version: 3.9

- name: Install dependencies
if: steps.get_changed_files.outputs.any_changed == 'true'
run: |
python -m pip install --upgrade pip
python -m pip install -r requirements.txt

- name: Run script to publish contents
if: steps.get_changed_files.outputs.any_changed == 'true'
env:
MASTODON_ACCESS_TOKEN: ${{ secrets.MASTODON_ACCESS_TOKEN }}
BLUESKY_USERNAME: ${{ secrets.BLUESKY_USERNAME }}
BLUESKY_PASSWORD: ${{ secrets.BLUESKY_PASSWORD }}
MATRIX_ACCESS_TOKEN: ${{ secrets.MATRIX_ACCESS_TOKEN }}
MATRIX_ROOM_ID: ${{ secrets.MATRIX_ROOM_ID }}
MATRIX_USER_ID: ${{ secrets.MATRIX_USER_ID }}
SLACK_ACCESS_TOKEN: ${{ secrets.SLACK_ACCESS_TOKEN }}
SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }}
CHANGED_FILES: ${{ steps.get_changed_files.outputs.all_changed_files }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_NUMBER: ${{ github.event.number }}
run: python -u lib/galaxy-social.py

- name: Commit changes
if: steps.get_changed_files.outputs.any_changed == 'true'
uses: stefanzweifel/git-auto-commit-action@v5
with:
file_pattern: "processed_files.json"
branch: "processed_files"
25 changes: 0 additions & 25 deletions .github/workflows/toot-together.yml

This file was deleted.

2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ dist/
downloads/
eggs/
.eggs/
lib/
# lib/
lib64/
parts/
sdist/
Expand Down
32 changes: 32 additions & 0 deletions .schema.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
type: object
properties:
media:
type: array
items:
type: string
uniqueItems: true
images:
type: array
items:
type: object
properties:
url:
type: string
format: uri
alt_text:
type: string
required: []
mentions:
type: object
additionalProperties:
type: array
items:
type: string
required: []
hashtags:
type: object
additionalProperties:
type: array
items:
type: string
required: []
Binary file modified README.md
Binary file not shown.
152 changes: 152 additions & 0 deletions lib/galaxy-social.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
import fnmatch
import importlib
import json
import os
import sys

import jsonschema
import markdown
import requests
import yaml
from bs4 import BeautifulSoup
from github_comment import comment_to_github

with open("plugins.yml", "r") as file:
plugins_config = yaml.safe_load(file)

plugins = {}
for plugin in plugins_config["plugins"]:
if "preview" in sys.argv and plugin["name"].lower() != "markdown":
continue

if plugin["enabled"]:
module_name, class_name = plugin["class"].rsplit(".", 1)

try:
module = importlib.import_module(f"plugins.{module_name}")
plugin_class = getattr(module, class_name)
except:
comment_to_github(
f"Error with plugin {module_name}.{class_name}.", error=True
)

try:
config = {
key: os.environ.get(value)
for key, value in plugin["config"].items()
if (not isinstance(value, int) and os.environ.get(value) is not None)
arash77 marked this conversation as resolved.
Show resolved Hide resolved
}
except:
comment_to_github(
f"Missing config for {module_name}.{class_name}.", error=True
)

try:
plugins[plugin["name"].lower()] = plugin_class(**config)
except:
comment_to_github(
f"Invalid config for {module_name}.{class_name}.", error=True
)


def parse_markdown_file(file_path):
with open(file_path, "r") as file:
content = file.read()
_, metadata, text = content.split("---\n", 2)
try:
metadata = yaml.safe_load(metadata)
with open(".schema.yaml", "r") as f:
schema = yaml.safe_load(f)
jsonschema.validate(instance=metadata, schema=schema)
except:
comment_to_github(f"Invalid metadata in {file_path}.", error=True)

metadata["media"] = [media.lower() for media in metadata["media"]]

for media in metadata["media"]:
if not any(item["name"].lower() == media for item in plugins_config["plugins"]):
comment_to_github(f"Invalid media {media}.", error=True)

metadata["mentions"] = (
{key.lower(): value for key, value in metadata["mentions"].items()}
if metadata.get("mentions")
else {}
)
metadata["hashtags"] = (
{key.lower(): value for key, value in metadata["hashtags"].items()}
if metadata.get("hashtags")
else {}
)
markdown_content = markdown.markdown(text.strip())
plain_content = BeautifulSoup(markdown_content, "html.parser").get_text(
separator="\n"
)
return plain_content, metadata


def process_markdown_file(file_path, processed_files):
content, metadata = parse_markdown_file(file_path)
if "preview" in sys.argv:
try:
plugins["markdown"].create_post(
content, [], [], metadata.get("images", []), media=metadata["media"]
)
return processed_files
except:
comment_to_github(f"Failed to create preview for {file_path}.", error=True)
stats = {}
url = {}
for media in metadata["media"]:
if file_path in processed_files and media in processed_files[file_path]:
stats[media] = processed_files[file_path][media]
continue
mentions = metadata.get("mentions", {}).get(media, [])
hashtags = metadata.get("hashtags", {}).get(media, [])
images = metadata.get("images", [])
stats[media], url[media] = plugins[media].create_post(
content, mentions, hashtags, images
)
url_text = "\n".join([f"[{media}]({link})" for media, link in url.items() if link])
comment_to_github(f"Posted to:\n\n{url_text}")

processed_files[file_path] = stats
print(f"Processed {file_path}: {stats}")
return processed_files


def main():
repo = os.getenv("GITHUB_REPOSITORY")
pr_number = os.getenv("PR_NUMBER")
url = f"https://api.github.com/repos/{repo}/pulls/{pr_number}/files"
response = requests.get(url)
print(response.json(), url)
if response.status_code == 200:
changed_files = response.json()
for file in changed_files:
raw_url = file["raw_url"]
if raw_url.endswith(".md"):
response = requests.get(raw_url)
if response.status_code == 200:
with open(file["filename"], "w") as f:
f.write(response.text)

processed_files = {}
if os.path.exists("processed_files.json"):
with open("processed_files.json", "r") as file:
processed_files = json.load(file)
changed_files = os.environ.get("CHANGED_FILES")
if changed_files:
for file_path in eval(changed_files.replace("\\", "")):
if file_path.endswith(".md"):
processed_files = process_markdown_file(file_path, processed_files)
else:
for root, _, files in os.walk("posts"):
for filename in fnmatch.filter(files, "*.md"):
file_path = os.path.join(root, filename)
processed_files = process_markdown_file(file_path, processed_files)
with open("processed_files.json", "w") as file:
json.dump(processed_files, file)


if __name__ == "__main__":
arash77 marked this conversation as resolved.
Show resolved Hide resolved
main()
25 changes: 25 additions & 0 deletions lib/github_comment.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import os

import requests


def comment_to_github(comment_text, error=False):
github_token = os.getenv("GITHUB_TOKEN")
repo_owner, repo_name = os.getenv("GITHUB_REPOSITORY").split("/")
pr_number = os.getenv("PR_NUMBER")
headers = {
"Accept": "application/vnd.github+json",
"Authorization": f"Bearer {github_token}",
"X-GitHub-Api-Version": "2022-11-28",
}
url = f"https://api.github.com/repos/{repo_owner}/{repo_name}/issues/{pr_number}/comments"
data = {"body": comment_text}
response = requests.post(url, headers=headers, json=data)
if response.status_code != 201:
raise Exception(
f"Failed to create github comment!, {response.json().get('message')}"
)
else:
if error:
raise Exception(comment_text)
return True
Loading