Class: Wikian::Post

Inherits:
Object
  • Object
show all
Defined in:
lib/wikian/post.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(args) ⇒ Post

Returns a new instance of Post.



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/wikian/post.rb', line 9

def initialize(args)
  @args = args

  # input wikitext file
  @input_file = args.find{|f| File.exist? f}
  raise WikiFileError unless input_file

  site = input_file.match(/\.(.*)\.wiki/)[1]

  @baseurl = "https://#{site}/w/api.php"

  @header = {}

  @username = ENV['WIKI_USER']

  @debug = (args & %w(-d --debug)).length > 0 ? true : false
rescue => e
  puts "#{e.class} in #{__FILE__}. #{e.message}"
  exit
end

Instance Attribute Details

#argsObject

Returns the value of attribute args.



6
7
8
# File 'lib/wikian/post.rb', line 6

def args
  @args
end

#baseurlObject

Returns the value of attribute baseurl.



6
7
8
# File 'lib/wikian/post.rb', line 6

def baseurl
  @baseurl
end

#body_textObject

Returns the value of attribute body_text.



6
7
8
# File 'lib/wikian/post.rb', line 6

def body_text
  @body_text
end

Returns the value of attribute csrf_cookie.



6
7
8
# File 'lib/wikian/post.rb', line 6

def csrf_cookie
  @csrf_cookie
end

#csrf_tokenObject

Returns the value of attribute csrf_token.



6
7
8
# File 'lib/wikian/post.rb', line 6

def csrf_token
  @csrf_token
end

#debugObject

Returns the value of attribute debug.



6
7
8
# File 'lib/wikian/post.rb', line 6

def debug
  @debug
end

#headerObject

Returns the value of attribute header.



6
7
8
# File 'lib/wikian/post.rb', line 6

def header
  @header
end

#input_fileObject

Returns the value of attribute input_file.



6
7
8
# File 'lib/wikian/post.rb', line 6

def input_file
  @input_file
end

Returns the value of attribute login_cookie.



6
7
8
# File 'lib/wikian/post.rb', line 6

def 
  @login_cookie
end

#login_tokenObject

Returns the value of attribute login_token.



6
7
8
# File 'lib/wikian/post.rb', line 6

def 
  @login_token
end

#queryObject

Returns the value of attribute query.



6
7
8
# File 'lib/wikian/post.rb', line 6

def query
  @query
end

#usernameObject

Returns the value of attribute username.



6
7
8
# File 'lib/wikian/post.rb', line 6

def username
  @username
end

Instance Method Details

#build_query_stringObject



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/wikian/post.rb', line 96

def build_query_string
  params={}
  params['action'] = 'edit'
  params['format'] = Wikian::RESPONSE_FORMAT
  params['title'] = input_file.sub(/\..*/,'')
  wikitext = File.read(input_file)
  if args.have?(%w(-a --append))
    params['appendtext'] = wikitext
  elsif args.have?(%w(-p --prepend))
    params['prependtext'] = wikitext
  else
    # pass the wikitext in request body
    @body_text = wikitext
  end
  if args.have?(%w(-c --captcha))
    params['captchaid'], params['captchaword'] = args[args.index('-c')+1].split(':')
  end
  if args.have?(%w(-m --message))
    params['summary'] = args[args.index('-m')+1]
  end
  if args.have?(%w(-s --section))
    params['section'] = args[args.index('-s')+1]
  end
  @query = URI.encode_www_form(params)
end


56
57
58
# File 'lib/wikian/post.rb', line 56

def csrf_cookie_file
  'csrf_cookie'
end

#expired_cookie?Boolean

check if the cookie is expired (older than an hour)

Returns:

  • (Boolean)


52
53
54
# File 'lib/wikian/post.rb', line 52

def expired_cookie?
  File.exist?(csrf_cookie_file) && ((Time.now - File.open(csrf_cookie_file).stat.ctime)/3600 > 1)
end


74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/wikian/post.rb', line 74

def get_csrf_cookie
  puts("\nGetting csrf cookie using 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' => )
  http = Net::HTTP.new(url.host, url.port)
  http.use_ssl = true
  res=http.request(req)
  @csrf_cookie = (res['set-cookie'])
  File.write(csrf_cookie_file, @csrf_cookie)
  puts(res.body) if debug
end

#get_csrf_tokenObject



87
88
89
90
91
92
93
94
# File 'lib/wikian/post.rb', line 87

def get_csrf_token
  puts("\nGetting csrf token using csrf cookies") if debug
  url = URI("#{baseurl}?action=query&meta=tokens&format=json&type=csrf")
  res = URI.open(url, header.merge('cookie' => csrf_cookie))
  json = JSON.parse(res.read)
  @csrf_token = json.dig('query','tokens','csrftoken')
  puts(json) if debug
end

#get_login_tokenObject



64
65
66
67
68
69
70
71
72
# File 'lib/wikian/post.rb', line 64

def 
  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')
  @login_cookie = (res.meta['set-cookie'])
  puts(json) if debug
end

#postObject



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/wikian/post.rb', line 30

def post
  # remove expired cookie
  if expired_cookie? || args.have?(%w(-r --remove-cookie))
    FileUtils.rm_f(csrf_cookie_file)
  end

  # csrf_cookie can be reused among multiple requests. But csrf_token must be updated on each request
  if File.exist?(csrf_cookie_file)
    @csrf_cookie = File.read(csrf_cookie_file)
  else
    

    get_csrf_cookie
  end
  get_csrf_token

  build_query_string

  upload_article
end


60
61
62
# File 'lib/wikian/post.rb', line 60

def (cookie)
  cookie.gsub(/secure;|path=.*?[,;]|httponly[;,]|samesite=.*?[;,]|expires=.....*?[,;]|domain=.*?;|max-age=.*?[;,]/i,'').squeeze(' ')
end

#upload_articleObject



122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/wikian/post.rb', line 122

def upload_article
  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' => csrf_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