<file_sep>class Poem < ApplicationRecord
  validates :balada, presence: true, uniqueness: true
end
<file_sep>Rails.application.routes.draw do
  root 'contest#index'


   post '/quiz', to: 'contest#quiz'

  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
<file_sep>class AddWordsToPoemLines < ActiveRecord::Migration[5.0]
  def change
    add_column :poem_lines, :first_word, :string
    add_column :poem_lines, :last_word, :string
    add_index :poem_lines, :first_word
    add_index :poem_lines, :last_word
  end
end
<file_sep>class PoemLine < ApplicationRecord
  validates :sort_letters, presence: true, uniqueness: true
end
<file_sep># This file should contain all the record creation needed to seed the database with its default values.
# The data can then be loaded with the rails db:seed command (or created alongside the database with db:setup).
#
# Examples:
#
#   movies = Movie.create([{ name: 'Star Wars' }, { name: 'Lord of the Rings' }])
#   Character.create(name: 'Luke', movie: movies.first)
require 'mechanize'
require 'colorize'



URL = "http://ilibrary.ru/text/"

    mechanize = Mechanize.new { |agent|
      agent.user_agent_alias = 'Linux Firefox'
    }

    page = mechanize.get("http://ilibrary.ru/author/pushkin/l.all/index.html")
    links = page.parser.css('.list a')

    id_poems = links.map { |l| l.attributes['href'].value }
      .select { |l| l =~ %r{/text/\d+/index\.html} }
      .map { |l| l.scan(/\d+/)[0] }.uniq



    num = 0
    size = id_poems.size
    puts "About to write #{size} poems..."

    Poem.delete_all
    # begin work with another model
    PoemLine.delete_all

    

    id_poems.each do |id|
      link = URL + id + "/p.1/index.html"

      page = mechanize.get(link)

      title = page.parser.css('.title h1').text
      text_arr = []
      page.parser.css('.vl').each do |line|
        text_arr << line.text.lstrip
        # begin work with another model
        # poem_line = PoemLine.new
        # poem_line.title = title
        # poem_line.line = line.text.lstrip
        # # second space has 160 asci value
        # letters_sorted_in_line = line.text.delete('.,!?:;()—«»').delete(' ').delete(" ").chars.sort.join('')
        # poem_line.sort_letters = letters_sorted_in_line
        # poem_line.length = letters_sorted_in_line.length
        # poem_line.save

        temp_line = line.text.gsub(/\u0097/, "\u2014")
        poem_line = PoemLine.new
        
        poem_line.title = title
        poem_line.line = temp_line.lstrip
        # second space has 160 asci value
        letters_sorted_in_line = temp_line.delete('.,!?:;()—«»').delete(' ').delete(" ").chars.sort.join('')
        poem_line.sort_letters = letters_sorted_in_line
        poem_line.length = letters_sorted_in_line.length
        # add first and last word in line
        line_on_words = temp_line.delete('.,!?:;()—«»').delete(" ").split(' ')
        poem_line.first_word = line_on_words.first
        poem_line.last_word = line_on_words.last
        poem_line.save
      end

      text = text_arr.join("\n")

      text.gsub!(/\u0097/, "\u2014") # replacement of unprintable symbol
      text.gsub!(/^\n/, "") # remove first \n


      puts "=".cyan*30
      puts title.green
      puts "#{num} of #{size}".cyan
      num += 1

      next if text.blank?

      


      poem = Poem.new
      poem.title = title
      poem.balada = text
      poem.save
end

<file_sep>class ContestController < ApplicationController
  skip_before_filter :verify_authenticity_token

  def index
    @temps = Temp.all.reverse
  end

  def quiz
    answer_params = referral_params_answer

    level = answer_params[:level]
    question = answer_params[:question]
    id = answer_params[:id]

    case level.to_s
    when '1'
      answer = first_level(question)
    when '2'
      answer = second_level(question)
    when '3'
      answer = second_level(question)
    when '4'
      answer = second_level(question)
    when '5'
      answer = fiveth_level(question)
    when '6'
      answer = sixth_level(question)
    when '7'
      answer = sixth_level(question)
    when '8'
      answer = eight_level(question)
    else
      answer = "No answer"
    end


    
    @@token ||= Token.last.value
    send_answer(answer, id, @@token)

    temp = Temp.new
    temp.answer = answer
    temp.question = question
    temp.id_poem = id
    temp.level = level
    temp.save
    
    render json: "ok"
  end

  def referral_params_answer
    json_params = ActionController::Parameters.new( JSON.parse(request.body.read) )
    return json_params.permit(:level, :question, :id)
  end

  URI = URI("http://pushkin.rubyroidlabs.com/quiz")


  def send_answer(answer, id, token)
    parameters = {
      answer: answer,
      token: token,
      task_id: id
    }  
   Net::HTTP.post_form(URI, parameters) 
  end

  # -------------------------------------------------------------------------
  # def first_level(question)
  #   Poem.find_by("balada ~* ?", question).try(:title)
  # end

  # def first_level(question)
  #   sorted_question = question.delete('.,!?:;()—«»').delete(' ').delete(" ").chars.sort
  #   sorted_question_line = sorted_question.join
  #   question_letters_count = sorted_question.size
  #   PoemLine.find_by(length: question_letters_count, sort_letters: sorted_question_line).try(:title)
  #   # PoemLine.find_by(line: question).try(:title)
  # end

  def first_level(question)
    sorted_question = question.delete('.,!?:;()—«»').delete(' ').delete(" ").chars.sort
    sorted_question_line = sorted_question.join
    PoemLine.find_by(sort_letters: sorted_question_line).try(:title)
  end

  # --------------------------------------------------------------------------
  # --------------------------------------------------------------------------
  # def second_level(questions)
  #   question = questions.split("\n").first

  #   question_parts = question.split('%WORD%').sort_by(&:length).reverse
  #   poem = Poem.find_by("balada ~* ?", question_parts[0]).balada
  #   return find_searched_words(poem, questions)
  # end

  # def find_searched_words(poem, questions)
  #   searched_words = []
  #   poem_on_line = poem.split("\n")

  #   questions.split("\n").each do |question|
  #     question_parts = question.split('%WORD%')

  #     poem_on_line.each do |line|
  #       if is_your_str?(question_parts, line)
  #         searched_word = line
  #         question_parts.each do |part|
  #           searched_word.sub!(part, "")
  #         end
  #         searched_words << searched_word.delete('.,!?:;()—')
  #         break
  #       end
  #     end 
  #   end

  #   return searched_words.join(',')
  # end

  # def is_your_str?(question_parts, line)
  #   question_parts.each do |part|
  #     return false unless line.include? part
  #   end
  #   return true
  # end
# ----------------------------------------------------------------------
# ----------------------------------------------------------------------
  def second_level(questions)
    indexes = []
    searched_words = []

    questions.split("\n").each_with_index do |question, num_question|
      question_parts = question.split('%WORD%')
      question_on_words = question.delete('.,!?:;()—«»').delete(" ").split(' ')
      if indexes.size > 0
        searched_words << return_searched_word(question_parts, PoemLine.find(indexes.first + num_question).line)
      else 
        if question_on_words.last == '%WORD%'
          PoemLine.where(first_word: question_on_words.first).each do |line|
            if is_your_str?(question_parts, line.line)
              indexes << line.id
              searched_words << return_searched_word(question_parts, line.line)
            end
          end
        else 
          PoemLine.where(last_word: question_on_words.last).each do |line|
            if is_your_str?(question_parts, line.line)
              indexes << line.id
              searched_words << return_searched_word(question_parts, line.line)
            end
          end
        end
      end
    end

    return searched_words.join(',')
  end

  def return_searched_word(question_parts,line)
    searched_word = line
    question_parts.each do |part|
      searched_word.sub!(part, "")
    end
    searched_word.delete('.,!?:;()—')
  end

  def is_your_str?(question_parts, line)
    question_parts.each do |part|
      return false unless line.include? part
    end
    return true
  end

# ----------------------------------------------------------------------

 # def fiveth_level(question)
 #    possible_sentence = create_all_possible_variation question
 #    regexp = possible_sentence.join('|')
 #    my_line = Poem.find_by("balada ~ ?", regexp).try(:balada).match(regexp).to_s

 #    return find_different_words(question, my_line)
 #  end

 #  def create_all_possible_variation(question)
 #    possible_sentence = []
 #    question_on_words = question.split(" ")

 #    question_on_words.count.times do 
 #      possible_sentence << question.split(" ")
 #    end
 #    possible_sentence.each_with_index do |arr, i|
 #      arr[i].sub!(/^[А-Яа-яA-Za-z\-«»]+/, "\\S+")
 #    end

 #    possible_sentence.map! { |a| a.join(" ") }
 #    return possible_sentence
 #  end

 #  def find_different_words(question, line)
 #    line_on_words = line.delete('.,!?:;()—').split(" ")
 #    question_on_words = question.delete('.,!?:;()—').split(" ")
 #    return ((line_on_words - question_on_words) | (question_on_words - line_on_words)).join(',')
 #  end
# ----------------------------------------------------------------------
# --------------------------------------------------------------------
   
  def fiveth_level(question)
    possible_sentence = create_all_possible_variation question
    regexp = possible_sentence.join('|')

    question_on_words = question.delete('.,!?:;()—«»').delete(" ").split(' ')
    PoemLine.where(last_word: question_on_words.last).
      or(PoemLine.where(first_word: question_on_words.first)).each do |line|
        if Regexp.new(regexp) =~ line.line
          return find_different_words(question, line.line)
        end
    end
    return ' '
  end

  def create_all_possible_variation(question)
    possible_sentence = []
    question_on_words = question.split(" ")

    question_on_words.count.times do |i|
      possible_sentence << question.split(" ")
      possible_sentence[i][i].sub!(/^[А-Яа-яA-Za-z\-«»]+/, "\\S+")
      possible_sentence[i] = possible_sentence[i].join(" ")
    end

    return possible_sentence
  end

  def find_different_words(question, line)
    line_on_words = line.delete('.,!?:;()—').split(" ")
    question_on_words = question.delete('.,!?:;()—').split(" ")
    return ((line_on_words - question_on_words) | (question_on_words - line_on_words)).join(',')
  end


# --------------------------------------------------------------------

  def sixth_level(question)
    sorted_question = question.delete(' ').delete(" ").chars.sort
    sorted_question_line = sorted_question.join
    PoemLine.find_by(sort_letters: sorted_question_line).try(:line)
    # question_letters_count = sorted_question.size
    # PoemLine.find_by(length: question_letters_count, sort_letters: sorted_question_line).line
  end
 # ----------------------------------------------------------------------
  def eight_level(question)
    question_on_letters = question.delete(' ').chars
    letters_question_count = question_on_letters.length

    PoemLine.where(length: letters_question_count).each do |line|
      if has_unsuitable_element?(line.sort_letters, question.delete(' '))
        return line.line
      end
    end
    return nil
  end

  def has_unsuitable_element?(arr1, arr2)
    arr1 = arr1.chars
    arr2 = arr2.chars
    unsuitable_array = []
    arr1.length.times do
      shift_element = arr2.shift 
      if arr1.include? shift_element
        arr1.delete_at( arr1.index shift_element)
      else
        unsuitable_array << shift_element
        return false if unsuitable_array.size > 1
      end
    end
    true
  end
 # ----------------------------------------------------------------------
end
