hackatime/app/controllers/my/heartbeat_imports_controller.rb
Mahad Kalam 667d3a7c93
WakaTime/Hackatime v1 imports + Settings v2 (#1062)
* Imports are back!!

* Settings UI v3

* Use Inertia forms for heartbeat imports

* Update app/javascript/pages/Users/Settings/Data.svelte

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* Update Bundle

* Fix broken Form/Button markup in Data.svelte settings page

* Update JS deps

* Greptile fixes

* Remove dead code

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-03-12 21:27:10 +00:00

95 lines
2.9 KiB
Ruby

class My::HeartbeatImportsController < ApplicationController
before_action :ensure_current_user
def create
if params[:heartbeat_file].blank? && params[:heartbeat_import].blank?
redirect_with_import_error("No import data provided.")
return
end
if params[:heartbeat_file].present?
start_dev_upload!
else
start_remote_import!
end
redirect_to my_settings_data_path
rescue DevelopmentOnlyError => e
redirect_with_import_error(e.message)
rescue HeartbeatImportRunner::FeatureDisabledError => e
redirect_with_import_error(e.message)
rescue HeartbeatImportRunner::CooldownError => e
flash[:cooldown_until] = e.retry_at.iso8601
redirect_with_import_error(e.message)
rescue HeartbeatImportRunner::ActiveImportError => e
redirect_with_import_error(e.message)
rescue HeartbeatImportRunner::InvalidProviderError, ActionController::ParameterMissing => e
redirect_with_import_error(e.message)
rescue => e
Sentry.capture_exception(e)
Rails.logger.error("Error starting heartbeat import for user #{current_user&.id}: #{e.message}")
redirect_with_import_error("error reading file: #{e.message}")
end
def show
run = HeartbeatImportRunner.find_run(user: current_user, import_id: params[:id])
if run.present?
run = HeartbeatImportRunner.refresh_remote_run!(run)
render json: HeartbeatImportRunner.serialize(run)
else
render json: { error: "Import not found" }, status: :not_found
end
end
private
class DevelopmentOnlyError < StandardError; end
def valid_json_file?(file)
file.content_type == "application/json" || file.original_filename.to_s.ends_with?(".json")
end
def start_dev_upload!
ensure_development
file = params[:heartbeat_file]
unless valid_json_file?(file)
raise HeartbeatImportRunner::InvalidProviderError, "pls upload only json (download from the button above it)"
end
HeartbeatImportRunner.start_dev_upload(user: current_user, uploaded_file: file)
end
def start_remote_import!
heartbeat_import = remote_import_params
if heartbeat_import[:api_key].blank?
raise HeartbeatImportRunner::InvalidProviderError, "API key is required."
end
HeartbeatImportRunner.start_remote_import(
user: current_user,
provider: heartbeat_import[:provider],
api_key: heartbeat_import[:api_key]
)
end
def ensure_current_user
return if current_user
render json: { error: "You must be logged in to view this page." }, status: :unauthorized
end
def ensure_development
return if Rails.env.development?
raise DevelopmentOnlyError, "Heartbeat import is only available in development."
end
def redirect_with_import_error(message)
redirect_to my_settings_data_path, inertia: { errors: { import: message } }
end
def remote_import_params
params.require(:heartbeat_import).permit(:provider, :api_key)
end
end