fa user and post controller cleanup
This commit is contained in:
5
Gemfile
5
Gemfile
@@ -62,6 +62,7 @@ group :development do
|
||||
# Use console on exceptions pages [https://github.com/rails/web-console]
|
||||
gem "web-console"
|
||||
gem "htmlbeautifier"
|
||||
gem "rails_live_reload"
|
||||
|
||||
# Speed up commands on slow machines / big apps [https://github.com/rails/spring]
|
||||
# gem "spring"
|
||||
@@ -107,6 +108,8 @@ gem "concurrent-ruby-ext", require: "concurrent"
|
||||
gem "concurrent-ruby-edge", require: "concurrent-edge"
|
||||
gem "pluck_each"
|
||||
gem "good_job"
|
||||
gem "zstd-ruby"
|
||||
gem "rszr"
|
||||
|
||||
gem "pg_query", ">= 2"
|
||||
gem "pghero", git: "https://github.com/dymk/pghero", ref: "e314f99"
|
||||
@@ -124,8 +127,6 @@ group :production do
|
||||
gem "sd_notify"
|
||||
end
|
||||
|
||||
# gem "pg_party"
|
||||
|
||||
gem "tailwindcss-rails", "~> 2.0"
|
||||
|
||||
gem "shakapacker"
|
||||
|
||||
16
Gemfile.lock
16
Gemfile.lock
@@ -174,6 +174,9 @@ GEM
|
||||
kaminari-core (1.2.2)
|
||||
libmf (0.3.0)
|
||||
ffi
|
||||
listen (3.8.0)
|
||||
rb-fsevent (~> 0.10, >= 0.10.3)
|
||||
rb-inotify (~> 0.9, >= 0.9.10)
|
||||
loofah (2.19.1)
|
||||
crass (~> 1.0.2)
|
||||
nokogiri (>= 1.5.9)
|
||||
@@ -252,6 +255,11 @@ GEM
|
||||
nokogiri (>= 1.6)
|
||||
rails-html-sanitizer (1.5.0)
|
||||
loofah (~> 2.19, >= 2.19.1)
|
||||
rails_live_reload (0.3.4)
|
||||
listen
|
||||
nio4r
|
||||
railties
|
||||
websocket-driver
|
||||
rails_semantic_logger (4.12.0)
|
||||
rack
|
||||
railties (>= 5.1)
|
||||
@@ -265,6 +273,9 @@ GEM
|
||||
zeitwerk (~> 2.5)
|
||||
rainbow (3.1.1)
|
||||
rake (13.0.6)
|
||||
rb-fsevent (0.11.2)
|
||||
rb-inotify (0.10.1)
|
||||
ffi (~> 1.0)
|
||||
react_on_rails (13.3.3)
|
||||
addressable
|
||||
connection_pool
|
||||
@@ -294,6 +305,7 @@ GEM
|
||||
rspec-mocks (~> 3.11)
|
||||
rspec-support (~> 3.11)
|
||||
rspec-support (3.12.0)
|
||||
rszr (1.3.0)
|
||||
ruby-prof (1.4.5)
|
||||
ruby-prof-speedscope (0.3.0)
|
||||
ruby-prof (~> 1.0)
|
||||
@@ -355,6 +367,7 @@ GEM
|
||||
xpath (3.2.0)
|
||||
nokogiri (~> 1.8)
|
||||
zeitwerk (2.6.6)
|
||||
zstd-ruby (1.5.5.0)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
@@ -393,11 +406,13 @@ DEPENDENCIES
|
||||
rack-cors
|
||||
rack-mini-profiler
|
||||
rails (~> 7.0.4, >= 7.0.4.2)
|
||||
rails_live_reload
|
||||
rails_semantic_logger
|
||||
rb-bsdiff!
|
||||
react_on_rails
|
||||
ripcord
|
||||
rspec-rails
|
||||
rszr
|
||||
ruby-prof
|
||||
ruby-prof-speedscope
|
||||
rufo
|
||||
@@ -415,6 +430,7 @@ DEPENDENCIES
|
||||
web-console
|
||||
webdrivers
|
||||
xdiff!
|
||||
zstd-ruby
|
||||
|
||||
RUBY VERSION
|
||||
ruby 3.2.0p0
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# Procfile for development using HMR
|
||||
# You can run these commands in separate shells
|
||||
rails: bundle exec rails s -p 3000
|
||||
tailwind: bundle exec rake tailwindcss:watch
|
||||
wp-client: HMR=true bin/webpacker-dev-server
|
||||
wp-server: HMR=true SERVER_BUNDLE_ONLY=yes bin/webpacker --watch
|
||||
wp-server: HMR=true SERVER_BUNDLE_ONLY=yes bin/webpacker --watch
|
||||
10
Rakefile
10
Rakefile
@@ -77,16 +77,18 @@ end
|
||||
namespace :db_sampler do
|
||||
task :export => :environment do
|
||||
url_names = ENV["url_names"] || raise("need 'url_names' (comma-separated)")
|
||||
outfile_path = ENV["outfile"] || raise("need 'outfile' (file path)")
|
||||
outfile = File.open(outfile_path, "wb")
|
||||
# outfile_path = ENV["outfile"] || raise("need 'outfile' (file path)")
|
||||
# outfile = File.open(outfile_path, "wb")
|
||||
outfile = $stdout
|
||||
DbSampler.new(outfile).export(url_names.split(","))
|
||||
ensure
|
||||
outfile.close if outfile
|
||||
end
|
||||
|
||||
task :import => [:environment] do
|
||||
infile_path = ENV["infile"] || raise("need 'infile' (file path)")
|
||||
infile = File.open(infile_path, "rb")
|
||||
# infile_path = ENV["infile"] || raise("need 'infile' (file path)")
|
||||
# infile = File.open(infile_path, "rb")
|
||||
infile = $stdin
|
||||
DbSampler.new(infile).import
|
||||
ensure
|
||||
infile.close if infile
|
||||
|
||||
3
app/assets/images/arrow-top-right-on-square.svg
Normal file
3
app/assets/images/arrow-top-right-on-square.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M13.5 6H5.25A2.25 2.25 0 003 8.25v10.5A2.25 2.25 0 005.25 21h10.5A2.25 2.25 0 0018 18.75V10.5m-10.5 6L21 3m0 0h-5.25M21 3v5.25" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 326 B |
6
app/controllers/blobs_controller.rb
Normal file
6
app/controllers/blobs_controller.rb
Normal file
@@ -0,0 +1,6 @@
|
||||
class BlobsController
|
||||
def show
|
||||
sha256 = HexUtil.hex2bin(params[:sha256])
|
||||
@blob = BlobEntryP.ensure(sha256: sha256)
|
||||
end
|
||||
end
|
||||
@@ -7,7 +7,11 @@ class Domain::Fa::PostsController < ApplicationController
|
||||
|
||||
# GET /domain/fa/posts
|
||||
def index
|
||||
@posts = Domain::Fa::Post.
|
||||
if params[:user_url_name]
|
||||
@user = Domain::Fa::User.find_by(url_name: params[:user_url_name]) || raise("404")
|
||||
end
|
||||
relation = @user ? @user.posts : Domain::Fa::Post
|
||||
@posts = relation.
|
||||
includes(:creator, :file).
|
||||
page(params[:page]).
|
||||
per(50).
|
||||
|
||||
@@ -1,71 +1,19 @@
|
||||
class Domain::Fa::UsersController < ApplicationController
|
||||
before_action :set_domain_fa_user, only: %i[ show edit update destroy ]
|
||||
before_action :set_user, only: %i[ show ]
|
||||
|
||||
# GET /domain/fa/users or /domain/fa/users.json
|
||||
def index
|
||||
@domain_fa_users = Domain::Fa::User.page(params[:page])
|
||||
@users = Domain::Fa::User.includes({ avatar: [:file] }).page(params[:page])
|
||||
end
|
||||
|
||||
# GET /domain/fa/users/1 or /domain/fa/users/1.json
|
||||
def show
|
||||
end
|
||||
|
||||
# GET /domain/fa/users/new
|
||||
def new
|
||||
@domain_fa_user = Domain::Fa::User.new
|
||||
end
|
||||
|
||||
# GET /domain/fa/users/1/edit
|
||||
def edit
|
||||
end
|
||||
|
||||
# POST /domain/fa/users or /domain/fa/users.json
|
||||
def create
|
||||
@domain_fa_user = Domain::Fa::User.new(domain_fa_user_params)
|
||||
|
||||
respond_to do |format|
|
||||
if @domain_fa_user.save
|
||||
format.html { redirect_to domain_fa_user_url(@domain_fa_user), notice: "User was successfully created." }
|
||||
format.json { render :show, status: :created, location: @domain_fa_user }
|
||||
else
|
||||
format.html { render :new, status: :unprocessable_entity }
|
||||
format.json { render json: @domain_fa_user.errors, status: :unprocessable_entity }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# PATCH/PUT /domain/fa/users/1 or /domain/fa/users/1.json
|
||||
def update
|
||||
respond_to do |format|
|
||||
if @domain_fa_user.update(domain_fa_user_params)
|
||||
format.html { redirect_to domain_fa_user_url(@domain_fa_user), notice: "User was successfully updated." }
|
||||
format.json { render :show, status: :ok, location: @domain_fa_user }
|
||||
else
|
||||
format.html { render :edit, status: :unprocessable_entity }
|
||||
format.json { render json: @domain_fa_user.errors, status: :unprocessable_entity }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# DELETE /domain/fa/users/1 or /domain/fa/users/1.json
|
||||
def destroy
|
||||
@domain_fa_user.destroy
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to domain_fa_users_url, notice: "User was successfully destroyed." }
|
||||
format.json { head :no_content }
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Use callbacks to share common setup or constraints between actions.
|
||||
def set_domain_fa_user
|
||||
@domain_fa_user = Domain::Fa::User.find(params[:id])
|
||||
end
|
||||
|
||||
# Only allow a list of trusted parameters through.
|
||||
def domain_fa_user_params
|
||||
params.fetch(:domain_fa_user, {})
|
||||
def set_user
|
||||
@user = Domain::Fa::User.find_by(url_name: params[:url_name])
|
||||
end
|
||||
end
|
||||
|
||||
@@ -83,20 +83,42 @@ class LogEntriesController < ApplicationController
|
||||
expires_dur = 1.year
|
||||
response.headers["Expires"] = expires_dur.from_now.httpdate
|
||||
expires_in expires_dur, public: true
|
||||
thumb = params[:thumb]
|
||||
raise("invalid thumb #{thumb}") if !thumb.blank? && !thumb_params(thumb)
|
||||
|
||||
log_entry = HttpLogEntry.find(params[:id])
|
||||
hex_sha256 = HexUtil.bin2hex(log_entry.response_sha256)
|
||||
return unless stale?(last_modified: Time.at(0), strong_etag: hex_sha256)
|
||||
etag = HexUtil.bin2hex(log_entry.response_sha256)
|
||||
etag += "-#{thumb}" if thumb
|
||||
return unless stale?(last_modified: Time.at(0), strong_etag: etag)
|
||||
|
||||
# images, videos, etc
|
||||
entry_response = log_entry.response
|
||||
if helpers.is_send_data_content_type?(entry_response.content_type)
|
||||
send_data(
|
||||
entry_response.contents,
|
||||
type: entry_response.content_type,
|
||||
disposition: "inline",
|
||||
filename: log_entry.uri.path,
|
||||
)
|
||||
if !thumb.blank? && helpers.is_thumbable_content_type?(entry_response.content_type)
|
||||
filename = "thumb-#{thumb}-#{log_entry.uri.path}"
|
||||
filename = filename[..File.extname(filename).length]
|
||||
filename += ".jpeg"
|
||||
file = Tempfile.new("thumb.jpeg", binmode: true)
|
||||
file.write(entry_response.contents)
|
||||
|
||||
image = Rszr::Image.load(file.path)
|
||||
image.resize!(*thumb_params(thumb))
|
||||
resized_image_contents = image.save_data(format: :jpeg)
|
||||
|
||||
send_data(
|
||||
resized_image_contents,
|
||||
type: "image/jpeg",
|
||||
disposition: "inline",
|
||||
filename: filename,
|
||||
)
|
||||
else
|
||||
send_data(
|
||||
entry_response.contents,
|
||||
type: entry_response.content_type,
|
||||
disposition: "inline",
|
||||
filename: log_entry.uri.path,
|
||||
)
|
||||
end
|
||||
elsif entry_response.content_type =~ /text\/plain/
|
||||
render plain: entry_response.contents
|
||||
elsif entry_response.content_type.starts_with? "text/html"
|
||||
@@ -108,4 +130,15 @@ class LogEntriesController < ApplicationController
|
||||
render plain: "no renderer for #{entry_response.content_type}"
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def thumb_params(thumb)
|
||||
case thumb
|
||||
when "small"
|
||||
[400, 300]
|
||||
when "medium"
|
||||
[800, 600]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -14,6 +14,10 @@ module LogEntriesHelper
|
||||
].any? { |ct| content_type.starts_with?(ct) }
|
||||
end
|
||||
|
||||
def is_thumbable_content_type?(content_type)
|
||||
is_renderable_image_type?(content_type)
|
||||
end
|
||||
|
||||
def is_renderable_video_type?(content_type)
|
||||
[
|
||||
"video/mp4",
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
class DbSampler
|
||||
include HasColorLogger
|
||||
include HasMeasureDuration
|
||||
|
||||
SCHEMA = {
|
||||
::Domain::Fa::User => [
|
||||
:avatar,
|
||||
@@ -41,22 +38,27 @@ class DbSampler
|
||||
end
|
||||
|
||||
def import
|
||||
puts "reading file..."
|
||||
$stderr.puts "reading file..."
|
||||
deferred = []
|
||||
while (line = @file.gets)
|
||||
line.chomp!
|
||||
model = Marshal.load(Base64.strict_decode64(line))
|
||||
model = Marshal.load(Zstd.decompress(Base64.strict_decode64(line)))
|
||||
|
||||
begin
|
||||
import_model(model)
|
||||
rescue ActiveRecord::InvalidForeignKey
|
||||
puts("defer #{model_id(model)}")
|
||||
deferred.push(model)
|
||||
ReduxApplicationRecord.transaction do
|
||||
begin
|
||||
import_model(model)
|
||||
rescue ActiveRecord::InvalidForeignKey
|
||||
$stderr.puts("defer #{model_id(model)}")
|
||||
deferred.push(model)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
deferred.each do |model|
|
||||
import_model(model)
|
||||
ReduxApplicationRecord.transaction do
|
||||
deferred.each do |model|
|
||||
import_model(model)
|
||||
rescue
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -77,14 +79,14 @@ class DbSampler
|
||||
exists = model.class.exists?(pk => id)
|
||||
|
||||
if exists
|
||||
puts("skipped existing #{model_id(model)}")
|
||||
$stderr.puts("skipped existing #{model_id(model)}")
|
||||
else
|
||||
model2 = model.class.new
|
||||
model.attribute_names.map(&:to_sym).each do |attr|
|
||||
model2.write_attribute(attr, model.read_attribute(attr))
|
||||
end
|
||||
model2.save(validate: false)
|
||||
puts("imported #{model_id(model)}")
|
||||
$stderr.puts("imported #{model_id(model)}")
|
||||
end
|
||||
end
|
||||
|
||||
@@ -94,18 +96,20 @@ class DbSampler
|
||||
user_depth += 1 if is_user
|
||||
return unless @handled.add?(model)
|
||||
|
||||
unless user_depth > 1 && is_user
|
||||
assocs = SCHEMA[model.class] || raise("invalid: #{model.class.name}")
|
||||
assocs.each do |assoc|
|
||||
model2 = model.send(assoc)
|
||||
next unless model2
|
||||
if model2.respond_to? :each
|
||||
model2.each do |model3|
|
||||
handle_model(model3, level + 1, user_depth)
|
||||
end
|
||||
else
|
||||
handle_model(model2, level + 1, user_depth)
|
||||
assocs = SCHEMA[model.class] || raise("invalid: #{model.class.name}")
|
||||
assocs.each do |assoc|
|
||||
if user_depth > 1
|
||||
next unless [:avatar, :disco].include?(assoc)
|
||||
end
|
||||
|
||||
model2 = model.send(assoc)
|
||||
next unless model2
|
||||
if model2.respond_to? :each
|
||||
model2.each do |model3|
|
||||
handle_model(model3, level + 1, user_depth)
|
||||
end
|
||||
else
|
||||
handle_model(model2, level + 1, user_depth)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -113,9 +117,9 @@ class DbSampler
|
||||
end
|
||||
|
||||
def dump(model, level)
|
||||
@file.puts(Base64.strict_encode64(Marshal.dump(model)))
|
||||
@file.puts(Base64.strict_encode64(Zstd.compress(Marshal.dump(model), 1)))
|
||||
id = model.send(model.class.primary_key)
|
||||
id = HexUtil.bin2hex(id) if model.class.primary_key == "sha256"
|
||||
puts ("-" * level) + " dumped #{model.class.name}/#{id}"
|
||||
$stderr.puts ("-" * level) + " dumped #{model.class.name}/#{id}"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -219,6 +219,10 @@ class Domain::Fa::User < ReduxApplicationRecord
|
||||
# TODO - maybe can look for posts as well, those might list an avatar
|
||||
end
|
||||
|
||||
def to_param
|
||||
url_name
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def similar_users_by(factor_col, exclude_followed_by)
|
||||
|
||||
@@ -1,38 +1,16 @@
|
||||
<% content_for :head do %>
|
||||
<style type="text/css" data-turbolinks-track>
|
||||
title {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
table td {
|
||||
border-right: 1px solid black;
|
||||
padding: 0 0.5em;
|
||||
}
|
||||
table td:last-child {
|
||||
border-right: none;
|
||||
}
|
||||
td.right {
|
||||
text-align: right;
|
||||
}
|
||||
</style>
|
||||
<% end %>
|
||||
<h1>FurAffinity Posts <%= page_str(params) %></h1>
|
||||
<div id="domain_fa_posts">
|
||||
<%= link_to "Previous page", path_to_prev_page(@posts) %>
|
||||
<%= link_to "Next page", path_to_next_page(@posts) %>
|
||||
<table>
|
||||
<tr>
|
||||
<th>Seen</th>
|
||||
<th>Scanned</th>
|
||||
<th>File</th>
|
||||
<th>State</th>
|
||||
<th>ID</th>
|
||||
<th>Title</th>
|
||||
<th>Creator</th>
|
||||
</tr>
|
||||
<% @posts.each do |post| %>
|
||||
<%= render partial: "index_row", locals: { post: post } %>
|
||||
<% end %>
|
||||
</table>
|
||||
<%= link_to "Previous page", path_to_prev_page(@posts) %>
|
||||
<%= link_to "Next page", path_to_next_page(@posts) %>
|
||||
<div class='mx-auto'>
|
||||
<% if @user %>
|
||||
<h1 class='text-2xl'><%= link_to(@user.name, @user, class: "underline") %>'s posts</h1>
|
||||
<% else %>
|
||||
<h1 class='text-2xl'>All FurAffinity posts, page <%= page_str(params) %></h1>
|
||||
<% end %>
|
||||
</div>
|
||||
<% # link_to "Previous page", path_to_prev_page(@posts) %>
|
||||
<% # link_to "Next page", path_to_next_page(@posts) %>
|
||||
<div class='flex-row'>
|
||||
<% @posts.each do |post| %>
|
||||
<div class=''>
|
||||
<img class='' alt='<%= post.title %>' src='<%= contents_log_entry_path(post.file, thumb: "small") %>' />
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
@@ -1,14 +1,53 @@
|
||||
<p style="color: green"><%= notice %></p>
|
||||
|
||||
<h1>Users</h1>
|
||||
|
||||
<div id="domain_fa_users">
|
||||
<% @domain_fa_users.each do |domain_fa_user| %>
|
||||
<%= render domain_fa_user %>
|
||||
<p>
|
||||
<%= link_to "Show this user", domain_fa_user %>
|
||||
</p>
|
||||
<section class='w-full'>
|
||||
<h1>Users</h1>
|
||||
<% @users.each do |user| %>
|
||||
<div class='mx-auto max-w-xl bg-slate-200 border-slate-300 border-2 my-2 p-2 rounded flex flex-row'>
|
||||
<% if (a = user.avatar&.log_entry) %>
|
||||
<img class='rounded-sm' alt='<%= user.name %> avatar' src='<%= contents_log_entry_path(a) %>' />
|
||||
<% else %>
|
||||
<div>(No avatar)</div>
|
||||
<% end %>
|
||||
<div class='flex-grow ml-2 flex-col'>
|
||||
<div class='flex-row'>
|
||||
<a
|
||||
class='
|
||||
text-lg text-black font-semibold
|
||||
underline decoration-dotted hover:decoration-solid'
|
||||
href='<%= domain_fa_user_path(user) %>'><%= user.name %></a>
|
||||
<a
|
||||
class='
|
||||
m-l-2 text-md text-slate-600
|
||||
underline decoration-dotted hover:decoration-solid'
|
||||
href="<%= domain_fa_user_posts_path(user) %>"
|
||||
>
|
||||
<%= pluralize(user.posts.count, "post") %>
|
||||
</a>
|
||||
</div>
|
||||
<p class='block text-md text-slate-600'>
|
||||
<% if user.scanned_page_at %>
|
||||
Scanned page <%= time_ago_in_words(user.scanned_page_at) %> ago
|
||||
<% else %>
|
||||
Not yet scanned page
|
||||
<% end %>
|
||||
</p>
|
||||
<p class='block text-md text-slate-600'>
|
||||
<% if user.scanned_gallery_at %>
|
||||
Scanned gallery <%= time_ago_in_words(user.scanned_gallery_at) %> ago
|
||||
<% else %>
|
||||
Not yet scanned gallery
|
||||
<% end %>
|
||||
</p>
|
||||
</div>
|
||||
<div class='flex'>
|
||||
<a class='
|
||||
self-start inline
|
||||
border-b text-slate-600 border-slate-600 border-dashed
|
||||
hover:border-black hover:text-black
|
||||
' target='_blank' rel='noopener noreferrer' href='https://www.furaffinity.net/user/<%= user.url_name %>'>
|
||||
FurAffinity
|
||||
<img class='w-4 h-4 align-text-top inline' src='<%= image_path("arrow-top-right-on-square.svg") %>'>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<%= link_to "New user", new_domain_fa_user_path %>
|
||||
</section>
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
<p style="color: green"><%= notice %></p>
|
||||
|
||||
<%= render @domain_fa_user %>
|
||||
|
||||
<%= render @user %>
|
||||
<div>
|
||||
<%= link_to "Edit this user", edit_domain_fa_user_path(@domain_fa_user) %> |
|
||||
<%= link_to "Edit this user", edit_domain_fa_user_path(@user) %> |
|
||||
<%= link_to "Back to users", domain_fa_users_path %>
|
||||
|
||||
<%= button_to "Destroy this user", @domain_fa_user, method: :delete %>
|
||||
<%= button_to "Destroy this user", @user, method: :delete %>
|
||||
</div>
|
||||
|
||||
@@ -30,7 +30,9 @@ Rails.application.routes.draw do
|
||||
|
||||
namespace :domain do
|
||||
namespace :fa do
|
||||
resources :users
|
||||
resources :users, param: :url_name do
|
||||
resources :posts, controller: "/domain/fa/posts"
|
||||
end
|
||||
resources :posts, param: :fa_id, only: [:index, :show] do
|
||||
post :scan_post, on: :member
|
||||
end
|
||||
@@ -39,6 +41,8 @@ Rails.application.routes.draw do
|
||||
|
||||
# Defines the root path route ("/")
|
||||
# root "articles#index"
|
||||
resources :blobs, only: [:show], slug: :sha256
|
||||
|
||||
resources :log_entries, only: [:index, :show] do
|
||||
get :contents, on: :member
|
||||
get :stats, on: :collection
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
const defaultTheme = require("tailwindcss/defaultTheme");
|
||||
|
||||
module.exports = {
|
||||
mode: "jit",
|
||||
content: [
|
||||
"./public/*.html",
|
||||
"./app/helpers/**/*.rb",
|
||||
|
||||
Reference in New Issue
Block a user