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
6 changes: 4 additions & 2 deletions app/controllers/projects_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,17 +64,19 @@ def new
end

def create
macondo_project_id = (params.dig(:project, :macondo_project_id) || params[:macondo_project_id]).presence

@project = current_user.projects.build(project_params)
@project.status = :draft
@project.devlog_mode = "website" if macondo_project_id
if @project.tier == Project::BUILD_REVIEW_TIER
@project.build_review = true
end
authorize @project

if @project.save
audit!("project.created", target: @project, metadata: { tier: @project.tier, build_review: @project.build_review })
macondo_project_id = params.dig(:project, :macondo_project_id).presence
ImportMacondoDataJob.perform_later(@project.id, macondo_project_id) if macondo_project_id
ImportMacondoDataJob.perform_now(@project.id, macondo_project_id) if macondo_project_id
redirect_to @project, notice: @project.build_review? ? "Build review created as draft." : "Project created as draft."
else
fallback_tier = @project.build_review? ? Project::BUILD_REVIEW_TIER : @project.tier
Expand Down
2 changes: 2 additions & 0 deletions app/javascript/pages/Projects/Form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -148,10 +148,12 @@ export default function ProjectsForm({
form.setData({
...form.data,
name: data.name || form.data.name,
subtitle: data.description || form.data.subtitle,
repo_link: data.repo_link || form.data.repo_link,
hackatime_projects: Array.isArray(data.hackatime_projects)
? data.hackatime_projects
: form.data.hackatime_projects,
devlog_mode: 'website',
macondo_project_id: data.macondo_project_id || '',
})

Expand Down
47 changes: 33 additions & 14 deletions app/jobs/import_macondo_data_job.rb
Original file line number Diff line number Diff line change
@@ -1,34 +1,53 @@
require "open-uri"

class ImportMacondoDataJob < ApplicationJob
queue_as :default

TRUSTED_CDN_HOST = "cdn.hackclub.com"

def perform(project_id, macondo_project_id)
project = Project.find_by(id: project_id)
return unless project
unless project
Rails.logger.warn("ImportMacondoDataJob: project #{project_id} not found, aborting")
return
end

data = MacondoService.get_project(macondo_project_id)
return unless data
return unless MacondoService.owned_by?(data, project.user)
return if MacondoService.shipped?(data)
unless data
Rails.logger.warn("ImportMacondoDataJob: Macondo project #{macondo_project_id} fetch failed, aborting")
return
end

attach_cover_image(project, data["thumbnail_url"]) if data["thumbnail_url"].present?
unless MacondoService.owned_by?(data, project.user)
Rails.logger.warn("ImportMacondoDataJob: ownership check failed for Macondo project #{macondo_project_id} (owner=#{data["owner"].inspect}), aborting")
return
end

if MacondoService.shipped?(data)
Rails.logger.warn("ImportMacondoDataJob: Macondo project #{macondo_project_id} already shipped, aborting")
return
end

Rails.logger.info("ImportMacondoDataJob: importing cover image and journals for project #{project_id} from Macondo project #{macondo_project_id}")
set_cover_image(project, data["thumbnail_url"]) if data["thumbnail_url"].present?
import_journals(project, data["journals"].presence || MacondoService.get_journals(macondo_project_id))
end

private
def set_cover_image(project, url)
uri = URI.parse(url)
unless uri.is_a?(URI::HTTPS) && uri.host == TRUSTED_CDN_HOST
Rails.logger.error("ImportMacondoDataJob cover image skipped: untrusted host (#{url.inspect})")
return
end

def attach_cover_image(project, url)
io = URI.open(url)
filename = File.basename(URI.parse(url).path.presence || "cover.png")
project.cover_image.attach(io: io, filename: filename)
project.update!(cover_image_url: url)
Rails.logger.info("ImportMacondoDataJob: cover image set for project #{project.id}")
rescue StandardError => e
Rails.logger.error("ImportMacondoDataJob cover image failed: #{e.message}")
Rails.logger.error("ImportMacondoDataJob cover image failed (#{url.inspect}): #{e.class}: #{e.message}")
end

def import_journals(project, journals)
Array(journals).each do |j|
title = j["short_brief"].presence || "Imported entry"
Array(journals).each_with_index do |j, i|
title = j["short_brief"].presence || "Imported entry #{j["id"] || i + 1}"
next if project.devlogs.exists?(title: title)

project.devlogs.create!(
Expand Down
Loading