Class: NeocitiesRed::Client
- Inherits:
-
Object
- Object
- NeocitiesRed::Client
- Defined in:
- lib/neocities_red/client.rb
Overview
HTTP client for the Neocities API.
Wraps all API interactions — listing, uploading, deleting, and querying site information. Supports both API-key (Bearer) and basic-auth (sitename/password) authentication.
Retries transient failures (429, 5xx) automatically via Faraday::Retry.
Constant Summary collapse
- API_URI =
Returns Base URL for the Neocities REST API.
"https://neocities.org/api/"
Instance Method Summary collapse
-
#delete(*paths) ⇒ Hash
Deletes one or more files from the remote Neocities site.
-
#delete_wrapper_with_dry_run(paths, dry_run: false) ⇒ Hash
Deletes one or more remote files, with optional dry-run support.
-
#download(url) ⇒ Faraday::Response
Downloads a file from a URL.
-
#get(path, params = {}) ⇒ Hash
Performs an HTTP GET request to the Neocities API.
-
#info(sitename) ⇒ Hash
Retrieves information and statistics for a Neocities site.
-
#initialize(opts = {}) ⇒ Client
constructor
Creates a new API client.
-
#key ⇒ Hash
Retrieves the API key for the currently authenticated user.
-
#list(path = nil) ⇒ Hash
Lists files on the remote Neocities site.
-
#post(path, args = {}) ⇒ Hash
Performs an HTTP POST request to the Neocities API.
-
#upload(path, remote_path = nil, dry_run: false) ⇒ Hash
Uploads a single file to the Neocities site.
-
#upload_hash(remote_path, sha1_hash) ⇒ Hash
Checks whether the remote file matches the given SHA1 hash.
Constructor Details
#initialize(opts = {}) ⇒ Client
Creates a new API client.
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/neocities_red/client.rb', line 48 def initialize(opts = {}) @uri = URI.parse API_URI @opts = opts @conn = Faraday.new(@uri) do |conn| conn..timeout = 30 conn..open_timeout = 10 conn.adapter :net_http conn.request :multipart conn.request :url_encoded conn.request :retry, max: 3, interval: 0.3, backoff_factor: 2, retry_statuses: [429, 500, 502, 503, 504], exceptions: [ Faraday::TimeoutError, Faraday::ConnectionFailed, Faraday::SSLError ] conn.response :follow_redirects end raise ArgumentError, "client requires a login (sitename/password) or an api_key" unless opts[:api_key] || (opts[:sitename] && opts[:password]) if opts[:api_key] @conn.request(:authorization, "Bearer", opts[:api_key]) else @conn.request(:authorization, :basic, opts[:sitename], opts[:password]) end end |
Instance Method Details
#delete(*paths) ⇒ Hash
Deletes one or more files from the remote Neocities site.
160 161 162 |
# File 'lib/neocities_red/client.rb', line 160 def delete(*paths) post "delete", "filenames" => paths end |
#delete_wrapper_with_dry_run(paths, dry_run: false) ⇒ Hash
Deletes one or more remote files, with optional dry-run support.
150 151 152 153 154 |
# File 'lib/neocities_red/client.rb', line 150 def delete_wrapper_with_dry_run(paths, dry_run: false) return { result: "success" } if dry_run delete(paths) end |
#download(url) ⇒ Faraday::Response
Downloads a file from a URL.
191 192 193 |
# File 'lib/neocities_red/client.rb', line 191 def download(url) @conn.get(url) end |
#get(path, params = {}) ⇒ Hash
Performs an HTTP GET request to the Neocities API.
179 180 181 182 183 184 185 |
# File 'lib/neocities_red/client.rb', line 179 def get(path, params = {}) uri = @uri + path uri.query = URI.encode_www_form params resp = @conn.get(uri) JSON.parse resp.body, symbolize_names: true end |
#info(sitename) ⇒ Hash
Retrieves information and statistics for a Neocities site.
170 171 172 |
# File 'lib/neocities_red/client.rb', line 170 def info(sitename) get "info", sitename: sitename end |
#key ⇒ Hash
Retrieves the API key for the currently authenticated user.
Only meaningful when authenticated via basic-auth (sitename/password).
95 96 97 |
# File 'lib/neocities_red/client.rb', line 95 def key get "key" end |
#list(path = nil) ⇒ Hash
Lists files on the remote Neocities site.
86 87 88 |
# File 'lib/neocities_red/client.rb', line 86 def list(path = nil) get "list", path: path end |
#post(path, args = {}) ⇒ Hash
Performs an HTTP POST request to the Neocities API.
200 201 202 203 204 205 |
# File 'lib/neocities_red/client.rb', line 200 def post(path, args = {}) uri = @uri + path resp = @conn.post(uri, args) JSON.parse resp.body, symbolize_names: true end |
#upload(path, remote_path = nil, dry_run: false) ⇒ Hash
Uploads a single file to the Neocities site.
Computes the SHA1 hash of the local file and compares it with the remote version. If the file already exists remotely with the same hash, the upload is skipped and an "exists" response is returned.
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/neocities_red/client.rb', line 121 def upload(path, remote_path = nil, dry_run: false) path = Pathname path raise ArgumentError, "#{path} does not exist." unless path.exist? rpath = remote_path || path.basename res = upload_hash(rpath.to_s, Digest::SHA1.file(path.to_s).hexdigest) file_exists_remotely = res[:files] ? res[:files][rpath.to_s.to_sym] == true : false if file_exists_remotely { result: "error", error_type: "file_exists", message: "file already exists and matches local file, not uploading" } else return { result: "success" } if dry_run File.open(path.to_s) do |file| post "upload", rpath.to_s => Faraday::Multipart::FilePart.new(file, "text/html") end end end |
#upload_hash(remote_path, sha1_hash) ⇒ Hash
Checks whether the remote file matches the given SHA1 hash.
Used by #upload to skip uploading files that haven't changed.
106 107 108 |
# File 'lib/neocities_red/client.rb', line 106 def upload_hash(remote_path, sha1_hash) post "upload_hash", remote_path => sha1_hash end |