# frozen_string_literal: true require_relative 'model' require_relative 'searchable' module Redd module Models # The starter class. class Session < Model include Searchable # @return [User] the logged-in user def me @me ||= Self.new(client) end # @return [FrontPage] the user's front page def front_page @front_page ||= FrontPage.new(client) end # @return [Modmail] the new modmail def modmail @modmail ||= Modmail.new(client) end # @return [LiveThread] the live thread def live_thread(id) LiveThread.new(client, id: id) end # @return [Hash] a breakdown of karma over subreddits def karma_breakdown client.get('/api/v1/me/karma').body[:data] end # Get a (lazily loaded) reddit user by their name. # @param name [String] the username # @return [User] def user(name) User.new(client, name: name) end # Returns whether a username is available. # @param username [String] the username to check # @return [Boolean] whether the username is available def username_available?(username) client.get('/api/username_available', user: username).body end # Get a (lazily loaded) subreddit by its name. # @param display_name [String] the subreddit's display name # @return [Subreddit] def subreddit(display_name) Subreddit.new(client, display_name: display_name) end # @return [Array] array of multireddits belonging to the user def my_multis client.get('/api/multi/mine').body.map { |m| client.unmarshal(m) } end # Get a (lazily loaded) multi by its path. # @param path [String] the multi's path, surrounded by a leading and trailing / # @return [Multireddit] def multi(path) Multireddit.new(client, path: path) end # Get submissions or comments by their fullnames. # @param fullnames [String, Array] one or an array of fullnames (e.g. t3_abc1234) # @return [Listing] # @deprecated Try the lazier {#from_fullnames} instead. def from_ids(*fullnames) client.model(:get, '/api/info', id: fullnames.join(',')) end # Create lazily-loaded objects from their fullnames (e.g. t1_abc123). # @param fullnames [String] fullname for a submission, comment, or subreddit. # @return [Array] def from_fullnames(*fullnames) # rubocop:disable Metrics/MethodLength fullnames.map do |name| if name.start_with?('t1_') Comment.new(client, name: name) elsif name.start_with?('t3_') Submission.new(client, name: name) elsif name.start_with?('t5_') Subreddit.new(client, name: name) else raise "unknown fullname #{name}" end end end # Get submissions or comments by their fullnames. # @param url [String] the object's url # @return [Submission, Comment, nil] the object, or nil if not found def from_url(url) client.model(:get, '/api/info', url: url).first end # Return a listing of the user's inbox (including comment replies and private messages). # # @param category ['inbox', 'unread', 'sent', 'moderator', 'messages', 'comments', # 'selfreply', 'mentions'] the category of messages to view # @param mark [Boolean] whether to remove the orangered from the user's inbox # @param params [Hash] a list of optional params to send with the request # @option params [String] :after return results after the given fullname # @option params [String] :before return results before the given fullname # @option params [Integer] :count (0) the number of items already seen in the listing # @option params [1..100] :limit (25) the maximum number of things to return # @return [Listing] def my_messages(category: 'inbox', mark: false, **params) client.model(:get, "/message/#{category}.json", params.merge(mark: mark)) end # Mark all messages as read. def read_all_messages client.post('/api/read_all_messages') end # @return [Hash] the user's preferences def my_preferences client.get('/api/v1/me/prefs').body end # Edit the user's preferences. # @param new_prefs [Hash] the changed preferences # @return [Hash] the new preferences # @see #my_preferences def edit_preferences(new_prefs = {}) client.request( :patch, '/api/v1/me/prefs', headers: { 'Content-Type' => 'application/json' }, body: JSON.generate(new_prefs) ).body end # @return [Array] the logged-in user's friends def friends client.get('/api/v1/me/friends').body[:data][:children].map do |h| User.new(client, name: h[:name], id: h[:id].sub('t2_', ''), since: h[:date]) end end # @return [Array] users blocked by the logged-in user def blocked client.get('/prefs/blocked').body[:data][:children].map do |h| User.new(client, name: h[:name], id: h[:id].sub('t2_', ''), since: h[:date]) end end # @return [Array] users trusted by the logged-in user def trusted client.get('/prefs/trusted').body[:data][:children].map do |h| User.new(client, name: h[:name], id: h[:id].sub('t2_', ''), since: h[:date]) end end # @return [Array] a list of categories the user's items are saved in def saved_categories client.get('/api/saved_categories').body end # Return a listing of the user's subreddits. # # @param type ['subscriber', 'contributor', 'moderator'] the type of subreddits # @param params [Hash] a list of optional params to send with the request # @option params [String] :after return results after the given fullname # @option params [String] :before return results before the given fullname # @option params [Integer] :count (0) the number of items already seen in the listing # @option params [1..100] :limit (25) the maximum number of things to return # @return [Listing] def my_subreddits(type, **params) client.model(:get, "/subreddits/mine/#{type}", params) end # Return trending subreddits. # @return [Hash] # @example # session.trending_subreddits # => { # "subreddit_names": [ # "AskLibertarians", # "OpTicGaming", # "Cuphead", # "AlmostParkour", # "TheGoodPlace" # ], # "comment_count": 176, # "comment_url": "/r/trendingsubreddits/comments/73dkin/trending_subreddits_for_..." # } def trending_subreddits client.get('/api/trending_subreddits').body end end end end