Files
danbooru/app/views/users/_statistics.html.erb
evazion 075199cd1e Remove /ip_addresses page.
Remove the /ip_addresses page. This page allowed moderators to search
users by IP, and to see recent activity tied to an IP. However, it was
limited to IPs tied to uploads, comments, dmails, artist edits, note
edits, and wiki edits.

Remove this page because it was limited in scope and because there are
better ways of doing what it did. The /user_events page is better at
catching sockpuppets because it tracks IPs for every login, not just for
certain types of edits. And the /user_actions page is better at
monitoring user activity because it shows all activity associated with
an account, not just for certain types of edits.

Removing this allows us to drop IP addresses from all tables besides the
user_events table. This is good because these IPs are no longer necessary
for any purpose, and because storing them forever is a liability.
2022-09-17 21:32:26 -05:00

295 lines
9.0 KiB
Plaintext

<div>
<h2>Statistics</h2>
<table width="100%" class="user-statistics table-sm">
<tbody>
<tr>
<th>User ID</th>
<td><%= user.id %></td>
</tr>
<tr>
<th>Join Date</th>
<td><%= presenter.join_date %></td>
</tr>
<% if policy(User).can_see_last_logged_in_at? %>
<tr>
<th>Last Seen</th>
<td><%= time_ago_in_words_tagged(user.last_logged_in_at) %></td>
</tr>
<% end %>
<% if policy(IpAddress).show? %>
<tr>
<th>Last IP</th>
<td>
<% if user.last_ip_addr.present? %>
<%= link_to user.last_ip_addr, ip_address_path(user.last_ip_addr) %>
<% else %>
<em>unknown</em>
<% end %>
</td>
</tr>
<% end %>
<% if policy(UserEvent).show? %>
<tr>
<th>User Events</th>
<td>
<% if user.last_ip_addr.present? %>
<%= link_to "By Name", user_events_path(search: { user_name: user.name }) %>,
<%= link_to "By IP", user_events_path(search: { user_session: { ip_addr: user.last_ip_addr }}) %>
<% else %>
<%= link_to "By Name", user_events_path(search: { user_name: user.name }) %>
<% end %>
<td>
</tr>
<% end %>
<% if policy(user.email_address).show? %>
<tr class="user-email-address">
<th>Email Address</th>
<td>
<% if user.email_address.present? %>
<%= user.email_address.address %>
<% if user == CurrentUser.user %>
(<%= link_to "edit", edit_user_email_path(user) %>)
<% end %>
<% if user.email_address.is_verified? %>
<%= checkmark_icon(class: "user-verified-email-icon", title: "Verified email") %>
<% elsif user == CurrentUser.user %>
<%= link_to verify_user_email_path(user) do %>
<%= exclamation_icon(class: "user-unverified-email-icon", title: "Unverified email. Click here to verify your email.") %>
<% end %>
<% else %>
<%= exclamation_icon(class: "user-unverified-email-icon", title: "Unverified email") %>
<% end %>
<% else %>
<em>none</em>
<% end %>
</td>
</tr>
<% end %>
<% if user.inviter %>
<tr>
<th>Promoter</th>
<td><%= link_to_user user.inviter %> <%= link_to "»", users_path(search: { inviter: { name: user.inviter.name }}) %></td>
</tr>
<% end %>
<tr>
<th>Level</th>
<td>
<%= user.level_string %>
<% if !user.is_gold? %>
<% if CurrentUser.user == user %>
(<%= link_to "Upgrade account", new_user_upgrade_path %>)
<% else %>
(<%= link_to "Gift upgrade", new_user_upgrade_path(user_id: user.id) %>)
<% end %>
<% end %>
</td>
</tr>
<tr>
<th>Permissions</th>
<td><%= presenter.permissions %></td>
</tr>
<% if user.is_banned? && user.active_ban.present? %>
<tr>
<th>Ban reason</th>
<td>
<span class="prose">
<%= format_text user.active_ban.reason, inline: true %>
(banned <%= humanized_duration(user.active_ban.duration) %>)
</span>
</td>
</tr>
<% end %>
<tr>
<th>Upload Limit</th>
<td>
<%= render "users/upload_limit", user: user %>
</td>
</tr>
<tr>
<th>Uploads</th>
<td>
<%= presenter.upload_count(self) %>
<% if presenter.has_uploads? %>
(<%= link_to "tag changes report", post_versions_path(search: { updater_name: user.name, version: 1 }, type: "current") %>)
<% end %>
<% if CurrentUser.is_moderator? %>
[<%= link_to "sample", posts_path(:tags => "user:#{user.name} order:random limit:#{PostSets::Post::MAX_PER_PAGE}") %>]
<% end %>
</td>
</tr>
<tr>
<th>Deleted Uploads</th>
<td>
<%= presenter.deleted_upload_count(self) %>
<% if CurrentUser.is_moderator? %>
[<%= link_to "sample", posts_path(:tags => "user:#{user.name} order:random limit:#{PostSets::Post::MAX_PER_PAGE} status:deleted") %>]
<% end %>
</td>
</tr>
<tr>
<th>Favorites</th>
<td>
<%= presenter.favorite_count(self) %>
<% if CurrentUser.is_moderator? %>
[<%= link_to "sample", posts_path(:tags => "fav:#{user.name} order:random limit:#{PostSets::Post::MAX_PER_PAGE}") %>]
<% end %>
</td>
</tr>
<% if CurrentUser.user == user || CurrentUser.user.is_admin? %>
<tr>
<th>Votes</th>
<td>
<%= link_to user.post_votes.active.count, post_votes_path(search: { user_name: user.name }) %> posts,
<%= link_to user.comment_votes.active.count, comment_votes_path(search: { user_name: user.name }) %> comments,
<%= link_to user.forum_post_votes.count, forum_post_votes_path(search: { creator_name: user.name }) %> forum posts
</td>
</tr>
<% end %>
<tr>
<th>Favorite Groups</th>
<td><%= presenter.favorite_group_count(self) %></td>
</tr>
<tr>
<th>Post Changes</th>
<td>
<%= presenter.post_version_count(self) %>
<% if CurrentUser.id == user.id %>
(<%= link_to "refresh", new_maintenance_user_count_fixes_path %>)
<% end %>
</td>
</tr>
<tr>
<th>Note Changes</th>
<td>
<%= presenter.note_version_count(self) %> in <%= presenter.noted_posts_count(self) %> posts
(<%= link_to "note changes report", note_versions_path(search: { updater_id: user.id, version: 1 }, type: "current") %>)
</td>
</tr>
<tr>
<th>Wiki Page Changes</th>
<td><%= presenter.wiki_page_version_count(self) %></td>
</tr>
<tr>
<th>Artist Changes</th>
<td><%= presenter.artist_version_count(self) %></td>
</tr>
<tr>
<th>Commentary Changes</th>
<td><%= presenter.artist_commentary_version_count(self) %></td>
</tr>
<% if PoolVersion.enabled? %>
<tr>
<th>Pool Changes</th>
<td><%= presenter.pool_version_count(self) %></td>
</tr>
<% end %>
<% if Danbooru.config.forum_enabled?.to_s.truthy? %>
<tr>
<th>Forum Posts</th>
<td><%= presenter.forum_post_count(self) %></td>
</tr>
<% end %>
<tr>
<th>Approvals</th>
<td><%= presenter.approval_count(self) %></td>
</tr>
<% if Danbooru.config.comments_enabled?.to_s.truthy? %>
<tr>
<th>Comments</th>
<td><%= presenter.comment_count(self) %> in <%= presenter.commented_posts_count(self) %> posts</td>
</tr>
<% end %>
<tr>
<th>Appeals</th>
<td><%= presenter.appeal_count(self) %></td>
</tr>
<% if CurrentUser.user.id == user.id || CurrentUser.is_moderator? %>
<tr>
<th>Flags</th>
<td><%= presenter.flag_count(self) %></td>
</tr>
<% end %>
<tr>
<th>Feedback</th>
<td><%= presenter.feedbacks(self) %></td>
</tr>
<% if policy(ModerationReport).can_see_moderation_reports? %>
<tr>
<th>Mod Reports</th>
<td>
<%= link_to "received:#{ModerationReport.received_by(user).count}", moderation_reports_path(search: { recipient_name: user.name }) %>
<%= link_to "submitted:#{ModerationReport.where(creator: user).count}", moderation_reports_path(search: { creator_name: user.name }) %>
</td>
</tr>
<% end %>
<% if policy(UserNameChangeRequest.new(user: user)).show? %>
<% user.user_name_change_requests.visible(CurrentUser.user).tap do |changes| %>
<% if changes.present? %>
<tr>
<th>Previous Names</th>
<td>
<%= changes.map do |change| %>
<% link_to change.original_name, change %>
<% end.join(", ").html_safe %>
</td>
</tr>
<% end %>
<% end %>
<% end %>
<% if CurrentUser.id == user.id %>
<% if SavedSearch.labels_for(CurrentUser.user.id).present? %>
<tr>
<th>Saved Searches</th>
<td>
<% SavedSearch.labels_for(CurrentUser.user.id).each do |label| %>
<%= link_to label, posts_path(tags: "search:#{label}") %>
<% end %>
</td>
</tr>
<% end %>
<tr>
<th>API Key</th>
<td>
<%= link_to "View", user_api_keys_path(CurrentUser.user) %>
(<%= link_to_wiki "help", "help:api" %>)
</td>
</tr>
<% end %>
</tbody>
</table>
</div>