mirror of
https://github.com/System-End/highway.git
synced 2026-04-19 19:45:10 +00:00
Add project cloning
This commit is contained in:
parent
edcdb98d18
commit
ed6e271577
4 changed files with 121 additions and 35 deletions
|
|
@ -1,14 +1,13 @@
|
|||
class ProjectsController < ApplicationController
|
||||
include MarkdownRenderable
|
||||
require "yaml"
|
||||
|
||||
def index
|
||||
@projects = Project.all
|
||||
|
||||
CloneProjectsJob.perform_later if @projects.empty?
|
||||
end
|
||||
|
||||
def show
|
||||
@project = Project.find(params[:repo], params[:project_name])
|
||||
render_not_found unless @project
|
||||
@project = Project.find(params[:user], params[:project_name])
|
||||
not_found unless @project
|
||||
end
|
||||
|
||||
def new
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
class Project
|
||||
include MarkdownRenderable
|
||||
attr_reader :repo, :project_name, :title, :author, :description, :created_at, :content
|
||||
attr_reader :user, :project_name, :title, :author, :description, :created_at, :content
|
||||
|
||||
def initialize(attributes = {})
|
||||
@repo = attributes[:repo]
|
||||
@user = attributes[:user]
|
||||
@project_name = attributes[:project_name]
|
||||
@title = attributes[:title]
|
||||
@author = attributes[:author]
|
||||
|
|
@ -13,55 +13,112 @@ class Project
|
|||
end
|
||||
|
||||
def name
|
||||
title
|
||||
title.presence || project_name.titleize
|
||||
end
|
||||
|
||||
def github_slug
|
||||
"#{repo}/#{project_name}"
|
||||
"#{user}/#{project_name}"
|
||||
end
|
||||
|
||||
def github_repo
|
||||
"https://github.com/#{github_slug}"
|
||||
end
|
||||
|
||||
def author_display
|
||||
return "@#{user}" if author.blank?
|
||||
author
|
||||
end
|
||||
|
||||
def user_link
|
||||
"https://github.com/#{user}"
|
||||
end
|
||||
|
||||
def created_at_date
|
||||
return nil unless created_at
|
||||
Date.parse(created_at)
|
||||
rescue Date::Error
|
||||
nil
|
||||
end
|
||||
|
||||
def formatted_created_at
|
||||
return nil unless created_at_date
|
||||
created_at_date.strftime("%B %d, %Y")
|
||||
end
|
||||
|
||||
def self.all
|
||||
Dir.glob(Rails.root.join("content/projects/*/*/journal.md")).map do |file|
|
||||
content = File.read(file)
|
||||
metadata, _ = parse_frontmatter(content)
|
||||
def has_creation_date?
|
||||
created_at_date.present?
|
||||
end
|
||||
|
||||
# Extract repo and project name from path
|
||||
path_parts = file.split("/")
|
||||
repo = path_parts[-3]
|
||||
project_name = path_parts[-2]
|
||||
def has_journal?
|
||||
# Find journal file, case-insensitive
|
||||
dir = Rails.root.join("content/projects", user, project_name)
|
||||
Dir.glob(File.join(dir, "*")).any? { |f| File.basename(f).downcase == "journal.md" }
|
||||
end
|
||||
|
||||
def self.all
|
||||
Dir.glob(Rails.root.join("content/projects/*/*")).map do |dir|
|
||||
next unless File.directory?(dir)
|
||||
|
||||
# Extract user and project name from path
|
||||
path_parts = dir.split("/")
|
||||
user = path_parts[-2]
|
||||
project_name = path_parts[-1]
|
||||
|
||||
# Find journal file, case-insensitive
|
||||
journal_path = Dir.glob(File.join(dir, "*")).find { |f| File.basename(f).downcase == "journal.md" }
|
||||
|
||||
metadata = {}
|
||||
if journal_path && File.exist?(journal_path)
|
||||
content = File.read(journal_path)
|
||||
metadata, _ = parse_frontmatter(content)
|
||||
end
|
||||
|
||||
unless Rails.env.development?
|
||||
next if user == "hackclub" && project_name == "awesome-project"
|
||||
end
|
||||
|
||||
new(
|
||||
repo: repo,
|
||||
user: user,
|
||||
project_name: project_name,
|
||||
title: metadata["title"],
|
||||
author: metadata["author"],
|
||||
description: metadata["description"],
|
||||
created_at: metadata["created_at"]
|
||||
)
|
||||
end.sort_by(&:created_at_date).reverse
|
||||
end.compact
|
||||
end
|
||||
|
||||
def self.find(repo, project_name)
|
||||
file_path = Rails.root.join("content/projects", repo, project_name, "journal.md")
|
||||
def self.working
|
||||
all.select do |project|
|
||||
journal_path = Rails.root.join("content/projects", project.user, project.project_name, "journal.md")
|
||||
next false unless File.exist?(journal_path)
|
||||
|
||||
content = File.read(journal_path)
|
||||
metadata, _ = parse_frontmatter(content)
|
||||
|
||||
# Check if all required metadata is present
|
||||
required_fields = [ "title", "author", "description", "created_at" ]
|
||||
next false unless required_fields.all? { |field| metadata[field].present? }
|
||||
|
||||
# Update the project with metadata
|
||||
project.instance_variable_set(:@title, metadata["title"])
|
||||
project.instance_variable_set(:@author, metadata["author"])
|
||||
project.instance_variable_set(:@description, metadata["description"])
|
||||
project.instance_variable_set(:@created_at, metadata["created_at"])
|
||||
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
def self.find(user, project_name)
|
||||
file_path = Rails.root.join("content/projects", user, project_name, "journal.md")
|
||||
return nil unless File.exist?(file_path)
|
||||
|
||||
content = File.read(file_path)
|
||||
metadata, markdown_content = parse_frontmatter(content)
|
||||
|
||||
new(
|
||||
repo: repo,
|
||||
user: user,
|
||||
project_name: project_name,
|
||||
title: metadata["title"],
|
||||
author: metadata["author"],
|
||||
|
|
|
|||
|
|
@ -1,19 +1,49 @@
|
|||
<div class="mt-16 md:mt-12 p-8 md:p-12">
|
||||
|
||||
<div class = "">
|
||||
<p class="font-bold text-3xl">Check out what others are building!</p>
|
||||
<p class="font-bold opacity-70 mt-8"><i><%= pluralize(@projects.count, "project") %> <%= @projects.count == 1 ? "has" : "have" %> been started:</i></p>
|
||||
<p class="font-bold text-3xl">Check out what others are building!</p>
|
||||
<p class="font-bold opacity-70 mt-8"><i><%= pluralize(@projects.count, "project") %> <%= @projects.count == 1 ? "has" : "have" %> been started:</i></p>
|
||||
|
||||
<div class="grid md:grid-cols-3 gap-4 mt-4 sm:grid-cols-2 grid-cols-1">
|
||||
<% @projects.each do |project| %>
|
||||
<%= link_to project_path(repo: project.repo, project_name: project.project_name), class: "block bg-[#2E2A54] border-2 border-[#544FFF] max-w-4xl py-8 px-8 rounded-lg text-white hover:bg-[#3A3A6D] transition duration-100 transition-transform hover:scale-102" do %>
|
||||
<h1 class="text-2xl"><%= project.name %> <span class="text-base text-[#96ABF9]">(<%= project.github_slug %>)</span></h1>
|
||||
<p class="mb-2">created by <span class="text-[#96ABF9]">[<%= project.author %>]</span></p>
|
||||
<p class="opacity-70"><%= project.description %></p>
|
||||
<p class="opacity-70 mt-2">Started on <%= project.formatted_created_at %></p>
|
||||
<div class="grid md:grid-cols-3 gap-4 mt-4 sm:grid-cols-2 grid-cols-1">
|
||||
<% @projects.each do |project| %>
|
||||
<div class="bg-[#2E2A54] border-2 border-[#544FFF] rounded-lg text-white hover:bg-[#3A3A6D] transition duration-100 transition-transform hover:scale-102 p-8 h-full flex flex-col">
|
||||
<% if project.has_journal? %>
|
||||
<%= link_to project_path(user: project.user, project_name: project.project_name), class: "block mb-2" do %>
|
||||
<h1 class="text-2xl font-bold"><%= project.name.truncate(25) %></h1>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<h1 class="text-2xl font-bold mb-2">
|
||||
<%= project.name.truncate(25) %>
|
||||
</h1>
|
||||
<p class="text-sm font-bold text-yellow-300">⚠️ This project lacks a <code>journal.md</code> file.</p>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
<%= link_to project.github_repo, target: "_blank", class: "text-base text-[#96ABF9] text-sm rounded px-2 py-1 inline-block" do %>
|
||||
[<%= project.github_slug %>]
|
||||
<% end %>
|
||||
<div class="mb-4 text-[#b3aaff] text-sm opacity-70">
|
||||
Created by
|
||||
<% if project.author.present? %>
|
||||
<%= link_to project.user_link, target: "_blank", class: "text-base text-[#96ABF9] text-sm rounded px-2 py-1 inline-block" do %>
|
||||
[<%= project.author %>]
|
||||
<% end %>
|
||||
<% else %>
|
||||
<%= project.author_display %>
|
||||
<% end %>
|
||||
<% if project.has_creation_date? %>
|
||||
<span class="ml-2">• Started on <%= project.formatted_created_at %></span>
|
||||
<% end %>
|
||||
</div>
|
||||
<% if project.description.present? %>
|
||||
<p class="opacity-80 mt-auto"><%= project.description.truncate(120) %></p>
|
||||
<% end %>
|
||||
<% if Rails.env.development? %>
|
||||
<summary>
|
||||
<details>
|
||||
<%= project.inspect %>
|
||||
</details>
|
||||
</summary>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
|
@ -13,7 +13,7 @@ Rails.application.routes.draw do
|
|||
root "landing#index"
|
||||
resources :users
|
||||
get "/projects", to: "projects#index"
|
||||
get "/projects/:repo/:project_name", to: "projects#show", as: :project
|
||||
get "/projects/:user/:project_name", to: "projects#show", as: :project
|
||||
|
||||
get "/info", to: "info#show"
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue