123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263 |
- get '/site_files/new_page' do
- require_login
- @title = 'New Page'
- erb :'site_files/new_page'
- end
- # Redirect from original path
- get '/site_files/new' do
- require_login
- redirect '/site_files/new_page'
- end
- post '/site_files/create' do
- require_login
- @errors = []
- filename = params[:filename]
- filename.gsub!(/[^a-zA-Z0-9_\-.]/, '')
- redirect_uri = '/dashboard'
- redirect_uri += "?dir=#{Rack::Utils.escape params[:dir]}" if params[:dir]
- if filename.nil? || filename.strip.empty?
- flash[:error] = 'You must provide a file name.'
- redirect redirect_uri
- end
- name = "#{filename}"
- name = "#{params[:dir]}/#{name}" if params[:dir]
- name = current_site.scrubbed_path name
- if current_site.file_exists?(name)
- flash[:error] = %{Web page "#{Rack::Utils.escape_html name}" already exists! Choose another name.}
- redirect redirect_uri
- end
- extname = File.extname name
- unless extname.match /^\.#{Site::EDITABLE_FILE_EXT}/i
- flash[:error] = "Must be an text editable file type (#{Site::VALID_EDITABLE_EXTENSIONS.join(', ')})."
- redirect redirect_uri
- end
- site_file = current_site.site_files_dataset.where(path: name).first
- if site_file
- flash[:error] = 'File already exists, cannot create.'
- redirect redirect_uri
- end
- if extname.match(/^\.html|^\.htm/i)
- current_site.install_new_html_file name
- else
- file_path = current_site.files_path(name)
- FileUtils.touch file_path
- File.chmod 0640, file_path
- site_file ||= SiteFile.new site_id: current_site.id, path: name
- site_file.size = 0
- site_file.set size: 0
- site_file.set sha1_hash: Digest::SHA1.hexdigest('')
- site_file.set updated_at: Time.now
- site_file.save
- end
- escaped_name = Rack::Utils.escape_html name
- flash[:success] = %{#{escaped_name} was created! <a style="color: #FFFFFF; text-decoration: underline" href="/site_files/text_editor/#{escaped_name}">Click here to edit it</a>.}
- redirect redirect_uri
- end
- def file_upload_response(error=nil)
- if error
- flash[:error] = error
- end
- if params[:from_button]
- query_string = params[:dir] ? "?"+Rack::Utils.build_query(dir: params[:dir]) : ''
- redirect "/dashboard#{query_string}"
- else
- halt 406, error if error
- halt 200, 'File(s) successfully uploaded.'
- end
- end
- def require_login_file_upload_ajax
- file_upload_response 'You are not signed in!' unless signed_in?
- end
- post '/site_files/delete' do
- require_login
- path = HTMLEntities.new.decode params[:filename]
- current_site.delete_file path
- flash[:success] = "Deleted #{Rack::Utils.escape_html params[:filename]}."
- dirname = Pathname(path).dirname
- dir_query = dirname.nil? || dirname.to_s == '.' ? '' : "?dir=#{Rack::Utils.escape dirname}"
- redirect "/dashboard#{dir_query}"
- end
- post '/site_files/rename' do
- require_login
- path = HTMLEntities.new.decode params[:path]
- new_path = HTMLEntities.new.decode params[:new_path]
- site_file = current_site.site_files.select {|s| s.path == path}.first
- escaped_path = Rack::Utils.escape_html path
- escaped_new_path = Rack::Utils.escape_html new_path
- if site_file.nil?
- flash[:error] = "File #{escaped_path} does not exist."
- else
- 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
- dir_query = dirname.nil? || dirname.to_s == '.' ? '' : "?dir=#{Rack::Utils.escape dirname}"
- redirect "/dashboard#{dir_query}"
- end
- get '/site_files/download' do
- require_login
- 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
- content_type 'application/zip'
- attachment "neocities-#{current_site.username}.zip"
- 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
- require_login
- dont_browser_cache
- not_found if params[:captures].nil? || params[:captures].length != 1
- filename = params[:captures].first
- attachment filename
- send_file current_site.current_files_path(filename)
- end
- get %r{\/site_files\/text_editor\/(.+)} do
- require_login
- 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'
- when /md/ then 'markdown'
- when /css/ then 'css'
- else
- nil
- end
- file_path = current_site.current_files_path @filename
- if File.directory? file_path
- flash[:error] = 'Cannot edit a directory.'
- redirect '/dashboard'
- end
- if !File.exist?(file_path)
- flash[:error] = 'We could not find the requested file.'
- redirect '/dashboard'
- end
- @title = "Editing #{@filename}"
- erb :'site_files/text_editor'
- end
- get '/site_files/allowed_types' do
- @title = 'Allowed File Types'
- erb :'site_files/allowed_types'
- end
- get '/site_files/hotlinking' do
- @title = 'Hotlinking Information'
- erb :'site_files/hotlinking'
- end
- 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
|