Class: Wikiwiki::Wiki

Inherits:
Object
  • Object
show all
Defined in:
lib/wikiwiki/wiki.rb

Overview

Represents a Wikiwiki wiki instance

Examples:

auth = Wikiwiki::Auth.password(password: "admin_password")
wiki = Wikiwiki::Wiki.new(wiki_id: "my-wiki", auth:)
wiki.page_names # => ["FrontPage", "SideBar", ...]
page = wiki.page(page_name: "FrontPage")

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(wiki_id:, auth:, rate_limiter: RateLimiter.default, logger: Logger.new($stdout)) ⇒ Wiki

Initializes a new Wiki instance

Parameters:

  • wiki_id (String)

    the wiki ID

  • auth (Wikiwiki::Auth::Password, Wikiwiki::Auth::ApiKey)

    authentication credentials

  • rate_limiter (RateLimiter) (defaults to: RateLimiter.default)

    rate limiter instance (default: RateLimiter.default)

  • logger (Logger) (defaults to: Logger.new($stdout))

    logger instance for API request/response logging (default: Logger.new($stdout))

Raises:

  • (ArgumentError)

    if logger is explicitly set to nil



27
28
29
30
31
32
33
# File 'lib/wikiwiki/wiki.rb', line 27

def initialize(wiki_id:, auth:, rate_limiter: RateLimiter.default, logger: Logger.new($stdout))
  raise ArgumentError, "logger cannot be nil" if logger.nil?

  @wiki_id = wiki_id
  @logger = logger
  @api = API.new(wiki_id:, auth:, logger:, rate_limiter:)
end

Instance Attribute Details

#loggerObject (readonly)

Returns the value of attribute logger.



18
19
20
# File 'lib/wikiwiki/wiki.rb', line 18

def logger
  @logger
end

Instance Method Details

#add_attachment(page_name:, attachment_name:, content:) ⇒ void

This method returns an undefined value.

Adds an attachment to a page

Parameters:

  • page_name (String)

    the name of the page

  • attachment_name (String)

    the name of the file

  • content (String)

    the binary file content

Raises:



154
155
156
157
158
# File 'lib/wikiwiki/wiki.rb', line 154

def add_attachment(page_name:, attachment_name:, content:)
  encoded_page_name = ERB::Util.url_encode(page_name)
  encoded_content = Base64.strict_encode64(content)
  api.put_attachment(encoded_page_name:, attachment_name:, encoded_content:)
end

#attachment(page_name:, attachment_name:, rev: nil) ⇒ Wikiwiki::Attachment

Retrieves a specific attachment on a page

Parameters:

  • page_name (String)

    the name of the page

  • attachment_name (String)

    the name of the attachment file

  • rev (String, nil) (defaults to: nil)

    optional MD5 hash to retrieve a specific revision

Returns:

Raises:

  • (Wikiwiki::Error)

    if the attachment does not exist

  • (ArgumentError)

    if rev is not a valid MD5 hash format



116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/wikiwiki/wiki.rb', line 116

def attachment(page_name:, attachment_name:, rev: nil)
  if rev && !rev.match?(/\A[0-9a-f]{32}\z/i)
    raise ArgumentError, "rev must be a valid MD5 hash (32 hexadecimal characters)"
  end

  encoded_page_name = ERB::Util.url_encode(page_name)
  encoded_attachment_name = ERB::Util.url_encode(attachment_name)
  data = api.get_attachment(encoded_page_name:, encoded_attachment_name:, rev:)

  content = Base64.strict_decode64(data["src"])

  if content.bytesize != data["size"]
    raise ContentIntegrityError, "Size mismatch: expected #{data["size"]}, got #{content.bytesize}"
  end

  calculated_md5 = Digest::MD5.hexdigest(content)
  if calculated_md5 != data["md5hash"]
    raise ContentIntegrityError, "MD5 hash mismatch: expected #{data["md5hash"]}, got #{calculated_md5}"
  end

  Attachment.new(
    page_name: data["page"],
    name: data["file"],
    size: data["size"],
    # NOTE: API returns time as Unix timestamp (integer) for attachments, not ISO8601 string
    time: Time.at(data["time"]),
    type: data["type"],
    content:
  )
end

#attachment_names(page_name:) ⇒ Array<String>

Retrieves attachment file names on a page

Parameters:

  • page_name (String)

    the name of the page

Returns:

  • (Array<String>)

    array of attachment file names

Raises:



100
101
102
103
104
105
106
# File 'lib/wikiwiki/wiki.rb', line 100

def attachment_names(page_name:)
  encoded_page_name = ERB::Util.url_encode(page_name)
  attachments_data = api.get_attachments(encoded_page_name:)
  attachments = attachments_data["attachments"]
  # API returns [] when no attachments, or Hash when attachments exist
  attachments.is_a?(Hash) ? attachments.keys : []
end

#delete_attachment(page_name:, attachment_name:) ⇒ void

This method returns an undefined value.

Deletes an attachment from a page

Parameters:

  • page_name (String)

    the name of the page

  • attachment_name (String)

    the name of the attachment file

Raises:



166
167
168
169
170
# File 'lib/wikiwiki/wiki.rb', line 166

def delete_attachment(page_name:, attachment_name:)
  encoded_page_name = ERB::Util.url_encode(page_name)
  encoded_attachment_name = ERB::Util.url_encode(attachment_name)
  api.delete_attachment(encoded_page_name:, encoded_attachment_name:)
end

#delete_page(page_name:) ⇒ void

This method returns an undefined value.

Deletes a page

Parameters:

  • page_name (String)

    the name of the page to delete

Raises:



90
91
92
93
# File 'lib/wikiwiki/wiki.rb', line 90

def delete_page(page_name:)
  encoded_page_name = ERB::Util.url_encode(page_name)
  api.put_page(encoded_page_name:, source: "")
end

#page(page_name:) ⇒ Wikiwiki::Page

Retrieves a page by name

Parameters:

  • page_name (String)

    the name of the page

Returns:

Raises:



59
60
61
62
63
64
65
66
67
68
# File 'lib/wikiwiki/wiki.rb', line 59

def page(page_name:)
  encoded_page_name = ERB::Util.url_encode(page_name)
  page_data = api.get_page(encoded_page_name:)
  Page.new(
    name: page_name,
    source: page_data["source"],
    # NOTE: API returns timestamp as ISO8601 string for pages
    timestamp: Time.iso8601(page_data["timestamp"])
  )
end

#page_namesArray<String>

Returns the list of all page names in the wiki

Returns:

  • (Array<String>)

    array of page names



52
# File 'lib/wikiwiki/wiki.rb', line 52

def page_names = api.get_pages["pages"].map {|p| p["name"] }

#tokenString

Returns the authentication token

Returns:

  • (String)

    JWT authentication token



38
# File 'lib/wikiwiki/wiki.rb', line 38

def token = api.token

#update_page(page_name:, source:) ⇒ void

Note:

To delete a page, use #delete_page instead

This method returns an undefined value.

Updates a page with new content

Parameters:

  • page_name (String)

    the name of the page to update

  • source (String)

    the new page source content (must not be empty)

Raises:

  • (ArgumentError)

    if source is empty

  • (Wikiwiki::Error)

    if the update fails



78
79
80
81
82
83
# File 'lib/wikiwiki/wiki.rb', line 78

def update_page(page_name:, source:)
  raise ArgumentError, "Page source must not be empty. Use delete_page to delete a page." if source.empty?

  encoded_page_name = ERB::Util.url_encode(page_name)
  api.put_page(encoded_page_name:, source:)
end

#urlURI::HTTPS

Returns the wiki URL

Returns:

  • (URI::HTTPS)

    the frozen wiki URL



45
46
47
# File 'lib/wikiwiki/wiki.rb', line 45

def url
  @url ||= URI.parse("https://wikiwiki.jp/#{wiki_id}/").freeze
end