mirror of
https://github.com/RSS-Bridge/rss-bridge.git
synced 2024-11-22 01:25:28 +03:00
[core] Add pr-html-generator (#2525)
This commit is contained in:
parent
105fbe9dda
commit
aff442de1b
3 changed files with 135 additions and 0 deletions
2
.github/prtester-requirements.txt
vendored
Normal file
2
.github/prtester-requirements.txt
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
beautifulsoup4>=4.10.0
|
||||
requests>=2.26.0
|
74
.github/prtester.py
vendored
Normal file
74
.github/prtester.py
vendored
Normal file
|
@ -0,0 +1,74 @@
|
|||
import requests
|
||||
from bs4 import BeautifulSoup
|
||||
import random
|
||||
import json
|
||||
import os.path
|
||||
|
||||
# This script is specifically written to be used in automation for https://github.com/RSS-Bridge/rss-bridge
|
||||
#
|
||||
# This will scrape the whitelisted bridges in the current state (port 3000) and the PR state (port 3001) of
|
||||
# RSS-Bridge, generate a feed for each of the bridges and save the output as html files.
|
||||
# It also replaces the default static CSS link with a hardcoded link to @em92's public instance, so viewing
|
||||
# the HTML file locally will actually work as designed.
|
||||
|
||||
def testBridges(bridges,status):
|
||||
for bridge in bridges:
|
||||
if bridge.get('data-ref'): # Some div entries are empty, this ignores those
|
||||
bridgeid = bridge.get('id')
|
||||
bridgeid = bridgeid.split('-')[1] # this extracts a readable bridge name from the bridge metadata
|
||||
bridgestring = '/?action=display&bridge=' + bridgeid + '&format=Html'
|
||||
forms = bridge.find_all("form")
|
||||
formid = 1
|
||||
for form in forms:
|
||||
# a bridge can have multiple contexts, named 'forms' in html
|
||||
# this code will produce a fully working formstring that should create a working feed when called
|
||||
# this will create an example feed for every single context, to test them all
|
||||
formstring = ''
|
||||
errormessages = []
|
||||
parameters = form.find_all("input")
|
||||
lists = form.find_all("select")
|
||||
# this for/if mess cycles through all available input parameters, checks if it required, then pulls
|
||||
# the default or examplevalue and then combines it all together into the formstring
|
||||
# if an example or default value is missing for a required attribute, it will throw an error
|
||||
# any non-required fields are not tested!!!
|
||||
for parameter in parameters:
|
||||
if parameter.get('type') == 'number' or parameter.get('type') == 'text':
|
||||
if parameter.has_attr('required'):
|
||||
if parameter.get('placeholder') == '':
|
||||
if parameter.get('value') == '':
|
||||
errormessages.append(parameter.get('name'))
|
||||
else:
|
||||
formstring = formstring + '&' + parameter.get('name') + '=' + parameter.get('value')
|
||||
else:
|
||||
formstring = formstring + '&' + parameter.get('name') + '=' + parameter.get('placeholder')
|
||||
# same thing, just for checkboxes. If a checkbox is checked per default, it gets added to the formstring
|
||||
if parameter.get('type') == 'checkbox':
|
||||
if parameter.has_attr('checked'):
|
||||
formstring = formstring + '&' + parameter.get('name') + '=on'
|
||||
for list in lists:
|
||||
formstring = formstring + '&' + list.get('name') + '=' + list.contents[0].get('value')
|
||||
if not errormessages:
|
||||
# if all example/default values are present, form the full request string, run the request, replace the static css
|
||||
# file with the url of em's public instance and then write it all to file.
|
||||
r = requests.get(URL + bridgestring + formstring)
|
||||
pagetext = r.text.replace('static/HtmlFormat.css','https://feed.eugenemolotov.ru/static/HtmlFormat.css')
|
||||
with open(os.getcwd() + "/results/" + bridgeid + '-' + status + '-context' + str(formid) + '.html', 'w+') as file:
|
||||
file.write(pagetext)
|
||||
else:
|
||||
# if there are errors (which means that a required value has no example or default value), log out which error appeared
|
||||
with open(os.getcwd() + "/results/" + bridgeid + '-' + status + '-context' + str(formid) + '.html', 'w+') as file:
|
||||
file.write(str(errormessages))
|
||||
formid += 1
|
||||
|
||||
gitstatus = ["current", "pr"]
|
||||
|
||||
for status in gitstatus: # run this twice, once for the current version, once for the PR version
|
||||
if status == "current":
|
||||
port = "3000" # both ports are defined in the corresponding workflow .yml file
|
||||
elif status == "pr":
|
||||
port = "3001"
|
||||
URL = "http://localhost:" + port
|
||||
page = requests.get(URL) # Use python requests to grab the rss-bridge main page
|
||||
soup = BeautifulSoup(page.content, "html.parser") # use bs4 to turn the page into soup
|
||||
bridges = soup.find_all("section") # get a soup-formatted list of all bridges on the rss-bridge page
|
||||
testBridges(bridges,status) # run the main scraping code with the list of bridges and the info if this is for the current version or the pr version
|
59
.github/workflows/prhtmlgenerator.yml
vendored
Normal file
59
.github/workflows/prhtmlgenerator.yml
vendored
Normal file
|
@ -0,0 +1,59 @@
|
|||
name: 'PR Testing'
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
test-pr:
|
||||
name: Generate HTML
|
||||
runs-on: ubuntu-latest
|
||||
# Needs additional permissions https://github.com/actions/first-interaction/issues/10#issuecomment-1041402989
|
||||
steps:
|
||||
- name: Check out self
|
||||
uses: actions/checkout@v2.3.2
|
||||
with:
|
||||
ref: ${{github.event.pull_request.head.ref}}
|
||||
repository: ${{github.event.pull_request.head.repo.full_name}}
|
||||
- name: Check out rss-bridge
|
||||
run: |
|
||||
PR=${{github.event.number}};
|
||||
mv .github/prtester-requirements.txt ./requirements.txt;
|
||||
mv .github/prtester.py .;
|
||||
wget https://patch-diff.githubusercontent.com/raw/$GITHUB_REPOSITORY/pull/$PR.patch;
|
||||
cat $PR.patch | grep " bridges/.*\.php" | sed "s= bridges/\(.*\)Bridge.php.*=\1=g" | sort | uniq > whitelist.txt
|
||||
- name: Start Docker - Current
|
||||
run: |
|
||||
docker run -d -v $GITHUB_WORKSPACE/whitelist.txt:/app/whitelist.txt -p 3000:80 ghcr.io/rss-bridge/rss-bridge:latest
|
||||
- name: Start Docker - PR
|
||||
run: |
|
||||
docker build -t prbuild .;
|
||||
docker run -d -v $GITHUB_WORKSPACE/whitelist.txt:/app/whitelist.txt -p 3001:80 prbuild
|
||||
- name: Setup python
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: '3.7'
|
||||
cache: 'pip'
|
||||
- name: Install requirements
|
||||
run: |
|
||||
cd $GITHUB_WORKSPACE
|
||||
pip install -r requirements.txt
|
||||
- name: Run bridge tests
|
||||
run: |
|
||||
mkdir results;
|
||||
python prtester.py
|
||||
- name: Find result files
|
||||
uses: tj-actions/glob@v7.10
|
||||
id: artifacts
|
||||
with:
|
||||
files: |
|
||||
./results/*.html
|
||||
- name: Upload results to PR
|
||||
uses: yamanq/pull-request-artifacts@v1.3.1
|
||||
with:
|
||||
commit: ${{ github.event.pull_request.head.sha }}
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
artifacts-branch: artifacts
|
||||
artifacts-prefix-url: "https://htmlpreview.github.io/?"
|
||||
artifacts: |
|
||||
${{ steps.artifacts.outputs.paths }}
|
Loading…
Reference in a new issue