forked from leouofa/QuasarAI
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request leouofa#114 from realstorypro/add-instapins
Adding InstaPins Functionality
- Loading branch information
Showing
26 changed files
with
487 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
class InstapinsController < ApplicationController | ||
include RestrictedAccess | ||
def index | ||
scope = set_scope | ||
|
||
@instapins = Instapin.send(scope).order(id: :desc).page params[:page] | ||
@total_instapins = Instapin.send(scope).count | ||
end | ||
|
||
def show | ||
@instapin = Instapin.find(params[:id]) | ||
end | ||
|
||
def edit | ||
@instapin = Instapin.find(params[:id]) | ||
@instapin_text = JSON.parse(@instapin.stem)["post"] | ||
end | ||
|
||
def update | ||
@instapin = Instapin.find(params[:id]) | ||
# Parse the JSON stored in the stem attribute | ||
stem_json = JSON.parse(@instapin.stem) | ||
|
||
# Update the "instapin" value in the parsed JSON object | ||
stem_json["post"] = params[:instapin][:stem] | ||
|
||
# Convert the JSON object back to a string and save it to the instapin's stem attribute | ||
@instapin.stem = stem_json.to_json | ||
|
||
# Turn off invalid JSON since its now valid | ||
@instapin.invalid_json = false | ||
|
||
# Save the InstaPin | ||
if @instapin.save | ||
redirect_to instapin_path(@instapin), notice: 'InstaPin was successfully updated.' | ||
else | ||
render :edit | ||
end | ||
end | ||
|
||
def approve | ||
@instapin = Instapin.find(params[:id]) | ||
@instapin.update(approved: true) | ||
redirect_to instapin_path(@instapin) | ||
end | ||
|
||
def disapprove | ||
@instapin = Instapin.find(params[:id]) | ||
@instapin.update(approved: false) | ||
redirect_to instapin_path(@instapin) | ||
end | ||
|
||
private | ||
|
||
def set_scope | ||
if params[:scope] && params[:scope] == 'pending' | ||
return 'needs_approval' | ||
elsif params[:scope] && params[:scope] == 'approved' | ||
return 'approved_instapins' | ||
elsif params[:scope] && params[:scope] == 'denied' | ||
return 'denied' | ||
elsif params[:scope] && params[:scope] == 'published' | ||
return 'published' | ||
end | ||
|
||
'all' | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
class Instapins::MakeStemJob < ApplicationJob | ||
queue_as :default | ||
include SettingsHelper | ||
|
||
def perform(discussion:) | ||
return if discussion.instapin.present? | ||
|
||
@client = OpenAI::Client.new | ||
|
||
prompts = discussion.story.sub_topic.prompts | ||
story = discussion.story | ||
|
||
system_role = <<~SYSTEM_ROLE | ||
#{s("prompts.#{prompts}.tweets.stem.system_role")} | ||
SYSTEM_ROLE | ||
|
||
brief = <<~BRIEF | ||
You have received the following story in JSON format: | ||
#{discussion.stem} | ||
BRIEF | ||
|
||
question = <<~QUESTION | ||
- You have received the following as a news story about `#{story.sub_topic.name}` and `#{story.tag.name}`. | ||
- It is your job to write #{s("prompts.#{prompts}.tweets.stem.tone")} 400 character `post` about this story. | ||
- You must include relevant 2 to 3 `hashtags` and 2 to 3 `emojis` into the `post`. | ||
- The return result MUST be in JSON format in the following structure: | ||
``` | ||
{ | ||
post: "this is a post", | ||
} | ||
``` | ||
QUESTION | ||
|
||
messages = [ | ||
{ role: "system", content: system_role }, | ||
{ role: "user", content: brief }, | ||
{ role: "user", content: question } | ||
] | ||
|
||
invalid_json = true | ||
counter = 0 | ||
response = nil | ||
|
||
while invalid_json && counter < 6 | ||
response = chat(messages:) | ||
|
||
counter += 1 | ||
|
||
break if response["error"].present? | ||
|
||
invalid_json = false if valid_json?(response["choices"][0]["message"]["content"]) | ||
Rails.logger.debug "invalid_json: #{invalid_json} | counter: #{counter}" | ||
end | ||
|
||
if response["error"].present? | ||
Instapin.create(discussion:, processed: true, invalid_json:) | ||
else | ||
Instapin.create(discussion:, stem: response["choices"][0]["message"]["content"], processed: true, invalid_json:) | ||
end | ||
end | ||
|
||
def valid_json?(json_string) | ||
JSON.parse(json_string) | ||
true | ||
rescue JSON::ParserError | ||
false | ||
end | ||
|
||
def chat(messages:) | ||
@client.chat( | ||
parameters: { | ||
model: ENV['OPENAI_GPT_MODEL'], # Required. | ||
messages:, | ||
temperature: 0.7 | ||
} | ||
) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
class Instapins::ProcessInstapinStemsJob < ApplicationJob | ||
queue_as :default | ||
|
||
def perform(*args) | ||
Discussion.ready_to_create_instapins.each do |discussion| | ||
Instapins::MakeStemJob.perform_now(discussion:) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
class Instapins::PublishInstapinJob < ApplicationJob | ||
queue_as :default | ||
|
||
def perform(discussion:) | ||
return if discussion.instapin.uploaded | ||
|
||
story = discussion.story | ||
instapin = discussion.instapin | ||
|
||
platforms = [] | ||
platforms.push 'pinterest' if ENV['PINTEREST_ENABLED'] | ||
platforms.push 'instagram' if ENV['INSTAGRAM_ENABLED'] | ||
platforms.push 'facebook' if ENV['FACEBOOK_ENABLED'] | ||
|
||
instapin_text = JSON.parse(instapin.stem)['post'] | ||
|
||
if story.sub_topic.ai_disclaimer | ||
instapin_text = "📟 AI Perspective: #{instapin_text}" | ||
end | ||
|
||
max_characters = 400 | ||
|
||
# Truncate truncated_instapin_text to fit within the max_characters limit | ||
# 31 characters are reserved for URL and a space | ||
truncated_instapin_text = instapin_text.truncate(max_characters - 31, omission: '...') | ||
|
||
landscape_images = discussion.story.imaginations.where(aspect_ratio: :landscape).sample(3) | ||
|
||
landscape_image_urls = landscape_images.map do |landscape_image| | ||
"https://ucarecdn.com/#{landscape_image.uploadcare.last['uuid']}/-/format/auto/-/quality/smart/-/resize/1440x/" | ||
end | ||
|
||
|
||
story_pro_discussion = StoryPro.get_discussion(discussion.story_pro_id) | ||
discussion_slug = story_pro_discussion["entry"]["slug"] | ||
category_slug = get_story_pro_category_slug(story) | ||
|
||
discussion_url = "#{ENV['STORYPRO_URL']}/discussions/#{category_slug}/#{discussion_slug}" | ||
|
||
full_instapin = "#{truncated_instapin_text} \n\n Read full story at: #{discussion_url}" | ||
|
||
carousel_items = landscape_image_urls.map do |landscape_url| | ||
{ | ||
name: discussion.parsed_stem["title"].truncate(50), | ||
link: discussion_url, | ||
picture: landscape_url | ||
} | ||
end | ||
|
||
return if platforms.blank? | ||
|
||
|
||
if platforms.include? 'instagram' | ||
Ayrshare.post_message(post: full_instapin, platforms: ['instagram'] , media_urls: landscape_image_urls) | ||
end | ||
|
||
if platforms.include? 'pinterest' | ||
Ayrshare.post_pinterest_message(post: truncated_instapin_text, | ||
platforms: ['pinterest'] , | ||
media_urls: landscape_image_urls.sample(1), | ||
pinterest_options: { | ||
title: discussion.parsed_stem["title"].truncate(100), | ||
link: discussion_url, | ||
boardId: story.sub_topic.pinterest_board | ||
}) | ||
end | ||
|
||
# if platforms.include? 'facebook' | ||
# Ayrshare.post_carousel(post: truncated_instapin_text, | ||
# facebook_options: { | ||
# carousel: { | ||
# link: discussion_url, | ||
# items: carousel_items | ||
# } | ||
# }) | ||
# end | ||
|
||
|
||
instapin.update(uploaded: true, published_at: Time.now.utc) | ||
end | ||
|
||
def get_story_pro_category_slug(story) | ||
story_pro_categories = StoryPro.get_categories | ||
found_story_pro_category = story_pro_categories.find { |c| c["id"] == story.sub_topic.storypro_category_id } | ||
found_story_pro_category['slug'] | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
class Instapins::PublishJob < ApplicationJob | ||
queue_as :default | ||
MAX_INSTAPINS_PUBLISHED_AT_A_TIME = 1 | ||
|
||
def perform(*args) | ||
settings = Setting.instance | ||
return unless settings.within_publish_window? | ||
|
||
Discussion.ready_to_upload_instapins.sample(MAX_INSTAPINS_PUBLISHED_AT_A_TIME).each do |discussion| | ||
Instapins::PublishInstapinJob.perform_now(discussion:) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.