<commit_before>#!/usr/bin/ruby

require 'sinatra'
require "sinatra/reloader" if development?
require "sinatra/config_file"
require 'instagram'
require 'date'
require 'sequel'

$db = Sequel.connect(ENV['DATABASE_URL'] || 'sqlite://threesixtyfive.db')
$db.create_table? :photos do
  primary_key :id
  Int :year
  Int :year_index
  Time :registered_at
  Time :created_at
  String :instagram_id
  String :photo_url
  String :thumb_url
  String :link_url
end rescue nil

class Photo < Sequel::Model
end

enable :sessions
config_file 'threesixtyfive.yaml'

Instagram.configure do |config|
  config.client_id = ENV["THREESIXTYFIVE_CLIENT_ID"] || settings.instagram[:client_id]
  config.client_secret = ENV["THREESIXTYFIVE_CLIENT_SECRET"] || settings.instagram[:client_secret]
end

get "/" do
  @photos = Photo.reverse_order(:created_at).all
  erb :index
end

get "/work" do
  unless session[:access_token]
    return '<a href="/work/connect">Connect with Instagram</a>'
  end

  "<h1>Work!</h1><a href='/work/check'>Check now</a> (#{Photo.count} photos)"
end

get "/work/db" do
  send_file File.join(settings.public_folder, 'threesixtyfive.db')
end

get "/work/db/delete" do
  Photo.truncate
  redirect "/work"
end

get "/work/check" do
  now = Date.today
  year = now.year
  check year
end

get "/work/check/:year" do |year|
  check year.to_i
end

get "/work/connect" do
  redirect Instagram.authorize_url(:redirect_uri => "#{request.base_url}/work/callback")
end

get "/work/callback" do
  response = Instagram.get_access_token(params[:code], :redirect_uri => "#{request.base_url}/work/callback")
  session[:access_token] = response.access_token
  redirect "/work"
end

def check(year)
  client = Instagram.client(:access_token => session[:access_token])

  tomorrow = DateTime.now.next_day.beginning_of_day
  puts tomorrow
  beginning_of_year = DateTime.new(year, 1, 1, 0, 0, 0, '+1')
  last_photo = Photo.reverse_order(:id).first

  if last_photo.nil?
    # first photo
    result = "Cannot find the first photo"
    all_media = at_least(client, 365, { :min_timestamp => beginning_of_year.to_time.to_i })
    all_media.sort { |a, b| a.created_time.to_i <=> b.created_time.to_i }.select! { |m| t = Time.at(m.created_time.to_i).to_datetime; t >= beginning_of_year && t < tomorrow }

    first_day = beginning_of_year
    while all_media.any? { |m| date_time(m.created_time).yday <= first_day.yday }
      media = all_media.select { |m| date_time(m.created_time).yday == first_day.yday }
      if media.count > 0
        media_item = select_best_photo(media)
        photo = photo_from_media_item(media_item)
        photo.save

        result = "Saved the first photo: <img src='#{photo.photo_url}'>\n"
        break
      end
      first_day = first_day.next_day
    end
  else
    min_id = last_photo.instagram_id
    result = "Completing since #{min_id}"

    all_media = at_least(client, 365, { :min_id => min_id })
    all_media.select! { |m| t = date_time(m.created_time); t > last_photo.created_at.to_datetime && t < tomorrow }

    last_day = last_photo.created_at.next_day.beginning_of_day
    while last_day < tomorrow && all_media.any? { |m| date_time(m.created_time).yday <= last_day.yday }
      media = all_media.select { |m| date_time(m.created_time).yday == last_day.yday }
      if media.count > 0
        media_item = select_best_photo(media)
        photo = photo_from_media_item(media_item)
        photo.save

        result << "Saved a photo: <img src='#{photo.photo_url}'><br>\n"
      end
      last_day = last_day.next_day
    end
  end

  result
end

def date_time(time)
  x = 1
  offset = (x * 3600) - Time.now.utc_offset
  puts offset
  Time.at(time.to_i + offset).to_datetime
end

def at_least(client, num, options = {})
  result = []
  options[:count] = 20<commit_msg>Meh, too eager.<commit_after>#!/usr/bin/ruby

require 'sinatra'
require "sinatra/reloader" if development?
require "sinatra/config_file"
require 'instagram'
require 'date'
require 'sequel'

$db = Sequel.connect(ENV['DATABASE_URL'] || 'sqlite://threesixtyfive.db')
$db.create_table? :photos do
  primary_key :id
  Int :year
  Int :year_index
  Time :registered_at
  Time :created_at
  String :instagram_id
  String :photo_url
  String :thumb_url
  String :link_url
end rescue nil

class Photo < Sequel::Model
end

enable :sessions
config_file 'threesixtyfive.yaml'

Instagram.configure do |config|
  config.client_id = ENV["THREESIXTYFIVE_CLIENT_ID"] || settings.instagram[:client_id]
  config.client_secret = ENV["THREESIXTYFIVE_CLIENT_SECRET"] || settings.instagram[:client_secret]
end

get "/" do
  @photos = Photo.reverse_order(:created_at).all
  erb :index
end

get "/work" do
  unless session[:access_token]
    return '<a href="/work/connect">Connect with Instagram</a>'
  end

  "<h1>Work!</h1><a href='/work/check'>Check now</a> (#{Photo.count} photos)"
end

get "/work/db" do
  send_file File.join(settings.public_folder, 'threesixtyfive.db')
end

get "/work/db/delete" do
  Photo.truncate
  redirect "/work"
end

get "/work/check" do
  now = Date.today
  year = now.year
  check year
end

get "/work/check/:year" do |year|
  check year.to_i
end

get "/work/connect" do
  redirect Instagram.authorize_url(:redirect_uri => "#{request.base_url}/work/callback")
end

get "/work/callback" do
  response = Instagram.get_access_token(params[:code], :redirect_uri => "#{request.base_url}/work/callback")
  session[:access_token] = response.access_token
  redirect "/work"
end

def check(year)
  client = Instagram.client(:access_token => session[:access_token])

  tomorrow = DateTime.now.next_day.beginning_of_day
  puts tomorrow
  beginning_of_year = DateTime.new(year, 1, 1, 0, 0, 0, '+1')
  last_photo = Photo.reverse_order(:id).first

  if last_photo.nil?
    # first photo
    result = "Cannot find the first photo"
    all_media = at_least(client, 365, { :min_timestamp => beginning_of_year.to_time.to_i })
    all_media.sort { |a, b| a.created_time.to_i <=> b.created_time.to_i }.select! { |m| t = Time.at(m.created_time.to_i).to_datetime; t >= beginning_of_year && t < tomorrow }

    first_day = beginning_of_year
    while all_media.any? { |m| date_time(m.created_time).yday <= first_day.yday }
      media = all_media.select { |m| date_time(m.created_time).yday == first_day.yday }
      if media.count > 0
        media_item = select_best_photo(media)
        photo = photo_from_media_item(media_item)
        photo.save

        result = "Saved the first photo: <img src='#{photo.photo_url}'>\n"
        break
      end
      first_day = first_day.next_day
    end
  else
    min_id = last_photo.instagram_id
    result = "Completing since #{min_id}"

    all_media = at_least(client, 365, { :min_id => min_id })
    all_media.select! { |m| t = date_time(m.created_time); t > last_photo.created_at.to_datetime && t < tomorrow }

    last_day = last_photo.created_at.to_datetime.next_day.beginning_of_day
    while last_day < tomorrow && all_media.any? { |m| date_time(m.created_time).yday <= last_day.yday }
      media = all_media.select { |m| date_time(m.created_time).yday == last_day.yday }
      if media.count > 0
        media_item = select_best_photo(media)
        photo = photo_from_media_item(media_item)
        photo.save

        result << "Saved a photo: <img src='#{photo.photo_url}'><br>\n"
      end
      last_day = last_day.next_day
    end
  end

  result
end

def date_time(time)
  x = 1
  offset = (x * 3600) - Time.now.utc_offset
  puts offset
  Time.at(time.to_i + offset).to_datetime
end

def at_least(client, num, options = {})
  result = []
  options[:count] = 20
{'fraction_non_alphanumeric': 0.1293421052631579, 'fraction_numerical': 0.0060526315789473685, 'mean_word_length': 3.8568690095846647, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 41, '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': '1410598', 'n_tokens_mistral': 2801, 'n_tokens_neox': 2738, 'n_words': 579}