Compare commits

..

4 Commits

Author SHA1 Message Date
f4f109f75d tweaks 2026-03-06 18:45:01 +01:00
7f402cd69b description for new pages 2026-03-06 18:27:01 +01:00
ed880bdd57 INSTRUCTIONS.md update 2026-03-06 17:28:47 +01:00
08463e18d0 make clean 2026-03-04 22:28:37 +01:00
4 changed files with 79 additions and 41 deletions

3
.gitignore vendored
View File

@@ -1,2 +1,3 @@
.env
output/*.md
output/*.md
output/*.txt

View File

@@ -1,22 +1,32 @@
You are writing a public-facing blog post on behalf of our development team. The post is based strictly on the content of our internal meeting notes — do not add any information, claims, or details that are not present in the source material.
# Task
## Tone and style
- Write a public-facing blog post on behalf of a development team.
- Rely strictly on internal meeting notes.
- Do not add any outside information or unverified claims.
Write in a warm, positive, and conversational tone. The audience is people who are interested in our project but are not necessarily technical experts. Avoid jargon where possible; when technical terms are necessary, briefly explain them in plain language.
# Style
The post should feel like an honest and enthusiastic update from a team that is proud of what they are building — not a press release or a sales pitch.
- Warm and enthusiastic tone.
- Concise, filler-free phrasing.
- Meaningful information in every sentence.
- Target audience is technical; use industry jargon.
- Do not explain basic concepts.
## Structure
# Content
- Start with a short, engaging opening paragraph that sets the context and draws the reader in.
- The body should walk through what the team has been working on, what progress has been made, and what challenges or decisions came up — all based on the meeting notes.
- End with a forward-looking closing paragraph that hints at what is coming next, based only on what the notes mention.
- Address every point in the source material.
- Guessing or speculating is strictly prohibited.
- If information is missing or unclear, do not invent details.
- Professional pride, not a marketing pitch or press release.
- Short, punchy opening to set the context.
- Body: completed work, progress, decisions, and challenges.
- Closing: future steps based only on the source material.
## Formatting
# Formatting
- Use Markdown.
- Use a single `#` heading for the title. Make the title specific and descriptive — not generic like "Project Update".
- Use `##` subheadings to break up longer posts if needed.
- Keep paragraphs short and readable — 3 to 5 sentences each.
- Do not use bullet points or numbered lists in the body. Write in flowing prose.
- Aim for 300 to 500 words in total.
- Single `#` for the title (specific and technical).
- Use `##` for subheadings.
- Short paragraphs (3-5 sentences each).
- No bullet points or lists in the body text; write in flowing prose.
- Total length: 300-500 words.

View File

@@ -1,23 +1,27 @@
ENV = export $(shell cat .env | grep -v '^\#' | grep -v '^$$' | xargs)
.PHONY: fetch write translate upload all
.PHONY: fetch write translate upload clean all
## Letölt egy wiki oldalt SOURCE.md-be
## Használat: make fetch URL=/path/to/page
## Downloads a wiki page into SOURCE.md
## Usage: make fetch URL=/path/to/page
fetch:
$(ENV) && python3 generator.py fetch $(URL)
@$(ENV) && python3 generator.py fetch $(URL)
## Blogposztot ír SOURCE.md-ből → BLOGPOST.md
## Writes a blog post from SOURCE.md → BLOGPOST.md
write:
$(ENV) && python3 generator.py write
@$(ENV) && python3 generator.py write
## Lefordítja BLOGPOST.md → TRANSLATED_BLOGPOST.md
## Translates BLOGPOST.md → TRANSLATED_BLOGPOST.md
translate:
$(ENV) && python3 generator.py translate
@$(ENV) && python3 generator.py translate
## Feltölti TRANSLATED_BLOGPOST.md-t a wikire
## Uploads TRANSLATED_BLOGPOST.md to the wiki
upload:
$(ENV) && python3 generator.py upload
@$(ENV) && python3 generator.py upload
## Teljes pipeline: write → translate → upload
## Deletes .md files from the output directory
clean:
@$(ENV) && python3 generator.py clean
## Full pipeline: write → translate → upload
all: write translate upload

View File

@@ -30,6 +30,7 @@ import urllib.error
OUTPUT_DIR = "output"
SOURCE_FILE = os.path.join(OUTPUT_DIR, "SOURCE.md")
SOURCE_TITLE_FILE = os.path.join(OUTPUT_DIR, "SOURCE_TITLE.txt")
BLOGPOST_FILE = os.path.join(OUTPUT_DIR, "BLOGPOST.md")
TRANSLATED_FILE = os.path.join(OUTPUT_DIR, "TRANSLATED_BLOGPOST.md")
INSTRUCTIONS_FILE = "INSTRUCTIONS.md"
@@ -83,9 +84,9 @@ query ($path: String!) {
"""
MUTATION_UPDATE_PAGE = """
mutation ($id: Int!, $content: String!) {
mutation ($id: Int!, $content: String!, $description: String!) {
pages {
update(id: $id, content: $content, tags: ["blog"]) {
update(id: $id, content: $content, description: $description, tags: ["blog"]) {
responseResult { succeeded message }
}
}
@@ -93,7 +94,7 @@ mutation ($id: Int!, $content: String!) {
"""
MUTATION_CREATE_PAGE = """
mutation ($path: String!, $title: String!, $content: String!) {
mutation ($path: String!, $title: String!, $content: String!, $description: String!) {
pages {
create(
path: $path
@@ -104,7 +105,7 @@ mutation ($path: String!, $title: String!, $content: String!) {
isPublished: true
isPrivate: false
tags: ["blog"]
description: ""
description: $description
) {
responseResult { succeeded message }
page { id }
@@ -191,13 +192,13 @@ class WikiJS:
page = resp.get("data", {}).get("pages", {}).get("singleByPath")
return page.get("id") if page else None
def update_page(self, page_id: int, content: str):
variables = {"id": page_id, "content": content}
def update_page(self, page_id: int, content: str, description: str):
variables = {"id": page_id, "content": content, "description": description}
resp = self.graphql(MUTATION_UPDATE_PAGE, variables)
return resp.get("data", {}).get("pages", {}).get("update", {}).get("responseResult", {}), resp
def create_page(self, path: str, title: str, content: str):
variables = {"path": path, "title": title, "content": content}
def create_page(self, path: str, title: str, content: str, description: str):
variables = {"path": path, "title": title, "content": content, "description": description}
resp = self.graphql(MUTATION_CREATE_PAGE, variables)
return resp.get("data", {}).get("pages", {}).get("create", {}).get("responseResult", {}), resp
@@ -242,6 +243,7 @@ class BlogWriter:
sys.exit(1)
write_file(SOURCE_FILE, page["content"])
write_file(SOURCE_TITLE_FILE, page["title"])
def write(self):
original_lang = require_env("ORIGINAL_LANG", "Hungarian")
@@ -275,6 +277,7 @@ class BlogWriter:
def upload(self):
content = read_file(TRANSLATED_FILE)
description = read_file(SOURCE_TITLE_FILE).strip()
# Extract H1 title
match = re.search(r"^#\s+(.+)", content, re.MULTILINE)
@@ -288,17 +291,18 @@ class BlogWriter:
page_path = f"blog/{kebab}"
print(f"→ Uploading to Wiki.js")
print(f" Title : {title}")
print(f" Path : /{page_path}")
print(f" Title : {title}")
print(f" Path : /{page_path}")
print(f" Description: {description}")
existing_id = self.wiki.find_page_id(page_path)
if existing_id:
print(f" Found existing page id={existing_id}, updating...")
result, resp = self.wiki.update_page(existing_id, content)
result, resp = self.wiki.update_page(existing_id, content, description)
else:
print(" Page not found, creating new...")
result, resp = self.wiki.create_page(page_path, title, content)
result, resp = self.wiki.create_page(page_path, title, content, description)
errors = resp.get("errors")
if errors:
@@ -311,6 +315,20 @@ class BlogWriter:
print(f"✓ Successfully uploaded to {self.wiki.base_domain}/{page_path}")
def clean(self):
"""Delete all .md files in the output directory."""
if not os.path.exists(OUTPUT_DIR):
print(f"→ Output directory '{OUTPUT_DIR}' does not exist. Nothing to clean.")
return
print(f"→ Cleaning {OUTPUT_DIR}/...")
count = 0
for filename in os.listdir(OUTPUT_DIR):
if filename.endswith(".md") or filename.endswith(".txt"):
os.remove(os.path.join(OUTPUT_DIR, filename))
count += 1
print(f"✓ Removed {count} Markdown files.")
# ---------------------------------------------------------------------------
# Entry point
@@ -329,13 +347,16 @@ def main():
p_fetch.add_argument("url", help="Page path or full URL, e.g. /my-page or https://wiki.example.com/my-page")
# write
subparsers.add_parser("write", help=f"Generate blog post from {SOURCE_FILE} using Gemini")
subparsers.add_parser("write", help=f"Generate blog post using Gemini")
# translate
subparsers.add_parser("translate", help=f"Translate {BLOGPOST_FILE} using Gemini")
subparsers.add_parser("translate", help=f"Translate generated blog post using Gemini")
# upload
subparsers.add_parser("upload", help=f"Upload {TRANSLATED_FILE} to Wiki.js")
subparsers.add_parser("upload", help=f"Upload translated blog post to Wiki.js")
# clean
subparsers.add_parser("clean", help=f"Delete all .md files in the {OUTPUT_DIR} directory")
args = parser.parse_args()
writer = BlogWriter()
@@ -348,6 +369,8 @@ def main():
writer.translate()
elif args.command == "upload":
writer.upload()
elif args.command == "clean":
writer.clean()
if __name__ == "__main__":