Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding uploaded images calculator #32

Merged
merged 4 commits into from
May 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion app/jobs/assemble_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ def perform(*_args)
# [x] Upload Imaginations to Uploadcare
Images::UploadImaginationsJob.perform_now

# [ ] Create Discussions from Stories
# [x] Mark Images with uploaded Imaginations as uploaded
Images::MarkUploadedImagesJob.perform_now

# [x] Create Discussions from Stories
Discussions::ProcessDiscussionStemsJob.perform_now

end
Expand Down
11 changes: 11 additions & 0 deletions app/jobs/images/mark_uploaded_images_job.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module Images
class MarkUploadedImagesJob < ApplicationJob
queue_as :default

def perform(*_args)
Image.unuploaded_with_three_uploaded_imaginations.each do |image|
image.update!(uploaded: true)
end
end
end
end
1 change: 1 addition & 0 deletions app/models/discussion.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
# story_id :bigint not null
# created_at :datetime not null
# updated_at :datetime not null
# published_at :datetime
#
class Discussion < ApplicationRecord
belongs_to :story
Expand Down
18 changes: 18 additions & 0 deletions app/models/image.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
# updated_at :datetime not null
# invalid_prompt :boolean default(FALSE)
# processed :boolean default(FALSE), not null
# uploaded :boolean default(FALSE)
#


################ LOGIC #################
Expand All @@ -18,6 +20,8 @@
# * If creating the imaginations fails, the `invalid_prompt` column is set to true.
# * The logic for setting `processed` and `invalid_prompt` is imagine_image_job.rb
# * The imagine_images_job.rb uses those variables to determine if it should create imaginations for the image.
#
# - The `uploaded` is marked true by the mark_image_uploaded_job.rb once all 3 imaginations have been uploaded.
########################################


Expand All @@ -28,6 +32,19 @@ class Image < ApplicationRecord
scope :to_process, -> { where(invalid_prompt: false).where.not(processed: true) }
scope :processed_and_valid, -> { where(processed: true, invalid_prompt: false) }

scope :with_three_uploaded_imaginations, lambda {
joins(:imaginations)
.group('images.id')
.having('count(imaginations.id) = 3 AND bool_and(imaginations.uploaded) = ?', true)
}

scope :uploaded_with_three_uploaded_imaginations, lambda {
with_three_uploaded_imaginations.where(uploaded: true)
}

scope :unuploaded_with_three_uploaded_imaginations, lambda {
with_three_uploaded_imaginations.where(uploaded: false)
}

def card_imagination
imaginations.where(aspect_ratio: :card).last
Expand All @@ -40,4 +57,5 @@ def landscape_imagination
def portrait_imagination
imaginations.where(aspect_ratio: :portrait).last
end

end
5 changes: 5 additions & 0 deletions db/migrate/20230514000342_add_uploaded_to_images.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddUploadedToImages < ActiveRecord::Migration[7.0]
def change
add_column :images, :uploaded, :boolean, default: false
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddPublishedDateToDiscussions < ActiveRecord::Migration[7.0]
def change
add_column :discussions, :published_at, :datetime
end
end
4 changes: 3 additions & 1 deletion db/schema.rb

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions spec/factories/discussions.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
# == Schema Information
#
# Table name: discussions
#
# id :bigint not null, primary key
# stem :text
# processed :boolean default(FALSE)
# invalid_json :boolean default(FALSE)
# uploaded :boolean default(FALSE)
# story_id :bigint not null
# created_at :datetime not null
# updated_at :datetime not null
# published_at :datetime
#
FactoryBot.define do
factory :discussion do
story
Expand Down
2 changes: 1 addition & 1 deletion spec/factories/images.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
# updated_at :datetime not null
# invalid_prompt :boolean default(FALSE)
# processed :boolean default(FALSE), not null
# uploaded :boolean default(FALSE)
#
# spec/factories/images.rb

FactoryBot.define do
factory :image do
Expand Down
98 changes: 98 additions & 0 deletions spec/jobs/discussions/make_stem_job_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
require 'rails_helper'

RSpec.describe Discussions::MakeStemJob, type: :job do
# let(:story) { double('Story') }
let(:story) { create(:story) }
let(:sub_topic) { double('SubTopic', prompts: 'default', name: 'sub_topic_name') }
let(:tag) { double('Tag', name: 'tag_name') }
let(:discussion) { nil }
let(:client) { instance_double('OpenAI::Client') }
let(:discussion_class) { class_double('Discussion').as_stubbed_const }

before do
allow(story).to receive(:sub_topic).and_return(sub_topic)
allow(story).to receive(:tag).and_return(tag)
allow(story).to receive(:discussion).and_return(discussion)
allow(story).to receive(:stem).and_return('stem')

allow(OpenAI::Client).to receive(:new).and_return(client)

allow(client).to receive(:chat).and_return({
'choices' => [
{'message' => {'content' => '{}' }}
]
})
end

it 'calls the OpenAI client with the correct parameters' do
expect(client).to receive(:chat).with(
parameters: {
model: "gpt-3.5-turbo",
messages: anything,
temperature: 0.7
}
)

described_class.perform_now(story: story)
end

context 'when the response is valid JSON' do
before do
allow(client).to receive(:chat).and_return({
'choices' => [
{'message' => {'content' => '{}' }}
]
})
end

it 'creates a discussion with the response content' do
expect(discussion_class).to receive(:create).with(
story: story,
stem: '{}',
processed: true,
invalid_json: false
)

described_class.perform_now(story: story)
end
end

context 'when the response is not valid JSON' do
before do
allow(client).to receive(:chat).and_return({
'choices' => [
{'message' => {'content' => 'not valid json' }}
]
})
end

it 'creates a discussion with invalid_json set to true' do
expect(discussion_class).to receive(:create).with(
story: story,
stem: 'not valid json',
processed: true,
invalid_json: true
)

described_class.perform_now(story: story)
end
end

context 'when the response contains an error' do
before do
allow(client).to receive(:chat).and_return({
'error' => 'error message'
})
end

it 'creates a discussion with invalid_json set to true' do
expect(discussion_class).to receive(:create).with(
story: story,
processed: true,
invalid_json: true
)

described_class.perform_now(story: story)
end
end
end
32 changes: 32 additions & 0 deletions spec/jobs/images/mark_uploaded_images_job_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
require 'rails_helper'

RSpec.describe Images::MarkUploadedImagesJob, type: :job do
include ActiveJob::TestHelper

subject(:job) { described_class.perform_later }

it 'queues the job' do
expect { job }
.to change(ActiveJob::Base.queue_adapter.enqueued_jobs, :size).by(1)
expect(described_class).to have_been_enqueued.on_queue('default')
end

describe '#perform' do
let!(:image1) { create(:image, uploaded: false) }
let!(:image2) { create(:image, uploaded: false) }
let!(:image3) { create(:image, uploaded: false) }

before do
# assuming unuploaded_with_three_uploaded_imaginations only returns images with 3 uploaded imaginations
allow(Image).to receive(:unuploaded_with_three_uploaded_imaginations).and_return([image1, image2, image3])
end

it 'marks images as uploaded' do
perform_enqueued_jobs { job }

[image1, image2, image3].each do |image|
expect(image.reload.uploaded).to be true
end
end
end
end
13 changes: 13 additions & 0 deletions spec/models/story_spec.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
# == Schema Information
#
# Table name: stories
#
# id :bigint not null, primary key
# created_at :datetime not null
# updated_at :datetime not null
# sub_topic_id :bigint not null
# stem :text
# processed :boolean default(FALSE)
# invalid_json :boolean default(FALSE)
# invalid_images :boolean default(FALSE)
#
require 'rails_helper'

RSpec.describe Story, type: :model do
Expand Down