tumblr_draftking 0.7.0.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|