From 6e364e85a3765b1e4855f3fdca8e1e4071e02aad Mon Sep 17 00:00:00 2001 From: Bastian <8929967+Kaiserdragon2@users.noreply.github.com> Date: Thu, 14 Mar 2024 12:07:12 +0100 Subject: [PATCH 1/7] change script to point to folder of request and updatable --- scripts/email_parser.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/scripts/email_parser.py b/scripts/email_parser.py index c66390c..b666a88 100644 --- a/scripts/email_parser.py +++ b/scripts/email_parser.py @@ -13,7 +13,7 @@ config = { "request_limit": 50, - "months_limit": 6, + "months_limit": 600, "min_requests": 5, "date_format": "X%d %B %Y", } @@ -24,7 +24,7 @@ def parse_args(): parser.add_argument("folder_path", type=str, help="Path to folder containing .eml files of requests") parser.add_argument("appfilter_path", type=str, help="Path to existing appfilter.xml to recognize potentially updatable appfilters") parser.add_argument("extracted_png_folder_path", type=str, help="Path to folder containing extracted PNGs") - parser.add_argument("requests_path", nargs="?", type=str, default=None, help="Existing requests.txt file to augment with new info (optional)") + parser.add_argument("requests_path", type=str, default=None, help="Path to folder containing the request.txt and updatable.txt") return parser.parse_args() @@ -33,7 +33,8 @@ def __init__(self, folder_path, appfilter_path, extracted_png_folder_path, reque self.folder_path = Path(folder_path) self.appfilter_path = Path(appfilter_path) self.extracted_png_folder_path = Path(extracted_png_folder_path) - self.requests_path = Path(requests_path) if requests_path else None + self.requests_path = Path(requests_path+'/requests.txt') if requests_path else None + self.updatable_path = Path(requests_path+'/updatable.txt') if requests_path else None self.filelist = list(self.folder_path.glob('*.eml')) self.data = {} @@ -51,7 +52,7 @@ def __init__(self, folder_path, appfilter_path, extracted_png_folder_path, reque def parse_existing(self): request_block_query = re.compile(r'\s.+)}\" drawable=\"(?P.+|)\"(/>| />)\s(https:\/\/play.google.com\/store\/apps\/details\?id=.+\shttps:\/\/f-droid\.org\/en\/packages\/.+\shttps:\/\/apt.izzysoft.de\/fdroid\/index\/apk\/.+\shttps:\/\/galaxystore.samsung.com\/detail\/.+\shttps:\/\/www.ecosia.org\/search\?q\=.+\s)Requested (?P\d+) times\s?(Last requested (?P\d+\.?\d+?))?', re.M) - if not self.requests_path: + if not self.requests_path.exists(): return with open(self.requests_path, 'r', encoding="utf8") as existing_file: contents = existing_file.read() @@ -285,11 +286,10 @@ def write_output(self): new_list = new_list_header.format(total_count=len(self.new_apps), date=date.today().strftime(config["date_format"]).replace("X0", "X").replace("X", "")) new_list += ''.join(self.new_apps) - requests_file_path = 'requests.txt' if not self.requests_path else self.requests_path - with open(requests_file_path, 'w', encoding='utf-8') as file: + with open(self.requests_path, 'w', encoding='utf-8') as file: file.write(new_list) if len(self.updatable): - with open('updatable.txt', 'w', encoding='utf-8') as file_two: + with open(self.updatable_path, 'w', encoding='utf-8') as file_two: file_two.write(''.join(self.updatable)) def main(self): From 8f1efea9853d7e21680feae655e9d3bc951b625b Mon Sep 17 00:00:00 2001 From: Bastian <8929967+Kaiserdragon2@users.noreply.github.com> Date: Thu, 14 Mar 2024 12:07:25 +0100 Subject: [PATCH 2/7] add updateable site --- docs/css/updatable.css | 192 ++++++++++++++++++++++++++++ docs/js/updatable.js | 271 ++++++++++++++++++++++++++++++++++++++++ docs/updatable.html | 47 +++++++ generated/updatable.txt | 3 + 4 files changed, 513 insertions(+) create mode 100644 docs/css/updatable.css create mode 100644 docs/js/updatable.js create mode 100644 docs/updatable.html create mode 100644 generated/updatable.txt diff --git a/docs/css/updatable.css b/docs/css/updatable.css new file mode 100644 index 0000000..349e368 --- /dev/null +++ b/docs/css/updatable.css @@ -0,0 +1,192 @@ +@font-face { + font-family: 'Inter'; + font-weight: 100 900; + font-display: swap; + font-style: oblique 0deg 10deg; + font-variation-settings: "slnt" 0deg; + src: url("../img/Inter.var.woff2") format("woff2"); + } + +body { + font-family: 'Inter', Arial, Helvetica, sans-serif, sans-serif; + margin-left: 4vw; + margin-right: 4vw; + background-color: white; +} + +.app-entry { + display: none; + /* Hide initially */ +} + +.copy-button { + cursor: pointer; + background-color: #4CAF50; + color: white; + border: none; + padding: 5px 15px; + text-align: center; + text-decoration: none; + display: inline-block; + font-size: 16px; + margin-bottom: 10px; + border-radius: 100px; +} + +.copy-button:hover { + background-color: #409943; +} + +#copy-notification { + display: none; + background-color: #4CAF50; + color: white; + padding: 10px; + position: fixed; + bottom: 10px; + right: 10px; + z-index: 1; +} + +#search-notification { + display: none; + background-color: #8b1708; + color: white; + padding: 10px; + position: fixed; + top: 20px; + right: 10px; + z-index: 1; +} + +#search-container { + display: flex; + width: 100%; + max-width: 400px; + margin: 0 auto; + align-items: center; + justify-content: center; + +} + +#search-input { + margin: 1em 0; + width: calc(100% - .5rem - 16px); + box-sizing: border-box !important; + overflow: visible; + min-height: 3rem; + border-radius: 4em; + background-color: #eee; + border: 1.5px solid #171717; + box-shadow: none; + outline: none; + padding: 0.8em 1.2em; + font-size: 16px; + font-weight: bold; + font-family: 'Inter', Arial, Helvetica, sans-serif, sans-serif; + +} + +.table-container { + max-height: 1200px; + /* Set maximum height for scrollable area */ + overflow-y: auto; + /* Enable vertical scrolling */ +} + +.table-container thead th { + position: sticky; + /* make the table heads sticky */ + top: 0px; + /* table head will be placed from the top of the table and sticks to it */ +} + +.sortable-header { + cursor: pointer; + /* Add cursor style for sorting */ + position: relative; +} + +.sortable-header::after { + content: ''; + position: absolute; + right: 8px; + top: 50%; + transform: translateY(-50%); + width: 0; + height: 0; + border-left: 4px solid transparent; + border-right: 4px solid transparent; +} + +.asc::after { + border-bottom: 4px solid #000000; +} + +.desc::after { + border-top: 4px solid #000000; +} + +table { + width: 99.5%; + border-collapse: collapse; +} + +th, +td { + border: 1px solid #ddd; + padding: 8px; + text-align: center; +} + +td:nth-child(1) { + width: 20%; +} +td:nth-child(2) { + min-width: 100px; +} + +td:nth-child(3) { + max-width: 50px; + ; +} + +tr:nth-child(even) { + background-color: #ebebeb; +} + +th { + background-color: #f2f2f2; +} + +h1 { + text-align: center; + margin-top: 20px; + margin-bottom: 20px; +} + +img { + filter: invert(); +} + +@media (prefers-color-scheme: dark) { + body { + background-color: #171717; + color: white; + } + tr:nth-child(even) { + background-color: rgb(37, 37, 37); + } + th { + background-color: #0f0f0f; + } + img { + filter: none; + } + .asc::after { + border-bottom: 4px solid white; + } + .desc::after { + border-top: 4px solid white; + } +} \ No newline at end of file diff --git a/docs/js/updatable.js b/docs/js/updatable.js new file mode 100644 index 0000000..8f25d6f --- /dev/null +++ b/docs/js/updatable.js @@ -0,0 +1,271 @@ + +var appEntriesDataGlobal = []; // Store the original data for sorting +// Lazy loading and virtualization +const batchSize = 50; // Number of rows to load at a time +let startIndex = 0; // Start index for lazy loading +let appEntriesData = []; // Store the original data for sorting +// Global variables to track sorting column and direction +let sortingColumnIndex = 3; +let sortingDirection = 'desc'; + +// Debounce function for search input +const debounce = (func, delay) => { + let timeoutId; + return (...args) => { + if (timeoutId) { + clearTimeout(timeoutId); + } + timeoutId = setTimeout(() => { + func.apply(null, args); + }, delay); + }; +}; + +// Fetch and process data +fetch('https://raw.githubusercontent.com/Arcticons-Team/Icon-Request-Dashboard/main/generated/updatable.txt') + .then(response => { + if (!response.ok) { + throw new Error(`HTTP error! Status: ${response.status}`); + } + return response.text(); + }) + .then(fileContent => { + const appEntries = fileContent.split(/(?=)/).filter(entry => entry.trim() !== ''); + + // Process each entry and store data + appEntries.slice(0).forEach(entry => { + const lines = entry.trim().split('\n'); + const appName = lines[0].trim().split('--')[1].trim(); + const appNameAppfilter = lines[0].trim(); + const appfilter = lines[1].trim().split('\n').join(' ').trim(); + appEntriesData.push({ + appName, + appNameAppfilter, + appfilter + }); + }); + appEntriesDataGlobal = appEntriesData; + + // Example usage: + fetch('https://raw.githubusercontent.com/Arcticons-Team/Arcticons/Icon-Request-Dashboard/docs/assets/combined_appfilter.xml') + .then(response => { + if (!response.ok) { + // If appfilter.xml cannot be loaded, render appEntriesData as is + console.error('Error fetching appfilter:', response.status); + lazyLoadAndRender(); + return; + } + return response.text(); + }) + .then(appfilterContent => { + if (!appfilterContent) { + // If appfilterContent is empty, render appEntriesData as is + console.error('Empty appfilter content'); + lazyLoadAndRender(); + return; + } + const filteredData = filterAppfilter(appEntriesData, appfilterContent); + appEntriesData = filteredData; + appEntriesDataGlobal = filteredData; + const table = document.querySelector('table'); + const headers = table.querySelectorAll('thead th'); + headers[sortingColumnIndex].classList.add(sortingDirection); + // Initial render + lazyLoadAndRender(); + }) + .catch(error => console.error('Error fetching or processing appfilter:', error)); + }) + .catch(error => console.error('Error fetching file:', error)); + + + + // Filter appEntriesData based on appfilter content + function filterAppfilter(appEntriesData, appfilterContent) { + const appfilterItems = parseAppfilter(appfilterContent); + const filteredOutEntries = []; + + const filteredData = appEntriesData.filter(entry => { + const entryAppfilter = entry.appfilter.trim().split('"')[1].trim(); + // Check if the entry is filtered out + const isFiltered = appfilterItems.some(component => component === entryAppfilter); + if (isFiltered) { + filteredOutEntries.push(entryAppfilter); + } + return !isFiltered; + }); + console.log("Filtered out entries:", filteredOutEntries); + return filteredData; + } + +// Parse appfilter content +function parseAppfilter(appfilterContent) { + const parser = new DOMParser(); + const xmlDoc = parser.parseFromString(appfilterContent, 'text/xml'); + const items = xmlDoc.querySelectorAll('item'); + const appfilterItems = []; + items.forEach(item => { + const component = item.getAttribute('component'); + if (component) { + appfilterItems.push(component.trim()); + } + }); + return appfilterItems; +} + +// Update header text +function updateHeaderText(newHeader) { + header = newHeader; + document.getElementById('header').innerText = newHeader; +} + +function lazyLoadAndRender() { + const dataBatch = appEntriesDataGlobal.slice(startIndex, startIndex + batchSize); + renderTable(dataBatch); + startIndex += batchSize; +} + +// Scroll event listener for lazy loading +const tableContainer = document.querySelector('.table-container'); +tableContainer.addEventListener('scroll', () => { + const { scrollTop, scrollHeight, clientHeight } = tableContainer; + if (scrollTop + clientHeight >= scrollHeight - 100) { + lazyLoadAndRender(); + } +}); + +// Function to clear existing table rows +function clearTable() { + const table = document.getElementById("app-entries"); + while (table.rows.length > 0) { + table.deleteRow(0); + } +} + +// Function to render the table based on provided data +function renderTable(data) { + const table = document.getElementById("app-entries"); + data.forEach((entry, index) => { + let row = table.insertRow(); + let cell1 = row.insertCell(0); + let cell2 = row.insertCell(1); + let cell3 = row.insertCell(2); + index = index + startIndex; + cell1.innerHTML = entry.appName; + cell2.innerHTML = entry.appfilter.replace('<', '<').replace('>', '>').replace(/"/g, '"').trim(); + cell3.innerHTML = ``; + }); +} + +// Update the table with filtered or sorted data +function updateTable(data) { + startIndex = 0; + clearTable(); // Clear existing table rows + appEntriesDataGlobal = data; + lazyLoadAndRender(); +} + +// Copy to clipboard function +function copyToClipboard(index) { + const entry = appEntriesDataGlobal[index]; + const copyText = `${entry.appNameAppfilter}\n${entry.appfilter}`; + navigator.clipboard.writeText(copyText).then(() => { + // Show the copy notification + document.getElementById('copy-notification').innerText = `Copied: ${copyText}`; + document.getElementById('copy-notification').style.display = 'block'; + + // Hide the notification after a few seconds + setTimeout(() => { + document.getElementById('copy-notification').style.display = 'none'; + }, 3000); + }).catch(error => { + console.error('Unable to copy to clipboard:', error); + }); +} + +// Search function +const filterAppEntries = debounce(() => { + const searchInput = document.getElementById('search-input').value.toLowerCase(); + const filteredData = appEntriesData.filter(entry => + entry.appName.toLowerCase().includes(searchInput) + ); + // If no results are found, show a notification + if (filteredData.length === 0) { + document.getElementById('search-notification').innerText = `No results found.`; + document.getElementById('search-notification').style.display = 'block'; + // Hide the notification after a few seconds + setTimeout(() => { + document.getElementById('search-notification').style.display = 'none'; + }, 5000); + } else { + document.getElementById('search-notification').style.display = 'none'; + const filteredandsortedData = sortData(sortingDirection, sortingColumnIndex, [...filteredData]) + updateTable(filteredandsortedData); + } +}, 500); + +// Sort table function +function sortTable(columnIndex) { + const table = document.querySelector('table'); + const headers = table.querySelectorAll('thead th'); + + // Determine the sorting direction + sortingDirection = headers[columnIndex].classList.contains('asc') ? 'desc' : 'asc'; + + // Remove sorting indicators from all headers + headers.forEach(header => { + header.classList.remove('asc', 'desc'); + }); + + // Add the appropriate sorting class to the clicked header + headers[columnIndex].classList.add(sortingDirection); + sortingColumnIndex = columnIndex; + // Sort the data + const sortedData = sortData(sortingDirection, columnIndex, [...appEntriesDataGlobal]); + + updateTable(sortedData); +} + +function sortData(sortingDirection, columnIndex, sortedData){ + sortedData.sort((a, b) => { + if (columnIndex === 4) { // Check if sorting the 'Last Requested' column + const cellA = getCellValue(a, columnIndex); + const cellB = getCellValue(b, columnIndex); + + // Handle dates + return sortingDirection === 'asc' ? cellA - cellB : cellB - cellA; + } else if (columnIndex === 3) { + const cellA = getCellValue(a, columnIndex); + const cellB = getCellValue(b, columnIndex); + + // Handle numerical values + if (!isNaN(cellA) && !isNaN(cellB)) { + return sortingDirection === 'asc' ? cellA - cellB : cellB - cellA; + } + } else { + // Default to string comparison + const cellA = a[Object.keys(a)[columnIndex]].toLowerCase(); + const cellB = b[Object.keys(b)[columnIndex]].toLowerCase(); + return sortingDirection === 'asc' ? cellA.localeCompare(cellB) : cellB.localeCompare(cellA); + } + }); + return sortedData; +} + +// Initial table rendering +function initializeTable() { + renderTable(appEntriesData); +} + +// Helper function to get cell value by column index +function getCellValue(row, columnIndex) { + const key = Object.keys(row)[columnIndex]; + if (key === 'lastRequestedTime') { + // Parse date strings to Date objects for sorting + const dateString = row[key].split(',')[0]; // Extract date part from the string + const [day, month, year] = dateString.split('/').map(Number); // Split the date string and convert parts to numbers + const timeString = row[key].split(',')[1].trim(); // Extract time part from the string + const [hour, minute, second] = timeString.split(':').map(Number); // Split the time string and convert parts to numbers + return new Date(year, month - 1, day, hour, minute, second); // Return a Date object with year, month, day, hour, minute, second + } + return isNaN(row[key]) ? row[key] : parseFloat(row[key]); +} \ No newline at end of file diff --git a/docs/updatable.html b/docs/updatable.html new file mode 100644 index 0000000..f5d83a4 --- /dev/null +++ b/docs/updatable.html @@ -0,0 +1,47 @@ + + + + + + + + Requested Apps + + + + + + + +

Possible appfilter Updates

+ + +
+ +
+ + +
+ + + + + + + + + +
App + NameAppfilter TextAppfilter
+
+ + +
+ + +
+ + + + + \ No newline at end of file diff --git a/generated/updatable.txt b/generated/updatable.txt new file mode 100644 index 0000000..fdbea4f --- /dev/null +++ b/generated/updatable.txt @@ -0,0 +1,3 @@ + + + From 25084174dc71c30f0cbee567b4f192c6e7b2563d Mon Sep 17 00:00:00 2001 From: Bastian <8929967+Kaiserdragon2@users.noreply.github.com> Date: Fri, 15 Mar 2024 18:15:09 +0100 Subject: [PATCH 3/7] Updateable --- docs/css/updatable.css | 42 +++++++++++++++++++++++++++++++++++++++++- docs/updatable.html | 14 +++++++++----- 2 files changed, 50 insertions(+), 6 deletions(-) diff --git a/docs/css/updatable.css b/docs/css/updatable.css index 349e368..9ffb81b 100644 --- a/docs/css/updatable.css +++ b/docs/css/updatable.css @@ -7,6 +7,39 @@ src: url("../img/Inter.var.woff2") format("woff2"); } + +.header-container { + width: 100%; + display: flex; + align-items: center; + justify-content: center; + margin-bottom: 20px;; +} + +#updatable-container { + margin-right: 15px; + width: 150px; + align-items: center; + justify-content: center;; +} + +#updatable-button { + cursor: pointer; + background-color: #4CAF50; + color: white; + border: none; + padding: 5px 15px; + text-align: center; + text-decoration: none; + display: inline-block; + font-size: 16px; + margin-bottom: 10px; + border-radius: 100px; +} +#updatable-button:hover { + background-color: #409943; +} + body { font-family: 'Inter', Arial, Helvetica, sans-serif, sans-serif; margin-left: 4vw; @@ -66,6 +99,7 @@ body { margin: 0 auto; align-items: center; justify-content: center; + padding-left: 165px; } @@ -80,7 +114,7 @@ body { border: 1.5px solid #171717; box-shadow: none; outline: none; - padding: 0.8em 1.2em; + padding: 0.8em 1.2em; font-size: 16px; font-weight: bold; font-family: 'Inter', Arial, Helvetica, sans-serif, sans-serif; @@ -142,6 +176,7 @@ td { td:nth-child(1) { width: 20%; } + td:nth-child(2) { min-width: 100px; } @@ -174,18 +209,23 @@ img { background-color: #171717; color: white; } + tr:nth-child(even) { background-color: rgb(37, 37, 37); } + th { background-color: #0f0f0f; } + img { filter: none; } + .asc::after { border-bottom: 4px solid white; } + .desc::after { border-top: 4px solid white; } diff --git a/docs/updatable.html b/docs/updatable.html index f5d83a4..c2729d8 100644 --- a/docs/updatable.html +++ b/docs/updatable.html @@ -13,11 +13,15 @@ -

Possible appfilter Updates

- - -
- +

Possible Appfilter Updates

+ +
+
+ +
+
+ +
From 950772a611f39cc886581f82ff674812bd2fce6d Mon Sep 17 00:00:00 2001 From: Bastian <8929967+Kaiserdragon2@users.noreply.github.com> Date: Fri, 15 Mar 2024 18:22:30 +0100 Subject: [PATCH 4/7] add button to link to updateable site --- docs/css/requests.css | 51 +++++++++++++++++++++++++++++++++++++++---- docs/index.html | 10 ++++++--- 2 files changed, 54 insertions(+), 7 deletions(-) diff --git a/docs/css/requests.css b/docs/css/requests.css index 0497da9..be7c3a2 100644 --- a/docs/css/requests.css +++ b/docs/css/requests.css @@ -5,7 +5,42 @@ font-style: oblique 0deg 10deg; font-variation-settings: "slnt" 0deg; src: url("../img/Inter.var.woff2") format("woff2"); - } +} + +.header-container { + width: 100%; + display: flex; + align-items: center; + justify-content: center; + margin-bottom: 20px; + ; +} + +#updatable-container { + margin-right: 15px; + width: 150px; + align-items: center; + justify-content: center; + ; +} + +#updatable-button { + cursor: pointer; + background-color: #4CAF50; + color: white; + border: none; + padding: 5px 15px; + text-align: center; + text-decoration: none; + display: inline-block; + font-size: 16px; + margin-bottom: 10px; + border-radius: 100px; +} + +#updatable-button:hover { + background-color: #409943; +} body { font-family: 'Inter', Arial, Helvetica, sans-serif, sans-serif; @@ -66,6 +101,7 @@ body { margin: 0 auto; align-items: center; justify-content: center; + padding-left: 165px; } @@ -80,7 +116,7 @@ body { border: 1.5px solid #171717; box-shadow: none; outline: none; - padding: 0.8em 1.2em; + padding: 0.8em 1.2em; font-size: 16px; font-weight: bold; font-family: 'Inter', Arial, Helvetica, sans-serif, sans-serif; @@ -143,6 +179,7 @@ td { td:nth-child(1) { width: 20%; } + td:nth-child(2) { min-width: 55px; max-width: 60px; @@ -179,6 +216,7 @@ h1 { margin-top: 20px; margin-bottom: 20px; } + h2 { text-align: center; margin-top: 20px; @@ -187,8 +225,8 @@ h2 { .links img { filter: invert(); - width:50px; - height:50px; + width: 50px; + height: 50px; } @media (prefers-color-scheme: dark) { @@ -196,18 +234,23 @@ h2 { background-color: #171717; color: white; } + tr:nth-child(even) { background-color: rgb(37, 37, 37); } + th { background-color: #0f0f0f; } + .links img { filter: none; } + .asc::after { border-bottom: 4px solid white; } + .desc::after { border-top: 4px solid white; } diff --git a/docs/index.html b/docs/index.html index 1799e47..357e1bc 100644 --- a/docs/index.html +++ b/docs/index.html @@ -16,9 +16,13 @@

Requested Apps

Date

- -
- +
+
+ +
+
+ +
From f316cde8f69b51c9f894a24750fe1352f15cfc5f Mon Sep 17 00:00:00 2001 From: Bastian <8929967+Kaiserdragon2@users.noreply.github.com> Date: Fri, 15 Mar 2024 18:26:01 +0100 Subject: [PATCH 5/7] Update README.md --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e363c8f..3832919 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,10 @@ It also checks your pull requests and removes the entries from the requests list ## How to set it up 1. Clone this repo -2. Open `docs/js/requests.js` Change `Arcticons-Team` to your username and possibly `Icon-Request-Dashboard` to your project name too. : `https://raw.githubusercontent.com/Arcticons-Team/Icon-Request-Dashboard/main/generated/requests.txt` +2. Open `docs/js/requests.js` and `docs/js/updatable.js` Change `Arcticons-Team` to your username and possibly `Icon-Request-Dashboard` to your project name too. : `https://raw.githubusercontent.com/Arcticons-Team/Icon-Request-Dashboard/main/generated/requests.txt` 3. Repeat the previous step for the combined appfilter. `https://raw.githubusercontent.com/Arcticons-Team/Arcticons/Icon-Request-Dashboard/docs/assets/combined_appfilter.xml` -4. Setup GitHub Pages in your repo's Settings: **Pages > Deploy from branch > main /docs** +4. Do the same for the `docs/index.html` and `docs/updatable.html`file. +5. Setup GitHub Pages in your repo's Settings: **Pages > Deploy from branch > main /docs** (Using it with localhost is possible too, if you don't use the GitHub actions) ## Process requests @@ -22,4 +23,4 @@ This generates a `requests.txt` file and an `updatable.txt` if existing apps hav - **mail_folder_path** if you followed step 3 it should be `mail/` - **appfilter_path** the folder where you keep your appfilter. - **extracted_png_folder_path** the location to save all PNGs from icon requests `../docs/extracted_png` -- **requests_path** the path to your requests.txt file `../generated/requests.txt` +- **requests_path** the path to the folder containing your requests.txt file `../generated/` From 417fe25b1ed5eb43684ab8cb0cb4debbc4721117 Mon Sep 17 00:00:00 2001 From: Bastian <8929967+Kaiserdragon2@users.noreply.github.com> Date: Fri, 15 Mar 2024 18:48:58 +0100 Subject: [PATCH 6/7] At variables to make it easier to adapt --- README.md | 6 +-- docs/index.html | 100 +++++++++++++++++++++---------------------- docs/js/requests.js | 21 ++++++++- docs/js/updatable.js | 20 ++++++++- docs/updatable.html | 89 +++++++++++++++++++------------------- 5 files changed, 134 insertions(+), 102 deletions(-) diff --git a/README.md b/README.md index 3832919..bf9c5d6 100644 --- a/README.md +++ b/README.md @@ -5,10 +5,8 @@ It also checks your pull requests and removes the entries from the requests list ## How to set it up 1. Clone this repo -2. Open `docs/js/requests.js` and `docs/js/updatable.js` Change `Arcticons-Team` to your username and possibly `Icon-Request-Dashboard` to your project name too. : `https://raw.githubusercontent.com/Arcticons-Team/Icon-Request-Dashboard/main/generated/requests.txt` -3. Repeat the previous step for the combined appfilter. `https://raw.githubusercontent.com/Arcticons-Team/Arcticons/Icon-Request-Dashboard/docs/assets/combined_appfilter.xml` -4. Do the same for the `docs/index.html` and `docs/updatable.html`file. -5. Setup GitHub Pages in your repo's Settings: **Pages > Deploy from branch > main /docs** +2. Open `docs/js/requests.js` and `docs/js/updatable.js` Change the variables at the top of the file from `Arcticons-Team` to your username and possibly `Icon-Request-Dashboard` to your project name and the branch name too. +3. Setup GitHub Pages in your repo's Settings: **Pages > Deploy from branch > main /docs** (Using it with localhost is possible too, if you don't use the GitHub actions) ## Process requests diff --git a/docs/index.html b/docs/index.html index 357e1bc..afa889f 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1,57 +1,57 @@ - - - - - Requested Apps - - - - - - - -

Requested Apps

-

Date

- -
-
- -
-
- -
+ + + + + Requested Apps + + + + + + + +

Requested Apps

+

Date

+ +
+
+
- - -
- - - - - - - - - - - - -
App - NameIconLinksRequested timesLast - RequestedAppfilter
+
+ +
- - -
- - -
- - - +
+ + +
+ + + + + + + + + + + + +
App + NameIconLinksRequested timesLast + RequestedAppfilter
+
+ + +
+ + +
+ + + \ No newline at end of file diff --git a/docs/js/requests.js b/docs/js/requests.js index 131ce8c..5d41f6f 100644 --- a/docs/js/requests.js +++ b/docs/js/requests.js @@ -1,3 +1,9 @@ +//Edit the following variables +var RepoOwner = "Arcticons-Team"; +var RepoName = "Icon-Request-Dashboard"; +var RepoBranch = "main"; + + // Array of Link Images const imageNames = ['img/requests/google-play-store.svg', 'img/requests/f-droid.svg', 'img/requests/izzyondroid.svg', 'img/requests/galaxystore.svg', 'img/requests/search-globe.svg']; var appEntriesDataGlobal = []; // Store the original data for sorting @@ -23,7 +29,7 @@ const debounce = (func, delay) => { }; // CHANGE THIS LINE -> Fetch and process data -fetch('https://raw.githubusercontent.com/Arcticons-Team/Icon-Request-Dashboard/main/generated/requests.txt') +fetch(`https://raw.githubusercontent.com/${RepoOwner}/${RepoName}/${RepoBranch}/generated/requests.txt`) .then(response => { if (!response.ok) { throw new Error(`HTTP error! Status: ${response.status}`); @@ -67,7 +73,7 @@ fetch('https://raw.githubusercontent.com/Arcticons-Team/Icon-Request-Dashboard/m appEntriesDataGlobal = appEntriesData; // Example usage: - fetch('https://raw.githubusercontent.com/Arcticons-Team/Arcticons/Icon-Request-Dashboard/docs/assets/combined_appfilter.xml') + fetch(`https://raw.githubusercontent.com/${RepoOwner}/${RepoName}/${RepoBranch}/docs/assets/combined_appfilter.xml`) .then(response => { if (!response.ok) { // If appfilter.xml cannot be loaded, render appEntriesData as is @@ -239,6 +245,17 @@ const filterAppEntries = debounce(() => { } }, 500); +// Accessing the button element by its id +const updatableButton = document.getElementById("updatable-button"); + +// Add an event listener to the button +updatableButton.addEventListener("click", function() { + // Define the URL to redirect to + const updatableURL = `https://${RepoOwner}.github.io/${RepoName}/`; + // Redirect to the specified URL + window.location.href = updatableURL; +}); + // Sort table function function sortTable(columnIndex) { const table = document.querySelector('table'); diff --git a/docs/js/updatable.js b/docs/js/updatable.js index 8f25d6f..45d0a44 100644 --- a/docs/js/updatable.js +++ b/docs/js/updatable.js @@ -1,3 +1,8 @@ +//Edit the following variables +var RepoOwner = "Arcticons-Team"; +var RepoName = "Icon-Request-Dashboard"; +var RepoBranch = "main"; + var appEntriesDataGlobal = []; // Store the original data for sorting // Lazy loading and virtualization @@ -22,7 +27,7 @@ const debounce = (func, delay) => { }; // Fetch and process data -fetch('https://raw.githubusercontent.com/Arcticons-Team/Icon-Request-Dashboard/main/generated/updatable.txt') +fetch(`https://raw.githubusercontent.com/${RepoOwner}/${RepoName}/${RepoBranch}/generated/updatable.txt`) .then(response => { if (!response.ok) { throw new Error(`HTTP error! Status: ${response.status}`); @@ -47,7 +52,7 @@ fetch('https://raw.githubusercontent.com/Arcticons-Team/Icon-Request-Dashboard/m appEntriesDataGlobal = appEntriesData; // Example usage: - fetch('https://raw.githubusercontent.com/Arcticons-Team/Arcticons/Icon-Request-Dashboard/docs/assets/combined_appfilter.xml') + fetch(`https://raw.githubusercontent.com/${RepoOwner}/${RepoName}/${RepoBranch}/docs/assets/combined_appfilter.xml`) .then(response => { if (!response.ok) { // If appfilter.xml cannot be loaded, render appEntriesData as is @@ -182,6 +187,17 @@ function copyToClipboard(index) { }); } +// Accessing the button element by its id +const updatableButton = document.getElementById("updatable-button"); + +// Add an event listener to the button +updatableButton.addEventListener("click", function() { + // Define the URL to redirect to + const updatableURL = `https://${RepoOwner}.github.io/${RepoName}/`; + // Redirect to the specified URL + window.location.href = updatableURL; +}); + // Search function const filterAppEntries = debounce(() => { const searchInput = document.getElementById('search-input').value.toLowerCase(); diff --git a/docs/updatable.html b/docs/updatable.html index c2729d8..43027ea 100644 --- a/docs/updatable.html +++ b/docs/updatable.html @@ -1,51 +1,52 @@ - - - - - Requested Apps - - - - - - - -

Possible Appfilter Updates

- -
-
- -
-
- -
+ + + + + Requested Apps + + + + + + + +

Possible Appfilter Updates

+ +
+
+
- - -
- - - - - - - - - -
App - NameAppfilter TextAppfilter
+
+ +
- - -
- - -
- - - +
+ + +
+ + + + + + + + + +
App + NameAppfilter TextAppfilter
+
+ + +
+ + +
+ + + \ No newline at end of file From 0b211df935691fba761bfb0baf2a08258c3a3e29 Mon Sep 17 00:00:00 2001 From: Bastian <8929967+Kaiserdragon2@users.noreply.github.com> Date: Fri, 15 Mar 2024 18:58:21 +0100 Subject: [PATCH 7/7] add variables to make it easier to adapt --- .github/workflows/combine_appfilter.py | 19 +++++++++++++------ README.md | 3 ++- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/.github/workflows/combine_appfilter.py b/.github/workflows/combine_appfilter.py index 7b34c45..4a100fe 100644 --- a/.github/workflows/combine_appfilter.py +++ b/.github/workflows/combine_appfilter.py @@ -5,15 +5,22 @@ import hashlib import requests + +# Get the repository +# Change this to your Repo +repo = g.get_repo("Arcticons-Team/Arcticons") + +# Get the branch name +# Change this to your branch name +branchName = "main" + + # Your GitHub token github_token = os.getenv('GITHUB_TOKEN') # Initialize the GitHub instance g = Github(github_token) -# Get the repository -repo = g.get_repo("Arcticons-Team/Arcticons") - def combine_xml_files(input_files, output_file): unique_components = set() output_root = ET.Element('resources') # Root element for the output XML tree @@ -112,7 +119,7 @@ def combine_all_appfilters(): # Try to get the content of the existing combined_appfilter.xml file try: - existing_file = repo.get_contents('docs/assets/combined_appfilter.xml', ref='icon-requests') + existing_file = repo.get_contents('docs/assets/combined_appfilter.xml', ref=branchName) print(existing_file) # Debugging statement if existing_file: try: @@ -149,11 +156,11 @@ def combine_all_appfilters(): try: if existing_content is None: # Create the combined_appfilter.xml file in the repository - repo.create_file('docs/assets/combined_appfilter.xml', 'Created combined appfilter.xml from pull requests', new_content, branch='icon-requests') + repo.create_file('docs/assets/combined_appfilter.xml', 'Created combined appfilter.xml from pull requests', new_content, branch=branchName) print("Created combined_appfilter.xml in the repository.") else: # Update the combined_appfilter.xml file in the repository - repo.update_file('docs/assets/combined_appfilter.xml', 'Updated combined appfilter.xml from pull requests', new_content, existing_sha, branch='icon-requests') + repo.update_file('docs/assets/combined_appfilter.xml', 'Updated combined appfilter.xml from pull requests', new_content, existing_sha, branch=branchName) print("Updated combined_appfilter.xml in the repository.") except Exception as e: print(f"Error updating/creating combined_appfilter.xml in the repository: {e}") diff --git a/README.md b/README.md index bf9c5d6..ad784e6 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,8 @@ It also checks your pull requests and removes the entries from the requests list 1. Clone this repo 2. Open `docs/js/requests.js` and `docs/js/updatable.js` Change the variables at the top of the file from `Arcticons-Team` to your username and possibly `Icon-Request-Dashboard` to your project name and the branch name too. -3. Setup GitHub Pages in your repo's Settings: **Pages > Deploy from branch > main /docs** +3. Open `.github/workflows/combine_appfilter.py` Change the Repository an the Branch to yours. +4. Setup GitHub Pages in your repo's Settings: **Pages > Deploy from branch > main /docs** (Using it with localhost is possible too, if you don't use the GitHub actions) ## Process requests