wikiwiki 0.5.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +36 -0
- data/README.ja.md +100 -3
- data/README.md +100 -3
- data/exe/wikiwiki +8 -0
- data/lib/wikiwiki/api.rb +42 -6
- data/lib/wikiwiki/auth/token.rb +23 -0
- data/lib/wikiwiki/auth.rb +6 -0
- data/lib/wikiwiki/cli/commands/attachment/delete.rb +34 -0
- data/lib/wikiwiki/cli/commands/attachment/get.rb +45 -0
- data/lib/wikiwiki/cli/commands/attachment/list.rb +37 -0
- data/lib/wikiwiki/cli/commands/attachment/put.rb +55 -0
- data/lib/wikiwiki/cli/commands/attachment/show.rb +44 -0
- data/lib/wikiwiki/cli/commands/auth.rb +32 -0
- data/lib/wikiwiki/cli/commands/base.rb +64 -0
- data/lib/wikiwiki/cli/commands/page/delete.rb +32 -0
- data/lib/wikiwiki/cli/commands/page/get.rb +46 -0
- data/lib/wikiwiki/cli/commands/page/list.rb +36 -0
- data/lib/wikiwiki/cli/commands/page/put.rb +44 -0
- data/lib/wikiwiki/cli/commands/page/show.rb +44 -0
- data/lib/wikiwiki/cli/formatter/json.rb +18 -0
- data/lib/wikiwiki/cli.rb +49 -0
- data/lib/wikiwiki/rate_limiter.rb +4 -12
- data/lib/wikiwiki/sliding_window.rb +1 -3
- data/lib/wikiwiki/version.rb +1 -1
- data/lib/wikiwiki/wiki.rb +22 -3
- data/lib/wikiwiki.rb +5 -1
- data/sig/dry/cli.rbs +9 -0
- data/sig/wikiwiki/api.rbs +5 -3
- data/sig/wikiwiki/auth/token.rbs +9 -0
- data/sig/wikiwiki/auth.rbs +2 -0
- data/sig/wikiwiki/cli/commands/attachment.rbs +87 -0
- data/sig/wikiwiki/cli/commands/auth.rbs +9 -0
- data/sig/wikiwiki/cli/commands/base.rbs +27 -0
- data/sig/wikiwiki/cli/commands/page.rbs +82 -0
- data/sig/wikiwiki/cli/formatter/json.rbs +9 -0
- data/sig/wikiwiki/cli.rbs +11 -0
- data/sig/wikiwiki/wiki.rbs +5 -1
- data/sig/wikiwiki.rbs +3 -0
- metadata +60 -8
- data/LICENSE.txt +0 -21
- data/mise.toml +0 -6
- data/rbs_collection.yaml +0 -12
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Wikiwiki
|
|
4
|
+
class CLI
|
|
5
|
+
module Commands
|
|
6
|
+
# Authenticate and output JWT token
|
|
7
|
+
class Auth < Base
|
|
8
|
+
desc "Authenticate and output JWT token"
|
|
9
|
+
|
|
10
|
+
option :json, aliases: ["-j"], type: :boolean, default: false, desc: "Output as JSON"
|
|
11
|
+
|
|
12
|
+
# Execute the auth command
|
|
13
|
+
#
|
|
14
|
+
# @param options [Hash] command options including wiki_id, auth credentials, json, verbose, out, err
|
|
15
|
+
# @return [void]
|
|
16
|
+
def call(out: $stdout, err: $stderr, **options)
|
|
17
|
+
wiki = create_wiki(out:, err:, **options)
|
|
18
|
+
token = wiki.token
|
|
19
|
+
|
|
20
|
+
if options[:json]
|
|
21
|
+
out.puts Formatter::JSON.new.format({"token" => token})
|
|
22
|
+
else
|
|
23
|
+
out.puts token
|
|
24
|
+
say("Authentication successful", out:, **options)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
register "auth", Auth
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Wikiwiki
|
|
4
|
+
class CLI
|
|
5
|
+
# CLI command implementations
|
|
6
|
+
#
|
|
7
|
+
# This module serves as a namespace for all CLI commands.
|
|
8
|
+
# Commands are organized into submodules (Page, Attachment) for better organization.
|
|
9
|
+
module Commands
|
|
10
|
+
# Base command class with global options
|
|
11
|
+
class Base < Dry::CLI::Command
|
|
12
|
+
option :wiki_id, aliases: ["-w"], desc: "Wiki ID (or set WIKIWIKI_WIKI_ID)"
|
|
13
|
+
option :token, desc: "JWT token for authentication (or set WIKIWIKI_TOKEN)"
|
|
14
|
+
option :api_key_id, desc: "API Key ID for authentication (or set WIKIWIKI_API_KEY_ID)"
|
|
15
|
+
option :secret, desc: "API Key Secret for authentication (or set WIKIWIKI_SECRET)"
|
|
16
|
+
option :password, desc: "Password for authentication (or set WIKIWIKI_PASSWORD)"
|
|
17
|
+
option :verbose, aliases: ["-v"], type: :boolean, default: false, desc: "Verbose output"
|
|
18
|
+
option :debug, type: :boolean, default: false, desc: "Debug mode"
|
|
19
|
+
|
|
20
|
+
private def create_wiki(wiki_id: nil, token: nil, api_key_id: nil, secret: nil, password: nil, debug: false, out: $stdout, err: $stderr, **)
|
|
21
|
+
# Fallback to environment variables if options are not provided
|
|
22
|
+
wiki_id ||= ENV.fetch("WIKIWIKI_WIKI_ID", nil)
|
|
23
|
+
token ||= ENV.fetch("WIKIWIKI_TOKEN", nil)
|
|
24
|
+
api_key_id ||= ENV.fetch("WIKIWIKI_API_KEY_ID", nil)
|
|
25
|
+
secret ||= ENV.fetch("WIKIWIKI_SECRET", nil)
|
|
26
|
+
password ||= ENV.fetch("WIKIWIKI_PASSWORD", nil)
|
|
27
|
+
|
|
28
|
+
raise ArgumentError, "Wiki ID must be provided via --wiki-id or WIKIWIKI_WIKI_ID" unless wiki_id
|
|
29
|
+
|
|
30
|
+
auth = if token
|
|
31
|
+
Wikiwiki::Auth.token(token:)
|
|
32
|
+
elsif api_key_id && secret
|
|
33
|
+
Wikiwiki::Auth.api_key(api_key_id:, secret:)
|
|
34
|
+
elsif password
|
|
35
|
+
Wikiwiki::Auth.password(password:)
|
|
36
|
+
else
|
|
37
|
+
raise ArgumentError, "Either --token, API key (--api-key-id and --secret), or --password must be provided (via options or environment variables)"
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
logger = create_logger(debug:, out:, err:)
|
|
41
|
+
Wiki.new(wiki_id:, auth:, logger:)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
private def create_logger(debug:, out: $stdout, err: $stderr)
|
|
45
|
+
if debug
|
|
46
|
+
Logger.new(err, level: Logger::DEBUG)
|
|
47
|
+
elsif out.tty?
|
|
48
|
+
Logger.new(err, level: Logger::WARN)
|
|
49
|
+
else
|
|
50
|
+
Logger.new(IO::NULL)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
private def verbose?(verbose:, json: false, **) = verbose && !json
|
|
55
|
+
|
|
56
|
+
private def say(message, verbose:, out: $stdout, **)
|
|
57
|
+
return unless verbose?(verbose:)
|
|
58
|
+
|
|
59
|
+
out.puts message
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Wikiwiki
|
|
4
|
+
class CLI
|
|
5
|
+
module Commands
|
|
6
|
+
module Page
|
|
7
|
+
# Delete a page
|
|
8
|
+
class Delete < Base
|
|
9
|
+
desc "Delete a page"
|
|
10
|
+
|
|
11
|
+
argument :page_name, required: true, desc: "Page name"
|
|
12
|
+
|
|
13
|
+
# Execute the delete command
|
|
14
|
+
#
|
|
15
|
+
# @param page_name [String] name of the page to delete
|
|
16
|
+
# @param out [IO] output stream
|
|
17
|
+
# @param err [IO] error stream
|
|
18
|
+
# @return [void]
|
|
19
|
+
def call(page_name:, out: $stdout, err: $stderr, **)
|
|
20
|
+
wiki = create_wiki(out:, err:, **)
|
|
21
|
+
|
|
22
|
+
wiki.delete_page(page_name:)
|
|
23
|
+
|
|
24
|
+
say("Page '#{page_name}' deleted successfully", out:, **)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
register "page delete", Page::Delete
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Wikiwiki
|
|
4
|
+
class CLI
|
|
5
|
+
module Commands
|
|
6
|
+
module Page
|
|
7
|
+
# Get page content
|
|
8
|
+
class Get < Base
|
|
9
|
+
desc "Get page content"
|
|
10
|
+
|
|
11
|
+
argument :page_name, required: true, desc: "Page name"
|
|
12
|
+
argument :output_file, required: false, desc: "Output file (stdout if omitted)"
|
|
13
|
+
option :force, aliases: ["-f"], type: :boolean, default: false, desc: "Overwrite existing file"
|
|
14
|
+
|
|
15
|
+
# Execute the get command
|
|
16
|
+
#
|
|
17
|
+
# @param page_name [String] name of the page to get
|
|
18
|
+
# @param output_file [String, nil] optional output file path
|
|
19
|
+
# @param force [Boolean] whether to overwrite existing file
|
|
20
|
+
# @param out [IO] output stream
|
|
21
|
+
# @param err [IO] error stream
|
|
22
|
+
# @return [void]
|
|
23
|
+
def call(page_name:, output_file: nil, force: false, out: $stdout, err: $stderr, **)
|
|
24
|
+
wiki = create_wiki(out:, err:, **)
|
|
25
|
+
|
|
26
|
+
# Check if output file exists when not forcing
|
|
27
|
+
if output_file && File.exist?(output_file) && !force
|
|
28
|
+
raise ArgumentError, "File '#{output_file}' already exists. Use --force to overwrite."
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
page = wiki.page(page_name:)
|
|
32
|
+
|
|
33
|
+
if output_file
|
|
34
|
+
File.write(output_file, page.source)
|
|
35
|
+
say("Page '#{page_name}' (#{page.source.bytesize} bytes) saved to #{output_file}", out:, **)
|
|
36
|
+
else
|
|
37
|
+
out.puts page.source
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
register "page get", Page::Get
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Wikiwiki
|
|
4
|
+
class CLI
|
|
5
|
+
# CLI command implementations
|
|
6
|
+
module Commands
|
|
7
|
+
# Page-related commands
|
|
8
|
+
module Page
|
|
9
|
+
# List all pages in the wiki
|
|
10
|
+
class List < Base
|
|
11
|
+
desc "List all pages"
|
|
12
|
+
|
|
13
|
+
option :json, aliases: ["-j"], type: :boolean, default: false, desc: "Output as JSON"
|
|
14
|
+
|
|
15
|
+
# Execute the list command
|
|
16
|
+
#
|
|
17
|
+
# @param options [Hash] command options including wiki_id, auth, json, verbose, out, err
|
|
18
|
+
# @return [void]
|
|
19
|
+
def call(out: $stdout, err: $stderr, **options)
|
|
20
|
+
wiki = create_wiki(out:, err:, **options)
|
|
21
|
+
page_names = wiki.page_names
|
|
22
|
+
|
|
23
|
+
if options[:json]
|
|
24
|
+
out.puts Formatter::JSON.new.format(page_names)
|
|
25
|
+
else
|
|
26
|
+
page_names.each {|name| out.puts name }
|
|
27
|
+
say("#{page_names.size} pages found", out:, **options)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
register "page list", Page::List
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Wikiwiki
|
|
4
|
+
class CLI
|
|
5
|
+
module Commands
|
|
6
|
+
module Page
|
|
7
|
+
# Upload/update page content (creates if not exists)
|
|
8
|
+
class Put < Base
|
|
9
|
+
desc "Upload/update page content (creates if not exists)"
|
|
10
|
+
|
|
11
|
+
argument :page_name, required: true, desc: "Page name"
|
|
12
|
+
argument :input_file, required: false, desc: "Input file (stdin if omitted)"
|
|
13
|
+
|
|
14
|
+
# Execute the put command
|
|
15
|
+
#
|
|
16
|
+
# @param page_name [String] name of the page to update
|
|
17
|
+
# @param input_file [String, nil] optional input file path (uses stdin if nil)
|
|
18
|
+
# @param out [IO] output stream
|
|
19
|
+
# @param err [IO] error stream
|
|
20
|
+
# @return [void]
|
|
21
|
+
# @raise [ArgumentError] if source content is empty
|
|
22
|
+
# @note To delete a page, use `wikiwiki page delete` instead
|
|
23
|
+
def call(page_name:, input_file: nil, out: $stdout, err: $stderr, **)
|
|
24
|
+
wiki = create_wiki(out:, err:, **)
|
|
25
|
+
|
|
26
|
+
source = if input_file
|
|
27
|
+
File.read(input_file)
|
|
28
|
+
else
|
|
29
|
+
$stdin.read
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
raise ArgumentError, "Page source must not be empty. Use 'wikiwiki page delete' to delete a page." if source.empty?
|
|
33
|
+
|
|
34
|
+
wiki.update_page(page_name:, source:)
|
|
35
|
+
|
|
36
|
+
say("Page '#{page_name}' updated successfully", out:, **)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
register "page put", Page::Put
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Wikiwiki
|
|
4
|
+
class CLI
|
|
5
|
+
module Commands
|
|
6
|
+
module Page
|
|
7
|
+
# Show page metadata
|
|
8
|
+
class Show < Base
|
|
9
|
+
desc "Show page metadata"
|
|
10
|
+
|
|
11
|
+
argument :page_name, required: true, desc: "Page name"
|
|
12
|
+
option :json, aliases: ["-j"], type: :boolean, default: false, desc: "Output as JSON"
|
|
13
|
+
|
|
14
|
+
# Execute the show command
|
|
15
|
+
#
|
|
16
|
+
# @param page_name [String] name of the page to show
|
|
17
|
+
# @param options [Hash] command options including wiki_id, auth, json, verbose, out, err
|
|
18
|
+
# @return [void]
|
|
19
|
+
def call(page_name:, out: $stdout, err: $stderr, **options)
|
|
20
|
+
wiki = create_wiki(out:, err:, **options)
|
|
21
|
+
page = wiki.page(page_name:)
|
|
22
|
+
|
|
23
|
+
metadata = {
|
|
24
|
+
"name" => page.name,
|
|
25
|
+
"timestamp" => page.timestamp.iso8601,
|
|
26
|
+
"source_size" => page.source.bytesize
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if options[:json]
|
|
30
|
+
out.puts Formatter::JSON.new.format(metadata)
|
|
31
|
+
else
|
|
32
|
+
out.puts "Name: #{metadata["name"]}"
|
|
33
|
+
out.puts "Timestamp: #{metadata["timestamp"]}"
|
|
34
|
+
out.puts "Source size: #{metadata["source_size"]} bytes"
|
|
35
|
+
say("Page metadata retrieved", out:, **options)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
register "page show", Page::Show
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "json"
|
|
4
|
+
|
|
5
|
+
module Wikiwiki
|
|
6
|
+
class CLI
|
|
7
|
+
module Formatter
|
|
8
|
+
# JSON output formatter for CLI commands
|
|
9
|
+
class JSON
|
|
10
|
+
# Format data as pretty-printed JSON
|
|
11
|
+
#
|
|
12
|
+
# @param data [Object] data to format (Hash, Array, etc.)
|
|
13
|
+
# @return [String] formatted JSON string
|
|
14
|
+
def format(data) = ::JSON.pretty_generate(data)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
data/lib/wikiwiki/cli.rb
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "dry/cli"
|
|
4
|
+
require "logger"
|
|
5
|
+
|
|
6
|
+
module Wikiwiki
|
|
7
|
+
# Command-line interface for Wikiwiki
|
|
8
|
+
#
|
|
9
|
+
# Provides commands for managing wiki pages and attachments through the terminal.
|
|
10
|
+
# Supports authentication via API key or password, with configurable logging and output modes.
|
|
11
|
+
class CLI
|
|
12
|
+
# Initialize the CLI with output streams
|
|
13
|
+
#
|
|
14
|
+
# @param out [IO] standard output (defaults to $stdout)
|
|
15
|
+
# @param err [IO] error output (defaults to $stderr)
|
|
16
|
+
def initialize(out: $stdout, err: $stderr)
|
|
17
|
+
@out = out
|
|
18
|
+
@err = err
|
|
19
|
+
@dry_cli = Dry::CLI.new(Commands)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Run the CLI with given arguments
|
|
23
|
+
#
|
|
24
|
+
# @param argv [Array<String>] command-line arguments
|
|
25
|
+
# @return [Integer] exit code (0 for success, 1 for error)
|
|
26
|
+
def run(argv)
|
|
27
|
+
@debug = argv.include?("--debug")
|
|
28
|
+
@dry_cli.call(arguments: argv, out: @out, err: @err)
|
|
29
|
+
0
|
|
30
|
+
rescue => e
|
|
31
|
+
handle_error(e)
|
|
32
|
+
1
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
attr_reader :out
|
|
36
|
+
attr_reader :err
|
|
37
|
+
|
|
38
|
+
# Handle and display errors
|
|
39
|
+
#
|
|
40
|
+
# @param error [Exception] the error to handle
|
|
41
|
+
# @return [void]
|
|
42
|
+
private def handle_error(error) = err.puts(@debug ? error.full_message : error.message)
|
|
43
|
+
|
|
44
|
+
# Command registry
|
|
45
|
+
module Commands
|
|
46
|
+
extend Dry::CLI::Registry
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -84,9 +84,7 @@ module Wikiwiki
|
|
|
84
84
|
#
|
|
85
85
|
# @return [void]
|
|
86
86
|
# @raise [RateLimitError] if rate limit is exceeded (with raise strategy)
|
|
87
|
-
def acquire!
|
|
88
|
-
@strategy.acquire!(self)
|
|
89
|
-
end
|
|
87
|
+
def acquire! = @strategy.acquire!(self)
|
|
90
88
|
|
|
91
89
|
# Get time in seconds until next request can be made
|
|
92
90
|
#
|
|
@@ -100,23 +98,17 @@ module Wikiwiki
|
|
|
100
98
|
# Check if a request can be made without exceeding any limits
|
|
101
99
|
#
|
|
102
100
|
# @return [Boolean] true if request is allowed
|
|
103
|
-
def can_request?
|
|
104
|
-
@windows.all?(&:can_request?)
|
|
105
|
-
end
|
|
101
|
+
def can_request? = @windows.all?(&:can_request?)
|
|
106
102
|
|
|
107
103
|
# Record a new request across all window limiters
|
|
108
104
|
#
|
|
109
105
|
# @return [void]
|
|
110
|
-
def record!
|
|
111
|
-
@windows.each(&:record!)
|
|
112
|
-
end
|
|
106
|
+
def record! = @windows.each(&:record!)
|
|
113
107
|
|
|
114
108
|
# Get maximum wait time across all window limiters
|
|
115
109
|
#
|
|
116
110
|
# @return [Float, nil] seconds to wait
|
|
117
|
-
def wait_time
|
|
118
|
-
@windows.map(&:wait_time).max
|
|
119
|
-
end
|
|
111
|
+
def wait_time = @windows.map(&:wait_time).max
|
|
120
112
|
|
|
121
113
|
attr_reader :mutex
|
|
122
114
|
end
|
data/lib/wikiwiki/version.rb
CHANGED
data/lib/wikiwiki/wiki.rb
CHANGED
|
@@ -17,8 +17,6 @@ module Wikiwiki
|
|
|
17
17
|
class Wiki
|
|
18
18
|
attr_reader :logger
|
|
19
19
|
|
|
20
|
-
private attr_reader :api, :wiki_id
|
|
21
|
-
|
|
22
20
|
# Initializes a new Wiki instance
|
|
23
21
|
#
|
|
24
22
|
# @param wiki_id [String] the wiki ID
|
|
@@ -34,6 +32,13 @@ module Wikiwiki
|
|
|
34
32
|
@api = API.new(wiki_id:, auth:, logger:, rate_limiter:)
|
|
35
33
|
end
|
|
36
34
|
|
|
35
|
+
# Returns the authentication token
|
|
36
|
+
#
|
|
37
|
+
# @return [String] JWT authentication token
|
|
38
|
+
def token = api.token
|
|
39
|
+
|
|
40
|
+
private attr_reader :api, :wiki_id
|
|
41
|
+
|
|
37
42
|
# Returns the wiki URL
|
|
38
43
|
#
|
|
39
44
|
# @return [URI::HTTPS] the frozen wiki URL
|
|
@@ -65,14 +70,28 @@ module Wikiwiki
|
|
|
65
70
|
# Updates a page with new content
|
|
66
71
|
#
|
|
67
72
|
# @param page_name [String] the name of the page to update
|
|
68
|
-
# @param source [String] the new page source content
|
|
73
|
+
# @param source [String] the new page source content (must not be empty)
|
|
69
74
|
# @return [void]
|
|
75
|
+
# @raise [ArgumentError] if source is empty
|
|
70
76
|
# @raise [Wikiwiki::Error] if the update fails
|
|
77
|
+
# @note To delete a page, use {#delete_page} instead
|
|
71
78
|
def update_page(page_name:, source:)
|
|
79
|
+
raise ArgumentError, "Page source must not be empty. Use delete_page to delete a page." if source.empty?
|
|
80
|
+
|
|
72
81
|
encoded_page_name = ERB::Util.url_encode(page_name)
|
|
73
82
|
api.put_page(encoded_page_name:, source:)
|
|
74
83
|
end
|
|
75
84
|
|
|
85
|
+
# Deletes a page
|
|
86
|
+
#
|
|
87
|
+
# @param page_name [String] the name of the page to delete
|
|
88
|
+
# @return [void]
|
|
89
|
+
# @raise [Wikiwiki::Error] if the deletion fails
|
|
90
|
+
def delete_page(page_name:)
|
|
91
|
+
encoded_page_name = ERB::Util.url_encode(page_name)
|
|
92
|
+
api.put_page(encoded_page_name:, source: "")
|
|
93
|
+
end
|
|
94
|
+
|
|
76
95
|
# Retrieves attachment file names on a page
|
|
77
96
|
#
|
|
78
97
|
# @param page_name [String] the name of the page
|
data/lib/wikiwiki.rb
CHANGED
|
@@ -32,12 +32,16 @@ module Wikiwiki
|
|
|
32
32
|
# Raised when HTTP status is 404
|
|
33
33
|
class ResourceNotFoundError < APIError; end
|
|
34
34
|
|
|
35
|
+
# Conflict error
|
|
36
|
+
# Raised when HTTP status is 409
|
|
37
|
+
class ConflictError < APIError; end
|
|
38
|
+
|
|
35
39
|
# Server error
|
|
36
40
|
# Raised when HTTP status is 5xx
|
|
37
41
|
class ServerError < APIError; end
|
|
38
42
|
|
|
39
43
|
loader = Zeitwerk::Loader.for_gem
|
|
40
|
-
loader.inflector.inflect("api" => "API")
|
|
44
|
+
loader.inflector.inflect("api" => "API", "cli" => "CLI", "json" => "JSON")
|
|
41
45
|
loader.setup
|
|
42
46
|
loader.eager_load
|
|
43
47
|
end
|
data/sig/dry/cli.rbs
ADDED
data/sig/wikiwiki/api.rbs
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
module Wikiwiki
|
|
2
2
|
class API
|
|
3
3
|
attr_reader logger: Logger
|
|
4
|
+
attr_reader token: String
|
|
4
5
|
|
|
5
|
-
def initialize: (wiki_id: String, auth: Auth::Password | Auth::ApiKey, logger: Logger, ?rate_limiter: RateLimiter) -> void
|
|
6
|
+
def initialize: (wiki_id: String, auth: Auth::Password | Auth::ApiKey | Auth::Token, logger: Logger, ?rate_limiter: RateLimiter) -> void
|
|
6
7
|
|
|
7
8
|
def get_pages: () -> Hash[String, Array[Hash[String, String]]]
|
|
8
9
|
|
|
@@ -20,7 +21,9 @@ module Wikiwiki
|
|
|
20
21
|
|
|
21
22
|
private
|
|
22
23
|
|
|
23
|
-
def authenticate: (Auth::Password | Auth::ApiKey auth) -> String
|
|
24
|
+
def authenticate: (Auth::Password | Auth::ApiKey | Auth::Token auth) -> String
|
|
25
|
+
|
|
26
|
+
def validate_token_expiry: (String token) -> void
|
|
24
27
|
|
|
25
28
|
def parse_json_response: (Net::HTTPResponse response) -> Hash[String, untyped]
|
|
26
29
|
|
|
@@ -31,6 +34,5 @@ module Wikiwiki
|
|
|
31
34
|
def log_response: (Net::HTTPResponse response) -> void
|
|
32
35
|
|
|
33
36
|
attr_reader wiki_id: String
|
|
34
|
-
attr_reader token: String
|
|
35
37
|
end
|
|
36
38
|
end
|
data/sig/wikiwiki/auth.rbs
CHANGED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
module Wikiwiki
|
|
2
|
+
class CLI
|
|
3
|
+
module Commands
|
|
4
|
+
module Attachment
|
|
5
|
+
class List < Base
|
|
6
|
+
def call: (
|
|
7
|
+
page_name: String,
|
|
8
|
+
?out: IO,
|
|
9
|
+
?err: IO,
|
|
10
|
+
?wiki_id: String?,
|
|
11
|
+
?api_key_id: String?,
|
|
12
|
+
?secret: String?,
|
|
13
|
+
?password: String?,
|
|
14
|
+
?json: bool,
|
|
15
|
+
?verbose: bool,
|
|
16
|
+
?debug: bool
|
|
17
|
+
) -> void
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
class Show < Base
|
|
21
|
+
def call: (
|
|
22
|
+
page_name: String,
|
|
23
|
+
file_name: String,
|
|
24
|
+
?out: IO,
|
|
25
|
+
?err: IO,
|
|
26
|
+
?wiki_id: String?,
|
|
27
|
+
?api_key_id: String?,
|
|
28
|
+
?secret: String?,
|
|
29
|
+
?password: String?,
|
|
30
|
+
?json: bool,
|
|
31
|
+
?verbose: bool,
|
|
32
|
+
?debug: bool
|
|
33
|
+
) -> void
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
class Get < Base
|
|
37
|
+
def call: (
|
|
38
|
+
page_name: String,
|
|
39
|
+
file_name: String,
|
|
40
|
+
?directory: String?,
|
|
41
|
+
?force: bool,
|
|
42
|
+
?out: IO,
|
|
43
|
+
?err: IO,
|
|
44
|
+
?wiki_id: String?,
|
|
45
|
+
?api_key_id: String?,
|
|
46
|
+
?secret: String?,
|
|
47
|
+
?password: String?,
|
|
48
|
+
?verbose: bool,
|
|
49
|
+
?debug: bool
|
|
50
|
+
) -> void
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
class Put < Base
|
|
54
|
+
def call: (
|
|
55
|
+
page_name: String,
|
|
56
|
+
file_path: String,
|
|
57
|
+
?name: String?,
|
|
58
|
+
?force: bool,
|
|
59
|
+
?out: IO,
|
|
60
|
+
?err: IO,
|
|
61
|
+
?wiki_id: String?,
|
|
62
|
+
?api_key_id: String?,
|
|
63
|
+
?secret: String?,
|
|
64
|
+
?password: String?,
|
|
65
|
+
?verbose: bool,
|
|
66
|
+
?debug: bool
|
|
67
|
+
) -> void
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
class Delete < Base
|
|
71
|
+
def call: (
|
|
72
|
+
page_name: String,
|
|
73
|
+
file_name: String,
|
|
74
|
+
?out: IO,
|
|
75
|
+
?err: IO,
|
|
76
|
+
?wiki_id: String?,
|
|
77
|
+
?api_key_id: String?,
|
|
78
|
+
?secret: String?,
|
|
79
|
+
?password: String?,
|
|
80
|
+
?verbose: bool,
|
|
81
|
+
?debug: bool
|
|
82
|
+
) -> void
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module Wikiwiki
|
|
2
|
+
class CLI
|
|
3
|
+
module Commands
|
|
4
|
+
class Base < Dry::CLI::Command
|
|
5
|
+
private
|
|
6
|
+
|
|
7
|
+
def create_wiki: (
|
|
8
|
+
?wiki_id: String?,
|
|
9
|
+
?token: String?,
|
|
10
|
+
?api_key_id: String?,
|
|
11
|
+
?secret: String?,
|
|
12
|
+
?password: String?,
|
|
13
|
+
?debug: bool,
|
|
14
|
+
?out: IO,
|
|
15
|
+
?err: IO,
|
|
16
|
+
**untyped
|
|
17
|
+
) -> Wiki
|
|
18
|
+
|
|
19
|
+
def create_logger: (debug: bool, ?out: IO, ?err: IO) -> Logger
|
|
20
|
+
|
|
21
|
+
def verbose?: (verbose: bool, ?json: bool, **untyped) -> bool
|
|
22
|
+
|
|
23
|
+
def say: (String message, verbose: bool, ?out: IO, **untyped) -> void
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|