appydave-tools 0.9.3 → 0.9.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7d25de201fe246c80fe143f7414bfa76a4c8dc35a4d4ba26086ad4597b699a26
4
- data.tar.gz: 9785e23d8743eb724082ceb7d9b699df06ca88e9ebc81401dc00f0af457527d3
3
+ metadata.gz: 8b6d7348b11097175604d3e0dfa967ad9667a36955b825f3ada9042229d35b86
4
+ data.tar.gz: 91997ead7011056d971b85e7680ee8a099dee006b944210e0766db23d2a40986
5
5
  SHA512:
6
- metadata.gz: 83964602096a76ca0dde6ad5362e5e521ac2fae2c2041f1cb1a989b11ac351892e9a47cc1b4d00afb3ed08d76b108a3192b04437a675c6bcf1d75ad19c423de0
7
- data.tar.gz: a902575b0e19003e6326b2605ee3a31636a0d70b399b7180a3464c532e5b3ca603bed1cded2b1999b4406905b584cae3cc40eff0946d1bdf44395223527a67a2
6
+ metadata.gz: 8c454d6b2b206b188cff7529094e9cf5b1895933083e7d712e43d55289e3d93be06b0307bb9dd66f13b4910e625e8108b88e58660df15eeb96abaa28f4e439a6
7
+ data.tar.gz: 1d1c25c9cf722bea8db372b6edca5d2fa3da909d097b0401e7f12e5d66a2dbb6dc15fe001f0b42a8e484ca4866f7755cd86d1f090608960bc4b980aacd34992b
data/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## [0.9.3](https://github.com/klueless-io/appydave-tools/compare/v0.9.2...v0.9.3) (2024-06-12)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * preperation fo the youtube automation tool ([42c1e1d](https://github.com/klueless-io/appydave-tools/commit/42c1e1d3a4ea53491b72140bbf35850e41ce0f1c))
7
+ * update rubocop version number ([b64739d](https://github.com/klueless-io/appydave-tools/commit/b64739d46a5b3ea6177c2f7512c720b6ed4e6257))
8
+
1
9
  ## [0.9.2](https://github.com/klueless-io/appydave-tools/compare/v0.9.1...v0.9.2) (2024-06-11)
2
10
 
3
11
 
@@ -7,6 +7,8 @@ require 'appydave/tools'
7
7
 
8
8
  # Process command line arguments for YouTubeVideoManager operations
9
9
  class YouTubeVideoManagerCLI
10
+ include KLog::Logging
11
+
10
12
  def initialize
11
13
  @commands = {
12
14
  'get' => method(:fetch_video_details)
@@ -30,14 +32,19 @@ class YouTubeVideoManagerCLI
30
32
  options = parse_options(args, 'get')
31
33
  manager = Appydave::Tools::YouTubeManager::GetVideo.new
32
34
  manager.get(options[:video_id])
33
- # json = JSON.pretty_generate(details)
34
- # puts json
35
35
 
36
- # report = Appydave::Tools::YouTubeManager::Reports::VideoDetailsReport.new
37
- # report.print(manager.data)
36
+ if manager.video?
37
+ # json = JSON.pretty_generate(details)
38
+ # puts json
39
+
40
+ # report = Appydave::Tools::YouTubeManager::Reports::VideoDetailsReport.new
41
+ # report.print(manager.data)
38
42
 
39
- report = Appydave::Tools::YouTubeManager::Reports::VideoContentReport.new
40
- report.print(manager.data)
43
+ report = Appydave::Tools::YouTubeManager::Reports::VideoContentReport.new
44
+ report.print(manager.data)
45
+ else
46
+ log.error "Video not found! Maybe it's private or deleted. ID: #{options[:video_id]}"
47
+ end
41
48
  end
42
49
 
43
50
  def parse_options(args, command)
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Appydave
4
+ module Tools
5
+ module Types
6
+ # Used by the ActiveModel attributes API to cast values to arrays
7
+ class ArrayType < ActiveModel::Type::Value
8
+ def cast(value)
9
+ case value
10
+ when String
11
+ value.split(',')
12
+ when Array
13
+ value
14
+ else
15
+ raise ArgumentError, "Cannot cast #{value.class} to Array"
16
+ end
17
+ end
18
+
19
+ def serialize(value)
20
+ value.join(',')
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Appydave
4
+ module Tools
5
+ module Types
6
+ # Used by the ActiveModel attributes API to cast values to hashes
7
+ class HashType < ActiveModel::Type::Value
8
+ def cast(value)
9
+ case value
10
+ when String
11
+ JSON.parse(value)
12
+ when Hash
13
+ value
14
+ else
15
+ raise ArgumentError, "Cannot cast #{value.class} to Hash"
16
+ end
17
+ end
18
+
19
+ def serialize(value)
20
+ value.to_json
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Appydave
4
+ module Tools
5
+ module Types
6
+ # Hash with indifferent access
7
+ class IndifferentAccessHash < Hash
8
+ def initialize(initial_hash = {})
9
+ super()
10
+ update(initial_hash)
11
+ end
12
+
13
+ def [](key)
14
+ super(convert_key(key))
15
+ end
16
+
17
+ def []=(key, value)
18
+ super(convert_key(key), value)
19
+ end
20
+
21
+ def fetch(key, *args)
22
+ super(convert_key(key), *args)
23
+ end
24
+
25
+ def delete(key)
26
+ super(convert_key(key))
27
+ end
28
+
29
+ private
30
+
31
+ def convert_key(key)
32
+ key.is_a?(Symbol) ? key.to_s : key
33
+ end
34
+
35
+ def update(initial_hash)
36
+ initial_hash.each do |key, value|
37
+ self[convert_key(key)] = value
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Appydave
4
4
  module Tools
5
- VERSION = '0.9.3'
5
+ VERSION = '0.9.4'
6
6
  end
7
7
  end
@@ -11,7 +11,8 @@ module Appydave
11
11
 
12
12
  SCOPE = [
13
13
  'https://www.googleapis.com/auth/youtube.readonly',
14
- 'https://www.googleapis.com/auth/youtube'
14
+ 'https://www.googleapis.com/auth/youtube',
15
+ 'https://www.googleapis.com/auth/youtube.force-ssl'
15
16
  ].freeze
16
17
 
17
18
  def self.authorize
@@ -22,11 +23,11 @@ module Appydave
22
23
  authorizer = Google::Auth::UserAuthorizer.new(client_id, SCOPE, token_store)
23
24
  user_id = 'default'
24
25
  credentials = authorizer.get_credentials(user_id)
25
- credentials = wait_for_authorization(authorizer) if credentials.nil?
26
+ credentials = wait_for_authorization(authorizer, user_id) if credentials.nil?
26
27
  credentials
27
28
  end
28
29
 
29
- def self.wait_for_authorization(authorizer)
30
+ def self.wait_for_authorization(authorizer, user_id)
30
31
  url = authorizer.get_authorization_url(base_url: REDIRECT_URI)
31
32
  puts 'Open the following URL in your browser and authorize the application:'
32
33
  puts url
@@ -7,13 +7,25 @@ module Appydave
7
7
  class GetVideo < YouTubeBase
8
8
  attr_reader :video_id
9
9
  attr_reader :data
10
- attr_reader :video
11
10
 
12
11
  def get(video_id)
12
+ @data = nil
13
13
  @video_id = video_id
14
14
  response = @service.list_videos('snippet,contentDetails,status,statistics', id: video_id)
15
- @video = response.items.first
15
+ video = response.items.first
16
16
 
17
+ return unless video
18
+
19
+ build_data(video)
20
+ end
21
+
22
+ def video?
23
+ !data.nil?
24
+ end
25
+
26
+ private
27
+
28
+ def build_data(video)
17
29
  data = {
18
30
  id: video.id,
19
31
  title: video.snippet.title,
@@ -37,8 +49,56 @@ module Appydave
37
49
  caption: video.content_details.caption,
38
50
  licensed_content: video.content_details.licensed_content
39
51
  }
52
+ # HAVE NOT FIGURED OUT THE PERMISSION ISSUE WITH THIS YET
53
+ # captions: get_captions(video.id) # Fetch captions and associate them
54
+ @data = Appydave::Tools::YouTubeManager::Models::YouTubeDetails.new(data)
55
+ end
56
+
57
+ def get_captions(video_id)
58
+ captions_response = @service.list_captions('snippet', video_id)
59
+ captions_response.items.map do |caption|
60
+ puts "Caption ID: #{caption.id}"
61
+ puts "Language: #{caption.snippet.language}"
62
+ puts "Status: #{caption.snippet.status}"
63
+ puts "Track Kind: #{caption.snippet.track_kind}"
64
+ puts "Name: #{caption.snippet.name}"
65
+ puts "Is Auto-Synced: #{caption.snippet.is_auto_synced}"
66
+ puts "Is CC: #{caption.snippet.is_cc}"
67
+ puts "Is Draft: #{caption.snippet.is_draft}"
68
+ puts "Last Updated: #{caption.snippet.last_updated}"
69
+
70
+ next unless caption.snippet.status == 'serving'
71
+
72
+ caption_data = {
73
+ caption_id: caption.id,
74
+ language: caption.snippet.language,
75
+ name: caption.snippet.name,
76
+ status: caption.snippet.status,
77
+ content: download_caption(caption)
78
+ }
79
+ caption_data
80
+ end.compact
81
+ end
82
+
83
+ def download_caption(caption)
84
+ content = ''
85
+ formats = %w[srv1 vtt srt ttml] # Try multiple formats to find a compatible one
86
+ formats.each do |format|
87
+ break if content.present?
40
88
 
41
- @data = Appydave::Tools::IndifferentAccessHash.new(data)
89
+ begin
90
+ @service.download_caption(caption.id, tfmt: format) do |result, error|
91
+ if error.nil?
92
+ content = result
93
+ else
94
+ puts "An error occurred while downloading caption #{caption.id} with format #{format}: #{error.message}"
95
+ end
96
+ end
97
+ rescue Google::Apis::ClientError => e
98
+ puts "An error occurred while downloading caption #{caption.id} with format #{format}: #{e.message}"
99
+ end
100
+ end
101
+ content
42
102
  end
43
103
  end
44
104
  end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_model'
4
+
5
+ module Appydave
6
+ module Tools
7
+ module YouTubeManager
8
+ module Models
9
+ # Model to store YouTube video captions (subtitles)
10
+ class Captions
11
+ include ActiveModel::Model
12
+ include ActiveModel::Attributes
13
+
14
+ attribute :caption_id, :string
15
+ attribute :language, :string
16
+ attribute :name, :string
17
+ attribute :status, :string
18
+ attribute :content, :string
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_model'
4
+
5
+ module Appydave
6
+ module Tools
7
+ module YouTubeManager
8
+ module Models
9
+ # Model to store YouTube video details
10
+ class YouTubeDetails
11
+ include ActiveModel::Model
12
+ include ActiveModel::Attributes
13
+
14
+ attribute :id, :string
15
+ attribute :title, :string
16
+ attribute :description, :string
17
+ attribute :published_at, :datetime
18
+ attribute :channel_id, :string
19
+ attribute :channel_title, :string
20
+ attribute :view_count, :integer
21
+ attribute :like_count, :integer
22
+ attribute :dislike_count, :integer
23
+ attribute :comment_count, :integer
24
+ attribute :privacy_status, :string
25
+ attribute :embeddable, :boolean
26
+ attribute :license, :string
27
+ attribute :recording_location, :string
28
+ attribute :recording_date, :datetime
29
+ attribute :tags, array: true
30
+ attribute :thumbnails, :hash
31
+ attribute :duration, :string
32
+ attribute :definition, :string
33
+ attribute :caption, :boolean
34
+ attribute :licensed_content, :boolean
35
+ # attribute :captions, :array, default: []
36
+
37
+ # def initialize(attributes = {})
38
+ # super
39
+ # self.captions = attributes[:captions].map { |caption| Captions.new(caption) } if attributes[:captions]
40
+ # end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -10,14 +10,14 @@ module Appydave
10
10
 
11
11
  def print(data)
12
12
  # log.heading 'Video Details Report'
13
- log.subheading data[:title]
14
- log.kv 'Published At', data[:published_at]
15
- log.kv 'View Count', data[:view_count]
16
- log.kv 'Like Count', data[:like_count]
17
- log.kv 'Dislike Count', data[:dislike_count]
18
- log.kv 'Tags', data[:tags]&.join(', ')
13
+ log.subheading data.title
14
+ log.kv 'Published At', data.published_at
15
+ log.kv 'View Count', data.view_count
16
+ log.kv 'Like Count', data.like_count
17
+ log.kv 'Dislike Count', data.dislike_count
18
+ log.kv 'Tags', data.tags.join(', ')
19
19
  log.line
20
- puts data[:description]
20
+ puts data.description
21
21
  log.line
22
22
  end
23
23
  end
@@ -8,6 +8,7 @@ require 'open3'
8
8
  require 'openai'
9
9
  require 'optparse'
10
10
  require 'k_log'
11
+ require 'active_model'
11
12
 
12
13
  require 'google/apis/youtube_v3'
13
14
  require 'googleauth'
@@ -17,7 +18,12 @@ require 'webrick'
17
18
  require 'pry'
18
19
 
19
20
  require 'appydave/tools/version'
20
- require 'appydave/tools/indifferent_access_hash'
21
+ require 'appydave/tools/types/indifferent_access_hash'
22
+ require 'appydave/tools/types/hash_type'
23
+ require 'appydave/tools/types/array_type'
24
+
25
+ ActiveModel::Type.register(:array, Appydave::Tools::Types::ArrayType)
26
+ ActiveModel::Type.register(:hash, Appydave::Tools::Types::HashType)
21
27
 
22
28
  require 'appydave/tools/gpt_context/file_collector'
23
29
 
@@ -38,6 +44,9 @@ require 'appydave/tools/bank_reconciliation/models/transaction'
38
44
  require 'appydave/tools/subtitle_master/clean'
39
45
 
40
46
  require 'appydave/tools/youtube_automation/gpt_agent'
47
+
48
+ require 'appydave/tools/youtube_manager/models/youtube_details'
49
+ require 'appydave/tools/youtube_manager/models/captions'
41
50
  require 'appydave/tools/youtube_manager/youtube_base'
42
51
  require 'appydave/tools/youtube_manager/authorization'
43
52
  require 'appydave/tools/youtube_manager/get_video'
data/package-lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "appydave-tools",
3
- "version": "0.9.3",
3
+ "version": "0.9.4",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "appydave-tools",
9
- "version": "0.9.3",
9
+ "version": "0.9.4",
10
10
  "devDependencies": {
11
11
  "@klueless-js/semantic-release-rubygem": "github:klueless-js/semantic-release-rubygem",
12
12
  "@semantic-release/changelog": "^6.0.3",
data/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "appydave-tools",
3
- "version": "0.9.3",
3
+ "version": "0.9.4",
4
4
  "description": "AppyDave YouTube Automation Tools",
5
5
  "scripts": {
6
6
  "release": "semantic-release"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: appydave-tools
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.3
4
+ version: 0.9.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Cruwys
@@ -10,6 +10,20 @@ bindir: exe
10
10
  cert_chain: []
11
11
  date: 2024-06-12 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activemodel
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '7'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '7'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: clipboard
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -169,17 +183,21 @@ files:
169
183
  - lib/appydave/tools/configuration/openai.rb
170
184
  - lib/appydave/tools/gpt_context/_doc.md
171
185
  - lib/appydave/tools/gpt_context/file_collector.rb
172
- - lib/appydave/tools/indifferent_access_hash.rb
173
186
  - lib/appydave/tools/name_manager/_doc.md
174
187
  - lib/appydave/tools/name_manager/project_name.rb
175
188
  - lib/appydave/tools/subtitle_master/_doc.md
176
189
  - lib/appydave/tools/subtitle_master/clean.rb
190
+ - lib/appydave/tools/types/array_type.rb
191
+ - lib/appydave/tools/types/hash_type.rb
192
+ - lib/appydave/tools/types/indifferent_access_hash.rb
177
193
  - lib/appydave/tools/version.rb
178
194
  - lib/appydave/tools/youtube_automation/_doc.md
179
195
  - lib/appydave/tools/youtube_automation/gpt_agent.rb
180
196
  - lib/appydave/tools/youtube_manager/_doc.md
181
197
  - lib/appydave/tools/youtube_manager/authorization.rb
182
198
  - lib/appydave/tools/youtube_manager/get_video.rb
199
+ - lib/appydave/tools/youtube_manager/models/captions.rb
200
+ - lib/appydave/tools/youtube_manager/models/youtube_details.rb
183
201
  - lib/appydave/tools/youtube_manager/reports/video_content_report.rb
184
202
  - lib/appydave/tools/youtube_manager/reports/video_details_report.rb
185
203
  - lib/appydave/tools/youtube_manager/youtube_base.rb
@@ -1,41 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Appydave
4
- module Tools
5
- # Hash with indifferent access
6
- class IndifferentAccessHash < Hash
7
- def initialize(initial_hash = {})
8
- super()
9
- update(initial_hash)
10
- end
11
-
12
- def [](key)
13
- super(convert_key(key))
14
- end
15
-
16
- def []=(key, value)
17
- super(convert_key(key), value)
18
- end
19
-
20
- def fetch(key, *args)
21
- super(convert_key(key), *args)
22
- end
23
-
24
- def delete(key)
25
- super(convert_key(key))
26
- end
27
-
28
- private
29
-
30
- def convert_key(key)
31
- key.is_a?(Symbol) ? key.to_s : key
32
- end
33
-
34
- def update(initial_hash)
35
- initial_hash.each do |key, value|
36
- self[convert_key(key)] = value
37
- end
38
- end
39
- end
40
- end
41
- end