tumblr_draftking 0.7.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.yardopts +7 -0
- data/CHANGELOG.md +80 -0
- data/LICENSE +67 -0
- data/README.md +293 -0
- data/Rakefile +22 -0
- data/bin/dk +7 -0
- data/lib/draftking/cli/cli_helpers.rb +61 -0
- data/lib/draftking/cli/cli_options.rb +31 -0
- data/lib/draftking/cli/commands/_template.rb +4 -0
- data/lib/draftking/cli/commands/accounts.rb +66 -0
- data/lib/draftking/cli/commands/blogs.rb +26 -0
- data/lib/draftking/cli/commands/comment.rb +34 -0
- data/lib/draftking/cli/commands/console.rb +18 -0
- data/lib/draftking/cli/commands/movedrafts.rb +33 -0
- data/lib/draftking/cli/commands/status.rb +24 -0
- data/lib/draftking/cli/commands/strip.rb +19 -0
- data/lib/draftking/cli/commands/tag.rb +21 -0
- data/lib/draftking/cli/commands/user_command.rb +45 -0
- data/lib/draftking/cli.rb +62 -0
- data/lib/draftking/client.rb +80 -0
- data/lib/draftking/config/config_setup.rb +56 -0
- data/lib/draftking/config.rb +151 -0
- data/lib/draftking/constants.rb +25 -0
- data/lib/draftking/dependency_patches.rb +2 -0
- data/lib/draftking/drafts.rb +53 -0
- data/lib/draftking/patches/thor.rb +12 -0
- data/lib/draftking/patches/tumblr_client.rb +10 -0
- data/lib/draftking/posts/post.rb +150 -0
- data/lib/draftking/posts/posts_helpers.rb +55 -0
- data/lib/draftking/posts.rb +173 -0
- data/lib/draftking/queue.rb +17 -0
- data/lib/draftking/reporter.rb +62 -0
- data/lib/draftking/tqueue/future_queue_methods.rb +97 -0
- data/lib/draftking/version.rb +3 -0
- data/lib/tasks/build.rake +33 -0
- data/lib/tasks/rubo.rake +36 -0
- data/lib/tumblr_draftking.rb +18 -0
- metadata +170 -0
@@ -0,0 +1,26 @@
|
|
1
|
+
module DK
|
2
|
+
class CLI < Thor
|
3
|
+
desc 'blogs', 'Display a list of blogs under the current account.'
|
4
|
+
option :simulate, type: :boolean, aliases: :s, desc: Options.op_strings[:simulate]
|
5
|
+
option :config, type: :string, desc: Options.op_strings[:config]
|
6
|
+
def blogs
|
7
|
+
configured?
|
8
|
+
self.class.blogs_print_list(get_dk_instance(process_options(options)))
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
# Print blog list
|
14
|
+
# @param dk [DK::Client] Instance of tumblr_draftking
|
15
|
+
def self.blogs_print_list(dk)
|
16
|
+
title = 'Blogs'
|
17
|
+
fields = %w(# blog_name)
|
18
|
+
rows = []
|
19
|
+
dk.user.blogs.each_with_index { |blog, idx| rows << [idx + 1, blog.name] }
|
20
|
+
report = Reporter.new(title: title, rows: rows, headers: fields)
|
21
|
+
|
22
|
+
report.show unless dk.simulate
|
23
|
+
report
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module DK
|
2
|
+
class CLI < Thor
|
3
|
+
desc 'comment <COMMENT>', 'Add a <COMMENT> to posts.'
|
4
|
+
long_desc <<-LONGDESC
|
5
|
+
`comment <COMMENT>` will add <COMMENT> to posts in your Drafts or Queue.
|
6
|
+
|
7
|
+
Any posts already containing <COMMENT> will be ignored.
|
8
|
+
To clear comments you've added, call `comment ' '`.
|
9
|
+
|
10
|
+
Note:
|
11
|
+
- Old tags are removed by default. Pass -k option to preserve them.
|
12
|
+
- Previous comments are be removed by default. Pass -K option to preserve them.
|
13
|
+
- New tags will be generated by from the comment contents. Use -t <tags> for additional tagging.
|
14
|
+
LONGDESC
|
15
|
+
option :limit, type: :numeric, aliases: :l, desc: Options.op_strings[:limit]
|
16
|
+
option :blog, type: :string, aliases: :b, desc: Options.op_strings[:blog]
|
17
|
+
option :add_tags, type: :string, aliases: :t, desc: Options.op_strings[:add_tags]
|
18
|
+
option :source, type: :string, aliases: :S, desc: Options.op_strings[:source]
|
19
|
+
option :simulate, type: :boolean, aliases: :s, desc: Options.op_strings[:simulate]
|
20
|
+
option :mute, type: :boolean, aliases: :m, desc: Options.op_strings[:mute]
|
21
|
+
option :keep_tags, type: :boolean, aliases: :k, desc: Options.op_strings[:keep_tags]
|
22
|
+
option :keep_comments, type: :boolean, aliases: :K, desc: Options.op_strings[:keep_comments]
|
23
|
+
option :credit, type: :boolean, desc: Options.op_strings[:credit], default: true
|
24
|
+
option :tags, type: :boolean, desc: Options.op_strings[:tags], default: true
|
25
|
+
option :config, type: :string, desc: Options.op_strings[:config]
|
26
|
+
def comment(comm)
|
27
|
+
configured?
|
28
|
+
opts = process_options(options)
|
29
|
+
opts[:comment] = comm
|
30
|
+
dk = get_dk_instance(opts)
|
31
|
+
dk.comment_posts(opts)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module DK
|
2
|
+
class CLI < Thor
|
3
|
+
desc 'console', 'Loads irb with $dk available in simulation mode.'
|
4
|
+
def console
|
5
|
+
configured?
|
6
|
+
self.class.launch_console
|
7
|
+
end
|
8
|
+
|
9
|
+
# Launch IRB with tumblr_draftking loaded as $dk
|
10
|
+
def self.launch_console
|
11
|
+
require 'irb'
|
12
|
+
require 'irb/completion'
|
13
|
+
ARGV.clear
|
14
|
+
$dk = DK::Client.new simulate: true
|
15
|
+
IRB.start
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module DK
|
2
|
+
class CLI < Thor
|
3
|
+
desc 'movedrafts, md', 'Move drafts to queue.'
|
4
|
+
long_desc <<-LONGDESC
|
5
|
+
`md` will move posts from your Drafts to your Queue.
|
6
|
+
|
7
|
+
Note:
|
8
|
+
- Old tags are removed by default. Pass -k option to preserve them.
|
9
|
+
- Previous comments are be removed by default. Pass -K option to preserve them.
|
10
|
+
- New tags will be generated by from the comment contents. Use -t <tags> for additional tagging.
|
11
|
+
LONGDESC
|
12
|
+
option :limit, type: :numeric, aliases: :l, desc: Options.op_strings[:limit]
|
13
|
+
option :blog, type: :string, aliases: :b, desc: Options.op_strings[:blog]
|
14
|
+
option :key_text, type: :string, aliases: :f, desc: Options.op_strings[:key_text]
|
15
|
+
option :comment, type: :string, aliases: :c, desc: Options.op_strings[:comment]
|
16
|
+
option :add_tags, type: :string, aliases: :t, desc: Options.op_strings[:add_tags]
|
17
|
+
option :simulate, type: :boolean, aliases: :s, desc: Options.op_strings[:simulate]
|
18
|
+
option :publish, type: :boolean, aliases: :p, desc: Options.op_strings[:publish]
|
19
|
+
option :mute, type: :boolean, aliases: :m, desc: Options.op_strings[:mute]
|
20
|
+
option :keep_tags, type: :boolean, aliases: :k, desc: Options.op_strings[:keep_tags]
|
21
|
+
option :keep_comments, type: :boolean, aliases: :K, desc: Options.op_strings[:keep_comments]
|
22
|
+
option :credit, type: :boolean, desc: Options.op_strings[:credit], default: true
|
23
|
+
option :tags, type: :boolean, desc: Options.op_strings[:tags], default: true
|
24
|
+
option :config, type: :string, desc: Options.op_strings[:config]
|
25
|
+
def movedrafts
|
26
|
+
configured?
|
27
|
+
opts = process_options(options)
|
28
|
+
dk = get_dk_instance(opts)
|
29
|
+
dk.drafts_to_queue(opts)
|
30
|
+
end
|
31
|
+
map 'md' => :movedrafts
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module DK
|
2
|
+
class CLI < Thor
|
3
|
+
desc 'status <BLOG>', 'Display queue/draft status for a blog.'
|
4
|
+
option :config, type: :string, desc: Options.op_strings[:config]
|
5
|
+
def status(blog = nil)
|
6
|
+
configured?
|
7
|
+
title = 'Status Report'
|
8
|
+
fields = %w(Blog Drafts Queued Q.Space)
|
9
|
+
opts = process_options(options.dup.merge(blog: blog))
|
10
|
+
dk = get_dk_instance(opts)
|
11
|
+
rows = begin
|
12
|
+
dk.user.blogs.map do |b|
|
13
|
+
next unless blog.nil? || b.name == blog
|
14
|
+
[b.name, b.drafts, b.queue, 300 - b.queue.to_i]
|
15
|
+
end.compact
|
16
|
+
rescue
|
17
|
+
[]
|
18
|
+
end
|
19
|
+
report = Reporter.new(title: title, rows: rows, headers: fields)
|
20
|
+
report.show unless simulate
|
21
|
+
report
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module DK
|
2
|
+
class CLI < Thor
|
3
|
+
desc 'strip', 'Strip old comments from posts.'
|
4
|
+
long_desc <<-LONGDESC
|
5
|
+
`strip` will delete other user's previous comments in your Drafts or Queue.
|
6
|
+
LONGDESC
|
7
|
+
option :limit, type: :numeric, aliases: :l, desc: Options.op_strings[:limit]
|
8
|
+
option :blog, type: :string, aliases: :b, desc: Options.op_strings[:blog]
|
9
|
+
option :source, type: :string, aliases: :S, desc: Options.op_strings[:source]
|
10
|
+
option :simulate, type: :boolean, aliases: :s, desc: Options.op_strings[:simulate]
|
11
|
+
option :config, type: :string, desc: Options.op_strings[:config]
|
12
|
+
def strip
|
13
|
+
configured?
|
14
|
+
opts = process_options(options)
|
15
|
+
dk = get_dk_instance(opts)
|
16
|
+
dk.strip_old_comments(opts)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module DK
|
2
|
+
class CLI < Thor
|
3
|
+
desc 'tag', 'Generate tags from post comments'
|
4
|
+
option :limit, type: :numeric, aliases: :l, desc: Options.op_strings[:limit]
|
5
|
+
option :blog, type: :string, aliases: :b, desc: Options.op_strings[:blog]
|
6
|
+
option :add_tags, type: :string, aliases: :t, desc: Options.op_strings[:add_tags]
|
7
|
+
option :source, type: :string, aliases: :S, desc: Options.op_strings[:source]
|
8
|
+
option :comment, type: :string, aliases: :c, desc: Options.op_strings[:comment]
|
9
|
+
option :simulate, type: :boolean, aliases: :s, desc: Options.op_strings[:simulate]
|
10
|
+
option :mute, type: :boolean, aliases: :m, desc: Options.op_strings[:mute]
|
11
|
+
option :keep_tags, type: :boolean, aliases: :k, desc: Options.op_strings[:keep_tags]
|
12
|
+
option :keep_comments, type: :boolean, aliases: :K, desc: Options.op_strings[:keep_comments]
|
13
|
+
option :credit, type: :boolean, desc: Options.op_strings[:credit], default: false
|
14
|
+
option :config, type: :string, desc: Options.op_strings[:config]
|
15
|
+
def tag
|
16
|
+
opts = process_options(options)
|
17
|
+
dk = get_dk_instance(opts)
|
18
|
+
dk.tag_posts(opts)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module DK
|
2
|
+
# User Defined Command
|
3
|
+
class UserCommand
|
4
|
+
REQUIRED_FIELDS = %w(command hoboken).freeze
|
5
|
+
def initialize(opts)
|
6
|
+
opts.each_pair do |k, v|
|
7
|
+
singleton_class.class_eval { attr_accessor k.to_s }
|
8
|
+
send("#{k}=", v)
|
9
|
+
end
|
10
|
+
check_required_fields
|
11
|
+
@command_result = nil
|
12
|
+
end
|
13
|
+
|
14
|
+
# Replace current process with execution of @command
|
15
|
+
def exec!
|
16
|
+
# Prefix test commands
|
17
|
+
command = prefix_command('bin/', Dir.pwd.include?('tumblr_draftking'))
|
18
|
+
command = add_config_name(command)
|
19
|
+
puts "User Command: #{command}"
|
20
|
+
exec(command)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def prefix_command(prfx, i_should = true)
|
26
|
+
# Add prefix to commands, but only once
|
27
|
+
return (prfx + @command).gsub(/^(#{prfx})+/, '\1') if i_should
|
28
|
+
@command
|
29
|
+
end
|
30
|
+
|
31
|
+
def add_config_name(command)
|
32
|
+
cfig = @config_name ? " --config #{@config_name}" : nil
|
33
|
+
return command + cfig unless command.include?(cfig)
|
34
|
+
command
|
35
|
+
end
|
36
|
+
|
37
|
+
def check_required_fields
|
38
|
+
REQUIRED_FIELDS.all? do |x|
|
39
|
+
# Field is accessible and populated
|
40
|
+
next if instance_variables.include?("@#{x}".to_sym) && !send(x.to_s).nil?
|
41
|
+
raise ArgumentError, "#{x}: required!"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# Helpers
|
2
|
+
require_relative 'cli/cli_helpers'
|
3
|
+
require_relative 'cli/cli_options'
|
4
|
+
|
5
|
+
# More complex CLI Commands
|
6
|
+
require_relative 'cli/commands/accounts'
|
7
|
+
require_relative 'cli/commands/blogs'
|
8
|
+
require_relative 'cli/commands/comment'
|
9
|
+
require_relative 'cli/commands/console'
|
10
|
+
require_relative 'cli/commands/movedrafts'
|
11
|
+
require_relative 'cli/commands/strip'
|
12
|
+
require_relative 'cli/commands/status'
|
13
|
+
require_relative 'cli/commands/tag'
|
14
|
+
|
15
|
+
# Stored User Commands
|
16
|
+
require_relative 'cli/commands/user_command'
|
17
|
+
|
18
|
+
module DK
|
19
|
+
# Command Line Interface
|
20
|
+
class CLI < Thor
|
21
|
+
include DK::CliHelpers
|
22
|
+
|
23
|
+
desc 'setup', 'Configure and save API keys.'
|
24
|
+
def setup
|
25
|
+
DK::Config.setup
|
26
|
+
end
|
27
|
+
|
28
|
+
desc 'version, -v', 'Display version.'
|
29
|
+
option :simulate, type: :boolean, aliases: :s, desc: Options.op_strings[:simulate]
|
30
|
+
def version
|
31
|
+
vstr = "tumblr_draftking #{DK::VERSION}"
|
32
|
+
puts vstr unless options[:simulate]
|
33
|
+
vstr
|
34
|
+
end
|
35
|
+
map '-v' => :version
|
36
|
+
|
37
|
+
desc 'update, check_for_updates', 'Check if DK update is available'
|
38
|
+
def check_for_updates
|
39
|
+
versions = open('https://rubygems.org/api/v1/versions/tumblr_draftking.json').read
|
40
|
+
latest = JSON.parse(versions, object_class: OpenStruct).first.number
|
41
|
+
puts "\n* UPDATE *\n\tDraftKing for Tumblr v#{latest} now available!\n\n" if latest != DK::VERSION
|
42
|
+
end
|
43
|
+
map 'update' => :check_for_updates
|
44
|
+
|
45
|
+
# Try to execute unrecognized command as User Command
|
46
|
+
def method_missing(method, *_args)
|
47
|
+
name, attribs = DK::Config.new.user_commands.select { |k, _v| k == method.to_s }.first
|
48
|
+
puts "Command '#{method}' not found." && return unless name && attribs
|
49
|
+
attribs[:name] = name
|
50
|
+
DK::UserCommand.new(attribs).exec!
|
51
|
+
end
|
52
|
+
|
53
|
+
# Figure out how to show a submenu of custom commands
|
54
|
+
desc 'custom', 'List available User Commands'
|
55
|
+
def custom
|
56
|
+
title = 'User Commands'
|
57
|
+
commands = DK::Config.new.config.user_commands.map { |n, d| UserCommand.new d.merge(name: n) }
|
58
|
+
headers = %w(name command description config_name)
|
59
|
+
Reporter.new(title: title, objects: commands, fields: headers).show
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
|
2
|
+
module DK
|
3
|
+
# Tumblr Client
|
4
|
+
class Client
|
5
|
+
include DK::TDrafts
|
6
|
+
include DK::TQueue
|
7
|
+
include DK::Posts
|
8
|
+
attr_accessor :client, :user
|
9
|
+
attr_accessor :blog, :blog_url
|
10
|
+
attr_accessor :q_size, :d_size, :q_space
|
11
|
+
|
12
|
+
# Options
|
13
|
+
attr_accessor :comment, :blog_name, :offset, :limit
|
14
|
+
attr_accessor :shuffle, :keep_tree, :test_data, :mute
|
15
|
+
attr_accessor :simulate, :keep_tags, :before_id, :credit
|
16
|
+
attr_accessor :message, :source, :auto_tag, :state
|
17
|
+
|
18
|
+
# Initialize instance of DraftKing for the specified blog
|
19
|
+
# @param options[:blog_name] [String] Target blog name
|
20
|
+
# @param options[:comment] [String] Default post comment
|
21
|
+
def initialize(options = {})
|
22
|
+
return unless configure_tumblr_client(options)
|
23
|
+
@client = Tumblr::Client.new
|
24
|
+
process_options(options)
|
25
|
+
act_on_blog(name: @blog_name)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Read Config
|
29
|
+
def process_options(options)
|
30
|
+
@blog_name = options[:blog_name] || @blog_name
|
31
|
+
@credit = options[:credit] || @credit
|
32
|
+
@key_text = options[:key_text] || @key_text
|
33
|
+
@keep_tree = options[:keep_tree] || @keep_tree
|
34
|
+
@keep_tags = options[:keep_tags] || @keep_tags
|
35
|
+
@message = options[:message] || @message
|
36
|
+
@mute = options[:mute] || @mute
|
37
|
+
@shuffle = options[:shuffle] || @shuffle
|
38
|
+
@simulate = options[:simulate] || @simulate
|
39
|
+
@state = options[:state] || @state
|
40
|
+
@test_data = options[:test_data] || @test_data
|
41
|
+
@tags = options[:add_tags] || @tags
|
42
|
+
@comment = options[:comment] || @comment.to_s
|
43
|
+
@auto_tag = options[:tags].nil? ? true : options[:tags]
|
44
|
+
@source = options[:source] || :draft
|
45
|
+
@before_id = options[:before_id] || 0
|
46
|
+
@offset = options[:offset] || 0
|
47
|
+
@limit = options[:limit]
|
48
|
+
end
|
49
|
+
|
50
|
+
# Configure tumblr_client gem
|
51
|
+
# @param options[:file] [String] JSON File with API Keys
|
52
|
+
# @param options[:keys] [Hash] Hash with API Keys
|
53
|
+
def configure_tumblr_client(options)
|
54
|
+
keys = DK::Config.validate_keys(options[:keys])
|
55
|
+
return DK::Config.configure_tumblr_gem(keys: keys) unless keys.nil?
|
56
|
+
DK::Config.configure_tumblr_gem(file: options[:config_file])
|
57
|
+
end
|
58
|
+
|
59
|
+
# Collect/Refresh Account Info
|
60
|
+
# @param name [String] Name of blog to target
|
61
|
+
def act_on_blog(name: nil)
|
62
|
+
return unless connected?
|
63
|
+
return if @client.info['status'] == 401
|
64
|
+
@user = JSON.parse(@client.info['user'].to_json, object_class: OpenStruct)
|
65
|
+
@blog_name = name ? name.gsub('.tumblr.com', '') : @user.blogs.first.name
|
66
|
+
@blog_url = tumblr_url(@blog_name)
|
67
|
+
@user.blogs.each do |blog|
|
68
|
+
next unless blog.name == @blog_name
|
69
|
+
@blog = blog
|
70
|
+
@q_size = blog.queue
|
71
|
+
@d_size = blog.drafts
|
72
|
+
@q_space = 300 - @q_size
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def connected?
|
77
|
+
!@client.nil?
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module DK
|
2
|
+
# Instance Configuration Methods
|
3
|
+
class Config
|
4
|
+
# Walk user through setup process
|
5
|
+
def self.setup
|
6
|
+
config = OpenStruct.new
|
7
|
+
config.user_commands = []
|
8
|
+
config.api_keys = {}
|
9
|
+
|
10
|
+
setup_display_instructions
|
11
|
+
account, as_default = setup_input_config_info(config)
|
12
|
+
setup_input_keys(config)
|
13
|
+
|
14
|
+
# Save credentials
|
15
|
+
save_file(config: config) if as_default.downcase.include?('y')
|
16
|
+
save_file(config: config, account: account)
|
17
|
+
end
|
18
|
+
|
19
|
+
# Setup instructions
|
20
|
+
def self.setup_display_instructions
|
21
|
+
puts "\n * Instructions *"
|
22
|
+
puts '1. Register a new application for your Tumblr account at https://www.tumblr.com/oauth/apps'
|
23
|
+
puts '2. Once complete, browse to https://api.tumblr.com/console/calls/user/info'
|
24
|
+
puts ' to get your API keys.'
|
25
|
+
end
|
26
|
+
|
27
|
+
# Account input dialog
|
28
|
+
def self.setup_input_config_info(config)
|
29
|
+
puts "\n * Configuration Settings *"
|
30
|
+
print 'Enter configuration name (account name): '
|
31
|
+
account = get_input
|
32
|
+
config.config_name = account
|
33
|
+
|
34
|
+
print 'Use this as your default config? (y/N): '
|
35
|
+
defconfig = get_input.downcase
|
36
|
+
|
37
|
+
[account, defconfig]
|
38
|
+
end
|
39
|
+
|
40
|
+
# API Key input dialog
|
41
|
+
def self.setup_input_keys(config)
|
42
|
+
puts "\n * API Key Input *"
|
43
|
+
print 'Enter consumer key: '
|
44
|
+
config.api_keys['consumer_key'] = get_input
|
45
|
+
|
46
|
+
print 'Enter consumer secret: '
|
47
|
+
config.api_keys['consumer_secret'] = get_input
|
48
|
+
|
49
|
+
print 'Enter oath token: '
|
50
|
+
config.api_keys['oauth_token'] = get_input
|
51
|
+
|
52
|
+
print 'Enter oath token secret: '
|
53
|
+
config.api_keys['oauth_token_secret'] = get_input
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,151 @@
|
|
1
|
+
require_relative 'config/config_setup'
|
2
|
+
require 'ostruct'
|
3
|
+
|
4
|
+
module DK
|
5
|
+
class Adapter
|
6
|
+
def initialize(data)
|
7
|
+
@data = data
|
8
|
+
end
|
9
|
+
|
10
|
+
def adapt
|
11
|
+
# return adapted data
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class ConfigAdapter < Adapter
|
16
|
+
def initialize(data, file = nil)
|
17
|
+
super(data)
|
18
|
+
@file = file
|
19
|
+
end
|
20
|
+
|
21
|
+
def adapt
|
22
|
+
if @data.keys.include?('consumer_key')
|
23
|
+
r = OpenStruct.new
|
24
|
+
r.user_commands = []
|
25
|
+
r.api_keys = @data
|
26
|
+
puts "Config #{@file} needs to be updated!"
|
27
|
+
print 'Enter a name for this configuration: '
|
28
|
+
r.config_name = DK::Config.get_input
|
29
|
+
Config.save_file(config: r, filename: @file)
|
30
|
+
end
|
31
|
+
r || @data
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Instance Configuration Methods
|
36
|
+
class Config
|
37
|
+
attr_accessor :config, :filename
|
38
|
+
def initialize(opts = {})
|
39
|
+
@filename = opts[:file]
|
40
|
+
@config = OpenStruct.new(load_config(@filename))
|
41
|
+
@def_conf = self.class.home_path_file(DK::CONFIG_FILENAME)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Easily access config opts
|
45
|
+
def method_missing(method, *_args)
|
46
|
+
@config.send(method) unless @config.nil?
|
47
|
+
end
|
48
|
+
|
49
|
+
# Load config from passed or default file
|
50
|
+
def load_config(file = nil)
|
51
|
+
file ||= self.class.home_path_file(DK::CONFIG_FILENAME)
|
52
|
+
return nil unless File.exist?(file.to_s)
|
53
|
+
ConfigAdapter.new(load_yaml_file(file), file).adapt
|
54
|
+
end
|
55
|
+
|
56
|
+
# Contents of YAML file
|
57
|
+
def load_yaml_file(file)
|
58
|
+
YAML.load_file(file)
|
59
|
+
rescue
|
60
|
+
YAML.parse_file(file)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Is this configuration the current default?
|
64
|
+
def is_default?
|
65
|
+
@filename == @def_conf
|
66
|
+
end
|
67
|
+
|
68
|
+
# Check that all 4 keys have been provided
|
69
|
+
# @param api_keys [Hash] API Keys
|
70
|
+
def self.validate_keys(api_keys)
|
71
|
+
return nil if api_keys.nil?
|
72
|
+
return nil unless api_keys.respond_to?(:keys)
|
73
|
+
return {} unless api_keys.keys.all? { |k| VALID_KEYS.include?(k.to_s) }
|
74
|
+
return {} if api_keys.values.include?(nil)
|
75
|
+
api_keys
|
76
|
+
end
|
77
|
+
|
78
|
+
# Configure Tumblr gem
|
79
|
+
# @param file [String] JSON File with API Keys
|
80
|
+
# @param keys [Hash] Hash with API Keys
|
81
|
+
def self.configure_tumblr_gem(file: nil, keys: nil)
|
82
|
+
api_keys = keys || load_api_keys(file: file) || load_api_keys(file: home_path_file(available_configs.first))
|
83
|
+
return false if api_keys.nil?
|
84
|
+
return false unless api_keys.size == 4
|
85
|
+
Tumblr.configure do |config|
|
86
|
+
api_keys.each do |key, value|
|
87
|
+
config.send(:"#{key}=", value)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
true
|
91
|
+
end
|
92
|
+
|
93
|
+
# Read API Keys from file
|
94
|
+
# @param file [String] JSON File with API Keys
|
95
|
+
def self.load_api_keys(file: nil)
|
96
|
+
file ||= home_path_file(DK::CONFIG_FILENAME)
|
97
|
+
exec('dk setup') unless File.exist?(file.to_s)
|
98
|
+
validate_keys(DK::Config.new(file: file).api_keys)
|
99
|
+
end
|
100
|
+
|
101
|
+
# Save Configuration to File
|
102
|
+
def self.save_file(config:, account: '', mute: false, filename: nil)
|
103
|
+
account = '.' + account unless account.empty?
|
104
|
+
path = filename || home_path_file(account + DK::CONFIG_FILENAME)
|
105
|
+
File.open(path, 'w') { |f| f.write YAML.dump config.to_h }
|
106
|
+
puts "\nConfiguration saved to #{path} #{'(Default)' if account.empty?}" unless mute
|
107
|
+
path
|
108
|
+
rescue
|
109
|
+
false
|
110
|
+
end
|
111
|
+
|
112
|
+
# Get input without quotes
|
113
|
+
def self.get_input
|
114
|
+
ARGV.clear
|
115
|
+
gets.chomp.gsub(/[\'\"]/, '')
|
116
|
+
end
|
117
|
+
|
118
|
+
# Does default configuration file exists
|
119
|
+
def self.configured?
|
120
|
+
!available_configs.empty?
|
121
|
+
end
|
122
|
+
|
123
|
+
# All .dkconfig files in home directory
|
124
|
+
def self.available_configs
|
125
|
+
glob = home_path_file('*' + DK::CONFIG_FILENAME)
|
126
|
+
Dir.glob(glob, File::FNM_DOTMATCH).map { |f| f.split('/').last }
|
127
|
+
end
|
128
|
+
|
129
|
+
# Path to file in home directory
|
130
|
+
def self.home_path_file(fname)
|
131
|
+
File.join Dir.home, fname
|
132
|
+
end
|
133
|
+
|
134
|
+
# Copy API Keys from alternate file to the default configuration file
|
135
|
+
def self.switch_default_config(file, mute = false)
|
136
|
+
return true if file.eql? DK::CONFIG_FILENAME
|
137
|
+
save_file config: DK::Config.new(file: home_path_file(file)).config, mute: mute
|
138
|
+
end
|
139
|
+
|
140
|
+
# Delete a configuration file from the home directory
|
141
|
+
def self.delete_config(file)
|
142
|
+
return false unless File.exist?(home_path_file(file))
|
143
|
+
File.delete(home_path_file(file))
|
144
|
+
true
|
145
|
+
rescue
|
146
|
+
false
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
DK::Config.available_configs
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module DK
|
2
|
+
# Posts
|
3
|
+
DRAFT = 'draft'.freeze
|
4
|
+
QUEUE = 'queue'.freeze
|
5
|
+
PUBLISH = 'published'.freeze
|
6
|
+
VALID_STATE = [DRAFT, QUEUE, PUBLISH].freeze
|
7
|
+
|
8
|
+
# Post
|
9
|
+
HTML_TAG_PATTERN = /<[\/]?[\w\d]+\s?(?:[\w\d\-]+=[^>]*>\s?)*>?/
|
10
|
+
|
11
|
+
# Config
|
12
|
+
CONFIG_FILENAME = '.dkconfig'.freeze
|
13
|
+
VALID_KEYS = %w(consumer_key consumer_secret oauth_token oauth_token_secret).freeze
|
14
|
+
|
15
|
+
# Credit Tag
|
16
|
+
CREDIT_TAG = 'DraftKing for Tumblr'.freeze
|
17
|
+
|
18
|
+
# Scaling
|
19
|
+
MAX_THREADS = 3
|
20
|
+
|
21
|
+
# PostReporter
|
22
|
+
REPORT_TITLE = 'Post Report'.freeze
|
23
|
+
REPORT_FIELDS = %w(id state comment tags).freeze
|
24
|
+
REPORT_SIM = ' (SIMULATION)'.freeze
|
25
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module DK
|
2
|
+
# Draft methods
|
3
|
+
module TDrafts
|
4
|
+
# Remove comment tree
|
5
|
+
# @param options[:limit] [int] Limit number of posts selected
|
6
|
+
# @param options[:mute] [bool] Suppress progress indicator?
|
7
|
+
# @param options[:simulate] [bool] Simulation?
|
8
|
+
# @return [int] Number of modified posts
|
9
|
+
def strip_old_comments(options = {})
|
10
|
+
options[:message] = 'Stripping previous comments: '
|
11
|
+
mod_count, _mod_posts = post_operation(options) do |post, _|
|
12
|
+
post.changed = true
|
13
|
+
end
|
14
|
+
mod_count
|
15
|
+
end
|
16
|
+
|
17
|
+
def strip_tags(options = {})
|
18
|
+
options[:message] = 'Stripping previous comments: '
|
19
|
+
mod_count, _mod_posts = post_operation(options) do |post, _|
|
20
|
+
post.clear_tags
|
21
|
+
end
|
22
|
+
mod_count
|
23
|
+
end
|
24
|
+
|
25
|
+
# Move Drafts to Queue
|
26
|
+
# @param options[:credit] [Bool] Give DK credit?
|
27
|
+
# @param options[:comment] [String] HTML or Text Comment
|
28
|
+
# @param options[:limit] [int] Limit number of posts selected
|
29
|
+
# @param options[:key_text] [string] Modify only posts containing key_text string
|
30
|
+
# @param options[:mute] [String] Suppress progress indicator
|
31
|
+
# @param options[:keep_tags] [bool] Preserve existing post tags
|
32
|
+
# @param options[:keep_tree] [bool] Preserve existing post comments
|
33
|
+
# @param options[:simulate] [bool] Simulation?
|
34
|
+
# @return [int] Number of modified posts
|
35
|
+
def drafts_to_queue(options = {})
|
36
|
+
options[:message] = 'Moving Drafts -> Queue: '
|
37
|
+
options[:shuffle] = true
|
38
|
+
options[:state] = DK::QUEUE
|
39
|
+
options[:limit] ||= @q_space
|
40
|
+
mod_count, _mod_posts = post_operation(options) do |post, index|
|
41
|
+
next false unless index_within_limit?(index, @q_space)
|
42
|
+
next false unless post.has_key_text?(@key_text)
|
43
|
+
post.replace_comment_with(@comment)
|
44
|
+
post.change_state(@state)
|
45
|
+
post.generate_tags(keep_tags: @keep_tags,
|
46
|
+
add_tags: @tags,
|
47
|
+
exclude: @comment,
|
48
|
+
credit: @credit) if @auto_tag
|
49
|
+
end
|
50
|
+
mod_count
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|