<commit_before>require 'json'
require 'logger'
require 'uri'

class Servant < ActiveRecord::Base
  validates_uniqueness_of :name

  def to_json(*a)
    {
      'name' => self.name,
      'url' => self.url.to_s,
      'protocol' => self.protocol,
      'status' => self.status
    }.to_json(*a)
  end

  def from_json(json)
    json_hash = JSON.parse(json)
    self.name = json_hash['name']
    self.url = json_hash['url']
    if json_hash.has_key?('protocol') then
      self.protocol = json_hash['protocol']
    end
  end

  def url=(new_url)
    write_attribute(:url, new_url.to_s)
  end

  def url
    URI.parse(read_attribute(:url))
  end

  def status
    # Three statuses are loading_roles, loading_protocol, and loaded.
    if not self.protocol? then
      :loading_protocol
    else
      # TODO(mtomczak): It's possible an error could occur.
      #   If so, need an :error status (and code and human-
      #   readable form).
      roles = self.roles
      if not roles or roles.include? nil then
        :loading_roles
      else
        :loaded
      end
    end
  end

  def role_urls
    # Returns the URLs associated with the roles (as an
    # array), or nil if the protocol does not exist.
    # Any invalid role URLs are returned as nil.
    # Relative URLs are yielded as absolute URLs (with the
    # servant's URL as the absolute location).
    if not self.protocol? then
      return nil
    end
    begin
      protocol_object = JSON.parse(self.protocol)
      protocol_url = self.url
      if not protocol_object.has_key? "roles" then
        return nil
      end
      role_urls = protocol_object["roles"].map { |role_object|
        if not role_object.has_key? "role_url" then
          nil
        else
          role_url = URI.parse(role_object["role_url"])
          if not role_url.host then
            new_url = URI.parse(protocol_url.to_s)
            new_url.path = role_url.path
            role_url = new_url
          end
          role_url
        end
      }
      return role_urls
    rescue JSON::ParserError => e
      log_error(:could_not_parse_protocol,
                "The servant's protocol could not be " +
                "parsed.")
      return nil
    end
  end
  
  def roles
    # Returns the roles associated with this protocol
    # (as an array), or nil if the roles do not exist 
    # (or cannot be loaded).
    #
    # The returned array has a Role object for each role,
    # or nil if the role object is missing.
    #
    # Errors that occur in parsing JSON result in an error
    # being logged.
    urls = role_urls<commit_msg>Converted to_json to as_json to handle new Rails behavior.<commit_after>require 'json'
require 'logger'
require 'uri'

class Servant < ActiveRecord::Base
  validates_uniqueness_of :name

  def as_json(*a)
    {
      'name' => self.name,
      'url' => read_attribute(:url),
      'protocol' => self.protocol,
      'status' => self.status,
    }
  end

  def from_json(json)
    json_hash = JSON.parse(json)
    self.name = json_hash['name']
    self.url = json_hash['url']
    if json_hash.has_key?('protocol') then
      self.protocol = json_hash['protocol']
    end
  end

  def url=(new_url)
    write_attribute(:url, new_url.to_s)
  end

  def url
    URI.parse(read_attribute(:url))
  end

  def status
    # Three statuses are loading_roles, loading_protocol, and loaded.
    if not self.protocol? then
      :loading_protocol
    else
      # TODO(mtomczak): It's possible an error could occur.
      #   If so, need an :error status (and code and human-
      #   readable form).
      roles = self.roles
      if not roles or roles.include? nil then
        :loading_roles
      else
        :loaded
      end
    end
  end

  def role_urls
    # Returns the URLs associated with the roles (as an
    # array), or nil if the protocol does not exist.
    # Any invalid role URLs are returned as nil.
    # Relative URLs are yielded as absolute URLs (with the
    # servant's URL as the absolute location).
    if not self.protocol? then
      return nil
    end
    begin
      protocol_object = JSON.parse(self.protocol)
      protocol_url = self.url
      if not protocol_object.has_key? "roles" then
        return nil
      end
      role_urls = protocol_object["roles"].map { |role_object|
        if not role_object.has_key? "role_url" then
          nil
        else
          role_url = URI.parse(role_object["role_url"])
          if not role_url.host then
            new_url = URI.parse(protocol_url.to_s)
            new_url.path = role_url.path
            role_url = new_url
          end
          role_url
        end
      }
      return role_urls
    rescue JSON::ParserError => e
      log_error(:could_not_parse_protocol,
                "The servant's protocol could not be " +
                "parsed.")
      return nil
    end
  end

  def roles
    # Returns the roles associated with this protocol
    # (as an array), or nil if the roles do not exist
    # (or cannot be loaded).
    #
    # The returned array has a Role object for each role,
    # or nil if the role object is missing.
    #
    # Errors that occur in parsing JSON result in an error
    # being logged.
    urls = role_urls
{'fraction_non_alphanumeric': 0.08023745691306013, 'fraction_numerical': 0.0, 'mean_word_length': 2.188644688644689, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 13, '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': '6137964', 'n_tokens_mistral': 1609, 'n_tokens_neox': 1582, 'n_words': 522}