<commit_before>require 'yaml'
require 'colored'
require 'highline'
require 'tempfile'

class PT::UI

  GLOBAL_CONFIG_PATH = ENV['HOME'] + "/.pt"
  LOCAL_CONFIG_PATH = Dir.pwd + '/.pt'

  def initialize(args)
    require 'pt/debugger' if ARGV.delete('--debug')
    @io = HighLine.new
    @global_config = load_global_config
    @client = PT::Client.new(@global_config[:api_number])
    @local_config = load_local_config
    @project = @client.get_project(@local_config[:project_id])
    command = args[0].to_sym rescue :my_work
    @params = args[1..-1]
    commands.include?(command.to_sym) ? send(command.to_sym) : help
  end

  def my_work
    title("My Work for #{user_s} in #{project_to_s}")
    stories = @client.get_my_work(@project, @local_config[:user_name])
    PT::TasksTable.new(stories).print @global_config
  end

  def todo
    title("My Work for #{user_s} in #{project_to_s}")
    stories = @client.get_my_work(@project, @local_config[:user_name])
    stories = stories.select { |story| story.current_state == "unscheduled" }
    PT::TasksTable.new(stories).print @global_config
  end

  def started
    # find by a single user
    if @params[0]
      stories = @project.stories(parameters: {filter: "owner:#{@params[0]} state:started"})
      PT::TasksTable.new(stories).print @global_config
    else
      # otherwise show them all
      title("Stories started for #{project_to_s}")
      stories = @project.stories(parameters: { filter:'state:started' })
      PT::TasksTable.new(stories).print @global_config
    end
  end

  def list
    if @params[0]
      if @params[0] == "all"
        stories = @client.get_work(@project)
        PT::TasksTable.new(stories).print @global_config
      else
        user = find_owner @params[0]
        if user
          stories = @client.get_my_work(@project, user)
          PT::TasksTable.new(stories).print @global_config
        end
      end
    else
      members = @client.get_members(@project)
      table = PT::MembersTable.new(members)
      user = select("Please select a member to see his tasks.", table).name
      title("Work for #{user} in #{project_to_s}")
      stories = @client.get_my_work(@project, user)
      PT::TasksTable.new(stories).print @global_config
    end
  end

  def recent
    title("Your recent stories from #{project_to_s}")
    stories = @project.stories.all( :id => @local_config[:recent_tasks] )
    PT::MultiUserTasksTable.new(stories).print @global_config
  end

  def label

    task = get_task_from_params "Please select a story to show"
    unless task
      message("No matches found for '#{@params[0]}', please use a valid pivotal story Id")
      return
    end

    if @params[1]
      label = @params[1]
    else
      label = ask("Which label?")
    end

    @client.add_label( @project, task, label );

  end

  # skip find member. TODO: reconsider find member
  # TODO: add method on pivotal tracker api github
  def create
    if @params[0]
      name = @params[0]
      owner = @params[1] || @local_config[:user_name]
      requester = @local_config[:user_name]
      task_type = task_type_or_nil(@params[1]) || task_type_or_nil(@params[2]) || 'feature'
    else
      title("Let's create a new task:")
      name = ask("Name for the new task:")
    end

    unless owner
      if ask('Do you want to assign it now? (y/n)').downcase == 'y'
        members = @client.get_members(@project)
        table = PT::MembersTable.new(members)
        owner = select("Please select a member to assign him the task.", table).name
      else
        owner = nil
      end
      requester = @local_config[:user_name]
      task_type = ask('Type? (c)hore, (b)ug, anything else for feature)')
    end

    task_type = case task_type
    when 'c', 'chore'
      'chore'
    when 'b', 'bug'
      'bug'
    else
      'feature'
    end
    result = nil

    # did you do a -m so you can add a description?
    if ARGV.include? "-m" or ARGV.include? "--m"
      editor = ENV.fetch('EDITOR') { 'vi' }
      temp_path = "/tmp/editor-#{ Process.pid }.txt"
      system "#{ editor } #{ temp_path }"
      
      description = File.read(temp_path)
      result = @client.create_task_with_description(@project, name, owner, requester, task_type, description)
      
    else
      result = @client.create_task(@project, name, owner, requester, task_type)
    end
    
    if result.errors.any?
      error(result.errors.errors)
    else
      congrats("#{task_type} for #{owner} created: #{result.url}")
    end
  end

  def open
    if @params[0]
      if task = @client.get_task_by_id(@project, @params[0])
        congrats("Opening #{task.name}")
        `open #{task.url}`
      else
        message("Story ##{@params[0]} not found")
      end
    else
      tasks = @client.get_my_open_tasks(@project, @local_config[:user_name])
      table = PT::TasksTable.new(tasks)
      title("Tasks for #{user_s} in #{project_to_s}")
      task = select("Please select a story to open it in the browser", table)
    end
  end

  def comment
    if @params[0]
      task = task_by_id_or_pt_id @params[0].to_i
      comment = @params[1]
      title("Adding a comment to #{task.name}")
    else
      tasks = @client.get_my_work(@project, @local_config[:user_name])
      table = PT::TasksTable.new(tasks)
      title("Tasks for #{user_s} in #{project_to_s}")
      task = select("Please select a story to comment it", table)
      comment = ask("Write your comment")
    end
    if @client.comment_task(@project, task, comment)
      congrats("Comment sent, thanks!")
      save_recent_task( task.id )
    else
      error("Ummm, something went wrong.")
    end
  end

  def assign
    if @params[0]
      task = task_by_id_or_pt_id @params[0].to_i
      owner = find_owner @params[1]
    else
      title("Tasks for #{user_s} in #{project_to_s}")
      tasks = @client.get_tasks_to_assign(@project, @local_config[:user_name])
      table = PT::TasksTable.new(tasks)
      task = select("Please select a task to assign it an owner", table)
    end
    
    unless owner
      members = @client.get_members(@project)
      table = PT::MembersTable.new(members)
      owner = select("Please select a member to assign him the task", table).name
    end
    result = @client.assign_task(@project, task, owner)
    
    if result.errors.any?
      error(result.errors.errors)
    else
      congrats("Task assigned to #{owner}, thanks!")
    end
  end

  def estimate
    if @params[0]
      task = task_by_id_or_pt_id @params[0].to_i
      title("Estimating '#{task.name}'")

      if [0,1,2,3].include? @params[1].to_i
        estimation = @params[1]
      end
    else
      tasks = @client.get_my_tasks_to_estimate(@project, @local_config[:user_name])
      table = PT::TasksTable.new(tasks)
      title("Tasks for #{user_s} in #{project_to_s}")
      task = select("Please select a story to estimate it", table)
    end

    estimation ||= ask("How many points you estimate for it? (#{@project.point_scale})")
    @client.estimate_task(@project, task, estimation)
    congrats("Task estimated, thanks!")
  end

  def start
    if @params[0]
      task = task_by_id_or_pt_id @params[0].to_i
      title("Starting '#{task.name}'")
    else
      tasks = @client.get_my_tasks_to_start(@project, @local_config[:user_name])
      table = PT::TasksTable.new(tasks)
      title("Tasks for #{user_s} in #{project_to_s}")
      task = select("Please select a story to mark it as started", table)
    end
    start_task task
  end

  def finish
    if @params[0]
      task = task_by_id_or_pt_id @params[0].to_i
      title("Finishing '#{task.name}'")
    else
      tasks = @client.get_my_tasks_to_finish(@project, @local_config[:user_name])
      table = PT::TasksTable.new(tasks)
      title("Tasks for #{user_s} in #{project_to_s}")
      task = select("Please select a story to mark it as finished", table)
    end
    finish_task task
  end

  def deliver
    if @params[0]
      task = task_by_id_or_pt_id @params[0].to_i
      title("Delivering '#{task.name}'")
    else
      tasks = @client.get_my_tasks_to_deliver(@project, @local_config[:user_name])
      table = PT::TasksTable.new(tasks)
      title("Tasks for #{user_s} in #{project_to_s}")
      task = select("Please select a story to mark it as delivered", table)
    end

    deliver_task task
  end

  def accept
    if @params[0]
      task = task_by_id_or_pt_id @params[0].to_i
      title("Accepting '#{task.name}'")
    else
      tasks = @client.get_my_tasks_to_accept(@project, @local_config[:user_name])
      table = PT::TasksTable.new(tasks)
      title("Tasks for #{user_s} in #{project_to_s}")
      task = select("Please select a story to mark it as accepted", table)
    end
    result = @client.mark_task_as(@project, task, 'accepted')
    if result.errors.any?
      error(result.errors.errors)
    else
      congrats("Task accepted, hooray!")
    end
  end

  def show
    title("Tasks for #{user_s} in #{project_to_s}")
    task = get_task_from_params "Please select a story to show"
    unless task
      message("No matches found for '#{@params[0]}', please use a valid pivotal story Id")
      return
    end
    show_task(task)
  end

  def tasks
    title("Open story tasks for #{user_s} in #{project_to_s}")
    task = get_task_from_params "Please select a story to show pending tasks"
    unless task
      message("No matches found for '#{@params[0]}', please use a valid pivotal story Id")
      return
    end
    story_task = get_open_story_task_from_params(task)

    if story_task.position == -1
      description = ask('Title for new task')
      task.tasks.create(:description => description)
      congrats("New todo task added to \"#{task.name}\"")
    else
      edit_story_task story_task
    end
  end

  # takes a comma separated list of ids and prints the collection of tasks
  def show_condensed
    title("Tasks for #{user_s} in #{project_to_s}")
      tasks = []
    if @params[0]
      @params[0].each_line(',') do |line|
        tasks << @client.get_task_by_id(@project, line.to_i)
      end
      table = PT::TasksTable.new(tasks)
      table.print
    end
  end

  def reject
    title("Tasks for #{user_s} in #{project_to_s}")
    if @params[0]
      tasks = @client.get_my_work(@project, @local_config[:user_name])
      table = PT::TasksTable.new(tasks)
      task = table[@params[0].to_i]
      title("Rejecting '#{task.name}'")
    else
      tasks = @client.get_my_tasks_to_reject(@project, @local_config[:user_name])
      table = PT::TasksTable.new(tasks)
      title("Tasks for #{user_s} in #{project_to_s}")
      task = select("Please select a story to mark it as rejected", table)
    end

    if @params[1]
      comment = @params[1]
    else
      comment = ask("Please explain why are you rejecting the task.")
    end

    if @client.comment_task(@project, task, comment)
      result = @client.mark_task_as(@project, task, 'rejected')
      congrats("Task rejected, thanks!")
    else
      error("Ummm, something went wrong.")
    end
  end

  def done
    if @params[0]
      task = task_by_id_or_pt_id @params[0].to_i

      #we need this for finding again later
      task_id = task.id

      if !@params[1] && task.estimate == -1
        error("You need to give an estimate for this task")
        return
      end

      if @params[1] && task.estimate == -1
          if [0,1,2,3].include? @params[1].to_i
            estimate_task(task, @params[1].to_i)
          end
          if @params[2]
            task = task_by_id_or_pt_id task_id
            @client.comment_task(@project, task, @params[2])
          end
      else
        @client.comment_task(@project, task, @params[1]) if @params[1]
      end

      task = task_by_id_or_pt_id task_id
      start_task task

      task = task_by_id_or_pt_id task_id
      finish_task task

      task = task_by_id_or_pt_id task_id
      deliver_task task
    end
  end

  def estimate_task task, difficulty
    result = @client.estimate_task(@project, task, difficulty)
    if result.errors.any?
      error(result.errors.errors)
    else
      congrats("Task estimated, thanks!")
    end
  end

  def start_task task
    result = @client.mark_task_as(@project, task, 'started')
    if result.errors.any?
      error(result.errors.errors)
    else
      congrats("Task started, go for it!")
    end
  end

  def finish_task task
    if task.story_type == 'chore'
      result = @client.mark_task_as(@project, task, 'accepted')
    else
      result = @client.mark_task_as(@project, task, 'finished')
    end
    if result.errors.any?
      error(result.errors.errors)
    else
      congrats("Another task bites the dust, yeah!")
    end
  end

  def deliver_task task
    return if task.story_type == 'chore'

    result = @client.mark_task_as(@project, task, 'delivered')
    error(result.errors.errors) if result.errors.any?
    if result.errors.any?
      error(result.errors.errors)
    else
      congrats("Task delivered, congrats!")
    end
  end

  def find
    if (story_id = @params[0].to_i).nonzero?
      if task = task_by_id_or_pt_id(@params[0].to_i)
        return show_task(task)
      else
        message("Task not found by id (#{story_id}), falling back to text search")
      end
    end

    if @params[0]
      tasks = @client.get_my_work(@project, @local_config[:user_name])
      matched_tasks = tasks.select do |story_task|
        story_task.name.downcase.index(@params[0]) && story_task.current_state != 'delivered'<commit_msg>rewrite start, finish, deliver, acceept<commit_after>require 'yaml'
require 'colored'
require 'highline'
require 'tempfile'

class PT::UI

  GLOBAL_CONFIG_PATH = ENV['HOME'] + "/.pt"
  LOCAL_CONFIG_PATH = Dir.pwd + '/.pt'

  def initialize(args)
    require 'pt/debugger' if ARGV.delete('--debug')
    @io = HighLine.new
    @global_config = load_global_config
    @client = PT::Client.new(@global_config[:api_number])
    @local_config = load_local_config
    @project = @client.get_project(@local_config[:project_id])
    command = args[0].to_sym rescue :my_work
    @params = args[1..-1]
    commands.include?(command.to_sym) ? send(command.to_sym) : help
  end

  def my_work
    title("My Work for #{user_s} in #{project_to_s}")
    stories = @client.get_my_work(@project, @local_config[:user_name])
    PT::TasksTable.new(stories).print @global_config
  end

  def todo
    title("My Work for #{user_s} in #{project_to_s}")
    stories = @client.get_my_work(@project, @local_config[:user_name])
    stories = stories.select { |story| story.current_state == "unscheduled" }
    PT::TasksTable.new(stories).print @global_config
  end

  def started
    # find by a single user
    if @params[0]
      stories = @project.stories(parameters: {filter: "owner:#{@params[0]} state:started"})
      PT::TasksTable.new(stories).print @global_config
    else
      # otherwise show them all
      title("Stories started for #{project_to_s}")
      stories = @project.stories(parameters: { filter:'state:started' })
      PT::TasksTable.new(stories).print @global_config
    end
  end

  def list
    if @params[0]
      if @params[0] == "all"
        stories = @client.get_work(@project)
        PT::TasksTable.new(stories).print @global_config
      else
        user = find_owner @params[0]
        if user
          stories = @client.get_my_work(@project, user)
          PT::TasksTable.new(stories).print @global_config
        end
      end
    else
      members = @client.get_members(@project)
      table = PT::MembersTable.new(members)
      user = select("Please select a member to see his tasks.", table).name
      title("Work for #{user} in #{project_to_s}")
      stories = @client.get_my_work(@project, user)
      PT::TasksTable.new(stories).print @global_config
    end
  end

  def recent
    title("Your recent stories from #{project_to_s}")
    stories = @project.stories.all( :id => @local_config[:recent_tasks] )
    PT::MultiUserTasksTable.new(stories).print @global_config
  end

  def label

    task = get_task_from_params "Please select a story to show"
    unless task
      message("No matches found for '#{@params[0]}', please use a valid pivotal story Id")
      return
    end

    if @params[1]
      label = @params[1]
    else
      label = ask("Which label?")
    end

    @client.add_label( @project, task, label );

  end

  # skip find member. TODO: reconsider find member
  # TODO: add method on pivotal tracker api github
  def create
    if @params[0]
      name = @params[0]
      owner = @params[1] || @local_config[:user_name]
      requester = @local_config[:user_name]
      task_type = task_type_or_nil(@params[1]) || task_type_or_nil(@params[2]) || 'feature'
    else
      title("Let's create a new task:")
      name = ask("Name for the new task:")
    end

    unless owner
      if ask('Do you want to assign it now? (y/n)').downcase == 'y'
        members = @client.get_members(@project)
        table = PT::MembersTable.new(members)
        owner = select("Please select a member to assign him the task.", table).name
      else
        owner = nil
      end
      requester = @local_config[:user_name]
      task_type = ask('Type? (c)hore, (b)ug, anything else for feature)')
    end

    task_type = case task_type
    when 'c', 'chore'
      'chore'
    when 'b', 'bug'
      'bug'
    else
      'feature'
    end
    result = nil

    # did you do a -m so you can add a description?
    if ARGV.include? "-m" or ARGV.include? "--m"
      editor = ENV.fetch('EDITOR') { 'vi' }
      temp_path = "/tmp/editor-#{ Process.pid }.txt"
      system "#{ editor } #{ temp_path }"
      
      description = File.read(temp_path)
      result = @client.create_task_with_description(@project, name, owner, requester, task_type, description)
      
    else
      result = @client.create_task(@project, name, owner, requester, task_type)
    end
    
    if result.errors.any?
      error(result.errors.errors)
    else
      congrats("#{task_type} for #{owner} created: #{result.url}")
    end
  end

  def open
    if @params[0]
      if task = @client.get_task_by_id(@project, @params[0])
        congrats("Opening #{task.name}")
        `open #{task.url}`
      else
        message("Story ##{@params[0]} not found")
      end
    else
      tasks = @client.get_my_open_tasks(@project, @local_config[:user_name])
      table = PT::TasksTable.new(tasks)
      title("Tasks for #{user_s} in #{project_to_s}")
      task = select("Please select a story to open it in the browser", table)
    end
  end

  def comment
    if @params[0]
      task = task_by_id_or_pt_id @params[0].to_i
      comment = @params[1]
      title("Adding a comment to #{task.name}")
    else
      tasks = @client.get_my_work(@project, @local_config[:user_name])
      table = PT::TasksTable.new(tasks)
      title("Tasks for #{user_s} in #{project_to_s}")
      task = select("Please select a story to comment it", table)
      comment = ask("Write your comment")
    end
    if @client.comment_task(@project, task, comment)
      congrats("Comment sent, thanks!")
      save_recent_task( task.id )
    else
      error("Ummm, something went wrong.")
    end
  end

  def assign
    if @params[0]
      task = task_by_id_or_pt_id @params[0].to_i
      owner = find_owner @params[1]
    else
      title("Tasks for #{user_s} in #{project_to_s}")
      tasks = @client.get_tasks_to_assign(@project, @local_config[:user_name])
      table = PT::TasksTable.new(tasks)
      task = select("Please select a task to assign it an owner", table)
    end
    
    unless owner
      members = @client.get_members(@project)
      table = PT::MembersTable.new(members)
      owner = select("Please select a member to assign him the task", table).name
    end
    result = @client.assign_task(@project, task, owner)
    
    if result.errors.any?
      error(result.errors.errors)
    else
      congrats("Task assigned to #{owner}, thanks!")
    end
  end

  def estimate
    if @params[0]
      task = task_by_id_or_pt_id @params[0].to_i
      title("Estimating '#{task.name}'")

      if [0,1,2,3].include? @params[1].to_i
        estimation = @params[1]
      end
    else
      tasks = @client.get_my_tasks_to_estimate(@project, @local_config[:user_name])
      table = PT::TasksTable.new(tasks)
      title("Tasks for #{user_s} in #{project_to_s}")
      task = select("Please select a story to estimate it", table)
    end

    estimation ||= ask("How many points you estimate for it? (#{@project.point_scale})")
    @client.estimate_task(@project, task, estimation)
    congrats("Task estimated, thanks!")
  end

  def start
    if @params[0]
      task = task_by_id_or_pt_id @params[0].to_i
      title("Starting '#{task.name}'")
    else
      tasks = @client.get_my_tasks_to_start(@project, @local_config[:user_name])
      table = PT::TasksTable.new(tasks)
      title("Tasks for #{user_s} in #{project_to_s}")
      task = select("Please select a story to mark it as started", table)
    end
    start_task task
  end

  def finish
    if @params[0]
      task = task_by_id_or_pt_id @params[0].to_i
      title("Finishing '#{task.name}'")
    else
      tasks = @client.get_my_tasks_to_finish(@project, @local_config[:user_name])
      table = PT::TasksTable.new(tasks)
      title("Tasks for #{user_s} in #{project_to_s}")
      task = select("Please select a story to mark it as finished", table)
    end
    finish_task task
  end

  def deliver
    if @params[0]
      task = task_by_id_or_pt_id @params[0].to_i
      title("Delivering '#{task.name}'")
    else
      tasks = @client.get_my_tasks_to_deliver(@project, @local_config[:user_name])
      table = PT::TasksTable.new(tasks)
      title("Tasks for #{user_s} in #{project_to_s}")
      task = select("Please select a story to mark it as delivered", table)
    end

    deliver_task task
  end

  def accept
    if @params[0]
      task = task_by_id_or_pt_id @params[0].to_i
      title("Accepting '#{task.name}'")
    else
      tasks = @client.get_my_tasks_to_accept(@project, @local_config[:user_name])
      table = PT::TasksTable.new(tasks)
      title("Tasks for #{user_s} in #{project_to_s}")
      task = select("Please select a story to mark it as accepted", table)
    end
    @client.mark_task_as(@project, task, 'accepted')
    congrats("Task accepted, hooray!")
  end

  def show
    title("Tasks for #{user_s} in #{project_to_s}")
    task = get_task_from_params "Please select a story to show"
    unless task
      message("No matches found for '#{@params[0]}', please use a valid pivotal story Id")
      return
    end
    show_task(task)
  end

  def tasks
    title("Open story tasks for #{user_s} in #{project_to_s}")
    task = get_task_from_params "Please select a story to show pending tasks"
    unless task
      message("No matches found for '#{@params[0]}', please use a valid pivotal story Id")
      return
    end
    story_task = get_open_story_task_from_params(task)

    if story_task.position == -1
      description = ask('Title for new task')
      task.tasks.create(:description => description)
      congrats("New todo task added to \"#{task.name}\"")
    else
      edit_story_task story_task
    end
  end

  # takes a comma separated list of ids and prints the collection of tasks
  def show_condensed
    title("Tasks for #{user_s} in #{project_to_s}")
      tasks = []
    if @params[0]
      @params[0].each_line(',') do |line|
        tasks << @client.get_task_by_id(@project, line.to_i)
      end
      table = PT::TasksTable.new(tasks)
      table.print
    end
  end

  # TODO implement story notes and  comment
  def reject
    title("Tasks for #{user_s} in #{project_to_s}")
    if @params[0]
      task = @client.get_story(@project, @params[0])
      title("Rejecting '#{task.name}'")
    else
      tasks = @client.get_my_tasks_to_reject(@project, @local_config[:user_name])
      table = PT::TasksTable.new(tasks)
      title("Tasks for #{user_s} in #{project_to_s}")
      task = select("Please select a story to mark it as rejected", table)
    end

    if @params[1]
      comment = @params[1]
    else
      comment = ask("Please explain why are you rejecting the task.")
    end

    if @client.comment_task(@project, task, comment)
      result = @client.mark_task_as(@project, task, 'rejected')
      congrats("Task rejected, thanks!")
    else
      error("Ummm, something went wrong.")
    end
  end

  def done
    if @params[0]
      task = task_by_id_or_pt_id @params[0].to_i

      #we need this for finding again later
      task_id = task.id

      if !@params[1] && task.estimate == -1
        error("You need to give an estimate for this task")
        return
      end

      if @params[1] && task.estimate == -1
          if [0,1,2,3].include? @params[1].to_i
            estimate_task(task, @params[1].to_i)
          end
          if @params[2]
            task = task_by_id_or_pt_id task_id
            @client.comment_task(@project, task, @params[2])
          end
      else
        @client.comment_task(@project, task, @params[1]) if @params[1]
      end

      task = task_by_id_or_pt_id task_id
      start_task task

      task = task_by_id_or_pt_id task_id
      finish_task task

      task = task_by_id_or_pt_id task_id
      deliver_task task
    end
  end

  def estimate_task task, difficulty
    result = @client.estimate_task(@project, task, difficulty)
    if result.errors.any?
      error(result.errors.errors)
    else
      congrats("Task estimated, thanks!")
    end
  end

  def start_task task
    @client.mark_task_as(@project, task, 'started')
    congrats("Task started, go for it!")
  end

  def finish_task task
    if task.story_type == 'chore'
      @client.mark_task_as(@project, task, 'accepted')
    else
      @client.mark_task_as(@project, task, 'finished')
    end
    congrats("Another task bites the dust, yeah!")
  end

  def deliver_task task
    return if task.story_type == 'chore'
    @client.mark_task_as(@project, task, 'delivered')
    congrats("Task delivered, congrats!")
  end

  def find
    if (story_id = @params[0].to_i).nonzero?
      if task = task_by_id_or_pt_id(@params[0].to_i)
        return show_task(task)
      else
        message("Task not found by id (#{story_id}), falling back to text search")
      end
    end

    if @params[0]
      tasks = @client.get_my_work(@project, @local_config[:user_name])
      matched_tasks = tasks.select do |story_task|
        story_task.name.downcase.index(@params[0]) && story_task.current_state != 'delivered'
{'fraction_non_alphanumeric': 0.12248890226469039, 'fraction_numerical': 0.005266721841847867, 'mean_word_length': 2.9167526152939445, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, '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': '5723013', 'n_tokens_mistral': 8775, 'n_tokens_neox': 8712, 'n_words': 2237}