Skip to content

Add project files #1

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

Merged
merged 1 commit into from
Nov 30, 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
Add project files
  • Loading branch information
codergeek121 committed Nov 30, 2023
commit a5ad92023014ed54e705de2b5ca21756351495e2
2 changes: 2 additions & 0 deletions openai_text_to_speech_with_rails/Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ ruby "3.2.2"

# Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main"
gem "rails", "~> 7.1.2"
gem "webmock"
gem "ruby-openai"

# The original asset pipeline for Rails [https://github.com/rails/sprockets-rails]
gem "sprockets-rails"
Expand Down
22 changes: 22 additions & 0 deletions openai_text_to_speech_with_rails/Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ GEM
xpath (~> 3.2)
concurrent-ruby (1.2.2)
connection_pool (2.4.1)
crack (0.4.5)
rexml
crass (1.0.6)
date (3.3.4)
debug (1.8.0)
Expand All @@ -102,8 +104,17 @@ GEM
drb (2.2.0)
ruby2_keywords
erubi (1.12.0)
event_stream_parser (1.0.0)
faraday (2.7.12)
base64
faraday-net_http (>= 2.0, < 3.1)
ruby2_keywords (>= 0.0.4)
faraday-multipart (1.0.4)
multipart-post (~> 2)
faraday-net_http (3.0.2)
globalid (1.2.1)
activesupport (>= 6.1)
hashdiff (1.0.1)
i18n (1.14.1)
concurrent-ruby (~> 1.0)
importmap-rails (1.2.3)
Expand All @@ -130,6 +141,7 @@ GEM
mini_mime (1.1.5)
minitest (5.20.0)
msgpack (1.7.2)
multipart-post (2.3.0)
mutex_m (0.2.0)
net-imap (0.4.7)
date
Expand Down Expand Up @@ -201,6 +213,10 @@ GEM
reline (0.4.1)
io-console (~> 0.5)
rexml (3.2.6)
ruby-openai (6.3.0)
event_stream_parser (>= 0.3.0, < 2.0.0)
faraday (>= 1)
faraday-multipart (>= 1)
ruby2_keywords (0.0.5)
rubyzip (2.3.2)
selenium-webdriver (4.15.0)
Expand Down Expand Up @@ -233,6 +249,10 @@ GEM
activemodel (>= 6.0.0)
bindex (>= 0.4.0)
railties (>= 6.0.0)
webmock (3.19.1)
addressable (>= 2.8.0)
crack (>= 0.3.2)
hashdiff (>= 0.4.0, < 2.0.0)
webrick (1.8.1)
websocket (1.2.10)
websocket-driver (0.7.6)
Expand All @@ -256,13 +276,15 @@ DEPENDENCIES
puma (>= 5.0)
rails (~> 7.1.2)
redis (>= 4.0.1)
ruby-openai
selenium-webdriver
sprockets-rails
sqlite3 (~> 1.4)
stimulus-rails
turbo-rails
tzinfo-data
web-console
webmock

RUBY VERSION
ruby 3.2.2p53
Expand Down
30 changes: 12 additions & 18 deletions openai_text_to_speech_with_rails/README.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,18 @@
# README
# OpenAI TTS with Rails

This README would normally document whatever steps are necessary to get the
application up and running.
Read more about the project in the actual blogpost: http://localhost:1313/posts/using-the-openai-text-to-speech-api-with-rails/

Things you may want to cover:
## Setup

* Ruby version
1. Run `bin/setup`.
2. Run `rails credentials:edit --environment development` and provide your own OpenAI API token `open_ai_access_token: <yourtokengoeshere>`
3. Run `rails server`
4. Visit [/articles](localhost:3000/articles)

* System dependencies
Have fun!

* Configuration
## Tests

* Database creation

* Database initialization

* How to run the test suite

* Services (job queues, cache servers, search engines, etc.)

* Deployment instructions

* ...
1. Run `bin/setup`.
2. Run `rails credentials:edit --environment test` and add `open_ai_access_token: test`
3. Run `rails test`
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
class ArticlesController < ApplicationController
before_action :set_article, only: %i[ show edit update destroy ]

# GET /articles or /articles.json
def index
@articles = Article.all
end

# GET /articles/1 or /articles/1.json
def show
end

# GET /articles/new
def new
@article = Article.new
end

# GET /articles/1/edit
def edit
end

# POST /articles or /articles.json
def create
@article = Article.new(article_params)

respond_to do |format|
if @article.save
format.html { redirect_to article_url(https://github.com/@article), notice: "Article was successfully created." }
format.json { render :show, status: :created, location: @article }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: @article.errors, status: :unprocessable_entity }
end
end
end

# PATCH/PUT /articles/1 or /articles/1.json
def update
respond_to do |format|
if @article.update(article_params)
format.html { redirect_to article_url(https://github.com/@article), notice: "Article was successfully updated." }
format.json { render :show, status: :ok, location: @article }
else
format.html { render :edit, status: :unprocessable_entity }
format.json { render json: @article.errors, status: :unprocessable_entity }
end
end
end

# DELETE /articles/1 or /articles/1.json
def destroy
@article.destroy!

respond_to do |format|
format.html { redirect_to articles_url, notice: "Article was successfully destroyed." }
format.json { head :no_content }
end
end

private
# Use callbacks to share common setup or constraints between actions.
def set_article
@article = Article.find(params[:id])
end

# Only allow a list of trusted parameters through.
def article_params
params.require(:article).permit(:content)
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
module ArticlesHelper
end
12 changes: 12 additions & 0 deletions openai_text_to_speech_with_rails/app/jobs/text_to_speech_job.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
class TextToSpeechJob < ApplicationJob
queue_as :default
retry_on Faraday::Error, wait: :polynomially_longer, attempts: 10

def perform(article)
response = TextToSpeech.new.speech(article.content)
article.audio.attach(
io: StringIO.new(response, 'rb'),
filename: "article--#{article.id}.mp3"
)
end
end
13 changes: 13 additions & 0 deletions openai_text_to_speech_with_rails/app/models/article.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
class Article < ApplicationRecord
broadcasts

has_one_attached :audio

after_commit :generate_audio_content_mp3, if: :content_previously_changed?

private

def generate_audio_content_mp3
TextToSpeechJob.perform_later(self)
end
end
16 changes: 16 additions & 0 deletions openai_text_to_speech_with_rails/app/models/text_to_speech.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
class TextToSpeech
def initialize
@client = OpenAI::Client.new(access_token: Rails.application.credentials.open_ai_access_token)
end

def speech(text)
@client.audio.speech(
parameters: {
model: "tts-1-hd",
input: text,
voice: "echo",
speed: 0.95
}
)
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<div id="<%= dom_id article %>">
<%= simple_format article.content %>

<% if article.audio.attached? %>
<%= audio_tag article.audio, controls: true %>
<% else %>
<p>Audio is generating...</p>
<% end %>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
json.extract! article, :id, :content, :created_at, :updated_at
json.url article_url(https://github.com/article,%20format:%20:json)
22 changes: 22 additions & 0 deletions openai_text_to_speech_with_rails/app/views/articles/_form.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<%= form_with(model: article) do |form| %>
<% if article.errors.any? %>
<div style="color: red">
<h2><%= pluralize(article.errors.count, "error") %> prohibited this article from being saved:</h2>

<ul>
<% article.errors.each do |error| %>
<li><%= error.full_message %></li>
<% end %>
</ul>
</div>
<% end %>

<div>
<%= form.label :content, style: "display: block" %>
<%= form.text_area :content %>
</div>

<div>
<%= form.submit %>
</div>
<% end %>
10 changes: 10 additions & 0 deletions openai_text_to_speech_with_rails/app/views/articles/edit.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<h1>Editing article</h1>

<%= render "form", article: @article %>

<br>

<div>
<%= link_to "Show this article", @article %> |
<%= link_to "Back to articles", articles_path %>
</div>
14 changes: 14 additions & 0 deletions openai_text_to_speech_with_rails/app/views/articles/index.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<p style="color: green"><%= notice %></p>

<h1>Articles</h1>

<div id="articles">
<% @articles.each do |article| %>
<%= render article %>
<p>
<%= link_to "Show this article", article %>
</p>
<% end %>
</div>

<%= link_to "New article", new_article_path %>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
json.array! @articles, partial: "articles/article", as: :article
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<h1>New article</h1>

<%= render "form", article: @article %>

<br>

<div>
<%= link_to "Back to articles", articles_path %>
</div>
11 changes: 11 additions & 0 deletions openai_text_to_speech_with_rails/app/views/articles/show.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<%= turbo_stream_from(@article) %>
<p style="color: green"><%= notice %></p>

<%= render @article %>

<div>
<%= link_to "Edit this article", edit_article_path(@article) %> |
<%= link_to "Back to articles", articles_path %>

<%= button_to "Destroy this article", @article, method: :delete %>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
json.partial! "articles/article", article: @article
5 changes: 0 additions & 5 deletions openai_text_to_speech_with_rails/bin/setup
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,6 @@ FileUtils.chdir APP_ROOT do
system! "gem install bundler --conservative"
system("bundle check") || system!("bundle install")

# puts "\n== Copying sample files =="
# unless File.exist?("config/database.yml")
# FileUtils.cp "config/database.yml.sample", "config/database.yml"
# end

puts "\n== Preparing database =="
system! "bin/rails db:prepare"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,9 @@

# Raise error when a before_action's only/except options reference missing actions
config.action_controller.raise_on_missing_callback_actions = true

config.action_controller.default_url_options = {
host: 'localhost',
port: '3000',
}
end
1 change: 1 addition & 0 deletions openai_text_to_speech_with_rails/config/routes.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
Rails.application.routes.draw do
resources :articles
# Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html

# Reveal health status on /up that returns 200 if the app boots with no exceptions, otherwise 500.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class CreateArticles < ActiveRecord::Migration[7.1]
def change
create_table :articles do |t|
t.text :content

t.timestamps
end
end
end
Loading