<commit_before>require_relative 'entities.rb'

class API_v1 < Grape::API
  version 'v1', using: :path, format: :json, vendor: 'hummingbird'

  #
  # Log response time to Riemann.
  #
  before do
    @start_time = Time.now
  end
  
  after do
    @end_time = Time.now
    lat = (@end_time - @start_time).to_f
    $riemann << {
      service: "api req",
      metric: lat,
      state: "ok"
    }
  end
  
  helpers do
    def warden; env['warden']; end
    def current_user
      warden.user
    end
    def user_signed_in?
      not current_user.nil?
    end
    def current_ability
      @current_ability ||= Ability.new(current_user)
    end
  end

  
  resource :users do
    desc "Return the entries in a user's library under a specific status.", {
      object_fields: Entities::Watchlist.documentation
    }
    params do
      requires :user_id, type: String
      requires :status, type: String
      optional :page, type: Integer
      optional :title_language_preference, type: String
    end
    get ':user_id/library' do
      @user = User.find(params[:user_id])
      status = Watchlist.status_parameter_to_status(params[:status])

      watchlists = @user.watchlists.accessible_by(current_ability).where(status: status).order(status == "Currently Watching" ? 'last_watched DESC' : 'created_at DESC').includes(:anime).page(params[:page]).per(100)
      
      title_language_preference = params[:title_language_preference]
      if title_language_preference.nil? and current_user
        title_language_preference = current_user.title_language_preference
      end
      title_language_preference ||= "canonical"
      
      present watchlists, with: Entities::Watchlist, title_language_preference: title_language_preference, genres: false
    end
    
    desc "Returns the user's feed."
    params do
      requires :user_id, type: String
      optional :page, type: Integer
    end
    get ":user_id/feed" do
      @user = User.find(params[:user_id])
      @stories = @user.stories.accessible_by(current_ability).order('updated_at DESC').includes(:substories).page(params[:page]).per(20)
      
      present @stories, with: Entities::Story, current_ability: current_ability, title_language_preference: (user_signed_in? ? current_user.title_language_preference : "canonical")
    end
    
    desc "Delete a substory from the user's feed."
    params do
      requires :user_id, type: String
      requires :substory_id, type: Integer
    end
    post ":user_id/feed/remove" do
      substory = Substory.find params[:substory_id]
      if current_ability.can? :destroy, substory
        substory.destroy
        return true
      else
        return false
      end
    end
  end
  
  resource :libraries do
    desc "Update a specific anime's details in a user's library."
    params do
      requires :anime_slug, type: String
    end
    post ':anime_slug' do
      return false unless user_signed_in?

      @anime = Anime.find(params["anime_slug"])
      @watchlist = Watchlist.find_or_create_by_anime_id_and_user_id(@anime.id, current_user.id)
        
      # Update status.
      if params[:status]
        status = Watchlist.status_parameter_to_status(params[:status])
        if @watchlist.status != status
          # Create an action if the status was changed.
          Substory.from_action({
            user_id: current_user.id,<commit_msg>If the substory was already deleted, return a true.<commit_after>require_relative 'entities.rb'

class API_v1 < Grape::API
  version 'v1', using: :path, format: :json, vendor: 'hummingbird'

  #
  # Log response time to Riemann.
  #
  before do
    @start_time = Time.now
  end
  
  after do
    @end_time = Time.now
    lat = (@end_time - @start_time).to_f
    $riemann << {
      service: "api req",
      metric: lat,
      state: "ok"
    }
  end
  
  helpers do
    def warden; env['warden']; end
    def current_user
      warden.user
    end
    def user_signed_in?
      not current_user.nil?
    end
    def current_ability
      @current_ability ||= Ability.new(current_user)
    end
  end

  
  resource :users do
    desc "Return the entries in a user's library under a specific status.", {
      object_fields: Entities::Watchlist.documentation
    }
    params do
      requires :user_id, type: String
      requires :status, type: String
      optional :page, type: Integer
      optional :title_language_preference, type: String
    end
    get ':user_id/library' do
      @user = User.find(params[:user_id])
      status = Watchlist.status_parameter_to_status(params[:status])

      watchlists = @user.watchlists.accessible_by(current_ability).where(status: status).order(status == "Currently Watching" ? 'last_watched DESC' : 'created_at DESC').includes(:anime).page(params[:page]).per(100)
      
      title_language_preference = params[:title_language_preference]
      if title_language_preference.nil? and current_user
        title_language_preference = current_user.title_language_preference
      end
      title_language_preference ||= "canonical"
      
      present watchlists, with: Entities::Watchlist, title_language_preference: title_language_preference, genres: false
    end
    
    desc "Returns the user's feed."
    params do
      requires :user_id, type: String
      optional :page, type: Integer
    end
    get ":user_id/feed" do
      @user = User.find(params[:user_id])
      @stories = @user.stories.accessible_by(current_ability).order('updated_at DESC').includes(:substories).page(params[:page]).per(20)
      
      present @stories, with: Entities::Story, current_ability: current_ability, title_language_preference: (user_signed_in? ? current_user.title_language_preference : "canonical")
    end
    
    desc "Delete a substory from the user's feed."
    params do
      requires :user_id, type: String
      requires :substory_id, type: Integer
    end
    post ":user_id/feed/remove" do
      begin
        substory = Substory.find params[:substory_id]
      rescue
        return true
      end
      if current_ability.can? :destroy, substory
        substory.destroy
        return true
      else
        return false
      end
    end
  end
  
  resource :libraries do
    desc "Update a specific anime's details in a user's library."
    params do
      requires :anime_slug, type: String
    end
    post ':anime_slug' do
      return false unless user_signed_in?

      @anime = Anime.find(params["anime_slug"])
      @watchlist = Watchlist.find_or_create_by_anime_id_and_user_id(@anime.id, current_user.id)
        
      # Update status.
      if params[:status]
        status = Watchlist.status_parameter_to_status(params[:status])
        if @watchlist.status != status
          # Create an action if the status was changed.
          Substory.from_action({
            user_id: current_user.id,
{'fraction_non_alphanumeric': 0.09182629039333236, 'fraction_numerical': 0.0020470829068577278, 'mean_word_length': 2.937823834196891, 'pattern_counts': {'":': 4, '<': 9, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3465747', 'n_tokens_mistral': 2124, 'n_tokens_neox': 2080, 'n_words': 526}