Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@

Website komunitas modern untuk DevOps Jogja yang dibangun dengan Flask dan Tailwind CSS.

![DevOps Jogja](static/images/cover.png)

## 🚀 Fitur

- **Modern Homepage** - Kesan teknologi infrastruktur dengan design responsif
- **Blog System** - Artikel dan blog teknologi dari file Markdown
- **Event Management** - Informasi event dari file Markdown
- **Event Management** - Informasi event dari file Markdown & integrasi Google Calendar
- **Organizer Profiles** - Profil pengurus dari file YAML
- **Community Calendar** - Sinkronisasi jadwal otomatis dengan Google Calendar
- **About Page** - Informasi komunitas dari file YAML
- **Responsive Design** - Menggunakan Tailwind CSS

Expand Down Expand Up @@ -85,7 +85,10 @@ devops-jogja-website/
│ │ ├── index.html # Event listing
│ │ └── event.html # Event detail
│ ├── organizer.html # Organizer page
│ └── about.html # About page
│ ├── schedule.html # Community Calendar schedule page
│ ├── about.html # About page
│ ├── gallery.html # Gallery page
│ └── 404.html # Error page
├── content/
│ ├── blog/ # Blog posts (Markdown)
│ ├── event/ # Events (Markdown)
Expand Down Expand Up @@ -132,6 +135,10 @@ featured_image: "event-image.jpg"
---

Deskripsi event Anda di sini...

### Community Calendar

Halaman schedule (`/schedule`) menggunakan integrasi Google Calendar API (via backend proxy) untuk menampilkan jadwal terbaru secara real-time. Link subscribe tersedia di bagian bawah halaman untuk memudahkan user menambahkan kalender ke akun Google mereka.
```

### Organizer Data
Expand Down
140 changes: 6 additions & 134 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,6 @@
import os
import glob
from datetime import datetime
from PIL import Image

# Try to import pillow_heif for HEIC support
try:
import pillow_heif

# Register HEIF opener with Pillow
pillow_heif.register_heif_opener()
HEIC_SUPPORTED = True
except ImportError:
print("Warning: pillow_heif not installed. HEIC files will be skipped.")
HEIC_SUPPORTED = False

app = Flask(__name__)

Expand All @@ -24,40 +12,6 @@
yaml_loader = YAMLLoader()


def convert_heic_to_jpg(heic_path, output_dir="static/images/gallery/converted"):
"""Convert HEIC file to JPG format"""
if not HEIC_SUPPORTED:
return None

try:
# Create output directory if it doesn't exist
os.makedirs(output_dir, exist_ok=True)

# Get filename without extension
base_name = os.path.splitext(os.path.basename(heic_path))[0]
jpg_path = os.path.join(output_dir, f"{base_name}.jpg")

# Check if converted file already exists
if os.path.exists(jpg_path):
return jpg_path.replace("static/", "")

# Convert HEIC to JPG
with Image.open(heic_path) as img:
# Convert to RGB if necessary
if img.mode != "RGB":
img = img.convert("RGB")

# Save as JPG with high quality
img.save(jpg_path, "JPEG", quality=90, optimize=True)
print(f"Converted {heic_path} to {jpg_path}")

return jpg_path.replace("static/", "")

except Exception as e:
print(f"Error converting {heic_path}: {e}")
return None


def get_image_path(image_name, image_type="blog"):
"""
Get the correct path for an image, checking multiple formats including WebP
Expand Down Expand Up @@ -98,87 +52,6 @@ def get_image_path(image_name, image_type="blog"):
return image_name


def get_gallery_images():
"""Get all images from gallery folder with HEIC support"""
gallery_path = "static/images/gallery"
image_extensions = [
"*.jpg",
"*.jpeg",
"*.png",
"*.gif",
"*.webp",
"*.HEIC",
"*.heic",
]
images = []

# Create gallery directory if it doesn't exist
os.makedirs(gallery_path, exist_ok=True)

for ext in image_extensions:
pattern = os.path.join(gallery_path, ext)
found_images = glob.glob(pattern, recursive=False)

for img in found_images:
# Skip files in subdirectories like 'converted'
if "/converted/" in img or "\\converted\\" in img:
continue

filename = os.path.basename(img)
file_ext = os.path.splitext(filename)[1].lower()

# Handle HEIC files
if file_ext in [".heic"]:
if not HEIC_SUPPORTED:
print(f"Skipping {filename} - HEIC support not available")
continue

# Convert HEIC to JPG
converted_path = convert_heic_to_jpg(img)
if converted_path:
# Use converted JPG file
images.append(
{
"path": converted_path,
"filename": os.path.basename(converted_path),
"alt": filename.split(".")[0]
.replace("-", " ")
.replace("_", " ")
.title(),
"original_format": "HEIC",
}
)
print(f"Added HEIC file: {filename} -> {converted_path}")
else:
# Fallback: skip this file if conversion failed
print(f"Skipping {filename} - conversion failed")
continue
else:
# Handle regular image files
relative_path = img.replace("static/", "")
images.append(
{
"path": relative_path,
"filename": filename,
"alt": filename.split(".")[0]
.replace("-", " ")
.replace("_", " ")
.title(),
"original_format": file_ext.upper().replace(".", ""),
}
)

# Sort by filename
images.sort(key=lambda x: x["filename"])

print(f"Gallery loaded: {len(images)} images total")
if images:
for img in images:
print(f" - {img['filename']} ({img['original_format']})")

return images


@app.route("/")
def index():
"""Homepage with modern tech infrastructure design"""
Expand All @@ -193,16 +66,15 @@ def index():
# Filter only active sponsors
active_sponsors = [sponsor for sponsor in sponsors if sponsor.get("active", True)]

# Get gallery images
gallery_images = get_gallery_images()
gallery_api_url = "https://devops-jogja-calendar.vercel.app/gallery"

return render_template(
"index.html",
latest_blogs=latest_blogs,
upcoming_events=upcoming_events,
latest_events=latest_events,
sponsors=active_sponsors,
gallery_images=gallery_images,
gallery_api_url=gallery_api_url,
current_page="index",
)

Expand Down Expand Up @@ -262,9 +134,11 @@ def about():
@app.route("/gallery")
def gallery():
"""Gallery page"""
gallery_images = get_gallery_images()
gallery_api_url = "https://devops-jogja-calendar.vercel.app/gallery"
return render_template(
"gallery.html", gallery_images=gallery_images, current_page="gallery"
"gallery.html",
gallery_api_url=gallery_api_url,
current_page="gallery"
)


Expand Down Expand Up @@ -340,6 +214,4 @@ def get_image_filter(image_name, image_type="blog"):
os.makedirs("content/event", exist_ok=True)
os.makedirs("static/organizer", exist_ok=True)
os.makedirs("static/images", exist_ok=True)
os.makedirs("static/images/gallery", exist_ok=True)

app.run(debug=True, host="0.0.0.0", port=3008)
92 changes: 9 additions & 83 deletions build.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,6 @@
from datetime import datetime
import glob
from urllib.parse import quote
from PIL import Image

# Try to import pillow_heif for HEIC support
try:
import pillow_heif
pillow_heif.register_heif_opener()
HEIC_SUPPORTED = True
except ImportError:
print("Warning: pillow_heif not installed. HEIC files will be skipped.")
HEIC_SUPPORTED = False


class StaticSiteBuilder:
Expand Down Expand Up @@ -135,75 +125,6 @@ def get_image_path(self, image_name, image_type="blog"):

return image_name

def convert_heic_to_jpg(self, heic_path, output_dir="static/images/gallery/converted"):
"""Convert HEIC file to JPG format"""
if not HEIC_SUPPORTED:
return None

try:
os.makedirs(output_dir, exist_ok=True)
base_name = os.path.splitext(os.path.basename(heic_path))[0]
jpg_path = os.path.join(output_dir, f"{base_name}.jpg")

if os.path.exists(jpg_path):
return jpg_path.replace("static/", "")

with Image.open(heic_path) as img:
if img.mode != "RGB":
img = img.convert("RGB")
img.save(jpg_path, "JPEG", quality=90, optimize=True)
print(f"Converted {heic_path} to {jpg_path}")

return jpg_path.replace("static/", "")

except Exception as e:
print(f"Error converting {heic_path}: {e}")
return None

def get_gallery_images(self):
"""Get all images from gallery folder with HEIC support"""
gallery_path = "static/images/gallery"
image_extensions = ["*.jpg", "*.jpeg", "*.png", "*.gif", "*.webp", "*.HEIC", "*.heic"]
images = []

os.makedirs(gallery_path, exist_ok=True)

for ext in image_extensions:
pattern = os.path.join(gallery_path, ext)
found_images = glob.glob(pattern, recursive=False)

for img in found_images:
if "/converted/" in img or "\\converted\\" in img:
continue

filename = os.path.basename(img)
file_ext = os.path.splitext(filename)[1].lower()

if file_ext in [".heic"]:
if not HEIC_SUPPORTED:
print(f"Skipping {filename} - HEIC support not available")
continue

converted_path = self.convert_heic_to_jpg(img)
if converted_path:
images.append({
"path": converted_path,
"filename": os.path.basename(converted_path),
"alt": filename.split(".")[0].replace("-", " ").replace("_", " ").title(),
"original_format": "HEIC",
})
else:
relative_path = img.replace("static/", "")
images.append({
"path": relative_path,
"filename": filename,
"alt": filename.split(".")[0].replace("-", " ").replace("_", " ").title(),
"original_format": file_ext.upper().replace(".", ""),
})

images.sort(key=lambda x: x["filename"])
print(f"Gallery loaded: {len(images)} images total")
return images

def clean_output_dir(self):
"""Clean the output directory"""
Expand Down Expand Up @@ -242,7 +163,7 @@ def build_homepage(self):
sponsors = sponsor_data.get("sponsors", []) if sponsor_data else []
active_sponsors = [sponsor for sponsor in sponsors if sponsor.get("active", True)]

gallery_images = self.get_gallery_images()
gallery_api_url = "https://devops-jogja-calendar.vercel.app/gallery"

# Add current_url for sharing
current_url = f"{self.app.jinja_env.globals['base_url']}/"
Expand All @@ -253,7 +174,7 @@ def build_homepage(self):
upcoming_events=upcoming_events,
latest_events=latest_events,
sponsors=active_sponsors,
gallery_images=gallery_images,
gallery_api_url=gallery_api_url,
current_url=current_url,
current_page="index",
)
Expand Down Expand Up @@ -427,9 +348,14 @@ def build_gallery_page(self):
"""Build gallery page"""
with self.app.app_context():
with self.app.test_request_context():
gallery_images = self.get_gallery_images()
gallery_api_url = "https://devops-jogja-calendar.vercel.app/gallery"
current_url = f"{self.app.jinja_env.globals['base_url']}/gallery/"
html = render_template("gallery.html", gallery_images=gallery_images, current_url=current_url, current_page="gallery")
html = render_template(
"gallery.html",
gallery_api_url=gallery_api_url,
current_url=current_url,
current_page="gallery"
)
self.save_page(html, "gallery/index.html")
print("\n🔧 Generating additional files...")
self.create_nojekyll_file()
Expand Down
Loading