Merge branch 'master' into patch-2

This commit is contained in:
Kyle Drake 2025-04-22 21:59:57 -05:00 committed by GitHub
commit 739a797a2e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
1286 changed files with 713001 additions and 5263 deletions

View file

@ -14,7 +14,7 @@ post '/site_files/create' do
require_login
@errors = []
filename = params[:pagefilename] || params[:filename]
filename = params[:filename]
filename.gsub!(/[^a-zA-Z0-9_\-.]/, '')
@ -39,7 +39,7 @@ post '/site_files/create' do
extname = File.extname name
unless extname.match /^\.#{Site::EDITABLE_FILE_EXT}/i
unless extname.empty? || extname.match(/^\.#{Site::EDITABLE_FILE_EXT}/i)
flash[:error] = "Must be an editable text file type (#{Site::VALID_EDITABLE_EXTENSIONS.join(', ')})."
redirect redirect_uri
end
@ -52,7 +52,10 @@ post '/site_files/create' do
end
if extname.match(/^\.html|^\.htm/i)
current_site.install_new_html_file name
begin
current_site.install_new_html_file name
rescue Sequel::UniqueConstraintViolation
end
else
file_path = current_site.files_path(name)
FileUtils.touch file_path
@ -75,7 +78,9 @@ post '/site_files/create' do
end
def file_upload_response(error=nil)
flash[:error] = error if error
if error
flash[:error] = error
end
if params[:from_button]
query_string = params[:dir] ? "?"+Rack::Utils.build_query(dir: params[:dir]) : ''
@ -88,75 +93,16 @@ end
def require_login_file_upload_ajax
file_upload_response 'You are not signed in!' unless signed_in?
file_upload_response 'Please contact support.' if banned?
end
post '/site_files/upload' do
if params[:filename]
require_login_file_upload_ajax
tempfile = Tempfile.new 'neocities_saving_file'
input = request.body.read
tempfile.set_encoding input.encoding
tempfile.write input
tempfile.close
params[:files] = [{filename: params[:filename], tempfile: tempfile}]
else
require_login
end
@errors = []
if params[:files].nil?
file_upload_response "Uploaded files were not seen by the server, cancelled. We don't know what's causing this yet. Please contact us so we can help fix it. Thanks!"
end
# For migration from original design.. some pages out there won't have the site_id param yet for a while.
site = params[:site_id].nil? ? current_site : Site[params[:site_id]]
unless site.owned_by?(current_site)
file_upload_response 'You do not have permission to save this file. Did you sign in as a different user?'
end
params[:files].each_with_index do |file,i|
dir_name = ''
dir_name = params[:dir] if params[:dir]
unless params[:file_paths].nil? || params[:file_paths].empty? || params[:file_paths].length == 0
file_path = params[:file_paths][i]
unless file_path.nil?
dir_name += '/' + Pathname(file_path).dirname.to_s
end
end
file[:filename] = "#{dir_name}/#{site.scrubbed_path file[:filename]}"
if current_site.file_size_too_large? file[:tempfile].size
file_upload_response "#{Rack::Utils.escape_html file[:filename]} is too large, upload cancelled."
end
if !site.okay_to_upload? file
file_upload_response %{#{Rack::Utils.escape_html file[:filename]}: file type (or content in file) is only supported by <a href="/supporter">supporter accounts</a>. <a href="/site_files/allowed_types">Why We Do This</a>}
end
end
uploaded_size = params[:files].collect {|f| f[:tempfile].size}.inject{|sum,x| sum + x }
if site.file_size_too_large? uploaded_size
file_upload_response "File(s) do not fit in your available free space, upload cancelled."
end
if site.too_many_files? params[:files].length
file_upload_response "Your site has exceeded the maximum number of files, please delete some files first."
end
results = site.store_files params[:files]
file_upload_response
end
post '/site_files/delete' do
require_login
path = HTMLEntities.new.decode params[:filename]
current_site.delete_file path
begin
current_site.delete_file path
rescue Sequel::NoExistingObject
# the deed was presumably already done
end
flash[:success] = "Deleted #{Rack::Utils.escape_html params[:filename]}."
dirname = Pathname(path).dirname
@ -171,12 +117,19 @@ post '/site_files/rename' do
new_path = HTMLEntities.new.decode params[:new_path]
site_file = current_site.site_files.select {|s| s.path == path}.first
res = site_file.rename new_path
escaped_path = Rack::Utils.escape_html path
escaped_new_path = Rack::Utils.escape_html new_path
if res.first == true
flash[:success] = "Renamed #{Rack::Utils.escape_html path} to #{Rack::Utils.escape_html new_path}"
if site_file.nil?
flash[:error] = "File #{escaped_path} does not exist."
else
flash[:error] = "Failed to rename #{Rack::Utils.escape_html path} to #{Rack::Utils.escape_html new_path}: #{Rack::Utils.escape_html res.last}"
res = site_file.rename new_path
if res.first == true
flash[:success] = "Renamed #{escaped_path} to #{escaped_new_path}"
else
flash[:error] = "Failed to rename #{escaped_path} to #{escaped_new_path}: #{Rack::Utils.escape_html res.last}"
end
end
dirname = Pathname(path).dirname
@ -185,18 +138,36 @@ post '/site_files/rename' do
redirect "/dashboard#{dir_query}"
end
get '/site_files/:username.zip' do |username|
get '/site_files/download' do
require_login
if current_site.too_big_to_download?
flash[:error] = 'Cannot download site as zip as it is too large (or contains too many files)'
redirect '/dashboard'
if !current_site.dl_queued_at.nil? && current_site.dl_queued_at > 1.hour.ago
flash[:error] = 'Site downloads are currently limited to once per hour, please try again later.'
redirect request.referer
end
zipfile_path = current_site.files_zip
content_type 'application/octet-stream'
content_type 'application/zip'
attachment "neocities-#{current_site.username}.zip"
send_file zipfile_path
current_site.dl_queued_at = Time.now
current_site.save_changes validate: false
directory_path = current_site.files_path
stream do |out|
ZipTricks::Streamer.open(out) do |zip|
Dir["#{directory_path}/**/*"].each do |file|
next if File.directory?(file)
zip_path = file.sub("#{directory_path}/", '')
zip.write_stored_file(zip_path) do |file_writer|
File.open(file, 'rb') do |file|
IO.copy_stream(file, file_writer)
end
end
end
end
end
end
get %r{\/site_files\/download\/(.+)} do
@ -213,7 +184,16 @@ get %r{\/site_files\/text_editor\/(.+)} do
dont_browser_cache
@filename = params[:captures].first
redirect '/site_files/text_editor?filename=' + Rack::Utils.escape(@filename)
end
get '/site_files/text_editor' do
require_login
dont_browser_cache
@filename = params[:filename]
extname = File.extname @filename
@ace_mode = case extname
when /htm|html/ then 'html'
when /js/ then 'javascript'
@ -254,3 +234,37 @@ get '/site_files/mount_info' do
@title = 'Site Mount Information'
erb :'site_files/mount_info'
end
post '/site_files/chat' do
require_login
dont_browser_cache
headers 'X-Accel-Buffering' => 'no'
halt(403) unless parent_site.supporter?
# Ensure the request is treated as a stream
stream do |out|
url = 'https://api.anthropic.com/v1/messages'
headers = {
"anthropic-version" => "2023-06-01",
"anthropic-beta" => "messages-2023-12-15",
"content-type" => "application/json",
"x-api-key" => $config['anthropic_api_key']
}
body = {
model: "claude-3-haiku-20240307",
system: params[:system],
messages: JSON.parse(params[:messages]),
max_tokens: 4096,
temperature: 0.5,
stream: true
}.to_json
res = HTTP.headers(headers).post(url, body: body)
while(buffer = res.body.readpartial)
out << buffer
end
end
end