require "mimemagic" require "faraday" require "digest/sha1" require "English" # Getting into the process for initializing faraday inside mediawiki api # gem is not really possible without an even bigger hack than this...so # this is less evil hax to piggyback on a middleware that's already used module FaradayMiddleware class FollowRedirects old_call = instance_method(:call) define_method(:call) do |env| CirrusSearchApiHelper.last_api_request_env = { "url" => env[:url].to_s, "body" => env[:body] } old_call.bind(self).call(env) end end end # Common code cirrus' test use when dealing with api. module CirrusSearchApiHelper class << self attr_accessor :last_api_request_env end def with_api yield rescue RSpec::Expectations::ExpectationNotMetError raise $ERROR_INFO, "#{$ERROR_INFO}\nLoaded from #{CirrusSearchApiHelper.last_api_request_env}", $ERROR_INFO.backtrace end def with_browser yield rescue RSpec::Expectations::ExpectationNotMetError raise $ERROR_INFO, "#{$ERROR_INFO}\nLoaded from #{browser.url}", $ERROR_INFO.backtrace end def edit_page(title, text, add) text = File.read("articles/" + text[1..-1]) if text.start_with?("@") fetched_text = get_page_text(title) # Note that the space keeps words from smashing together text = fetched_text + " " + text if add return if fetched_text.strip == text.strip result = api.create_page(title, text) expect(result.status).to eq 200 expect(result.warnings?).to eq false end # Gets page text using the api. def get_page_text(title) fetched_text = api.get_wikitext(title) return "" if fetched_text.status == 404 fetched_text.status.should eq 200 fetched_text.body.strip.force_encoding("utf-8") end # Search for a particular string using the api def search_for(search, options) data = api.query(options.merge( list: "search", srsearch: search, srprop: "snippet|titlesnippet|redirectsnippet|sectionsnippet|categorysnippet|isfilematch", formatversion: 2 )) data["query"] end # Get suggestions for a particular string using the api def suggestions_for(search) api.action( :opensearch, search: search, token_type: false ) end # Get suggestions for a particular string using the api def suggestions_with_profile(search, profile) api.action( :opensearch, search: search, profile: profile, token_type: false ) end # Get suggestions for a particular string using the new suggestions api def suggestions_for_api(search, limit = nil) req = {} req["limit"] = limit if limit api.action(:opensearch, req.merge( search: search, cirrusUseCompletionSuggester: "yes", token_type: false )) end def sha1_for_image(title) existing = api.prop( :imageinfo, titles: title, iiprop: "sha1", iilimit: 1 ) # api will always return 1 item, if non existent it will have the id -1 return false if existing.data["pages"].first[0] == "-1" existing.data["pages"].first[1]["imageinfo"][0]["sha1"] end # Uploads a file if the file's SHA1 doesn't match what is already uploaded. def upload_file(title, contents, description) contents = "articles/" + contents sha1 = Digest::SHA1.hexdigest(File.read(contents)) remote_sha1 = sha1_for_image(title) return if sha1 == remote_sha1 ignorewarnings = remote_sha1 != false api.action( :upload, filename: title, file: Faraday::UploadIO.new(contents, MimeMagic.by_path(contents)), text: "#{description}\nsha1: #{sha1}", # must ignorewarnings to upload new version of a file ignorewarnings: ignorewarnings ? 1 : 0 ) end # Locate a category id def page_id_of(title) res = api.query( titles: title ) res["query"]["pages"].first[1]["pageid"] end end