<commit_before>#!/usr/bin/env ruby -w

require 'optparse'
require 'ostruct'
require 'httparty'
require 'json'
require 'io/console'
class ShowMoocData

  def run(args)
    pos = DATA.pos
    rest = DATA.read

    @notes = begin JSON.parse(rest) rescue  {} end

    @options = OpenStruct.new
    opt = OptionParser.new do |opts|
      opts.banner = "Usage: show-mooc-details.rb [options]"

      opts.on("-f", "--force", "Reload data from server") do |v|
        @options.reload = true
      end
      opts.on("-u", "--user username", "Show details for user") do |v|
        @options.user = v
      end
      opts.on("-e", "--email emailaddress", "Show details for user") do |v|
        @options.user_email = v
      end
      opts.on("-t", "--tmc-account tmc-account", "Show details for user") do |v|
        @options.user_tmc_username = v
      end
      opts.on("-l", "--list", "Show the basic list") do |v|
        @options.list = true
      end
      opts.on_tail("-h", "--help", "Show this message") do
        puts opts
        exit
      end
    end
    opt.parse!(args)

    json = maybe_fetch_json(get_auth())
    if @options.user
      show_info_about(@options.user, 'username', json)
    elsif @options.user_email
      show_info_about(@options.user_email, 'email', json)
    elsif @options.user_tmc_username
      show_info_about(@options.user_tmc_username, 'username', json)
    elsif @options.list
      list_and_filter_participants(json)
    else
      puts opt
      abort
    end

    DATA.reopen(__FILE__, "r+")
    DATA.truncate(pos)
    DATA.seek(pos)
    DATA.puts @notes.to_json
  end

  def get_auth
    print 'username: '
    username = $stdin.gets.strip
    print 'password: '
    password = $stdin.noecho(&:gets).strip
    {username: username, password: password}
  end

  def maybe_fetch_json(auth)
    if @options.reload or @notes['user_info'].nil? or @notes['week_data'].nil?
      url = "http://tmc.mooc.fi/mooc/participants.json?api_version=7&utf8=%E2%9C%93&filter_koko_nimi=&column_username=1&column_email=1&column_koko_nimi=1&column_hakee_yliopistoon_2014=1&group_completion_course_id=18"
      user_info = JSON.parse(HTTParty.get(url, basic_auth: auth).body)['participants']
      week_data = fetch_week_datas(auth)
      @notes['user_info'] = user_info.clone
      @notes['week_data'] = week_data.clone
      {participants: user_info, week_data: week_data}
    else
      {participants: @notes['user_info'].clone, week_data: @notes['week_data'].clone}
    end
  end

  def show_info_about(user, user_field = 'username', json)
    participants = json[:participants]
    week_data = json[:week_data]
    my_user = participants.find{|a| a[user_field] == user }
    if my_user.nil?
      abort "User not found"
    end
    formatted_print_user_details ["Username", my_user['username']]
    formatted_print_user_details ["Email", my_user['email']]
    formatted_print_user_details ["Hakee yliopistoon", my_user['hakee_yliopistoon_2014']]
    formatted_print_user_details ["Koko nimi", my_user['koko_nimi']]
    missing_points = get_points_info_for_user(my_user, week_data)

    formatted_print_user_details ["Missing points", "===================================="]
    missing_points.each do |k,v|
      formatted_print_user_details [k, v.join(", ")]
    end
  end

  def formatted_print_user_details(details)
    puts "%18s: %-20s" % details
  end

  def fetch_week_datas(auth)
    base_url = "http://tmc.mooc.fi/mooc/courses/18/points/"
    weeks = %w(1 2 3 4 5 6 7 8 9 10 11 12)
    rest = ".json?api_version=7"
    week_data = {}
    weeks.each do |week|
      week_data[week] = JSON.parse(HTTParty.get(base_url + week + rest, basic_auth: auth).body)['users_to_points']
    end
    week_data
  end

  def list_and_filter_participants(json)
    wanted_fields = %W(username email koko_nimi)

    participants = json[:participants]
    week_data = json[:week_data]
    everyone_in_course = participants.size
    only_applying!(participants)
    hakee_yliopistoon = participants.size

    puts "%-20s %-35s %-25s %-120s" % ["Username", "Email", "Real name", "Missing points"]
    puts '-'*200
    participants.each do |participant|
      nice_string_in_array = wanted_fields.map do |key|
        participant[key]
      end
      nice_string_in_array << missing_points_to_list_string(get_points_info_for_user(participant, week_data))
      puts "%-20s %-35s %-25s %-120s" % nice_string_in_array
    end

    puts
    puts
    puts "Stats: "
    puts "%25s: %4d" % ["Kaikenkaikkiaan kurssilla", everyone_in_course]
    puts "%25s: %4d" % ["Hakee yliopistoon", hakee_yliopistoon]

  end

  def missing_points_to_list_string(missing_by_week)
    str = ""
    missing_by_week.keys.each do |week|
      missing = missing_by_week[week]
      unless missing.nil? or missing.length == 0
        str << week
        str << ": "
        str << missing.join(",")
        str << "  "
      end
    end

    str

  end

  def get_points_info_for_user(participant, week_data)
    # TODO: täydennä data viikoille 11 ja 12
    compulsory_exercises = {'6' => %w(102.1 102.2 102.3 103.1 103.2 103.3), '7' => %w(116.1 116.2 116.3), '8' => %w(124.1 124.2 124.3 124.4),
                            '9' => %w(134.1 134.2 134.3 134.4 134.5), '10' => %w(141.1 141.2 141.3 141.4), '11' => %w(), '12' => %w()}
    points_by_week = {}
    week_data.keys.each do |week|
      points_by_week[week] = week_data[week][participant['username']]
    end


    missing_by_week = {}
    points_by_week.keys.each  do |week|
      weeks_points = points_by_week[week] || [] #palauttaa arrayn
      weeks_compulsory_points = compulsory_exercises[week] || []
      missing_by_week[week] = weeks_compulsory_points - weeks_points
    end

    missing_by_week
  end

  def only_applying!(participants)
    participants.select! do |participant|
      participant['hakee_yliopistoon_2014']
    end
  end
end

ShowMoocData.new.run(ARGV)

__END__<commit_msg>upgraded points to week 5<commit_after>#!/usr/bin/env ruby -w

require 'optparse'
require 'ostruct'
require 'httparty'
require 'json'
require 'io/console'
class ShowMoocData

  def run(args)
    pos = DATA.pos
    rest = DATA.read

    @notes = begin JSON.parse(rest) rescue  {} end

    @options = OpenStruct.new
    opt = OptionParser.new do |opts|
      opts.banner = "Usage: show-mooc-details.rb [options]"

      opts.on("-f", "--force", "Reload data from server") do |v|
        @options.reload = true
      end
      opts.on("-u", "--user username", "Show details for user") do |v|
        @options.user = v
      end
      opts.on("-e", "--email emailaddress", "Show details for user") do |v|
        @options.user_email = v
      end
      opts.on("-t", "--tmc-account tmc-account", "Show details for user") do |v|
        @options.user_tmc_username = v
      end
      opts.on("-l", "--list", "Show the basic list") do |v|
        @options.list = true
      end
      opts.on_tail("-h", "--help", "Show this message") do
        puts opts
        exit
      end
    end
    opt.parse!(args)

    json = maybe_fetch_json(get_auth())
    if @options.user
      show_info_about(@options.user, 'username', json)
    elsif @options.user_email
      show_info_about(@options.user_email, 'email', json)
    elsif @options.user_tmc_username
      show_info_about(@options.user_tmc_username, 'username', json)
    elsif @options.list
      list_and_filter_participants(json)
    else
      DATA.reopen(__FILE__, "r+")
      DATA.truncate(pos)
      DATA.seek(pos)
      DATA.puts @notes.to_json
      puts opt
      abort
    end

    DATA.reopen(__FILE__, "r+")
    DATA.truncate(pos)
    DATA.seek(pos)
    DATA.puts @notes.to_json
  end

  def get_auth
    print 'username: '
    username = $stdin.gets.strip
    print 'password: '
    password = $stdin.noecho(&:gets).strip
    {username: username, password: password}
  end

  def maybe_fetch_json(auth)
    if @options.reload or @notes['user_info'].nil? or @notes['week_data'].nil?
      url = "http://tmc.mooc.fi/mooc/participants.json?api_version=7&utf8=%E2%9C%93&filter_koko_nimi=&column_username=1&column_email=1&column_koko_nimi=1&column_hakee_yliopistoon_2014=1&group_completion_course_id=18"
      user_info = JSON.parse(HTTParty.get(url, basic_auth: auth).body)['participants']
      week_data = fetch_week_datas(auth)
      @notes['user_info'] = user_info.clone
      @notes['week_data'] = week_data.clone
      {participants: user_info, week_data: week_data}
    else
      {participants: @notes['user_info'].clone, week_data: @notes['week_data'].clone}
    end
  end

  def show_info_about(user, user_field = 'username', json)
    participants = json[:participants]
    week_data = json[:week_data]
    my_user = participants.find{|a| a[user_field] == user }
    if my_user.nil?
      abort "User not found"
    end
    formatted_print_user_details ["Username", my_user['username']]
    formatted_print_user_details ["Email", my_user['email']]
    formatted_print_user_details ["<NAME>", my_user['hakee_yliopistoon_2014']]
    formatted_print_user_details ["Koko nimi", my_user['koko_nimi']]
    missing_points = get_points_info_for_user(my_user, week_data)

    formatted_print_user_details ["Missing points", "===================================="]
    missing_points.each do |k,v|
      formatted_print_user_details [k, v.join(", ")]
    end
  end

  def formatted_print_user_details(details)
    puts "%18s: %-20s" % details
  end

  def fetch_week_datas(auth)
    base_url = "http://tmc.mooc.fi/mooc/courses/18/points/"
    weeks = %w(1 2 3 4 5 6 7 8 9 10 11 12)
    rest = ".json?api_version=7"
    week_data = {}
    weeks.each do |week|
      week_data[week] = JSON.parse(HTTParty.get(base_url + week + rest, basic_auth: auth).body)['users_to_points']
    end
    week_data
  end

  def list_and_filter_participants(json)
    wanted_fields = %W(username email koko_nimi)

    participants = json[:participants]
    week_data = json[:week_data]
    everyone_in_course = participants.size
    only_applying!(participants)
    hakee_yliopistoon = participants.size

    puts "%-20s %-35s %-25s %-120s" % ["Username", "Email", "Real name", "Missing points"]
    puts '-'*200
    participants.each do |participant|
      nice_string_in_array = wanted_fields.map do |key|
        participant[key]
      end
      nice_string_in_array << missing_points_to_list_string(get_points_info_for_user(participant, week_data))
      puts "%-20s %-35s %-25s %-120s" % nice_string_in_array
    end

    puts
    puts
    puts "Stats: "
    puts "%25s: %4d" % ["Kaikenkaikkiaan kurssilla", everyone_in_course]
    puts "%25s: %4d" % ["Hakee yliopistoon", hakee_yliopistoon]

  end

  def missing_points_to_list_string(missing_by_week)
    str = ""
    missing_by_week.keys.each do |week|
      missing = missing_by_week[week]
      unless missing.nil? or missing.length == 0
        str << week
        str << ": "
        str << missing.join(",")
        str << "  "
      end
    end

    str

  end

  def get_points_info_for_user(participant, week_data)
    # TODO: täydennä data viikoille 11 ja 12
    compulsory_exercises = {'6' => %w(102.1 102.2 102.3 103.1 103.2 103.3), '7' => %w(116.1 116.2 116.3), '8' => %w(124.1 124.2 124.3 124.4),
                            '9' => %w(134.1 134.2 134.3 134.4 134.5), '10' => %w(141.1 141.2 141.3 141.4), '11' => %w(151.1 151.2 151.3 151.4), '12' => %w()}
    points_by_week = {}
    week_data.keys.each do |week|
      points_by_week[week] = week_data[week][participant['username']]
    end


    missing_by_week = {}
    points_by_week.keys.each  do |week|
      weeks_points = points_by_week[week] || [] #palauttaa arrayn
      weeks_compulsory_points = compulsory_exercises[week] || []
      missing_by_week[week] = weeks_compulsory_points - weeks_points
    end

    missing_by_week
  end

  def only_applying!(participants)
    participants.select! do |participant|
      participant['hakee_yliopistoon_2014']
    end
  end
end

ShowMoocData.new.run(ARGV)

__END__
{'fraction_non_alphanumeric': 0.13635228502455674, 'fraction_numerical': 0.030716723549488054, 'mean_word_length': 3.1802366040361867, 'pattern_counts': {'":': 2, '<': 24, '<?xml version=': 0, '>': 18, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4693735', 'n_tokens_mistral': 4586, 'n_tokens_neox': 4296, 'n_words': 879}