mediawiktory 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (243) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile.lock +63 -0
  3. data/README.md +103 -0
  4. data/bin/mediawiktory +13 -0
  5. data/doc/mediawiki_api_types.md +14 -0
  6. data/examples/query.rb +15 -0
  7. data/examples/query_generator.rb +15 -0
  8. data/lib/faraday/naive_cache.rb +40 -0
  9. data/lib/media_wiktory.rb +1 -0
  10. data/lib/mediawiktory/action.rb +48 -0
  11. data/lib/mediawiktory/array_with_keys.rb +41 -0
  12. data/lib/mediawiktory/client.rb +22 -0
  13. data/lib/mediawiktory/generated/abusefiltercheckmatch.rb +9 -0
  14. data/lib/mediawiktory/generated/abusefilterchecksyntax.rb +6 -0
  15. data/lib/mediawiktory/generated/abusefilterevalexpression.rb +6 -0
  16. data/lib/mediawiktory/generated/abusefilters.rb +12 -0
  17. data/lib/mediawiktory/generated/abusefilterunblockautopromote.rb +8 -0
  18. data/lib/mediawiktory/generated/abuselog.rb +14 -0
  19. data/lib/mediawiktory/generated/actions_mixin.rb +313 -0
  20. data/lib/mediawiktory/generated/addstudents.rb +9 -0
  21. data/lib/mediawiktory/generated/allcategories.rb +15 -0
  22. data/lib/mediawiktory/generated/alldeletedrevisions.rb +27 -0
  23. data/lib/mediawiktory/generated/allfileusages.rb +14 -0
  24. data/lib/mediawiktory/generated/allimages.rb +23 -0
  25. data/lib/mediawiktory/generated/alllinks.rb +15 -0
  26. data/lib/mediawiktory/generated/allmessages.rb +19 -0
  27. data/lib/mediawiktory/generated/allpages.rb +21 -0
  28. data/lib/mediawiktory/generated/allredirects.rb +15 -0
  29. data/lib/mediawiktory/generated/alltransclusions.rb +15 -0
  30. data/lib/mediawiktory/generated/allusers.rb +17 -0
  31. data/lib/mediawiktory/generated/antispoof.rb +6 -0
  32. data/lib/mediawiktory/generated/backlinks.rb +14 -0
  33. data/lib/mediawiktory/generated/betafeatures.rb +7 -0
  34. data/lib/mediawiktory/generated/block.rb +18 -0
  35. data/lib/mediawiktory/generated/blocks.rb +16 -0
  36. data/lib/mediawiktory/generated/bouncehandler.rb +7 -0
  37. data/lib/mediawiktory/generated/categories.rb +12 -0
  38. data/lib/mediawiktory/generated/categoryinfo.rb +7 -0
  39. data/lib/mediawiktory/generated/categorymembers.rb +23 -0
  40. data/lib/mediawiktory/generated/centralauthtoken.rb +5 -0
  41. data/lib/mediawiktory/generated/centralnoticechoicedata.rb +7 -0
  42. data/lib/mediawiktory/generated/centralnoticelogs.rb +11 -0
  43. data/lib/mediawiktory/generated/centralnoticequerycampaign.rb +6 -0
  44. data/lib/mediawiktory/generated/checktoken.rb +8 -0
  45. data/lib/mediawiktory/generated/checkuser.rb +14 -0
  46. data/lib/mediawiktory/generated/checkuserlog.rb +13 -0
  47. data/lib/mediawiktory/generated/cirrus-config-dump.rb +5 -0
  48. data/lib/mediawiktory/generated/cirrus-mapping-dump.rb +5 -0
  49. data/lib/mediawiktory/generated/cirrus-settings-dump.rb +5 -0
  50. data/lib/mediawiktory/generated/cirrus-suggest.rb +8 -0
  51. data/lib/mediawiktory/generated/clearhasmsg.rb +5 -0
  52. data/lib/mediawiktory/generated/close-open-topic.rb +10 -0
  53. data/lib/mediawiktory/generated/compare.rb +11 -0
  54. data/lib/mediawiktory/generated/contenttranslation.rb +12 -0
  55. data/lib/mediawiktory/generated/contenttranslationlangtrend.rb +8 -0
  56. data/lib/mediawiktory/generated/contenttranslationstats.rb +5 -0
  57. data/lib/mediawiktory/generated/contenttranslationsuggestions.rb +10 -0
  58. data/lib/mediawiktory/generated/contributors.rb +12 -0
  59. data/lib/mediawiktory/generated/coordinates.rb +12 -0
  60. data/lib/mediawiktory/generated/createaccount.rb +18 -0
  61. data/lib/mediawiktory/generated/cxconfiguration.rb +7 -0
  62. data/lib/mediawiktory/generated/cxdelete.rb +10 -0
  63. data/lib/mediawiktory/generated/cxpublish.rb +18 -0
  64. data/lib/mediawiktory/generated/cxpublishedtranslations.rb +9 -0
  65. data/lib/mediawiktory/generated/cxtoken.rb +7 -0
  66. data/lib/mediawiktory/generated/delete.rb +14 -0
  67. data/lib/mediawiktory/generated/deletedrevisions.rb +22 -0
  68. data/lib/mediawiktory/generated/deletedrevs.rb +20 -0
  69. data/lib/mediawiktory/generated/deleteeducation.rb +10 -0
  70. data/lib/mediawiktory/generated/deleteglobalaccount.rb +9 -0
  71. data/lib/mediawiktory/generated/duplicatefiles.rb +10 -0
  72. data/lib/mediawiktory/generated/echomarkread.rb +10 -0
  73. data/lib/mediawiktory/generated/echomarkseen.rb +8 -0
  74. data/lib/mediawiktory/generated/edit-header.rb +11 -0
  75. data/lib/mediawiktory/generated/edit-post.rb +12 -0
  76. data/lib/mediawiktory/generated/edit-title.rb +10 -0
  77. data/lib/mediawiktory/generated/edit-topic-summary.rb +11 -0
  78. data/lib/mediawiktory/generated/edit.rb +35 -0
  79. data/lib/mediawiktory/generated/editlist.rb +20 -0
  80. data/lib/mediawiktory/generated/editmassmessagelist.rb +10 -0
  81. data/lib/mediawiktory/generated/emailuser.rb +11 -0
  82. data/lib/mediawiktory/generated/embeddedin.rb +13 -0
  83. data/lib/mediawiktory/generated/enlist.rb +13 -0
  84. data/lib/mediawiktory/generated/expandtemplates.rb +11 -0
  85. data/lib/mediawiktory/generated/extlinks.rb +11 -0
  86. data/lib/mediawiktory/generated/extracts.rb +14 -0
  87. data/lib/mediawiktory/generated/exturlusage.rb +13 -0
  88. data/lib/mediawiktory/generated/fancycaptchareload.rb +5 -0
  89. data/lib/mediawiktory/generated/featuredfeed.rb +8 -0
  90. data/lib/mediawiktory/generated/featureusage.rb +10 -0
  91. data/lib/mediawiktory/generated/feedcontributions.rb +15 -0
  92. data/lib/mediawiktory/generated/feedrecentchanges.rb +21 -0
  93. data/lib/mediawiktory/generated/feedwatchlist.rb +14 -0
  94. data/lib/mediawiktory/generated/filearchive.rb +15 -0
  95. data/lib/mediawiktory/generated/filerepoinfo.rb +7 -0
  96. data/lib/mediawiktory/generated/filerevert.rb +10 -0
  97. data/lib/mediawiktory/generated/fileusage.rb +11 -0
  98. data/lib/mediawiktory/generated/flagconfig.rb +5 -0
  99. data/lib/mediawiktory/generated/flagged.rb +5 -0
  100. data/lib/mediawiktory/generated/flow-parsoid-utils.rb +10 -0
  101. data/lib/mediawiktory/generated/flow.rb +8 -0
  102. data/lib/mediawiktory/generated/flowinfo.rb +6 -0
  103. data/lib/mediawiktory/generated/flowthank.rb +8 -0
  104. data/lib/mediawiktory/generated/gadgetcategories.rb +8 -0
  105. data/lib/mediawiktory/generated/gadgets.rb +11 -0
  106. data/lib/mediawiktory/generated/geosearch.rb +15 -0
  107. data/lib/mediawiktory/generated/gettingstartedgetpages.rb +9 -0
  108. data/lib/mediawiktory/generated/globalallusers.rb +14 -0
  109. data/lib/mediawiktory/generated/globalblock.rb +12 -0
  110. data/lib/mediawiktory/generated/globalblocks.rb +14 -0
  111. data/lib/mediawiktory/generated/globalgroups.rb +7 -0
  112. data/lib/mediawiktory/generated/globalusage.rb +10 -0
  113. data/lib/mediawiktory/generated/globaluserinfo.rb +8 -0
  114. data/lib/mediawiktory/generated/globaluserrights.rb +12 -0
  115. data/lib/mediawiktory/generated/help.rb +10 -0
  116. data/lib/mediawiktory/generated/imageinfo.rb +19 -0
  117. data/lib/mediawiktory/generated/imagerotate.rb +5 -0
  118. data/lib/mediawiktory/generated/images.rb +10 -0
  119. data/lib/mediawiktory/generated/imageusage.rb +14 -0
  120. data/lib/mediawiktory/generated/import.rb +15 -0
  121. data/lib/mediawiktory/generated/info.rb +10 -0
  122. data/lib/mediawiktory/generated/iwbacklinks.rb +12 -0
  123. data/lib/mediawiktory/generated/iwlinks.rb +13 -0
  124. data/lib/mediawiktory/generated/jsonconfig.rb +8 -0
  125. data/lib/mediawiktory/generated/langbacklinks.rb +12 -0
  126. data/lib/mediawiktory/generated/langlinks.rb +14 -0
  127. data/lib/mediawiktory/generated/languagesearch.rb +7 -0
  128. data/lib/mediawiktory/generated/links.rb +11 -0
  129. data/lib/mediawiktory/generated/linkshere.rb +11 -0
  130. data/lib/mediawiktory/generated/listmembership.rb +10 -0
  131. data/lib/mediawiktory/generated/listpages.rb +14 -0
  132. data/lib/mediawiktory/generated/lists.rb +15 -0
  133. data/lib/mediawiktory/generated/liststudents.rb +9 -0
  134. data/lib/mediawiktory/generated/lock-topic.rb +10 -0
  135. data/lib/mediawiktory/generated/logevents.rb +19 -0
  136. data/lib/mediawiktory/generated/login.rb +11 -0
  137. data/lib/mediawiktory/generated/logout.rb +5 -0
  138. data/lib/mediawiktory/generated/managetags.rb +11 -0
  139. data/lib/mediawiktory/generated/massmessage.rb +10 -0
  140. data/lib/mediawiktory/generated/mmsites.rb +6 -0
  141. data/lib/mediawiktory/generated/mobileview.rb +21 -0
  142. data/lib/mediawiktory/generated/moderate-post.rb +11 -0
  143. data/lib/mediawiktory/generated/moderate-topic.rb +10 -0
  144. data/lib/mediawiktory/generated/move.rb +18 -0
  145. data/lib/mediawiktory/generated/new-topic.rb +11 -0
  146. data/lib/mediawiktory/generated/notifications.rb +17 -0
  147. data/lib/mediawiktory/generated/oldreviewedpages.rb +15 -0
  148. data/lib/mediawiktory/generated/opensearch.rb +12 -0
  149. data/lib/mediawiktory/generated/options.rb +12 -0
  150. data/lib/mediawiktory/generated/pageimages.rb +10 -0
  151. data/lib/mediawiktory/generated/pagepropnames.rb +8 -0
  152. data/lib/mediawiktory/generated/pageprops.rb +8 -0
  153. data/lib/mediawiktory/generated/pageswithprop.rb +11 -0
  154. data/lib/mediawiktory/generated/pageterms.rb +8 -0
  155. data/lib/mediawiktory/generated/pagetriageaction.rb +11 -0
  156. data/lib/mediawiktory/generated/pagetriagelist.rb +21 -0
  157. data/lib/mediawiktory/generated/pagetriagestats.rb +10 -0
  158. data/lib/mediawiktory/generated/pagetriagetagging.rb +13 -0
  159. data/lib/mediawiktory/generated/pagetriagetemplate.rb +7 -0
  160. data/lib/mediawiktory/generated/paraminfo.rb +11 -0
  161. data/lib/mediawiktory/generated/parse.rb +31 -0
  162. data/lib/mediawiktory/generated/parsoid-batch.rb +6 -0
  163. data/lib/mediawiktory/generated/patrol.rb +9 -0
  164. data/lib/mediawiktory/generated/prefixsearch.rb +10 -0
  165. data/lib/mediawiktory/generated/protect.rb +15 -0
  166. data/lib/mediawiktory/generated/protectedtitles.rb +14 -0
  167. data/lib/mediawiktory/generated/purge.rb +15 -0
  168. data/lib/mediawiktory/generated/query.rb +20 -0
  169. data/lib/mediawiktory/generated/querypage.rb +9 -0
  170. data/lib/mediawiktory/generated/random.rb +11 -0
  171. data/lib/mediawiktory/generated/recentchanges.rb +20 -0
  172. data/lib/mediawiktory/generated/redirects.rb +11 -0
  173. data/lib/mediawiktory/generated/refresheducation.rb +9 -0
  174. data/lib/mediawiktory/generated/reply.rb +11 -0
  175. data/lib/mediawiktory/generated/review.rb +10 -0
  176. data/lib/mediawiktory/generated/reviewactivity.rb +10 -0
  177. data/lib/mediawiktory/generated/revisiondelete.rb +14 -0
  178. data/lib/mediawiktory/generated/revisions.rb +25 -0
  179. data/lib/mediawiktory/generated/rollback.rb +13 -0
  180. data/lib/mediawiktory/generated/rsd.rb +5 -0
  181. data/lib/mediawiktory/generated/scribunto-console.rb +10 -0
  182. data/lib/mediawiktory/generated/search.rb +15 -0
  183. data/lib/mediawiktory/generated/setglobalaccountstatus.rb +12 -0
  184. data/lib/mediawiktory/generated/setnotificationtimestamp.rb +18 -0
  185. data/lib/mediawiktory/generated/siteinfo.rb +11 -0
  186. data/lib/mediawiktory/generated/sitematrix.rb +12 -0
  187. data/lib/mediawiktory/generated/spamblacklist.rb +6 -0
  188. data/lib/mediawiktory/generated/stabilize.rb +12 -0
  189. data/lib/mediawiktory/generated/stashedit.rb +14 -0
  190. data/lib/mediawiktory/generated/stashimageinfo.rb +12 -0
  191. data/lib/mediawiktory/generated/strikevote.rb +10 -0
  192. data/lib/mediawiktory/generated/tag.rb +13 -0
  193. data/lib/mediawiktory/generated/tags.rb +9 -0
  194. data/lib/mediawiktory/generated/templatedata.rb +13 -0
  195. data/lib/mediawiktory/generated/templates.rb +11 -0
  196. data/lib/mediawiktory/generated/thank.rb +9 -0
  197. data/lib/mediawiktory/generated/titleblacklist.rb +9 -0
  198. data/lib/mediawiktory/generated/tokens.rb +6 -0
  199. data/lib/mediawiktory/generated/transcludedin.rb +11 -0
  200. data/lib/mediawiktory/generated/transcodereset.rb +9 -0
  201. data/lib/mediawiktory/generated/transcodestatus.rb +5 -0
  202. data/lib/mediawiktory/generated/ulslocalization.rb +6 -0
  203. data/lib/mediawiktory/generated/unblock.rb +10 -0
  204. data/lib/mediawiktory/generated/undelete.rb +12 -0
  205. data/lib/mediawiktory/generated/undo-edit-header.rb +8 -0
  206. data/lib/mediawiktory/generated/undo-edit-post.rb +8 -0
  207. data/lib/mediawiktory/generated/undo-edit-topic-summary.rb +8 -0
  208. data/lib/mediawiktory/generated/upload.rb +26 -0
  209. data/lib/mediawiktory/generated/usercontribs.rb +18 -0
  210. data/lib/mediawiktory/generated/userdailycontribs.rb +8 -0
  211. data/lib/mediawiktory/generated/userinfo.rb +7 -0
  212. data/lib/mediawiktory/generated/userrights.rb +12 -0
  213. data/lib/mediawiktory/generated/users.rb +9 -0
  214. data/lib/mediawiktory/generated/videoinfo.rb +14 -0
  215. data/lib/mediawiktory/generated/view-header.rb +8 -0
  216. data/lib/mediawiktory/generated/view-post-history.rb +8 -0
  217. data/lib/mediawiktory/generated/view-post.rb +8 -0
  218. data/lib/mediawiktory/generated/view-topic-history.rb +7 -0
  219. data/lib/mediawiktory/generated/view-topic-summary.rb +8 -0
  220. data/lib/mediawiktory/generated/view-topic.rb +7 -0
  221. data/lib/mediawiktory/generated/view-topiclist.rb +15 -0
  222. data/lib/mediawiktory/generated/visualeditor.rb +13 -0
  223. data/lib/mediawiktory/generated/visualeditoredit.rb +19 -0
  224. data/lib/mediawiktory/generated/watch.rb +16 -0
  225. data/lib/mediawiktory/generated/watchlist.rb +20 -0
  226. data/lib/mediawiktory/generated/watchlistraw.rb +16 -0
  227. data/lib/mediawiktory/generated/wikibase.rb +7 -0
  228. data/lib/mediawiktory/generated/wikilove.rb +12 -0
  229. data/lib/mediawiktory/generated/wikisets.rb +10 -0
  230. data/lib/mediawiktory/generated/zeroconfig.rb +7 -0
  231. data/lib/mediawiktory/mw_module.rb +320 -0
  232. data/lib/mediawiktory/query.rb +60 -0
  233. data/lib/mediawiktory/version.rb +3 -0
  234. data/lib/mediawiktory.rb +16 -0
  235. data/lib/nokogiri/more.rb +72 -0
  236. data/mediawiktory.gemspec +30 -0
  237. data/script/data/api.yaml +40239 -0
  238. data/script/lib/api.rb +14 -0
  239. data/script/lib/module.rb +132 -0
  240. data/script/lib/parameter.rb +133 -0
  241. data/script/parse_api.rb +21 -0
  242. data/test/cache.rb +15 -0
  243. metadata +340 -0
@@ -0,0 +1,10 @@
1
+ module MediaWiktory
2
+ class Wikisets < MWModule
3
+ symbol :wikisets
4
+ prefix "ws"
5
+ param :from, Params::String
6
+ param :prop, Params::List[Params::Enum["type", "wikisincluded", "wikisnotincluded"]]
7
+ param :limit, Params::IntegerOrMax
8
+ param :orderbyname, Params::Boolean
9
+ end
10
+ end
@@ -0,0 +1,7 @@
1
+ module MediaWiktory
2
+ class Zeroconfig < Action
3
+ symbol :zeroconfig
4
+ param :type, Params::Enum["config", "message"]
5
+ param :agent, Params::String
6
+ end
7
+ end
@@ -0,0 +1,320 @@
1
+ module MediaWiktory
2
+ module Params
3
+ class Param
4
+ attr_reader :name, :value
5
+
6
+ def initialize(name, value = nil)
7
+ @name = name
8
+ self.value = value if value
9
+ end
10
+
11
+ def value=(val)
12
+ valid?(val) or
13
+ fail(ArgumentError, "Invalid value #{val.inspect} for param #{name} (#{self.class})")
14
+
15
+ @value = val
16
+ end
17
+
18
+ def to_param(prefix = nil)
19
+ {"#{prefix}#{name}" => value_to_param}
20
+ end
21
+
22
+ def value_to_param
23
+ value.to_s
24
+ end
25
+
26
+ def self.valid?(val)
27
+ true
28
+ end
29
+
30
+ def valid?(val)
31
+ self.class.valid?(val)
32
+ end
33
+ end
34
+
35
+ class String < Param
36
+ def self.valid?(val)
37
+ val.kind_of?(::String)
38
+ end
39
+ end
40
+
41
+ class Boolean < Param
42
+ def self.valid?(val)
43
+ [true, false].include?(val)
44
+ end
45
+ end
46
+
47
+ class Integer < Param
48
+ def self.valid?(val)
49
+ val.kind_of?(::Integer)
50
+ end
51
+ end
52
+
53
+ class IntegerOrMax < Integer
54
+ def self.valid?(val)
55
+ super || val == 'max'
56
+ end
57
+ end
58
+
59
+ class Timestamp < Param
60
+ def self.valid?(val)
61
+ val.kind_of?(::Time)
62
+ end
63
+
64
+ def value_to_param
65
+ value.iso8601
66
+ end
67
+ end
68
+
69
+ class Enum < Param
70
+ class << self
71
+ def [](*values)
72
+ Class.new(self){
73
+ self.allowed_values = values
74
+ }
75
+ end
76
+
77
+ attr_accessor :allowed_values
78
+
79
+ def inspect
80
+ "#<Enum#{allowed_values}>"
81
+ end
82
+
83
+ alias_method :to_s, :inspect
84
+ end
85
+
86
+ def self.valid?(val)
87
+ allowed_values or fail(NotImplementedError, "Abstract enum used as a param type")
88
+ allowed_values.include?(val)
89
+ end
90
+ end
91
+
92
+ class List < Param
93
+ class << self
94
+ def [](type)
95
+ Class.new(self){
96
+ self.member_type = type
97
+ }
98
+ end
99
+
100
+ attr_accessor :member_type
101
+
102
+ def inspect
103
+ "#<List#{member_type}>"
104
+ end
105
+
106
+ alias_method :to_s, :inspect
107
+ end
108
+
109
+ def self.valid?(val)
110
+ member_type or fail(NotImplementedError, "Abstract list used as param type")
111
+ val.is_a?(Array) && val.all?{|v| member_type.valid?(v)}
112
+ end
113
+
114
+ def value_to_param
115
+ value.join('|')
116
+ end
117
+ end
118
+
119
+ class Module < Param
120
+ class << self
121
+ def [](*values)
122
+ Class.new(self){
123
+ self.allowed_values = values
124
+ }
125
+ end
126
+
127
+ attr_accessor :allowed_values
128
+ end
129
+
130
+ def value=(val)
131
+ super(val && MWModule.coerce(val))
132
+ end
133
+
134
+ def to_param(prefix = nil)
135
+ {"#{prefix}#{name}" => value.class.symbol.to_s}.merge(value_to_param)
136
+ end
137
+
138
+ def value_to_param
139
+ if name == :generator
140
+ value.to_param.map{|k, v| ["g#{k}", v]}.to_h
141
+ else
142
+ value.to_param
143
+ end
144
+ end
145
+
146
+ def self.valid?(val)
147
+ allowed_values or fail(NotImplementedError, "Abstract module used as a param type")
148
+ allowed_values.include?(val.class.symbol)
149
+ end
150
+ end
151
+
152
+ class Modules < Param
153
+ class << self
154
+ def [](*values)
155
+ Class.new(self){
156
+ self.allowed_values = values
157
+ }
158
+ end
159
+
160
+ attr_accessor :allowed_values
161
+ end
162
+
163
+ def value=(val)
164
+ super(val && coerce_modules(val))
165
+ end
166
+
167
+ def to_param(prefix = nil)
168
+ {
169
+ "#{prefix}#{name}" => value.map{|v|v.class.symbol}.join('|')
170
+ }.merge(value_to_param)
171
+ end
172
+
173
+ def value_to_param
174
+ if name == :generator
175
+ value.map(&:to_param).inject({}, :merge).
176
+ map{|k, v| ["g#{k}", v]}.to_h
177
+ else
178
+ value.map(&:to_param).inject({}, :merge)
179
+ end
180
+ end
181
+
182
+ def self.valid?(val)
183
+ allowed_values or fail(NotImplementedError, "Abstract module used as a param type")
184
+ val.all?{|v| allowed_values.include?(v.class.symbol)}
185
+ end
186
+
187
+ private
188
+
189
+ def coerce_modules(value)
190
+ # making array of 1-item hashes
191
+ value.map{|val|
192
+ case val
193
+ when Symbol
194
+ {val => {}}
195
+ when Hash
196
+ val.map{|k, v| {k => v}}
197
+ when MWModule
198
+ val
199
+ else
200
+ fail(ArgumentError, "#{val} can not be coerced into module")
201
+ end
202
+ }.flatten.map{|h| MWModule.coerce(h)}
203
+ end
204
+ end
205
+ end
206
+
207
+ class MWModule
208
+
209
+ class << self
210
+ def list
211
+ @list ||= {}
212
+ end
213
+
214
+ def symbol(sym = nil)
215
+ return @symbol unless sym
216
+ @symbol = sym
217
+ MWModule.list[sym] = self
218
+ end
219
+
220
+ def prefix(pref = nil)
221
+ return @prefix unless pref
222
+ @prefix = pref
223
+ end
224
+
225
+ def coerce(value)
226
+ case value
227
+ when Symbol
228
+ MWModule.list.key?(value) or
229
+ fail(ArgumentError, "Unsupported module: #{value} for #{self}")
230
+ MWModule.list[value].new
231
+
232
+ when Hash
233
+ value.count == 1 or
234
+ fail(ArgumentError, "Too many values for module initialization")
235
+
236
+ name, attr = value.first
237
+ MWModule.list.key?(name) or
238
+ fail(ArgumentError, "Unsupported module: #{name} for #{self}")
239
+
240
+ attr.is_a?(Hash) or
241
+ fail(ArgumentError, "Module only can be initialized with a hash, #{attr.class} given")
242
+
243
+ MWModule.list[name].new(attr)
244
+ when MWModule
245
+ value
246
+ else
247
+ fail ArgumentError, "Can not coerce #{value} into module"
248
+ end
249
+ end
250
+
251
+ def params
252
+ @params ||= {}
253
+ end
254
+
255
+ def param(name, type)
256
+ params[name] = type
257
+
258
+ define_method(name){|*arg|
259
+ return param(name).value if arg.empty?
260
+
261
+ dup.tap{|dup|
262
+ case
263
+ when type.ancestors.include?(Params::List) ||
264
+ type.ancestors.include?(Params::Modules)
265
+ dup.param(name).value = arg.flatten
266
+ else
267
+ dup.param(name).value = arg.first
268
+ end
269
+ }
270
+ }
271
+ end
272
+
273
+ def request_method
274
+ @request_method || :get
275
+ end
276
+
277
+ def post!
278
+ @request_method = :post
279
+ end
280
+ end
281
+
282
+ def initialize(**values)
283
+ @params = Hash.new{|h, name|
284
+ self.class.params.key?(name) or
285
+ fail(ArgumentError, "Unknown param: #{name} for #{self}")
286
+ h[name] = self.class.params[name].new(name)
287
+ }
288
+
289
+ values.each do |k, v|
290
+ set(k, v)
291
+ end
292
+ end
293
+
294
+ def dup
295
+ self.class.new(to_h)
296
+ end
297
+
298
+ def to_h
299
+ @params.map{|n, p| [n, p.value]}.to_h
300
+ end
301
+
302
+ def param(name)
303
+ @params[name]
304
+ end
305
+
306
+ def to_param
307
+ @params.values.
308
+ map{|p| p.to_param(self.class.prefix)}.
309
+ inject({}, :merge)
310
+ end
311
+
312
+ protected
313
+
314
+ def set(name, value)
315
+ self.class.params.key?(name) or
316
+ fail(ArgumentError, "Unknown param: #{name} for #{self}")
317
+ @params[name] = self.class.params[name].new(name, value)
318
+ end
319
+ end
320
+ end
@@ -0,0 +1,60 @@
1
+ require_relative 'array_with_keys'
2
+
3
+ module MediaWiktory
4
+ class Query
5
+ def continue(additional_params)
6
+ client.get(to_param.merge(additional_params))
7
+ end
8
+
9
+ class Response < Action::Response
10
+ def pages
11
+ @pages ||= ArrayWithKeys.from_hash(raw.query.pages || {})
12
+ end
13
+
14
+ def continue?
15
+ !raw.continue.nil?
16
+ end
17
+
18
+ def continue!
19
+ continue? or fail(RuntimeError, "Response can not be continued")
20
+
21
+ merge!(action.perform(raw.continue))
22
+
23
+ self
24
+ end
25
+
26
+ def continue
27
+ dup.continue!
28
+ end
29
+
30
+ private
31
+
32
+ def merge!(other)
33
+ # FIXME: not the brightest code in my life, faithfully
34
+ # FIXME2: after this merge, only @pages are updated, but @raw.query.pages IS NOT
35
+ other.pages.to_h.each do |k, p|
36
+ if (existing = pages[k])
37
+ merge_page(existing, p)
38
+ else
39
+ pages.push(p, p.id)
40
+ end
41
+ end
42
+
43
+ raw.continue = other.raw.continue
44
+ end
45
+
46
+ def merge_page(existing, other)
47
+ other.each do |k, v|
48
+ case existing[k]
49
+ when Array
50
+ existing[k].concat(v)
51
+ when Hash
52
+ existing[k].merge!(v)
53
+ else
54
+ existing[k] = v
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,3 @@
1
+ module MediaWiktory
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,16 @@
1
+ require 'addressable/uri'
2
+ require 'faraday'
3
+
4
+ module MediaWiktory
5
+ %w[client mw_module action].each do |mod|
6
+ require_relative "mediawiktory/#{mod}"
7
+ end
8
+
9
+ Dir[File.expand_path('../mediawiktory/generated/*.rb', __FILE__)].each do |gen|
10
+ require gen
11
+ end
12
+
13
+ %w[query].each do |mod|
14
+ require_relative "mediawiktory/#{mod}"
15
+ end
16
+ end
@@ -0,0 +1,72 @@
1
+ require 'naught'
2
+
3
+ module Nokogiri
4
+ module More
5
+ module NodeChildrenGroups
6
+ def children_groups(*selectors)
7
+ groups = []
8
+ flat = children.select{|node| selectors.any?{|s| node.matches?(s)}}
9
+ while !flat.empty?
10
+ groups << make_group(flat, selectors)
11
+ end
12
+ groups
13
+ end
14
+
15
+ #include NodeOnlyFor
16
+
17
+ def each_term
18
+ children_groups('dt', 'dd')
19
+ end
20
+
21
+ private
22
+
23
+ def make_group(flat, selectors)
24
+ sel = selectors.dup
25
+ group = [[]]
26
+ while !flat.empty?
27
+ if flat.first.matches?(sel.first)
28
+ group.last << flat.shift
29
+ elsif sel.size > 1 && flat.first.matches?(sel[1])
30
+ sel.shift
31
+ group << []
32
+ group.last << flat.shift
33
+ else
34
+ break
35
+ end
36
+ end
37
+ group
38
+ end
39
+ end
40
+
41
+ NodeNaught = Naught.build do |config|
42
+ config.black_hole
43
+
44
+ # so you can just `at?(selector).tap{|node| ...`
45
+ # and never be inside `tap`, if it's not found
46
+ def tap
47
+ self
48
+ end
49
+ end
50
+
51
+ module NodeQuestMethods
52
+ def at?(selector)
53
+ at(selector) || NodeNaught.new
54
+ end
55
+
56
+ def at_css?(selector)
57
+ at_css(selector) || NodeNaught.new
58
+ end
59
+
60
+ def at_xpath?(selector)
61
+ at_xpath(selector) || NodeNaught.new
62
+ end
63
+
64
+ def find_child?(selector)
65
+ find_child(selector) || NodeNaught.new
66
+ end
67
+ end
68
+ end
69
+
70
+ Nokogiri::XML::Node.send(:include, More::NodeChildrenGroups)
71
+ Nokogiri::XML::Node.send(:include, More::NodeQuestMethods)
72
+ end
@@ -0,0 +1,30 @@
1
+ require './lib/mediawiktory/version'
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = 'mediawiktory'
5
+ s.version = MediaWiktory::VERSION
6
+ s.authors = ['Victor Shepelev']
7
+ s.email = 'zverok.offline@gmail.com'
8
+ s.homepage = 'https://github.com/molybdenum-99/mediawiktory'
9
+
10
+ s.summary = 'Full-featured MediaWiki client with Arel-like queries'
11
+ s.licenses = ['MIT']
12
+
13
+ s.files = `git ls-files`.split($RS).reject do |file|
14
+ file =~ /^(?:
15
+ spec\/.*
16
+ |Gemfile
17
+ |Rakefile
18
+ |\.rspec
19
+ |\.gitignore
20
+ |\.rubocop.yml
21
+ |\.travis.yml
22
+ )$/x
23
+ end
24
+ s.require_paths = ["lib"]
25
+
26
+ s.add_dependency 'faraday'
27
+ s.add_dependency 'faraday_middleware'
28
+ s.add_dependency 'hashie'
29
+ s.add_dependency 'addressable'
30
+ end