character_forge / apply_agpl_license.py
ghmk's picture
Initial deployment of Character Forge
5b6e956
#!/usr/bin/env python3
"""
Script to apply GNU AGPL v3 license to Character Forge project.
This script downloads the official AGPL v3 license text and updates project files.
"""
import urllib.request
import os
from datetime import datetime
# Official GNU AGPL v3 license URL
AGPL_V3_URL = "https://www.gnu.org/licenses/agpl-3.0.txt"
# Copyright holders
COPYRIGHT_HOLDERS = "Gregor Hubert, Max Koch \"cronos3k\" (GK -/a/- ghmk.de)"
CURRENT_YEAR = datetime.now().year
def download_license():
"""Download the official GNU AGPL v3 license text."""
print("Downloading GNU AGPL v3 license from gnu.org...")
try:
with urllib.request.urlopen(AGPL_V3_URL) as response:
license_text = response.read().decode('utf-8')
print("[OK] License downloaded successfully")
return license_text
except Exception as e:
print(f"[ERROR] Error downloading license: {e}")
return None
def create_license_file(license_text):
"""Create the LICENSE file with copyright notice."""
print("\nCreating LICENSE file...")
# Add copyright notice at the top
full_license = f"""Character Forge
Copyright (C) {CURRENT_YEAR} {COPYRIGHT_HOLDERS}
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
================================================================================
{license_text}
"""
try:
with open("LICENSE", "w", encoding="utf-8") as f:
f.write(full_license)
print("[OK] LICENSE file created")
return True
except Exception as e:
print(f"[ERROR] Error creating LICENSE file: {e}")
return False
def create_notice_file():
"""Create updated NOTICE file for AGPL."""
print("\nCreating NOTICE file...")
notice_text = f"""Character Forge - AI Image Generation Platform
Copyright (C) {CURRENT_YEAR} {COPYRIGHT_HOLDERS}
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
================================================================================
IMPORTANT: License for Generated Content
While this SOFTWARE is licensed under GNU AGPL v3, the OUTPUTS you create
with this software (images, character sheets, compositions) belong to YOU
and are NOT covered by the AGPL license.
You are free to:
- Use generated images for any purpose (personal or commercial)
- Sell your generated artwork
- Use characters in games, animations, or other projects
- Keep your generated content private or share it
The AGPL only applies to the software code itself, not your creative outputs.
================================================================================
COMMERCIAL USE RESTRICTIONS
The GNU AGPL v3 license means:
βœ“ FREE to use personally or for education
βœ“ FREE to modify and improve
βœ“ Your generated images/characters are YOURS to use commercially
βœ— If you integrate this software into a commercial product or service,
you MUST release your entire codebase under AGPL v3
βœ— You cannot create a proprietary/closed-source product using this code
βœ— If you run this as a network service, you must provide source code
This prevents companies from taking this free software and building
commercial platforms without contributing back to the community.
================================================================================
THIRD-PARTY DEPENDENCIES
This project uses the following third-party software:
- Streamlit (Apache License 2.0)
Copyright (c) Streamlit Inc.
https://github.com/streamlit/streamlit
- google-generativeai (Apache License 2.0)
Copyright (c) Google LLC
https://github.com/google/generative-ai-python
- Pillow (PIL License)
Copyright (c) 1997-2011 by Secret Labs AB
Copyright (c) 1995-2011 by Fredrik Lundh
https://github.com/python-pillow/Pillow
- Gradio (Apache License 2.0)
Copyright (c) Gradio
https://github.com/gradio-app/gradio
Each dependency retains its original license. See individual packages
for their specific terms.
================================================================================
CONTACT
For questions about licensing or commercial use:
- Authors: {COPYRIGHT_HOLDERS}
- Project: https://github.com/yourusername/character-forge
For commercial licensing inquiries or exceptions to AGPL terms,
please contact the authors.
================================================================================
"""
try:
with open("NOTICE", "w", encoding="utf-8") as f:
f.write(notice_text)
print("[OK] NOTICE file created")
return True
except Exception as e:
print(f"[ERROR] Error creating NOTICE file: {e}")
return False
def update_readme():
"""Update README.md with new license information."""
print("\nUpdating README.md...")
try:
with open("README.md", "r", encoding="utf-8") as f:
readme = f.read()
# Replace Apache license badge with AGPL badge
readme = readme.replace(
"[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)",
"[![License: AGPL v3](https://img.shields.io/badge/License-AGPL%20v3-blue.svg)](https://www.gnu.org/licenses/agpl-3.0)"
)
# Update license section
license_section = """## πŸ“ License
GNU Affero General Public License v3.0 (AGPL-3.0)
**What this means:**
βœ“ **Free to use**: Personal, educational, and research use is completely free
βœ“ **Your content is yours**: Images and characters you generate belong to you
βœ“ **Modify freely**: You can modify and improve the software
βœ“ **Share improvements**: Modified versions must also be open source
βœ— **No proprietary integration**: Cannot be integrated into closed-source commercial products
βœ— **Network use = source sharing**: If you run this as a service, you must share your source code
**For commercial services or products**, any modifications or integrations must be released
under AGPL-3.0. This ensures the software remains free and open for everyone.
**For generated content**: Your images, characters, and creative outputs are yours to use
however you want - commercially or otherwise. The AGPL only applies to the software itself.
See [LICENSE](LICENSE) for full details and [NOTICE](NOTICE) for important information.
For commercial licensing inquiries or questions, please contact the authors."""
# Replace the license section
if "## πŸ“ License" in readme:
start = readme.find("## πŸ“ License")
end = readme.find("\n## ", start + 1)
if end == -1:
end = readme.find("\n---", start + 1)
readme = readme[:start] + license_section + readme[end:]
with open("README.md", "w", encoding="utf-8") as f:
f.write(readme)
print("[OK] README.md updated")
return True
except Exception as e:
print(f"[ERROR] Error updating README: {e}")
return False
def main():
"""Main function to apply AGPL license."""
print("=" * 70)
print("Character Forge - Applying GNU AGPL v3 License")
print("=" * 70)
# Download license
license_text = download_license()
if not license_text:
print("\n[ERROR] Failed to download license. Please check your internet connection.")
return False
# Create files
success = True
success &= create_license_file(license_text)
success &= create_notice_file()
success &= update_readme()
if success:
print("\n" + "=" * 70)
print("[SUCCESS] LICENSE SUCCESSFULLY APPLIED!")
print("=" * 70)
print("\nFiles updated:")
print(" - LICENSE (GNU AGPL v3)")
print(" - NOTICE (usage terms and clarifications)")
print(" - README.md (license badge and section)")
print("\nYour project is now licensed under GNU AGPL v3.")
print("Generated content (images/characters) belongs to users.")
print("Software code must remain open source if redistributed.")
return True
else:
print("\n[ERROR] Some files failed to update. Please check errors above.")
return False
if __name__ == "__main__":
main()