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

Autogenerate keywords base on files #313

Merged
merged 13 commits into from
Oct 23, 2024
112 changes: 112 additions & 0 deletions .github/keywords/keywords-generator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import os
import json
import openai
import subprocess
from dotenv import load_dotenv

# Load environment variables from the .env file
load_dotenv()

# Set up the OpenAI API key
openai.api_key = os.getenv("OPENAI_API_KEY")

# Path to the main folder (the "icons" folder)
main_folder = "./icons"

# JSON file where synonyms will be stored
synonyms_json_file = "icons/icons-keywords.json"

# Load the JSON file if it already exists
if os.path.exists(synonyms_json_file):
with open(synonyms_json_file, "r", encoding="utf-8") as f:
synonyms_dictionary = json.load(f)
else:
synonyms_dictionary = {}

# Remove common style indicators from the filename and return
def preprocess_filename(filename):
return filename.replace("-filled.svg", "").replace("-light.svg", "").replace("-regular.svg", "")

# Function to recursively list all unique SVG filenames without their paths
def list_concepts(folder):
concepts = set() # Use a set to avoid duplicates
for root, dirs, files in os.walk(folder):
# Filter and preprocess SVG filenames before adding to the set
for file in files:
if file.endswith('.svg') and not file.startswith('.'):
processed_file = preprocess_filename(file)
concepts.add(processed_file)
return list(concepts) # Convert set to list before returning

# Function to generate synonyms using GPT
def generate_synonyms(concept):
prompt = f"Generate 12 synonyms for the concept '{concept}' mixing English, Spanish, Portuguese, and German (in this order). Return them as a plain list of words, without quotes, numbering, or separation by language. the order of the synonyms should be English, Spanish, Portuguese, and German. For example: alert lamp cross, warning light plus, signal illumination cross, luz de alarma cruz, luz de advertencia plus, iluminación de señal cruz, Alarmleuchte Kreuz, Warnlicht plus, Signalbeleuchtung Kreuz"

response = openai.ChatCompletion.create(
model="gpt-4",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": prompt}
],
max_tokens=100,
temperature=0.7,
)

# Get the generated response
raw_synonyms = response['choices'][0]['message']['content'].strip()

# Clean the output, removing unnecessary characters and convert it to a list
synonyms = [synonym.strip(' "[]') for synonym in raw_synonyms.split(',')]

return synonyms

# Get concepts from the icons folder
concepts = set(list_concepts(main_folder)) # Convert to set for efficiency

# Counter to know how many new concepts have been processed
new_concepts = 0

# Remove entries in synonyms_dictionary that no longer have corresponding icons
keys_to_remove = [key for key in synonyms_dictionary if key not in concepts]
for key in keys_to_remove:
del synonyms_dictionary[key]
print(f"Concept removed: {key}")

# Update the JSON file only with new concepts
for concept in concepts:
if concept not in synonyms_dictionary:
print(f"Generating synonyms for: {concept}")
try:
# Generate synonyms using GPT
generated_synonyms = generate_synonyms(concept)
# Save the synonyms in the dictionary
synonyms_dictionary[concept] = generated_synonyms
new_concepts += 1
print(f"Concept generated: {concept} - Synonyms: {generated_synonyms}")
except Exception as e:
print(f"Error generating synonyms for {concept}: {e}")
# In case of error, save generic synonyms to avoid leaving it empty
synonyms_dictionary[concept] = ["synonym1", "synonym2", "synonym3"]
print(f"Concept generated with generic synonyms: {concept}")

# Only save if there are new concepts or if concepts have been removed
if new_concepts > 0 or keys_to_remove:
# Save the updated and alphabetically sorted dictionary in the JSON file
with open(synonyms_json_file, "w", encoding="utf-8") as f:
json.dump(synonyms_dictionary, f, ensure_ascii=False, indent=4, sort_keys=True)
print(f"{new_concepts} new concepts have been generated.")
print(f"{len(keys_to_remove)} obsolete concepts have been removed.")
else:
print("No new concepts or obsolete concepts found.")

# Run Prettier to format the JSON file
try:
subprocess.run(["npx", "prettier", "--write", synonyms_json_file], check=True)
print(f"The file {synonyms_json_file} has been formatted with Prettier.")
except subprocess.CalledProcessError as e:
print(f"Error formatting the file with Prettier: {e}")

# Count the total number of concepts
total_concepts = len(concepts)
print(f"Total concepts processed: {total_concepts}")
print("Process completed. The icons-keywords.json file has been updated and sorted alphabetically.")
6 changes: 6 additions & 0 deletions .github/workflows/auto-generator.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,13 @@ jobs:

- run: sudo python3 .github/md-generator/generate_markdown.py icons

- name: Check for changes
id: git_status
run: |
git diff --exit-code || echo "changes"

- name: Commit & Push in ${{ env.GITHUB_REF_SLUG_URL }}
if: steps.git_status.outputs.result == 'changes'
run: |
git add .
git config user.name "github-actions"
Expand Down
57 changes: 57 additions & 0 deletions .github/workflows/keywords-generator.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
name: Keywords autogenerated

on:
workflow_dispatch:
pull_request:
branches:
- production
paths:
- "icons/**"

jobs:
generate-keywords:
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Get branch name
uses: rlespinasse/github-slug-action@v3.x

- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: "3.x"

- name: Upgrade pip, setuptools, and wheel
run: |
pip install --upgrade pip setuptools wheel

# Paso 3: Instalar dependencias de Python
- name: Install dependencies
run: |
pip install openai python-dotenv --use-pep517

- name: Install prettier
run: npm install -g prettier

- name: Run keywords generator
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
working-directory: .github/keywords
run: python3 keywords-generator.py

- name: Check for changes
id: git_status
run: |
git diff --exit-code || echo "changes"

- name: Commit & Push in ${{ env.GITHUB_REF_SLUG_URL }}
if: steps.git_status.outputs.result == 'changes'
run: |
git add .
git config user.name "github-actions"
git config user.email "github-actions[bot]@users.noreply.github.com"
git commit -am "update changelog"
git push origin ${{ env.GITHUB_REF_SLUG_URL }}
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
.AppleDouble
.LSOverride
*.idea
*.env

# Icon must end with two
Icon
Expand Down Expand Up @@ -60,4 +61,5 @@ o2-new-filled.json
#figma-export-icons
o2-new-regular.json
#figma-export-icons
o2-new-light.json
o2-new-light.json

5 changes: 2 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@ Mística-icons is built to grow, that means that If you need a new icon, you hav
1. Check If mistica-icons doesn't cover your need in [this list](https://github.com/Telefonica/mistica-icons/blob/production/README.md)
2. Read [Brand Factory](https://brandfactory.telefonica.com/hub/134) icons guidelines by brand
3. Create a new icon following the guidelines and **with 3 weights!** _(light / regular / filled)_
4. Provide 3 synonyms for this icon. [Keywords file](icons/icons-keywords.json)
5. Create an issue [here](https://github.com/Telefonica/mistica-design/issues/new?assignees=&labels=fundamentals%3A+icons%2Crequest+%E2%9C%A8&template=icon_request.yml&title=Title)
6. That's all! We will review If your icon have all the needs to add it to mistica-icons
4. Create an issue [here](https://github.com/Telefonica/mistica-design/issues/new?assignees=&labels=fundamentals%3A+icons%2Crequest+%E2%9C%A8&template=icon_request.yml&title=Title)
5. That's all! We will review If your icon have all the needs to add it to mistica-icons

# Report an icon bug

Expand Down
2 changes: 1 addition & 1 deletion icons/icons-keywords.json
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

automatic sort

Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,8 @@
"dartboard": ["darts target", "bullseye board", "throwing game", "tablero de dardos", "alvo de dardos", "Dartbrett"],
"data": ["information", "facts", "data points", "datos", "informações", "Daten"],
"data-10-gb": ["10 gigabytes of data", "data plan", "data allocation", "10 gigabytes de datos", "plano de dados", "10 Gigabyte Daten"],
"data-30-gb": ["30 gigabytes of data", "data plan", "data allocation", "30 gigabytes de datos", "plano de dados", "30 Gigabyte Daten"],
"data-100-gb": ["100 gigabytes of data", "large data plan", "huge data allocation", "100 gigabytes de datos", "plano de datos grande", "100 Gigabyte Daten"],
"data-30-gb": ["30 gigabytes of data", "data plan", "data allocation", "30 gigabytes de datos", "plano de dados", "30 Gigabyte Daten"],
"data-alert": ["data warning", "usage alert", "data notification", "advertencia de datos", "alerta de uso", "Datenbenachrichtigung"],
"data-bonus": ["extra data", "bonus allocation", "additional data", "datos adicionales", "alocação de bônus", "zusätzliche Daten"],
"data-centre": ["data center", "server farm", "information hub", "centro de datos", "centro de servidores", "Datenzentrum"],
Expand Down
Loading