README.md in mangadex-5.4.9 vs README.md in mangadex-5.4.11

- old
+ new

@@ -21,10 +21,344 @@ $ gem install mangadex ## Usage Please note that I tried my best to follow Mangadex's naming conventions for [their documentation](https://api.mangadex.org). Track the progress [here in an issue](https://github.com/thedrummeraki/mangadex/issues/5). -To find out how to use the gem, you're welcome to [check this out](lib/mangadex). +Although a work a in progress, feel free to [check this out](lib/mangadex). + +### Basic Usage + +Here's a couple of cool things you can do with the gem: + +#### Get a list of manga + +```ruby +response = Mangadex::Manga.list +manga = response.data # Array of #<Mangadex::Manga> +``` + +#### Get a manga by id, with cover_art + +```ruby +manga_id = 'd86cf65b-5f6c-437d-a0af-19a31f94ec55' +response = Mangadex::Manga.get(manga_id, includes: :cover_art) +entity = response.data # Object of #<Mangadex::Manga> + +# Original size +entity.cover_art.image_url(size: :original) +entity.cover_art.image_url(size: :medium) +entity.cover_art.image_url(size: :small) # default size +``` + +#### Get a manga's chapter list, ordered by volume and chapter number + +```ruby +manga_id = 'd86cf65b-5f6c-437d-a0af-19a31f94ec55' +manga_response = Mangadex::Manga.get(manga_id, includes: :cover_art) +entity = manga_response.data + +chapter_response = Mangadex::Chapter.list( + manga: entity.id, + order: { volume: 'asc', chapter: 'asc' }, + translated_language: 'en', +) +chapters = chapter_response.data # Array of #<Mangadex::Chapter> +``` + +#### Get a chapter's pages + +```ruby +chapter_id = 'e7bb1892-7f83-4a89-bccc-0d6d403a85fc' +chapter = Mangadex::Chapter.get(chapter_id).data +pages = chapter.page_urls # Data saver true by default +``` + +#### Search for manga by title + +```ruby +response = Mangadex::Manga.list(title: 'Ijiranaide nagatoro') +found_manga = response.data +``` + +#### Authenticate + +```ruby +Mangadex::Auth.login(username: 'username', password: 'password') do |user| + # `user` is of type Mangadex::Api::User + puts(user.mangadex_user_id) + puts(user.session) + puts(user.refresh) + puts(user.session_valid_until) +end +``` + +You can access the authenticated user by using context: + +```ruby +user = Mangadex.context.user +``` + +#### Refresh the user's token + +```ruby +Mangadex.context.user.refresh_session! do |user| + # `user` is of type Mangadex::Api::User + puts(user.mangadex_user_id) + puts(user.session) + puts(user.refresh) + puts(user.session_valid_until) +end +``` + +#### Create an public MDList, add then remove a manga + +```ruby +Mangadex::Auth.login(...) +response = Mangadex::CustomList.create(name: 'My awesome list!', visibility: 'public') +custom_list = response.data + +manga_id = 'd86cf65b-5f6c-437d-a0af-19a31f94ec55' +# Add the manga +custom_list.add_manga(manga_id) + +# Remove the manga +custom_list.remove_manga(manga_id) + +# Get manga list +manga = custom_list.manga_details.data # Array of #<Mangadex::Manga> +``` + +### Are you on Rails? + +This gem tries its best to be agnostic to popular frameworks like Rails. Here's however a couple of things to can do to integrate the gem to your project. + +First, add the gem to your `Gemfile`. + +#### Configurating the gem + +Create a initilizer file to `config/initializers/mangadex.rb`. You can add the following: + +```ruby +Mangadex.configure do |config| + # Override the default content ratings + config.default_content_ratings = %w(safe suggestive) + + # Override the Mangadex API URL (ie: proxy) + config.mangadex_url = 'https://my-proxy-mangadex-url.com' +end +``` + +#### Authenticate your users + +This could be useful if you want to support authentication. You will need to persist your user's session, refresh token and session expiry date. + +##### Persist the user information + +If you haven't done so, create your user. + +```ruby +class CreateUsers < ActiveRecord::Migration[6.1] + def change + create_table :users do |t| + t.string :mangadex_user_id, null: false + t.string :username + t.string :session + t.string :refresh + t.datetime :session_valid_until + + t.timestamps + end + end +end + +``` + +Already created your `User` class? Make sure it has all of the following: +- `mangade_user_id`: ID used to identify your user on Mangadex +- `username`: Your username +- `session`: The session token (valid for 15 minutes) +- `refresh`: The refresh token, used to refresh the session (valid for 1 month) +- `session_valid_until`: The time `session` session expires at + +If anything is missing, create a migration. + +#### Authentication flow on the controller + +Add these methods to your controller's helper (ie: `ApplicationHelper`): + +```ruby +module ApplicationHelper + def current_user + @current_user ||= User.find_by(id: session[:id]) + end + + def logged_in? + current_user.present? + end + + def log_in(user) + # `user` is an instance of your `User` class + session[:id] = user.id6 + end + + def log_out + # Logout from Mangadex + Mangadex::Auth.logout + + # Remove the session + session.delete(:id) + end +end +``` + +First make sure `ApplicationController` includes the helper above + +```ruby +class ApplicationController < ActionController::Base + include ApplicationHelper + + # ... +end +``` + +We recommend creating a controller for authentication. Here's how you can implement the login and logout actions: + +```ruby +# app/controllers/session_controller.rb +class SessionController < ApplicationController + # GET /login + def new + # render the login form + end + + # POST /login + def create + username = params[:username] + password = params[:password] + + # You can also use `email` instead of `username` to log in + user = Mangadex::Auth.login(username: username, password: password) do |mangadex_user| + # Find the user by mangadex user id (or initialize if it doesn't exist) + our_user = User.find_or_initialize_by(mangadex_user_id: mangadex_user.mangadex_user_id) do |new_user| + new_user.username = mangadex_user.data.username + end + + # Update the session info data + our_user.session = mangadex_user.session + our_user.refresh = mangadex_user.refresh + our_user.session_valid_until = mangadex_user.session_valid_until + + # ...then save the user + our_user.save! + our_user + end + + # `user` will be an instance of your `User` class + # Now, we can log in then redirect to the root. + log_in(user) + redirect_to(root_path) + rescue Mangadex::Errors::AuthenticationError => error + # See https://api.mangadex.org/docs.html to learn more about errors + Rails.logger.error(error.response.errors) + + # Handle authentication errors here + end + + # DELETE /logout + def destroy + log_out + + redirect_to(root_path) + end +end +``` + +Finally, add the routes. + +```ruby +# config/routes.rb +Rails.application.routes.draw do + # ... + get '/login' => 'session#new' + post '/login' => 'session#create' + delete '/logout' => 'session#destroy' +end +``` + +#### Protected resources + +Here's an example of a controller that requires every action to be logged in. This is based on the steps above. + +```ruby +class ProtectedController < ApplicationController + before_action :ensure_logged_in! + + private + + def ensure_logged_in! + return if logged_in? + + redirect_to(login_path) # go to /login + end +end +``` + +We're going with managing (list, create, show, edit, delete) MDLists (ie: custom lists). __We're not using strong params below to keep things simple, but you should, especially when mutating data (ie: creating and editing)__. + +```ruby +class CustomListsController < ProtectedController + # GET /custom_list + def index + @custom_lists = Mangadex::CustomList.list + end + + # GET /custom_list/new + def new + # new custom list form + end + + # POST /custom_list + def create + @custom_list = Mangadex::CustomList.create( + name: params[:name], + visibility: params[:visibility], + manga: params[:manga], # Manga ID + ) + end + + # GET /custom_list/<id> + def show + @custom_list = Mangadex::CustomList.get(params[:id]) + end + + # GET /custom_list/<id>/edit + def edit + @custom_list = Mangadex::CustomList.get(params[:id]) + # edit custom list form + end + + # PUT /custom_list/<id> + # PATCH /custom_list/<id> + def update + # Note: when updating the custom list, be sure to pass in + # the current version number! + @custom_list = Mangadex::CustomList.update( + params[:id], + { + name: params[:name], + visibility: params[:visibility], + manga: params[:manga], + version: params[:version].to_i, + } + ) + end + + # DELETE /custom_list/<id> + def destroy + Mangadex::CustomList.delete(params[:id]) + end +end +``` ## Development After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.