tumblr_draftking 0.7.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +7 -0
  3. data/CHANGELOG.md +80 -0
  4. data/LICENSE +67 -0
  5. data/README.md +293 -0
  6. data/Rakefile +22 -0
  7. data/bin/dk +7 -0
  8. data/lib/draftking/cli/cli_helpers.rb +61 -0
  9. data/lib/draftking/cli/cli_options.rb +31 -0
  10. data/lib/draftking/cli/commands/_template.rb +4 -0
  11. data/lib/draftking/cli/commands/accounts.rb +66 -0
  12. data/lib/draftking/cli/commands/blogs.rb +26 -0
  13. data/lib/draftking/cli/commands/comment.rb +34 -0
  14. data/lib/draftking/cli/commands/console.rb +18 -0
  15. data/lib/draftking/cli/commands/movedrafts.rb +33 -0
  16. data/lib/draftking/cli/commands/status.rb +24 -0
  17. data/lib/draftking/cli/commands/strip.rb +19 -0
  18. data/lib/draftking/cli/commands/tag.rb +21 -0
  19. data/lib/draftking/cli/commands/user_command.rb +45 -0
  20. data/lib/draftking/cli.rb +62 -0
  21. data/lib/draftking/client.rb +80 -0
  22. data/lib/draftking/config/config_setup.rb +56 -0
  23. data/lib/draftking/config.rb +151 -0
  24. data/lib/draftking/constants.rb +25 -0
  25. data/lib/draftking/dependency_patches.rb +2 -0
  26. data/lib/draftking/drafts.rb +53 -0
  27. data/lib/draftking/patches/thor.rb +12 -0
  28. data/lib/draftking/patches/tumblr_client.rb +10 -0
  29. data/lib/draftking/posts/post.rb +150 -0
  30. data/lib/draftking/posts/posts_helpers.rb +55 -0
  31. data/lib/draftking/posts.rb +173 -0
  32. data/lib/draftking/queue.rb +17 -0
  33. data/lib/draftking/reporter.rb +62 -0
  34. data/lib/draftking/tqueue/future_queue_methods.rb +97 -0
  35. data/lib/draftking/version.rb +3 -0
  36. data/lib/tasks/build.rake +33 -0
  37. data/lib/tasks/rubo.rake +36 -0
  38. data/lib/tumblr_draftking.rb +18 -0
  39. 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,2 @@
1
+ require_relative 'patches/tumblr_client.rb'
2
+ require_relative 'patches/thor.rb'
@@ -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
@@ -0,0 +1,12 @@
1
+ # Patch for Thor long_desc display
2
+ class Thor
3
+ # Thor::Shell Patch
4
+ module Shell
5
+ # Eliminate awkward text wrapping
6
+ class Basic
7
+ def print_wrapped(message, _options = {})
8
+ stdout.puts message
9
+ end
10
+ end
11
+ end
12
+ end