<commit_before># frozen_string_literal: true

require 'json'

require_relative 'auth'
require_relative 'services'

require 'sinatra/base'
require 'sinatra/json'
require 'sinatra/param'

module JobBoard
  class JobDeliveryAPI < Sinatra::Base
    helpers Sinatra::Param

    before { content_type :json }

    helpers do
      include JobBoard::Auth::GuestDetect
    end

    before '/jobs*' do
      halt 403, JSON.dump('@type' => 'error', error: 'just no') if guest?
    end

    post '/jobs' do
      from = request.env.fetch('HTTP_FROM')
      JobBoard.logger.debug('received legacy jobs request', from: from)
      json(jobs: [], unavailable_jobs: [])
    end

    post '/jobs/add' do
      job = JSON.parse(request.body.read)
      site = request.env.fetch('travis.site')
      JobBoard.logger.debug(
        'parsed job',
        job_id: job.fetch('id', '<unknown>'), site: site
      )
      db_job = JobBoard::Services::CreateOrUpdateJob.run(job: job, site: site)
      if db_job.nil?
        JobBoard.logger.error(
          'failed to create or update job',
          job_id: job.fetch('id'), site: site
        )
        halt 400, JSON.dump('@type' => 'error', error: 'what')
      end
      JobBoard.logger.info('added', job_id: job.fetch('id'), site: site)
      [201, { 'Content-Length' => '0' }, '']
    end

    post '/jobs/pop' do
      param :queue, String, blank: true, required: true

      unless request.env.key?('HTTP_FROM')
        halt 412, JSON.dump(
          '@type' => 'error', error: 'missing from header'
        )
      end

      queue = params[:queue].to_s.sub(/^builds\./, '')
      from = request.env.fetch('HTTP_FROM')
      site = request.env.fetch('travis.site')

      job_id = JobBoard::Services::AllocateJob.run(
        from: from,
        queue_name: queue,
        site: site
      )

      if job_id.nil?
        JobBoard.logger.debug(
          'no jobs available',
          queue: queue, from: from, site: site
        )
        halt 204
      end

      JobBoard.logger.info(
        'popped',
        queue: queue, from: from, site: site, job_id: job_id
      )

      status 200
      json('@queue' => queue, 'job_id' => job_id)
    end

    post '/jobs/:job_id/claim' do
      param :queue, String, blank: true, required: true

      unless request.env.key?('HTTP_FROM')
        halt 412, JSON.dump(
          '@type' => 'error', error: 'missing from header'
        )
      end

      queue = params[:queue].to_s.sub(/^builds\./, '')
      from = request.env.fetch('HTTP_FROM')
      site = request.env.fetch('travis.site')
      job_id = params[:job_id]

      unless JobBoard::Services::RefreshJobClaim.run(
        job_id: job_id,
        from: from,
        queue_name: queue,
        site: site
      )
        JobBoard.logger.warn(
          'job id is not claimed',
          job_id: job_id, claimed: claimed_id,
          queue: queue, from: from, site: site
        )
        halt 409
      end

      JobBoard.logger.debug(
        'claim refreshed',
        queue: queue, from: from, site: site, job_id: job_id
      )
      status 200
      json('@queue' => queue, '@job_id' => job_id)
    end

    get '/jobs/:job_id' do
      job_id = params.fetch('job_id')
      site = request.env.fetch('travis.site')
      infra = request.env.fetch('travis.infra', '')
      from = request.env.fetch('HTTP_FROM')
      job = JobBoard::Services::FetchJob.run(
        job_id: job_id, site: site, infra: infra
      )
      halt 404, JSON.dump('@type' => 'error', error: 'no such job') if job.nil?
      if job.is_a?(JobBoard::Services::FetchJobScript::BuildScriptError)
        halt 424, JSON.dump(
          '@type' => 'error',
          error: 'job script fetch error',
          upstream_error: job.message
        )
      end
      JobBoard.logger.info(
        'fetched', job_id: job_id, site: site, infra: infra, from: from
      )
      json job
    end

    delete '/jobs/:job_id' do
      job_id = params.fetch('job_id')
      site = request.env.fetch('travis.site')
      from = request.env.fetch('HTTP_FROM')
      JobBoard::Services::DeleteJob.run(job_id: job_id, site: site)
      JobBoard.logger.info('deleted', job_id: job_id, site: site, from: from)
      [204, {}, '']
    end
  end
end<commit_msg>Fetch the `from` value actively or passively<commit_after># frozen_string_literal: true

require 'json'

require_relative 'auth'
require_relative 'services'

require 'sinatra/base'
require 'sinatra/json'
require 'sinatra/param'

module JobBoard
  class JobDeliveryAPI < Sinatra::Base
    helpers Sinatra::Param

    before { content_type :json }

    helpers do
      include JobBoard::Auth::GuestDetect
    end

    before '/jobs*' do
      halt 403, JSON.dump('@type' => 'error', error: 'just no') if guest?
    end

    post '/jobs' do
      JobBoard.logger.debug('received legacy jobs request', from: from)
      json(jobs: [], unavailable_jobs: [])
    end

    post '/jobs/add' do
      job = JSON.parse(request.body.read)
      site = request.env.fetch('travis.site')
      JobBoard.logger.debug(
        'parsed job',
        job_id: job.fetch('id', '<unknown>'), site: site
      )
      db_job = JobBoard::Services::CreateOrUpdateJob.run(job: job, site: site)
      if db_job.nil?
        JobBoard.logger.error(
          'failed to create or update job',
          job_id: job.fetch('id'), site: site
        )
        halt 400, JSON.dump('@type' => 'error', error: 'what')
      end
      JobBoard.logger.info('added', job_id: job.fetch('id'), site: site)
      [201, { 'Content-Length' => '0' }, '']
    end

    post '/jobs/pop' do
      param :queue, String, blank: true, required: true

      unless request.env.key?('HTTP_FROM')
        halt 412, JSON.dump(
          '@type' => 'error', error: 'missing from header'
        )
      end

      queue = params[:queue].to_s.sub(/^builds\./, '')
      site = request.env.fetch('travis.site')

      job_id = JobBoard::Services::AllocateJob.run(
        from: from!,
        queue_name: queue,
        site: site
      )

      if job_id.nil?
        JobBoard.logger.debug(
          'no jobs available',
          queue: queue, from: from!, site: site
        )
        halt 204
      end

      JobBoard.logger.info(
        'popped',
        queue: queue, from: from!, site: site, job_id: job_id
      )

      status 200
      json('@queue' => queue, 'job_id' => job_id)
    end

    post '/jobs/:job_id/claim' do
      param :queue, String, blank: true, required: true

      unless request.env.key?('HTTP_FROM')
        halt 412, JSON.dump(
          '@type' => 'error', error: 'missing from header'
        )
      end

      queue = params[:queue].to_s.sub(/^builds\./, '')
      site = request.env.fetch('travis.site')
      job_id = params[:job_id]

      unless JobBoard::Services::RefreshJobClaim.run(
        job_id: job_id,
        from: from!,
        queue_name: queue,
        site: site
      )
        JobBoard.logger.warn(
          'job id is not claimed',
          job_id: job_id, claimed: claimed_id,
          queue: queue, from: from!, site: site
        )
        halt 409
      end

      JobBoard.logger.debug(
        'claim refreshed',
        queue: queue, from: from!, site: site, job_id: job_id
      )
      status 200
      json('@queue' => queue, '@job_id' => job_id)
    end

    get '/jobs/:job_id' do
      job_id = params.fetch('job_id')
      site = request.env.fetch('travis.site')
      infra = request.env.fetch('travis.infra', '')
      job = JobBoard::Services::FetchJob.run(
        job_id: job_id, site: site, infra: infra
      )
      halt 404, JSON.dump('@type' => 'error', error: 'no such job') if job.nil?
      if job.is_a?(JobBoard::Services::FetchJobScript::BuildScriptError)
        halt 424, JSON.dump(
          '@type' => 'error',
          error: 'job script fetch error',
          upstream_error: job.message
        )
      end
      JobBoard.logger.info(
        'fetched', job_id: job_id, site: site, infra: infra, from: from
      )
      json job
    end

    delete '/jobs/:job_id' do
      job_id = params.fetch('job_id')
      site = request.env.fetch('travis.site')
      JobBoard::Services::DeleteJob.run(job_id: job_id, site: site)
      JobBoard.logger.info('deleted', job_id: job_id, site: site, from: from)
      [204, {}, '']
    end

    def from!
      request.env.fetch('HTTP_FROM')
    end

    def from
      request.env.fetch('HTTP_FROM', request.env.fetch('REMOTE_ADDR', '???'))
    end
  end
end
{'fraction_non_alphanumeric': 0.14013861153529897, 'fraction_numerical': 0.00869258780688359, 'mean_word_length': 2.2471395881006866, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 27, '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': '648568', 'n_tokens_mistral': 2876, 'n_tokens_neox': 2749, 'n_words': 668}