bsky user registerd at scanning

This commit is contained in:
Dylan Knutson
2025-08-12 22:27:22 +00:00
parent 420a44a27d
commit 6df6f63060
9 changed files with 256 additions and 60 deletions

View File

@@ -31,7 +31,7 @@ module Domain::UsersHelper
end
def domain_user_registered_at_ts_for_view(user)
case user
when Domain::User::FaUser, Domain::User::E621User
when Domain::User::FaUser, Domain::User::E621User, Domain::User::BlueskyUser
user.registered_at
else
nil

View File

@@ -29,6 +29,29 @@ class Domain::Bluesky::Job::ScanUserJob < Domain::Bluesky::Job::Base
private
sig { params(user: Domain::User::BlueskyUser).void }
def set_user_registration_time(user)
audit_log = http_client.get("https://plc.directory/#{user.did}/log/audit")
if audit_log.status_code != 200
fatal_error(
format_tags(
"failed to get user registration time",
make_tags(status_code: audit_log.status_code),
),
)
end
audit_log_data =
T.cast(JSON.parse(audit_log.body), T::Array[T::Hash[String, T.untyped]])
if (data = audit_log_data.first)
registered_at = Time.parse(data["createdAt"]).in_time_zone("UTC")
user.registered_at = registered_at
logger.info(
format_tags("set user registration time", make_tags(registered_at:)),
)
end
end
sig { params(user: Domain::User::BlueskyUser).void }
def scan_user_profile(user)
logger.info(format_tags("scanning user profile"))
@@ -51,30 +74,6 @@ class Domain::Bluesky::Job::ScanUserJob < Domain::Bluesky::Job::Base
begin
profile_data = JSON.parse(response.body)
if profile_data["error"]
fatal_error(
format_tags(
"profile API error",
make_tags(error: profile_data["error"]),
),
)
end
record = profile_data["value"]
if record
# Update user profile information
user.description = record["description"]
user.display_name = record["displayName"]
user.profile_raw = record
# Process avatar if present
if record["avatar"] && record["avatar"]["ref"]
process_user_avatar(user, record["avatar"])
end
end
user.scanned_profile_at = Time.zone.now
rescue JSON::ParserError => e
fatal_error(
format_tags(
@@ -83,6 +82,31 @@ class Domain::Bluesky::Job::ScanUserJob < Domain::Bluesky::Job::Base
),
)
end
if profile_data["error"]
fatal_error(
format_tags(
"profile API error",
make_tags(error: profile_data["error"]),
),
)
end
record = profile_data["value"]
if record
# Update user profile information
user.description = record["description"]
user.display_name = record["displayName"]
user.profile_raw = record
# Process avatar if present
if record["avatar"] && record["avatar"]["ref"]
process_user_avatar(user, record["avatar"])
end
end
set_user_registration_time(user)
user.scanned_profile_at = Time.zone.now
end
sig do

View File

@@ -1,34 +0,0 @@
<section class="sky-section animated-shadow-sky divide-y">
<h2 class="section-header">User Stats</h2>
<% stat_rows_for_user(user).each do |stat_row| %>
<% label = stat_row.name %>
<% value = stat_row.value %>
<% fa_icon_class = stat_row.fa_icon_class %>
<div class="flex items-center px-4 py-2 gap-2">
<span class="grow text-slate-900 truncate"><%= label %></span>
<span class="text-slate-500 relative group">
<% value_str = case value %>
<% when Integer %>
<% number_with_delimiter(value, delimiter: ",") %>
<% when HasTimestampsWithDueAt::TimestampScanInfo %>
<% value.ago_in_words %>
<% else %>
<% value %>
<% end %>
<% if stat_row.link_to %>
<%= link_to value_str, stat_row.link_to, class: "blue-link" %>
<% else %>
<%= value_str %>
<% end %>
<% if fa_icon_class %>
<i class="fa-solid <%= fa_icon_class %>"></i>
<% end %>
<% if stat_row.hover_title %>
<div class="absolute hidden group-hover:block bg-slate-800 text-white text-sm rounded px-2 py-1 top-1/2 -translate-y-1/2 right-full mr-2 whitespace-nowrap">
<%= stat_row.hover_title %>
</div>
<% end %>
</span>
</div>
<% end %>
</section>