ruqqus 0.1.0 → 1.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bd42579f445107afb73ab5bddc39fda6140c1fed069b05f65dd9cf57553ae3d8
4
- data.tar.gz: 7e4e2e8ef4de56a77004e94454ef47d0312d80de869efba80061214ae29bc729
3
+ metadata.gz: 1274eade9799203bd720c94da255a81a0e0295da9e438519a687626c1db7f0b7
4
+ data.tar.gz: 96fe1b73d77d38004981f476ddca3acde81577755de6939f77c6c4ea65fdc693
5
5
  SHA512:
6
- metadata.gz: a5261490b9979f2c5817ad9ab8708862cae3e98870631ec6e31cdda4c068465a773bd08a54a5a3d04a3e7dc7bbcd8b655b03d9ec59ee9aa45d7cee84621b7c79
7
- data.tar.gz: e48634320aafc078099254ae5b74e4222b1ea2b8b043c71bd76168b53607c56e58ca43b196da7ef0ead733439abc7c3f3006add27392f700c3a165dbcd3f37ab
6
+ metadata.gz: da793dbcee6ae0cd28b6f5160f85a752804a44ceb00f295291209e2529a3ba39ed26300f43b8b9df95f4ce41b7c3c10b97f60550eed9b9ce5c27c50b4252a638
7
+ data.tar.gz: 92b77622dcaf2fa8129e013465a91186d1de731eb927bcd219fac8160c7afccceb2beecf4f509f7e3b9fe95c8b9431955d301566eeaa5608302a2331ce87743c
data/.gitignore CHANGED
@@ -1,8 +1,171 @@
1
- /.bundle/
2
- /.yardoc
3
- /_yardoc/
1
+
2
+ # Created by https://www.toptal.com/developers/gitignore/api/ruby,rubymine+all,visualstudiocode
3
+ # Edit at https://www.toptal.com/developers/gitignore?templates=ruby,rubymine+all,visualstudiocode
4
+
5
+ ### Ruby ###
6
+ *.gem
7
+ *.rbc
8
+ /.config
4
9
  /coverage/
5
- /doc/
10
+ /InstalledFiles
6
11
  /pkg/
7
12
  /spec/reports/
13
+ /spec/examples.txt
14
+ /test/tmp/
15
+ /test/version_tmp/
8
16
  /tmp/
17
+
18
+ # Used by dotenv library to load environment variables.
19
+ # .env
20
+
21
+ # Ignore Byebug command history file.
22
+ .byebug_history
23
+
24
+ ## Specific to RubyMotion:
25
+ .dat*
26
+ .repl_history
27
+ build/
28
+ *.bridgesupport
29
+ build-iPhoneOS/
30
+ build-iPhoneSimulator/
31
+
32
+ ## Specific to RubyMotion (use of CocoaPods):
33
+ #
34
+ # We recommend against adding the Pods directory to your .gitignore. However
35
+ # you should judge for yourself, the pros and cons are mentioned at:
36
+ # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
37
+ # vendor/Pods/
38
+
39
+ ## Documentation cache and generated files:
40
+ /.yardoc/
41
+ /_yardoc/
42
+ /doc/
43
+ /rdoc/
44
+
45
+ ## Environment normalization:
46
+ /.bundle/
47
+ /vendor/bundle
48
+ /lib/bundler/man/
49
+
50
+ # for a library or gem, you might want to ignore these files since the code is
51
+ # intended to run in multiple environments; otherwise, check them in:
52
+ Gemfile.lock
53
+ # .ruby-version
54
+ # .ruby-gemset
55
+
56
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
57
+ .rvmrc
58
+
59
+ # Used by RuboCop. Remote config files pulled in from inherit_from directive.
60
+ # .rubocop-https?--*
61
+
62
+ ### Ruby Patch ###
63
+ # Used by RuboCop. Remote config files pulled in from inherit_from directive.
64
+ # .rubocop-https?--*
65
+
66
+ ### RubyMine+all ###
67
+ # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
68
+ # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
69
+
70
+ # User-specific stuff
71
+ .idea/**/workspace.xml
72
+ .idea/**/tasks.xml
73
+ .idea/**/usage.statistics.xml
74
+ .idea/**/dictionaries
75
+ .idea/**/shelf
76
+
77
+ # Generated files
78
+ .idea/**/contentModel.xml
79
+
80
+ # Sensitive or high-churn files
81
+ .idea/**/dataSources/
82
+ .idea/**/dataSources.ids
83
+ .idea/**/dataSources.local.xml
84
+ .idea/**/sqlDataSources.xml
85
+ .idea/**/dynamic.xml
86
+ .idea/**/uiDesigner.xml
87
+ .idea/**/dbnavigator.xml
88
+
89
+ # Gradle
90
+ .idea/**/gradle.xml
91
+ .idea/**/libraries
92
+
93
+ # Gradle and Maven with auto-import
94
+ # When using Gradle or Maven with auto-import, you should exclude module files,
95
+ # since they will be recreated, and may cause churn. Uncomment if using
96
+ # auto-import.
97
+ # .idea/artifacts
98
+ # .idea/compiler.xml
99
+ # .idea/jarRepositories.xml
100
+ # .idea/modules.xml
101
+ # .idea/*.iml
102
+ # .idea/modules
103
+ # *.iml
104
+ # *.ipr
105
+
106
+ # CMake
107
+ cmake-build-*/
108
+
109
+ # Mongo Explorer plugin
110
+ .idea/**/mongoSettings.xml
111
+
112
+ # File-based project format
113
+ *.iws
114
+
115
+ # IntelliJ
116
+ out/
117
+
118
+ # mpeltonen/sbt-idea plugin
119
+ .idea_modules/
120
+
121
+ # JIRA plugin
122
+ atlassian-ide-plugin.xml
123
+
124
+ # Cursive Clojure plugin
125
+ .idea/replstate.xml
126
+
127
+ # Crashlytics plugin (for Android Studio and IntelliJ)
128
+ com_crashlytics_export_strings.xml
129
+ crashlytics.properties
130
+ crashlytics-build.properties
131
+ fabric.properties
132
+
133
+ # Editor-based Rest Client
134
+ .idea/httpRequests
135
+
136
+ # Android studio 3.1+ serialized cache file
137
+ .idea/caches/build_file_checksums.ser
138
+
139
+ ### RubyMine+all Patch ###
140
+ # Ignores the whole .idea folder and all .iml files
141
+ # See https://github.com/joeblau/gitignore.io/issues/186 and https://github.com/joeblau/gitignore.io/issues/360
142
+
143
+ .idea/
144
+
145
+ # Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023
146
+
147
+ *.iml
148
+ modules.xml
149
+ .idea/misc.xml
150
+ *.ipr
151
+
152
+ # Sonarlint plugin
153
+ .idea/sonarlint
154
+
155
+ ### VisualStudioCode ###
156
+ .vscode/*
157
+ !.vscode/settings.json
158
+ !.vscode/tasks.json
159
+ !.vscode/launch.json
160
+ !.vscode/extensions.json
161
+ *.code-workspace
162
+
163
+ ### VisualStudioCode Patch ###
164
+ # Ignore all local history of files
165
+ .history
166
+
167
+ # End of https://www.toptal.com/developers/gitignore/api/ruby,rubymine+all,visualstudiocode
168
+
169
+ # JSON file containing the token for test user during development
170
+ /token.json
171
+ /test.rb
@@ -0,0 +1,6 @@
1
+ --readme README.md
2
+ --title 'Ruqqus'
3
+ --charset utf-8
4
+ --markup markdown
5
+ --protected
6
+ lib/**/*.rb
@@ -2,7 +2,53 @@
2
2
 
3
3
  Documentation for library API changes.
4
4
 
5
- ## Version 0.1
5
+ Versioning system:
6
6
 
7
- *
8
- *
7
+ `MAJOR.MINOR.REVISION`
8
+
9
+ * `MAJOR` Corresponds to the native Ruqqus API major version
10
+ * `MINOR` Indicates possible breaking API changes for existing code
11
+ * `REVISION` Added functionality, bug-fixes, and other non-breaking alterations
12
+
13
+ ## Version 1.1.3
14
+
15
+ * Implemented browser-based confirmation process
16
+ * Implemented capturing confirmation code from `localhost` OAuth redirects
17
+ * Fixed bug in querying guild/username availability
18
+
19
+ ## Version 1.1.2
20
+
21
+ * Implemented enumerating comments of guilds and posts
22
+
23
+ ## Version 1.1.1
24
+
25
+ * BUGFIX: Added acceptance of variable args to `Token#to_json`
26
+ * BUGFIX: Fixed regex validator in `ruqqus-oauth` for the client ID
27
+ * Separated the client ID/secret from the `Token` class, and placed within `Client` to now handle this logic
28
+
29
+ ## Version 1.1.0
30
+
31
+ * Implemented `Ruqqus::Token` class to handle OAuth2 authentication
32
+ * Added `Ruqqus::Client` class as the primary object for API usage
33
+ * Implemented post creation
34
+ * Implemented comment creation and deletion
35
+ * Implementing querying for reserved usernames/guilds
36
+ * Implemented retrieving posts of guilds
37
+ * Implemented retrieving posts and comments of users
38
+ * Implemented voting on posts and comments as a user
39
+ * Implemented enumerating all guilds
40
+ * Implemented enumerating through all posts
41
+ * Refactored `Ruqqus.user_info` to `Ruqqus::Client#user`
42
+ * Refactored `Ruqqus.guild_info` to `Ruqqus::Client#guild`
43
+ * Refactored `Ruqqus.post_info` to `Ruqqus::Client#post`
44
+ * Refactored `Ruqqus.comment_info` to `Ruqqus::Client#comment`
45
+ * Many improvements in code and better adhesion to DRY principles
46
+ * Added helper method to automate uploading and creating image posts on Ruqqus via Imgur
47
+
48
+ ## Version 1.0.1
49
+
50
+ * Changed validation for `fomr_url` methods in `Post` and `Comment` to also accept relative URIs.
51
+
52
+ ## Version 1.0.0
53
+
54
+ * Initial release, 100% coverage of existing Ruqqus API
data/Gemfile CHANGED
@@ -1,7 +1,4 @@
1
- source "https://rubygems.org"
1
+ source 'https://rubygems.org'
2
2
 
3
- # Specify your gem's dependencies in ruqqus.gemspec
3
+ # Dependencies specified in ruqqus.gemspec
4
4
  gemspec
5
-
6
- gem "rake", "~> 12.0"
7
- gem "minitest", "~> 5.0"
data/README.md CHANGED
@@ -1,8 +1,21 @@
1
+ <p align="center">
2
+ <img src="https://raw.githubusercontent.com/ruqqus/ruqqus/master/ruqqus/assets/images/logo/ruqqus_text_logo.png" width="250"/>
3
+ </p>
4
+
5
+ <hr>
6
+
1
7
  # Ruqqus
2
8
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/ruqqus`. To experiment with that code, run `bin/console` for an interactive prompt.
9
+ A Ruby API implementation for [Ruqqus](https://ruqqus.com/), an [open-source](https://github.com/ruqqus/ruqqus) platform for online communities, free of censorship and moderator abuse by design. [Sign up](https://ruqqus.com/signup?ref=foreverzer0
10
+ ) if you haven't yet!
4
11
 
5
- TODO: Delete this and the text above, and describe your gem
12
+ [![Build Status](https://travis-ci.org/ForeverZer0/ruqqus.svg?branch=master)](https://travis-ci.org/ForeverZer0/ruqqus)
13
+ [![Gem Version](https://badge.fury.io/rb/ruqqus.svg)](https://rubygems.org/gems/ruqqus)
14
+ [![Inline docs](http://inch-ci.org/github/ForeverZer0/ruqqus.svg?branch=master)](http://inch-ci.org/github/ForeverZer0/ruqqus)
15
+ [![Maintainability](https://api.codeclimate.com/v1/badges/c39f44a706302e4cd340/maintainability)](https://codeclimate.com/github/ForeverZer0/ruqqus/maintainability)
16
+ [![OpenIssues](https://img.shields.io/github/issues/ForeverZer0/ruqqus)](https://github.com/ForeverZer0/ruqqus/issues)
17
+ [![License](https://img.shields.io/github/license/ForeverZer0/ruqqus)](https://opensource.org/licenses/MIT)
18
+ [![Ruby](https://img.shields.io/badge/powered%20by-ruby-red)](https://www.ruby-lang.org/en/)
6
19
 
7
20
  ## Installation
8
21
 
@@ -20,20 +33,240 @@ Or install it yourself as:
20
33
 
21
34
  $ gem install ruqqus
22
35
 
36
+ To use the `ruqqus-oauth` helper to generate user tokens for desktop development:
37
+
38
+ $ gem install ruqqus --development
39
+
40
+ ## Authentication
41
+
42
+ Ruqqus enables 3rd-party client authorization using the [OAuth2 protocol](https://oauth.net/2/). Before it is possible
43
+ to interact with the API, you will need to first [register an application](https://ruqqus.com/settings/apps), which can
44
+ be supply you with an API key/secret pair. This key will allow you to authorize users and grant privileges with an
45
+ assortment of scopes to fit your needs.
46
+
47
+ ### Desktop Development
48
+
49
+ This gem includes a tool to automate obtaining a client code for users, primarily aimed for desktop developers who do
50
+ not have a server running to receive the redirect URL. The tool requires the `mechanize` and `tty-prompt` gems, which
51
+ are not included by default.
52
+
53
+ To install the tool with its dependencies, install this gem with the following flag.
54
+
55
+ $ gem insall ruqqus --development
56
+
57
+ Once installed, simply run `ruqqus-oauth`. You will be prompted to input the API key that was issued by Ruqqus to your
58
+ approved application, and the user credentials for the account you with to authorize, such as that for a bot. Once
59
+ executed, an authorization code will be displayed on-screen, which you can then use to create a token.
60
+
61
+ ```ruby
62
+ require 'ruqqus'
63
+
64
+ client_id = 'XXXXXX' # Received after registering application
65
+ client_secret = 'XXXXXX' # Received after registering application
66
+ code = 'XXXXXX' # The generated code (or the one you obtained via traditional means)
67
+
68
+ # You must implement a responsible way of storing this token for reuse.
69
+ token = Ruqqus::Token.new(client_id, client_secret, code)
70
+ client = Ruqqus::Client.new(client_id, client_secret, token)
71
+
72
+ # Alternatively, you can create a new token and a client with a single call.
73
+ # This will perform the "grant" action of the code while creating it automatically
74
+ client = Ruqqus::Client.new(client_id, client_secret, code)
75
+ ```
76
+
77
+ The token will automatically refresh itself as-needed, but you will need to handle storing its new value for repeated
78
+ uses. To facilitate this and make it easier, there is a callback that can be subscribed to which will be called each
79
+ time the access key is updated.
80
+
81
+ ```ruby
82
+ # Load an existing token that has already been authorized
83
+ token = Ruqqus::Token.load_json('./token.json')
84
+
85
+ # Create your client
86
+ client = Ruqqus::Client.new(client_id, client_secret, token)
87
+
88
+ # Set the callback block to automatically update the saved token when it refreshes
89
+ client.token_refreshed do |t|
90
+ t.save_json('./token.json')
91
+ end
92
+ ```
93
+
94
+ The token obtains sensitive material, and due to the security issues of storing it in plain text, this functionality is
95
+ left to the user. The token is essentially the equivalent of your user credentials for Ruqqus, so bear that in mind how
96
+ and where you store this information so that it is not compromised.
97
+
23
98
  ## Usage
24
99
 
25
- TODO: Write usage instructions here
100
+ See the [documentation](https://www.rubydoc.info/gems/ruqqus) for a complete API reference (100% coverage).
26
101
 
27
- ## Development
102
+ ### Features
28
103
 
29
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
104
+ The bulk of the API is obviously related to performing actions as a user, such as posting, commenting, voting, etc.. The
105
+ following highlights some of these features.
30
106
 
31
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
107
+ * Vote on posts and comments
108
+ * Create posts (text/link/image)
109
+ * Automated image upload via anonymous upload to Imgur ([API Key](https://imgur.com/account/settings/apps) required)
110
+ * Create/edit/delete comments
111
+ * Enumerate all existing guilds
112
+ * Enumerate all posts in a guild
113
+ * Enumerate all posts on the "front page", "all", etc., with sorting and filtering
114
+ * Enumerate all posts/comments of users (excluding private/banned/blocked accounts)
32
115
 
33
- ## Contributing
116
+ #### Misc. Examples
117
+
118
+ Some random examples displaying the ease in performing various operations.
119
+
120
+ ##### Let's do some voting!
121
+ ```ruby
122
+ client.each_user_post('captainmeta4') do |post|
123
+ # Upvote our fearless leader's posts
124
+ client.vote_post(post, 1)
125
+ end
126
+
127
+ client.each_user_comment('captainmeta4') do |comment|
128
+ # ...and his comments.
129
+ client.vote_comment(comment, 1)
130
+ end
131
+ ```
132
+
133
+ ##### Monitor For New Posts
134
+ ```ruby
135
+ delay = 10
136
+ puts 'Watching for new posts, press Ctrl+C to quit'
137
+ loop do
138
+ time = Time.now
139
+ sleep(delay)
140
+
141
+ puts "Checking the front page for new posts since #{time}"
142
+ client.each_post(sort: :new, filter: :all) do |post|
143
+ # Stop checking post once we encounter one older than this iteration
144
+ break if post.created < time
145
+ # Do something about this new post showing up in All
146
+ puts "Found a new post: '#{post.title}'"
147
+ end
148
+ end
149
+ ```
150
+ ##### Download all images from a guild
151
+ ```ruby
152
+ require 'open-uri'
153
+ domains = %w[i.ruqqus.com i.imgur.com]
154
+
155
+ Dir.mkdir('./tree_pics') unless Dir.exist?('./tree_pics')
156
+ client.each_guild_post('Trees', sort: :new) do |post|
157
+ next unless domains.include?(post.domain)
158
+ ext = File.extname(post.url)
159
+ ext = '.jpg' if ext.empty? # We don't care, just an example
160
+ path = File.join('./tree_pics', post.id + ext)
161
+ URI.open(post.url) { |src| File.open(path, 'wb') { |dst| dst.write(src.read) } }
162
+ end
163
+ ```
164
+
165
+ ### Types
34
166
 
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/ruqqus.
167
+ The Ruqqus API exposes four primary types:
168
+
169
+ * Users
170
+ * Guilds
171
+ * Posts
172
+ * Comments
173
+
174
+ Nearly all client operations interact with one or more of these entities in some way. Each of these types also has an
175
+ `#id` property that can be used with other related API functions, such as voting, replying, deleting, etc. The full
176
+ documentation listing all properties they obtain can be found [here](https://www.rubydoc.info/gems/ruqqus), but the API
177
+ is rather intuitive. Here are some samples of their basic
178
+ usage.
179
+
180
+ #### Users
181
+
182
+ Obtain information about users.
183
+
184
+ ```ruby
185
+ user = client.user_info('foreverzer0')
186
+
187
+ # Get user's total rep (as well as separate for comments/posts)
188
+ user.total_rep
189
+ #=> 22234
190
+
191
+ # Enumerate earned badges
192
+ user.badges.map(&:to_s)
193
+ #=> ["Joined Ruqqus during open beta", "Verified Email", "Recruited 10 friends to join Ruqqus"]
194
+
195
+ # Retrieve a Time object for when user created account
196
+ user.created
197
+ #=> 2020-06-16 21:59:04 -0400
198
+ ```
199
+
200
+ #### Guilds
201
+
202
+ Obtain information about guilds.
203
+
204
+ ```ruby
205
+ guild = client.guild('Ruby')
206
+
207
+ # Query the number of members, description, accent color, etc.
208
+ guild.member_count
209
+ #=> 43
210
+
211
+ # Links to guild's banner, profile, etc.
212
+ guild.banner_url
213
+ #=> "https://i.ruqqus.com/board/ruby/banner-2.png"
214
+
215
+ # Check for flags such as NSFW, NSFL, deletion, banned, "offensive", etc.
216
+ guild.nsfw?
217
+ #=> false
218
+ ```
219
+
220
+ #### Posts
221
+
222
+ Obtain information about posts.
223
+
224
+ ```ruby
225
+ # Post IDs can be found within any link to a post.
226
+ # https://ruqqus.com/post/<POST ID>/<POST TITLE>
227
+
228
+ post_id = '2e0x'
229
+ post = client.post(post_id)
230
+
231
+ # Obtain relevant information pertaining the guilds on Ruqqus
232
+
233
+ post.author_name
234
+ #=> "Galadriel"
235
+
236
+ post.title
237
+ #=> "Made this project in Ruby On Rails"
238
+
239
+ post.url
240
+ #=> "https://ruqqus-metrics.com/"
241
+
242
+ post.score
243
+ #=> 10
244
+ ```
245
+
246
+ #### Comments
247
+
248
+ Obtain information about comments. Comments are very similar to posts, but have a few unique methods for obtaining their nesting level, parent post/comment, etc.
249
+
250
+ ```ruby
251
+ # Post IDs can be found within any link to a post.
252
+ # https://ruqqus.com/post/<POST ID>/<POST TITLE>/<COMMENT ID>
253
+
254
+ comment_id = '67mt'
255
+ comment = client.comment(comment_id)
256
+
257
+ client.post(comment.post).title
258
+ #=> "Hi. I'm Josh Roehl, singer and songwriter of the hit song \"Endless Summer\". I am hosting an AMA here."
259
+
260
+ comment.body
261
+ #=> "I'm fully aware that I'm not a very good singer. Let's call it half-singing, half-rapping."
262
+
263
+ client.user(comment.author_name).ban_reason
264
+ #=> "Spam"
265
+ ```
266
+
267
+ ## Contributing
36
268
 
269
+ Bug reports and pull requests are welcome on GitHub at https://github.com/ForeverZer0/ruqqus.
37
270
 
38
271
  ## License
39
272