mirror of
https://github.com/mustbeperfect/definitive-opensource.git
synced 2026-04-17 15:43:26 +02:00
Refactoring and experimental generation code
This commit is contained in:
0
readmes/linux.md
Normal file
0
readmes/linux.md
Normal file
0
readmes/selfhosted.md
Normal file
0
readmes/selfhosted.md
Normal file
0
readmes/windows.md
Normal file
0
readmes/windows.md
Normal file
1349
resources/backup/lastmanualreadme.md
Normal file
1349
resources/backup/lastmanualreadme.md
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1 +1,62 @@
|
||||
|
||||
<table align="center">
|
||||
<tr>
|
||||
<td>🇺🇦 v0.5.2-beta</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h1 align="center">[ definitive-opensource ] </h1>
|
||||
<p align="center"> A definitive list of the best of everything open source</p>
|
||||
|
||||
<p align="center"><code>Status: Active</code> - <code>Projects: 422</code></p>
|
||||
|
||||
> [!TIP]
|
||||
> Discussions and contributions are welcome! This project is in it's early stages and a lot hasn't been ironed out yet. For more information on [contributing](.github/CONTRIBUTING.md) and [guidelines](resources/dev/GUIDELINES.md) for open-source software submissions, consult their respective pages.
|
||||
|
||||
> [!CAUTION]
|
||||
> We are currently undergoing major changes and refactoring as we migrate to a JSON file with Python scripts that generate the READMEs.
|
||||
|
||||
> [!NOTE]
|
||||
> My MacOS [configuration](https://docs.google.com/document/d/1QF7wpvlFG7mfWtCGrFfyIUwgYzOYeSBDAIDvgiIJk44/edit?usp=sharing).
|
||||
|
||||
##
|
||||
|
||||
<h4 align="center">
|
||||
<a href="https://github.com/mustbeperfect/definitive-opensource/blob/main/resources/dev/GUIDELINES.md">Guidelines</a>
|
||||
<span> · </span>
|
||||
<a href="https://github.com/mustbeperfect/definitive-opensource/issues">Issues</a>
|
||||
<span> · </span>
|
||||
<a href="https://github.com/mustbeperfect/definitive-opensource/blob/main/.github/CONTRIBUTING.md">Contributing</a>
|
||||
</h4>
|
||||
|
||||
##
|
||||
|
||||
**Our Goal -** There's plenty of awesome lists on GitHub, many focusing on open source specifically. However I've found them including many long-deprecated apps, cluttered with smaller projects on the verge of extinction, or missing a lot of modern open source projects.
|
||||
|
||||
This list aims to serve as a single centralized location for the best of open source, characterized by a solid user base, solid set of contributors, visible long term growth, and overall product quality.
|
||||
|
||||
<details>
|
||||
<summary><b>More Information</b></summary><br />
|
||||
Definitive-opensource aims to consolidate only the best open source projects. Our guidelines include strict minimum requirements and additional research for vetting. For a project to pass it's likely popular enough to survive far into the future, however we continously monitor projects on the list and remove anything that no longer fits the criteria.
|
||||
<p> </p>
|
||||
It is a fundamental goal for this list to be as neutral as possible and simply present options, not persuade or redact, regardless of the maintainer's opinion. Projects that fit the criteria, which by passing will inherently be used by thousands to millions, are put on the list. This list is "curated" - not relative to opinion but statistics and facts.
|
||||
<p> </p>
|
||||
Although the list is called definitive, in this context it doesn't quite mean the implied dictionary definition of finality. This project can only survive and thrive through continuous contributions by the community, as this list is, in itself, open source.
|
||||
</details>
|
||||
|
||||
## Project Status
|
||||
```css
|
||||
Active - Active Development
|
||||
```
|
||||
```
|
||||
Incremental - Minor Updates
|
||||
```
|
||||
```
|
||||
Maintenence - Critical Fixes
|
||||
```
|
||||
```
|
||||
Idle - Temporarily Paused
|
||||
```
|
||||
```
|
||||
Abandoned - Development Halted
|
||||
```
|
||||
|
||||
43
source/lib/tags.md
Normal file
43
source/lib/tags.md
Normal file
@@ -0,0 +1,43 @@
|
||||
## Tags
|
||||
|
||||
### Alerts
|
||||
`🟡` `🟠` `🔴` `⭕` - Security incident **(Minor, Moderate, Major, Critical)**
|
||||
|
||||
`🚫` - Potentially abandoned
|
||||
|
||||
`🛑` - Potentially closed source
|
||||
|
||||
`⁉️` - Suspicious license
|
||||
|
||||
`🟥` - Corporate influence
|
||||
|
||||
`🧪` - Experimental (Pre-Alpha)
|
||||
|
||||
`🚧` - Critically unstable/buggy
|
||||
|
||||
`❌` - On watch for removal
|
||||
|
||||
### Highlights
|
||||
`💥` - Disruptive
|
||||
|
||||
`🌍` - Influential
|
||||
|
||||
`🌟` - Pioneering
|
||||
|
||||
`💡` - Innovative
|
||||
|
||||
### Awards (At 10k Stars)
|
||||
`🏆` - Crown of open source
|
||||
|
||||
`🥈` - Second
|
||||
|
||||
`🥉` - Third
|
||||
|
||||
### Platforms
|
||||
`Cross` - Cross-platform (MacOS, Windows, Linux)
|
||||
|
||||
`Mobile` - Android and IOS
|
||||
|
||||
`CLI+` - CLI in addition to GUI
|
||||
|
||||
`Windows`, `MacOS`, `Linux`, `Android`, `IOS`, `CLI`, `SelfHost`, `Web`, `VSCode`, `JetBrains`, `Chromium`, `Firefox`, `Plugin`, `Extension`, `N/A`
|
||||
51
source/scripts/contents_generator.py
Normal file
51
source/scripts/contents_generator.py
Normal file
@@ -0,0 +1,51 @@
|
||||
import json
|
||||
|
||||
def load_data():
|
||||
with open("categories.json", "r", encoding="utf-8") as f:
|
||||
categories_data = json.load(f)
|
||||
with open("applications.json", "r", encoding="utf-8") as f:
|
||||
applications_data = json.load(f)
|
||||
return categories_data, applications_data
|
||||
|
||||
def generate_markdown(platform_filter=None):
|
||||
categories_data, applications_data = load_data()
|
||||
categories = sorted(categories_data["categories"], key=lambda x: x["Name"].lower())
|
||||
subcategories = sorted(categories_data["subcategories"], key=lambda x: x["Name"].lower())
|
||||
applications = sorted(applications_data["applications"], key=lambda x: x["name"].lower())
|
||||
|
||||
markdown_content = []
|
||||
markdown_content.append("## Contents\n")
|
||||
|
||||
category_map = {cat["id"]: cat["Name"] for cat in categories}
|
||||
subcategory_map = {sub["id"]: sub for sub in subcategories}
|
||||
|
||||
categorized_apps = {sub["id"]: [] for sub in subcategories}
|
||||
for app in applications:
|
||||
if app["category"] in categorized_apps:
|
||||
if platform_filter:
|
||||
if platform_filter in [p.strip('`').lower() for p in app["platforms"]]:
|
||||
categorized_apps[app["category"]].append(app)
|
||||
else:
|
||||
categorized_apps[app["category"]].append(app)
|
||||
|
||||
for cat in categories:
|
||||
cat_id = cat["id"]
|
||||
markdown_content.append(f"# {cat['Name']} - [Go to top](#contents)\n")
|
||||
for sub in subcategories:
|
||||
if sub["parent"] == cat_id and categorized_apps[sub["id"]]:
|
||||
markdown_content.append(f"### {sub['Name']}\n")
|
||||
markdown_content.append("| Name | Description | Platform | Stars |\n| --- | --- | --- | --- |")
|
||||
for app in categorized_apps[sub["id"]]:
|
||||
platforms = " ".join(app["platforms"])
|
||||
stars_badge = f"[-2]}/{app['link'].split('/')[-1]}?style=for-the-badge&label=%20&color=white)"
|
||||
tags = " ".join(app["tags"])
|
||||
markdown_content.append(f"| [{app['name']}]({app['link']}) {tags} | {app['description']} | {platforms} | {stars_badge} |")
|
||||
markdown_content.append("")
|
||||
|
||||
return "\n".join(markdown_content)
|
||||
|
||||
if __name__ == "__main__":
|
||||
markdown_output = generate_markdown()
|
||||
with open("contents.md", "w", encoding="utf-8") as f:
|
||||
f.write(markdown_output)
|
||||
print("Generated contents.md")
|
||||
@@ -1,83 +1,36 @@
|
||||
import json
|
||||
import re
|
||||
import os
|
||||
|
||||
from tableofcontents_generator import generate_table_of_contents
|
||||
from contents_generator import generate_markdown
|
||||
|
||||
def generate_markdown(applications, categories, subcategories):
|
||||
# Organize categories and subcategories
|
||||
category_map = {cat["id"]: cat["Name"] for cat in categories}
|
||||
subcategory_map = {sub["id"]: (sub["Name"], sub["parent"]) for sub in subcategories}
|
||||
|
||||
# Organize applications into subcategories
|
||||
subcategory_apps = {}
|
||||
for app in applications:
|
||||
subcategory = app.get("category", "")
|
||||
if subcategory not in subcategory_apps:
|
||||
subcategory_apps[subcategory] = []
|
||||
subcategory_apps[subcategory].append(app)
|
||||
|
||||
# Sort subcategories alphabetically
|
||||
sorted_subcategories = sorted(subcategory_map.items(), key=lambda x: x[1][0].lower())
|
||||
|
||||
# Sort applications within subcategories
|
||||
for subcategory in subcategory_apps:
|
||||
subcategory_apps[subcategory] = sorted(subcategory_apps[subcategory], key=lambda x: x["name"].lower())
|
||||
|
||||
# Build markdown
|
||||
markdown = "# Contents\n\n"
|
||||
|
||||
# Sort categories alphabetically
|
||||
sorted_categories = sorted(category_map.items(), key=lambda x: x[1].lower())
|
||||
|
||||
for cat_id, cat_name in sorted_categories:
|
||||
markdown += f"# {cat_name} - [Go to top](#contents)\n\n"
|
||||
|
||||
for sub_id, (sub_name, parent_id) in sorted_subcategories:
|
||||
if parent_id == cat_id:
|
||||
markdown += f"### {sub_name}\n\n"
|
||||
markdown += "| Name | Description | Platform | Stars |\n"
|
||||
markdown += "| --- | --- | --- | --- |\n"
|
||||
|
||||
if sub_id in subcategory_apps:
|
||||
for app in subcategory_apps[sub_id]:
|
||||
tags = " ".join([f"`{tag}`" for tag in app.get("tags", [])]) if app.get("tags") else ""
|
||||
platforms = " ".join(app.get("platforms", []))
|
||||
repo_owner, repo_name = app["link"].split("/")[-2:]
|
||||
stars = f""
|
||||
markdown += f"| [{app['name']}]({app['link']}) {tags} | {app['description']} | {platforms} | {stars} |\n"
|
||||
|
||||
markdown += "\n"
|
||||
|
||||
return markdown
|
||||
|
||||
|
||||
def save_markdown(content, output_path):
|
||||
with open(output_path, 'w', encoding='utf-8') as file:
|
||||
file.write(content)
|
||||
def load_file(filename):
|
||||
with open(filename, "r", encoding="utf-8") as f:
|
||||
return f.read()
|
||||
|
||||
def generate_readme(platform="all"):
|
||||
header_map = {
|
||||
"cross": "crossheader.md",
|
||||
"macos": "macosheader.md",
|
||||
"windows": "windowsheader.md",
|
||||
"selfhost": "selfhostheader.md",
|
||||
}
|
||||
|
||||
header_file = header_map.get(platform, "header.md")
|
||||
header = load_file(header_file)
|
||||
tags = load_file("tags.md")
|
||||
footer = load_file("footer.md")
|
||||
|
||||
toc = generate_table_of_contents()
|
||||
content = generate_markdown(platform)
|
||||
|
||||
readme_content = "\n".join([header, tags, toc, content, footer])
|
||||
|
||||
output_file = f"readmes/{platform}.md" if platform != "all" else "source/testing/test.md"
|
||||
with open(output_file, "w", encoding="utf-8") as f:
|
||||
f.write(readme_content)
|
||||
print(f"Generated {output_file}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
applications_path = "source/data/applications.json" # Update with actual path
|
||||
categories_path = "source/data/categories.json" # Update with actual path
|
||||
output_path = "source/testing/test.md"
|
||||
|
||||
try:
|
||||
with open(applications_path, 'r', encoding='utf-8') as file:
|
||||
applications_data = json.load(file)
|
||||
if isinstance(applications_data, list):
|
||||
applications_data = {"applications": applications_data}
|
||||
except json.JSONDecodeError as e:
|
||||
print(f"Error reading {applications_path}: {e}")
|
||||
applications_data = {"applications": []}
|
||||
|
||||
try:
|
||||
with open(categories_path, 'r', encoding='utf-8') as file:
|
||||
categories_data = json.load(file)
|
||||
except json.JSONDecodeError as e:
|
||||
print(f"Error reading {categories_path}: {e}")
|
||||
categories_data = {"categories": [], "subcategories": []}
|
||||
|
||||
markdown_content = generate_markdown(applications_data.get("applications", []),
|
||||
categories_data.get("categories", []),
|
||||
categories_data.get("subcategories", []))
|
||||
save_markdown(markdown_content, output_path)
|
||||
print(f"Generated {output_path}")
|
||||
for platform in ["all", "cross", "macos", "windows", "selfhost"]:
|
||||
generate_readme(platform)
|
||||
|
||||
50
source/scripts/tableofcontents_generator.py
Normal file
50
source/scripts/tableofcontents_generator.py
Normal file
@@ -0,0 +1,50 @@
|
||||
import json
|
||||
|
||||
def load_categories():
|
||||
with open("categories.json", "r", encoding="utf-8") as f:
|
||||
return json.load(f)
|
||||
|
||||
def generate_table_of_contents():
|
||||
data = load_categories()
|
||||
categories = sorted(data["categories"], key=lambda x: x["Name"].lower())
|
||||
subcategories = sorted(data["subcategories"], key=lambda x: x["Name"].lower())
|
||||
|
||||
toc = ["## Contents\n"]
|
||||
|
||||
# Alphabetical section
|
||||
toc.append("<details>\n <summary><b>Alphabetical</b></summary> <br />\n")
|
||||
for sub in subcategories:
|
||||
toc.append(f" - [{sub['Name']}](#{sub['id']})")
|
||||
toc.append("</details>\n")
|
||||
|
||||
# Categorized section
|
||||
toc.append("<details open>\n <summary><b>Categorized</b></summary> <br />\n")
|
||||
|
||||
category_map = {cat["id"]: cat["Name"] for cat in categories}
|
||||
organized_subcategories = {}
|
||||
|
||||
for sub in subcategories:
|
||||
parent = sub["parent"]
|
||||
if parent not in organized_subcategories:
|
||||
organized_subcategories[parent] = []
|
||||
organized_subcategories[parent].append(sub)
|
||||
|
||||
for cat in categories:
|
||||
cat_id = cat["id"]
|
||||
toc.append(f" - {cat['Name']}")
|
||||
if cat_id in organized_subcategories:
|
||||
for sub in organized_subcategories[cat_id]:
|
||||
toc.append(f" - [{sub['Name']}](#{sub['id']})")
|
||||
|
||||
# Other category at the end
|
||||
if "other" in organized_subcategories:
|
||||
toc.append(" - [Other](#other)")
|
||||
|
||||
toc.append("</details>\n")
|
||||
return "\n".join(toc)
|
||||
|
||||
if __name__ == "__main__":
|
||||
toc_content = generate_table_of_contents()
|
||||
with open("tableofcontents.md", "w", encoding="utf-8") as f:
|
||||
f.write(toc_content)
|
||||
print("Generated tableofcontents.md")
|
||||
@@ -1,4 +1,4 @@
|
||||
# Contents
|
||||
# Contents (All Platforms)
|
||||
|
||||
# Artificial Intelligence (AI) - [Go to top](#contents)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user