Class: Wikian::Post
- Inherits:
-
Object
- Object
- Wikian::Post
- Defined in:
- lib/wikian/post.rb
Instance Attribute Summary collapse
-
#args ⇒ Object
Returns the value of attribute args.
-
#baseurl ⇒ Object
Returns the value of attribute baseurl.
-
#body_text ⇒ Object
Returns the value of attribute body_text.
-
#csrf_cookie ⇒ Object
Returns the value of attribute csrf_cookie.
-
#csrf_token ⇒ Object
Returns the value of attribute csrf_token.
-
#debug ⇒ Object
Returns the value of attribute debug.
-
#header ⇒ Object
Returns the value of attribute header.
-
#input_file ⇒ Object
Returns the value of attribute input_file.
-
#latest_content ⇒ Object
Returns the value of attribute latest_content.
-
#latest_revision ⇒ Object
Returns the value of attribute latest_revision.
-
#login_cookie ⇒ Object
Returns the value of attribute login_cookie.
-
#login_token ⇒ Object
Returns the value of attribute login_token.
-
#metadata ⇒ Object
Returns the value of attribute metadata.
-
#params ⇒ Object
Returns the value of attribute params.
-
#query ⇒ Object
Returns the value of attribute query.
-
#username ⇒ Object
Returns the value of attribute username.
Instance Method Summary collapse
- #build_query_string ⇒ Object
- #csrf_cookie_file ⇒ Object
-
#expired_cookie? ⇒ Boolean
check if the cookie is expired (older than an hour).
- #get_csrf_cookie ⇒ Object
- #get_csrf_token ⇒ Object
- #get_latest_revision ⇒ Object
- #get_login_token ⇒ Object
-
#initialize(args) ⇒ Post
constructor
A new instance of Post.
-
#long_to_short_options ⇒ Object
transform long options like ‘–message’ to short options like ‘-m’.
-
#merge_versions(content_one, content_two) ⇒ Object
merge two version with diff.
- #post ⇒ Object
- #remove_cookie_metadata(cookie) ⇒ Object
- #update_metadata ⇒ Object
- #upload_article ⇒ Object
Constructor Details
#initialize(args) ⇒ Post
Returns a new instance of Post.
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/wikian/post.rb', line 12 def initialize(args) @args = args # input wikitext file raise WikiFileError unless @input_file = args.find{|f| File.exist? f} site = input_file.match(/\.(.*)\.wiki/)&.[](1) raise(WikiFileNameError, "Use the Input file name convention <article_name>.<site>.wiki") unless site @baseurl = "https://#{site}/w/api.php" @header = {} @username = ENV['WIKI_USER'] @debug = (args & %w(-d)).length > 0 ? true : false rescue => e puts "#{e.class} in #{__FILE__}", e. exit end |
Instance Attribute Details
#args ⇒ Object
Returns the value of attribute args.
8 9 10 |
# File 'lib/wikian/post.rb', line 8 def args @args end |
#baseurl ⇒ Object
Returns the value of attribute baseurl.
8 9 10 |
# File 'lib/wikian/post.rb', line 8 def baseurl @baseurl end |
#body_text ⇒ Object
Returns the value of attribute body_text.
8 9 10 |
# File 'lib/wikian/post.rb', line 8 def body_text @body_text end |
#csrf_cookie ⇒ Object
Returns the value of attribute csrf_cookie.
8 9 10 |
# File 'lib/wikian/post.rb', line 8 def end |
#csrf_token ⇒ Object
Returns the value of attribute csrf_token.
8 9 10 |
# File 'lib/wikian/post.rb', line 8 def csrf_token @csrf_token end |
#debug ⇒ Object
Returns the value of attribute debug.
8 9 10 |
# File 'lib/wikian/post.rb', line 8 def debug @debug end |
#header ⇒ Object
Returns the value of attribute header.
8 9 10 |
# File 'lib/wikian/post.rb', line 8 def header @header end |
#input_file ⇒ Object
Returns the value of attribute input_file.
8 9 10 |
# File 'lib/wikian/post.rb', line 8 def input_file @input_file end |
#latest_content ⇒ Object
Returns the value of attribute latest_content.
8 9 10 |
# File 'lib/wikian/post.rb', line 8 def latest_content @latest_content end |
#latest_revision ⇒ Object
Returns the value of attribute latest_revision.
8 9 10 |
# File 'lib/wikian/post.rb', line 8 def latest_revision @latest_revision end |
#login_cookie ⇒ Object
Returns the value of attribute login_cookie.
8 9 10 |
# File 'lib/wikian/post.rb', line 8 def end |
#login_token ⇒ Object
Returns the value of attribute login_token.
8 9 10 |
# File 'lib/wikian/post.rb', line 8 def login_token @login_token end |
#metadata ⇒ Object
Returns the value of attribute metadata.
8 9 10 |
# File 'lib/wikian/post.rb', line 8 def end |
#params ⇒ Object
Returns the value of attribute params.
8 9 10 |
# File 'lib/wikian/post.rb', line 8 def params @params end |
#query ⇒ Object
Returns the value of attribute query.
8 9 10 |
# File 'lib/wikian/post.rb', line 8 def query @query end |
#username ⇒ Object
Returns the value of attribute username.
8 9 10 |
# File 'lib/wikian/post.rb', line 8 def username @username end |
Instance Method Details
#build_query_string ⇒ Object
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
# File 'lib/wikian/post.rb', line 123 def build_query_string @params={} params['action'] = 'edit' params['format'] = Wikian::RESPONSE_FORMAT params['title'] = input_file.sub(/\..*/,'') = File.exist?(Wikian.) ? YAML.load(File.open(Wikian.)) : {} params['starttimestamp'] = if = .dig('meta', params['title'], 'timestamp') else FileUtils.mkdir_p(Wikian.) = {'meta' => {params['title'] => {'timestamp' => File.mtime(input_file).utc.iso8601}}} File.write(Wikian., YAML.dump()) end wikitext = File.read(input_file) if args.have?(%w(-a)) params['appendtext'] = wikitext elsif args.have?(%w(-p)) params['prependtext'] = wikitext else # pass the wikitext in request body @body_text = wikitext end if args.have?(%w(-c)) params['captchaid'], params['captchaword'] = args[args.index('-c')+1].split(':') end if args.have?(%w(-m)) params['summary'] = args[args.index('-m')+1] end if args.have?(%w(-s)) params['section'] = args[args.index('-s')+1] end end |
#csrf_cookie_file ⇒ Object
73 74 75 |
# File 'lib/wikian/post.rb', line 73 def 'csrf_cookie' end |
#expired_cookie? ⇒ Boolean
check if the cookie is expired (older than an hour)
69 70 71 |
# File 'lib/wikian/post.rb', line 69 def File.exist?() && ((Time.now - File.open().stat.ctime)/3600 > 1) end |
#get_csrf_cookie ⇒ Object
91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/wikian/post.rb', line 91 def puts("\nGetting csrf cookie using token #{login_token}") if debug url = URI("#{baseurl}?action=login&lgname=#{username}&format=json") req = Net::HTTP::Post.new(url, header.merge('cookie' => , 'content-type' => 'application/x-www-form-urlencoded')) req.set_form_data('lgpassword' => ENV['SECRET_WIKI_PASS'], 'lgtoken' => login_token) http = Net::HTTP.new(url.host, url.port) http.use_ssl = true res=http.request(req) = (res['set-cookie']) File.write(, ) puts(res.body) if debug end |
#get_csrf_token ⇒ Object
114 115 116 117 118 119 120 121 |
# File 'lib/wikian/post.rb', line 114 def get_csrf_token puts("\nGetting csrf token using csrf cookies") if debug url = URI("#{baseurl}?action=query&meta=tokens&format=json&prop=info|revisions&rvprop=timestamp") res = URI.open(url, header.merge('cookie' => )) json = JSON.parse(res.read) @csrf_token = json.dig('query','tokens','csrftoken') puts(json) if debug end |
#get_latest_revision ⇒ Object
104 105 106 107 108 109 110 111 112 |
# File 'lib/wikian/post.rb', line 104 def get_latest_revision res = URI.open("#{baseurl}?action=query&prop=revisions&titles=#{params['title']}&rvslots=main&rvprop=content|timestamp&format=json") @latest_revision = JSON.parse(res.read).dig('query', 'pages').values.first.dig('revisions').first params['basetimestamp'] = latest_revision['timestamp'] @latest_content = latest_revision.dig('slots', 'main', 'content') || latest_revision.dig('slots', 'main', '*') || latest_revision.dig('slots', '*') || latest_revision.dig('*') end |
#get_login_token ⇒ Object
81 82 83 84 85 86 87 88 89 |
# File 'lib/wikian/post.rb', line 81 def get_login_token puts("Getting login token/cookie") if debug url = URI("#{baseurl}?action=query&meta=tokens&format=json&type=login") res = URI.open(url) json = JSON.parse(res.read) @login_token = json.dig('query','tokens','logintoken') = (res.['set-cookie']) puts(json) if debug end |
#long_to_short_options ⇒ Object
transform long options like ‘–message’ to short options like ‘-m’
36 37 38 |
# File 'lib/wikian/post.rb', line 36 def args.map! {|opt| opt[0,2] == '--' ? opt[1,2] : opt} end |
#merge_versions(content_one, content_two) ⇒ Object
merge two version with diff. TODO the merge command is ADDING differences, but it should MERGE differences.
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
# File 'lib/wikian/post.rb', line 159 def merge_versions(content_one, content_two) tmp_local = Tempfile.open {|f| f.write content_one; f} tmp_latest = Tempfile.open {|f| f.write content_two; f} diff_cmd = "diff #{tmp_local.path} #{tmp_latest.path}" system("#{diff_cmd}") # raise error until the above TODO is solved raise WikiMergeError, "Please merge with latest version and try again" merge_cmd = "diff --line-format %L #{tmp_local.path} #{tmp_latest.path}" @body_text = %x(#{merge_cmd}) rescue => e puts "#{e.class} in #{__FILE__}", e. exit end |
#post ⇒ Object
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/wikian/post.rb', line 40 def post # remove expired cookie if || args.have?(%w(-r)) FileUtils.rm_f() end # csrf_cookie can be reused among multiple requests. But csrf_token must be updated on each request if File.exist?() = File.read() else get_login_token end build_query_string get_latest_revision if !args.include?('-f') && @body_text && Time.parse(params['starttimestamp']) < Time.parse(params['basetimestamp']) puts "Edit conflict detected" merge_versions(@body_text, latest_content) end get_csrf_token upload_article end |
#remove_cookie_metadata(cookie) ⇒ Object
77 78 79 |
# File 'lib/wikian/post.rb', line 77 def () .gsub(/secure;|path=.*?[,;]|httponly[;,]|samesite=.*?[;,]|expires=.....*?[,;]|domain=.*?;|max-age=.*?[;,]/i,'').squeeze(' ') end |
#update_metadata ⇒ Object
176 177 178 179 |
# File 'lib/wikian/post.rb', line 176 def ['meta'].merge!(params['title'] => {'timestamp' => Time.now.utc.iso8601}) File.write(Wikian., YAML.dump()) end |
#upload_article ⇒ Object
181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 |
# File 'lib/wikian/post.rb', line 181 def upload_article @query = URI.encode_www_form(params) puts("\nUploading the wiki article using csrf token #{csrf_token}") if debug url = URI("#{baseurl}?#{query}") req = Net::HTTP::Post.new(url, header.merge('cookie' => , 'content-type' => 'application/x-www-form-urlencoded')) http = Net::HTTP.new(url.host, url.port) req_body = body_text.nil? ? {token: csrf_token} : {token: csrf_token, text: body_text} req.set_form_data(req_body) http = Net::HTTP.new(url.host, url.port) http.use_ssl = true res=http.request(req) json = JSON.parse(res.body) puts(json) if debug if json.dig('error') puts "An error occurred while uploding the file", "Try pasing the '-r' option to remove '#{csrf_cookie_file}'", "Or pass '-d' option for debugging" else puts "Article uploaded" end end |