<commit_before>require_relative "app/repositories/story_repository"
require_relative "app/repositories/feed_repository"

require_relative "app/commands/stories/mark_as_read"
require_relative "app/commands/stories/mark_as_unread"

require_relative "app/commands/stories/mark_as_starred"
require_relative "app/commands/stories/mark_as_unstarred"
require_relative "app/commands/stories/mark_feed_as_read"
require_relative "app/commands/stories/mark_group_as_read"

module Fever
  class Response
    def initialize(params)
      @response = {
        api_version: 3,
        auth: 1,
        last_refreshed_on_time: Time.now.to_i
      }

      process_params(params)
    end

    def to_json
      @response.to_json
    end

  protected

    def process_params(params)
      keys = params.keys.map{|k| k.to_sym}

      if keys.include?(:groups)
        @response[:groups] = groups
        @response[:feeds_groups] = feeds_groups
      end

      if keys.include?(:feeds)
        @response[:feeds] = feeds.map{|f| f.as_fever_json}
        @response[:feeds_groups] = feeds_groups
      end

      if keys.include?(:favicons)
        @response[:favicons] = favicons
      end

      if keys.include?(:items)
        item_ids = params[:with_ids].split(',') rescue nil
        @response[:items] = items(item_ids, params[:since_id])
        @response[:total_items] = total_items(item_ids)
      end

      if keys.include?(:links)
        @response[:links] = links
      end

      if keys.include?(:unread_item_ids)
        @response[:unread_item_ids] = unread_item_ids
      end

      if keys.include?(:saved_item_ids)
        @response[:saved_item_ids] = saved_item_ids
      end

      case params[:mark]
      when "item"
        case params[:as]
        when "read"
          MarkAsRead.new(params[:id]).mark_as_read
        when "unread"
          MarkAsUnread.new(params[:id]).mark_as_unread
        when "saved"
          MarkAsStarred.new(params[:id]).mark_as_starred
        when "unsaved"
          MarkAsUnstarred.new(params[:id]).mark_as_unstarred
        end
      when "feed"
        MarkFeedAsRead.new(params[:id], params[:before]).mark_feed_as_read
      when "group"
        MarkGroupAsRead.new(params[:id], params[:before]).mark_group_as_read
      end
    end

    def groups
      [
        {
          id: 1,
          title: "All items"
        }
      ]
    end

    def feeds_groups
      [
        {
          group_id: 1,
          feed_ids: Feed.all.map{|f| f.id}.join(",")
        }
      ]
    end

    def feeds
      FeedRepository.list
    end

    def favicons
      [
        {
          id: 0,
          data: "image/gif;base64,R0lGODlhAQABAIAAAObm5gAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=="
        }
      ]
    end

    def items(item_ids, since_id)
      items = item_ids ? stories_by_ids(item_ids) : unread_stories(since_id)
      items.map{|s| s.as_fever_json}
    end

    def total_items(item_ids)
      items = item_ids ? stories_by_ids(item_ids) : unread_stories
      items.count
    end

    def links
      []
    end

    def unread_item_ids
      unread_stories.map{|s| s.id}.join(',')
    end

    def saved_item_ids
      all_starred_stories.map{|s| s.id}.join(',')
    end

    def unread_stories(since_id = nil)
      if since_id
        StoryRepository.unread_since_id(since_id)
      else
        StoryRepository.unread
      end
    end

    def all_starred_stories
      Story.where(is_starred: true)
    end

    def stories_by_ids(ids)
      StoryRepository.fetch_by_ids(ids)
    end
  end
end
<commit_msg>Split read and sync operations into separate classes<commit_after>require_relative "app/repositories/story_repository"
require_relative "app/repositories/feed_repository"

require_relative "app/commands/stories/mark_as_read"
require_relative "app/commands/stories/mark_as_unread"

require_relative "app/commands/stories/mark_as_starred"
require_relative "app/commands/stories/mark_as_unstarred"
require_relative "app/commands/stories/mark_feed_as_read"
require_relative "app/commands/stories/mark_group_as_read"

module Fever
  class Authentication
    def call(params)
      { auth: 1, last_refreshed_on_time: Time.now.to_i }
    end
  end

  class ReadGroups
    def call(params)
      if params.keys.include?('groups')
        { groups: groups }
      else
        {}
      end
    end

    private

    def groups
      [
        {
          id: 1,
          title: "All items"
        }
      ]
    end
  end

  class ReadFeeds
    def call(params)
      if params.keys.include?('feeds')
        { feeds: feeds }
      else
        {}
      end
    end

    private

    def feeds
      FeedRepository.list.map{|f| f.as_fever_json}
    end
  end

  class ReadFeedsGroups
    def call(params)
      if params.keys.include?('feeds') || params.keys.include?('groups')
        { feeds_groups: feeds_groups }
      else
        {}
      end
    end

    private

    def feeds_groups
      [
        {
          group_id: 1,
          feed_ids: Feed.all.map{|f| f.id}.join(",")
        }
      ]
    end
  end

  class ReadFavicons
    def call(params)
      if params.keys.include?('favicons')
        { favicons: favicons }
      else
        {}
      end
    end

    private

    def favicons
      [
        {
          id: 0,
          data: "image/gif;base64,R0lGODlhAQABAIAAAObm5gAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=="
        }
      ]
    end
  end

  class ReadItems
    def call(params)
      if params.keys.include?('items')
        item_ids = params[:with_ids].split(',') rescue nil

        {
            items: items(item_ids, params[:since_id]),
            total_items: total_items(item_ids)
        }
      else
        {}
      end
    end

    private

    def items(item_ids, since_id)
      items = item_ids ? stories_by_ids(item_ids) : unread_stories(since_id)
      items.map{|s| s.as_fever_json }
    end

    def total_items(item_ids)
      items = item_ids ? stories_by_ids(item_ids) : unread_stories
      items.count
    end

    def stories_by_ids(ids)
      StoryRepository.fetch_by_ids(ids)
    end

    def unread_stories(since_id = nil)
      if since_id
        StoryRepository.unread_since_id(since_id)
      else
        StoryRepository.unread
      end
    end
  end

  class ReadLinks
    def call(params)
      if params.keys.include?('links')
        { links: links }
      else
        {}
      end
    end

    private

    def links
      []
    end
  end

  class SyncUnreadItemIds
    def call(params)
      if params.keys.include?('unread_item_ids')
        { unread_item_ids: unread_item_ids }
      else
        {}
      end
    end

    private

    def unread_item_ids
      unread_stories.map{|s| s.id}.join(',')
    end

    def unread_stories(since_id = nil)
      if since_id
        StoryRepository.unread_since_id(since_id)
      else
        StoryRepository.unread
      end
    end
  end

  class SyncSavedItemIds
    def call(params)
      if params.keys.include?('saved_item_ids')
        { saved_item_ids: saved_item_ids }
      else
        {}
      end
    end

    private

    def saved_item_ids
      all_starred_stories.map{|s| s.id}.join(',')
    end


    def all_starred_stories
      Story.where(is_starred: true)
    end
  end

  class Response
    def initialize(params)
      @response = { api_version: 3 }

      @response.merge! Authentication.new.call(params)
      @response.merge! ReadFeeds.new.call(params)
      @response.merge! ReadGroups.new.call(params)
      @response.merge! ReadFeedsGroups.new.call(params)
      @response.merge! ReadFavicons.new.call(params)
      @response.merge! ReadItems.new.call(params)
      @response.merge! ReadLinks.new.call(params)
      @response.merge! SyncUnreadItemIds.new.call(params)
      @response.merge! SyncSavedItemIds.new.call(params)

      process_params(params)
    end

    def to_json
      @response.to_json
    end

  protected

    def process_params(params)
      case params[:mark]
      when "item"
        case params[:as]
        when "read"
          MarkAsRead.new(params[:id]).mark_as_read
        when "unread"
          MarkAsUnread.new(params[:id]).mark_as_unread
        when "saved"
          MarkAsStarred.new(params[:id]).mark_as_starred
        when "unsaved"
          MarkAsUnstarred.new(params[:id]).mark_as_unstarred
        end
      when "feed"
        MarkFeedAsRead.new(params[:id], params[:before]).mark_feed_as_read
      when "group"
        MarkGroupAsRead.new(params[:id], params[:before]).mark_group_as_read
      end
    end
  end
end

{'fraction_non_alphanumeric': 0.09542163046017285, 'fraction_numerical': 0.00233590282644242, 'mean_word_length': 2.2670736360167876, 'pattern_counts': {'":': 0, '<': 3, '<?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': '6566018', 'n_tokens_mistral': 2954, 'n_tokens_neox': 2843, 'n_words': 496}