auto_pilot 0.1.0

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: df0efed56cf92bacccd4dc170f0ee6a13cdf5888
4
+ data.tar.gz: c52a0e8f003690337ab5c68d5fbbbe21bdab7f1d
5
+ SHA512:
6
+ metadata.gz: ade5f6da90c08bcb33208111b928389533df86860f3391173ce37b8a37918585a9264181f35fdc47e2e7a2eb5d610fdfeeb971aa5ad47bd3fed893421639bfec
7
+ data.tar.gz: 1fb19844424b6fdfdddbc733f4a58cdb1d78c813de0826dc4a3ab3a9b73f5693a49880bc29f77e065ba277857822d110fd9876b43c758443f35ca2604be4a181
data/.gitignore ADDED
@@ -0,0 +1,35 @@
1
+ *.log
2
+ *.gem
3
+ *.rbc
4
+ *.so
5
+ *.o
6
+ *.a
7
+ .bundle
8
+ .config
9
+ .yardoc
10
+ .rvmrc
11
+ .ruby-gemset
12
+ .ruby-version
13
+ vendor/ruby
14
+ doc
15
+ tmp
16
+ pkg
17
+ rdoc
18
+ Gemfile.lock
19
+ InstalledFiles
20
+ _yardoc
21
+ lib/bundler/man
22
+ spec/reports
23
+ test/tmp
24
+ test/version_tmp
25
+ mkmf.log
26
+ .bundle
27
+ coverage
28
+ *.swp
29
+ *.dump
30
+
31
+ /blog/
32
+ /stackoverflow/
33
+ test/stackoverflow
34
+ /auto_pilot_config.rb
35
+ /.env
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.3
4
+ # addons:
5
+ # code_climate:
6
+ # repo_token: 1213..
data/Gemfile ADDED
@@ -0,0 +1,18 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ r_version = RUBY_VERSION.to_f
6
+
7
+ group :development do
8
+ gem 'rubocop'
9
+ if r_version > 2
10
+ gem 'pry-byebug'
11
+ else
12
+ gem 'pry-debugger'
13
+ end
14
+ gem 'rubycritic'
15
+ gem 'simplecov'
16
+ end
17
+
18
+ # gem 'codeclimate-test-reporter', group: :test, require: nil
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Luke Fender
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,51 @@
1
+ # AutoPilot
2
+ [![Travis CI](https://travis-ci.org/lfender6445/auto_pilot.svg?branch=master)](https://travis-ci.org/lfender6445/auto_pilot)
3
+ [![Code Climate](https://codeclimate.com/github/lfender6445/auto_pilot/badges/gpa.svg)](https://codeclimate.com/github/lfender6445/auto_pilot)
4
+ <!--
5
+ [![Test Coverage](https://codeclimate.com/github/lfender6445/auto_pilot/badges/coverage.svg)](https://codeclimate.com/github/lfender6445/auto_pilot)
6
+ -->
7
+
8
+ use this ruby gem to convert your [stackoverflow](http://www.stackoverflow.com/) profile to a [jekyll blog](https://help.github.com/articles/using-jekyll-with-pages/)
9
+
10
+
11
+ # usage
12
+ supports conversion to html or [markdown](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet)
13
+
14
+ ## Installation
15
+
16
+ Add this line to your application's Gemfile:
17
+
18
+ ```ruby
19
+ gem 'auto_pilot'
20
+ ```
21
+
22
+ And then execute:
23
+
24
+ $ bundle
25
+
26
+ Or install it yourself as:
27
+
28
+ $ gem install auto_pilot
29
+
30
+ ## Usage
31
+
32
+ TODO: Write usage instructions here
33
+
34
+ ## Contributing
35
+
36
+ 1. Fork it ( https://github.com/[my-github-username]/auto_pilot/fork )
37
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
38
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
39
+ 4. Push to the branch (`git push origin my-new-feature`)
40
+ 5. Create a new Pull Request
41
+
42
+ ## todo
43
+
44
+ create config file and object
45
+ support date range restriction
46
+ support html conversion
47
+ enable switching placemnet of answers and questions
48
+
49
+ # api
50
+ api.stackexchange.com/2.1
51
+
data/Rakefile ADDED
@@ -0,0 +1,35 @@
1
+ require 'bundler/gem_tasks'
2
+
3
+ namespace :log do
4
+ desc 'Truncates all *.log files in log/ to zero bytes (specify which logs with LOGS=test,development)'
5
+ task :clear do
6
+ log_files.each do |file|
7
+ clear_log_file(file)
8
+ end
9
+ end
10
+
11
+ def log_files
12
+ if ENV['LOGS']
13
+ ENV['LOGS'].split(',')
14
+ .map { |file| "log/#{file.strip}.log" }
15
+ .select { |file| File.exist?(file) }
16
+ else
17
+ FileList['log/*.log']
18
+ end
19
+ end
20
+
21
+ def clear_log_file(file)
22
+ f = File.open(file, 'w')
23
+ f.close
24
+ end
25
+ end
26
+
27
+ require 'rake/testtask'
28
+
29
+ Rake::TestTask.new(:test) do |t|
30
+ t.libs << 'lib' << 'test'
31
+ t.pattern = 'test/**/test_*.rb'
32
+ t.verbose = true
33
+ end
34
+
35
+ task default: 'test'
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'auto_pilot/util/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'auto_pilot'
8
+ spec.version = AutoPilot::VERSION
9
+ spec.authors = ['Luke Fender']
10
+ spec.email = ['lfender6445@gmail.com']
11
+ spec.summary = 'convert your stackoverflow to a github blog'
12
+ spec.description = 'convert your stackoverflow to a github blog'
13
+ spec.homepage = ''
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_dependency 'nokogiri', '~> 1.6.3.1'
22
+ spec.add_dependency 'httparty', '~> 0.11.0'
23
+ spec.add_dependency 'reverse_markdown', '~> 0.7.0'
24
+ spec.add_dependency 'ruby-stackoverflow', '~> 0.0.3'
25
+
26
+ spec.add_development_dependency 'bundler', '~> 1.7'
27
+ spec.add_development_dependency 'rake', '~> 10.3.2'
28
+ spec.add_development_dependency 'minitest', '~> 5.4.1'
29
+ spec.add_development_dependency 'webmock', '~> 1.18.0'
30
+ end
data/bin/autopilot ADDED
@@ -0,0 +1,157 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'pry' if ENV['DEBUG']
4
+
5
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
6
+
7
+ begin
8
+ require 'auto_pilot'
9
+ rescue LoadError
10
+ require 'rubygems'
11
+ require 'auto_pilot'
12
+ end
13
+
14
+ require 'fileutils'
15
+
16
+ def get_root
17
+ Gem::Specification.find_by_name('auto_pilot').gem_dir
18
+ rescue Gem::LoadError
19
+ Dir.pwd
20
+ end
21
+
22
+ ROOT = get_root
23
+
24
+ class Application
25
+ CONF_TEMPLATE = 'auto_pilot_config.rb'
26
+
27
+ def initialize
28
+ show_banner
29
+ ask_user_for_configuration
30
+ download_answers_and_write_files
31
+ end
32
+
33
+ private
34
+
35
+ def ask_user_for_configuration
36
+ if File.exist?("#{ROOT}/#{CONF_TEMPLATE}")
37
+ log.out "found existing configuration at #{ROOT}/#{CONF_TEMPLATE}\n"
38
+ load_configuration
39
+ else
40
+ log.out "do you want to create a configuration file? y/n\n"
41
+ answer = $stdin.gets.chomp
42
+ if answer == 'y'
43
+ add_configuration_file
44
+ load_configuration
45
+ update_config_with_user
46
+ ask_user_to_keep_going
47
+ else
48
+ use_default_configuration
49
+ end
50
+ end
51
+ end
52
+
53
+ def ask_user_to_keep_going
54
+ log.yellow 'would you like to continue with configuration defaults? y/n'
55
+ answer = $stdin.gets.chomp
56
+ unless answer == 'y'
57
+ log.out 'when ready, resume by running `autopilot`'
58
+ abort
59
+ end
60
+ end
61
+
62
+ def update_config_with_user
63
+ user = ask_for_user
64
+ update_config_with_answer if user.nil? || user == ''
65
+ template = "#{ROOT}/#{CONF_TEMPLATE}"
66
+ text = File.read(template)
67
+ new_contents = text.gsub(/username/, AutoPilot.configuration.user)
68
+ File.open(template, 'w') { |file| file.puts new_contents }
69
+ reload_config
70
+ validate_config
71
+ end
72
+
73
+ def validate_config
74
+ end
75
+
76
+ def load_configuration
77
+ load "#{ROOT}/#{CONF_TEMPLATE}"
78
+ end
79
+ alias_method :reload_config, :load_configuration
80
+
81
+ def use_default_configuration
82
+ AutoPilot.configure do |config|
83
+ config.user = ask_for_user
84
+ config.format = [:md]
85
+ config.folder = "#{ROOT}/stackoverflow"
86
+ config.disable_front_matter = false
87
+ config.max_pages = 1
88
+ config.date = { start: '2000-01-00', end: todays_date }
89
+ end
90
+ end
91
+
92
+ def todays_date
93
+ Time.now.to_s.split(' ').first
94
+ end
95
+
96
+ def ask_for_user
97
+ log.out "enter a stackoverflow username:\n"
98
+ answer = $stdin.gets.chomp
99
+ if answer.nil? or answer == ''
100
+ log.red '- invalid username, try again'
101
+ ask_for_user
102
+ else
103
+ AutoPilot.configuration.user = answer
104
+ end
105
+ end
106
+
107
+ def copy_with_path(src, dst)
108
+ FileUtils.mkdir_p(File.dirname(dst))
109
+ FileUtils.cp(src, dst)
110
+ end
111
+
112
+ def add_configuration_file
113
+ template = "#{ROOT}/lib/auto_pilot/templates/auto_pilot_config.rb"
114
+ copy_with_path(template, CONF_TEMPLATE)
115
+ log.green "- created ./#{CONF_TEMPLATE}"
116
+ update_gitignore
117
+ end
118
+
119
+ def update_gitignore
120
+ gitignore = "#{ROOT}/.gitignore"
121
+ if File.exist?(gitignore)
122
+ unless already_updated_gitignore
123
+ log.green 'would you like to add configuration to .gitignore? y/n'
124
+ answer = $stdin.gets.chomp
125
+ if answer == 'y'
126
+ open(gitignore, 'a') do |f|
127
+ f.puts '/auto_pilot_config.rb'
128
+ end
129
+ log.green 'updated .gitignore'
130
+ end
131
+ end
132
+ end
133
+ end
134
+
135
+ def already_updated_gitignore
136
+ File.read("#{ROOT}/.gitignore").match(CONF_TEMPLATE)
137
+ end
138
+
139
+ def download_answers_and_write_files
140
+ # AutoPilot.write_files(AutoPilot.get_answers)
141
+ AutoPilot.write_files(AutoPilot.get_api_answers)
142
+ end
143
+
144
+ def log
145
+ AutoPilot::Log
146
+ end
147
+
148
+ def show_banner
149
+ puts <<-BLOCK.unindent
150
+ *************
151
+ -=AUTOPILOT=-
152
+ *************
153
+ BLOCK
154
+ end
155
+ end
156
+
157
+ Application.new
data/lib/auto_pilot.rb ADDED
@@ -0,0 +1,50 @@
1
+ require_relative 'core/string'
2
+ require_relative 'auto_pilot/configure'
3
+ require_relative 'auto_pilot/api'
4
+ require_relative 'auto_pilot/request'
5
+ require_relative 'auto_pilot/document_parser'
6
+ require_relative 'auto_pilot/markdown_converter'
7
+ require_relative 'auto_pilot/html_converter'
8
+
9
+ module AutoPilot
10
+ class << self
11
+ BASE_URL = 'http://stackoverflow.com/questions'
12
+
13
+ # def get_answers(_user = '', _options = {})
14
+ # # TODO: id stubs, replace with API
15
+ # question_ids = [19_348_076]
16
+ # answer_ids = [25_536_701]
17
+ # parsed_documents = []
18
+ # question_ids.each do |id|
19
+ # doc = Request.fetch page_with_my_answer(id)
20
+ # parsed_documents << DocumentParser.new(doc, id, answer_ids.first)
21
+ # end
22
+ # parsed_documents
23
+ # end
24
+
25
+ def get_api_answers
26
+ parsed_documents = []
27
+ answers = AutoPilot::API.new.get_answers
28
+ answers.each do |answer|
29
+ question_id = answer[:question_id]
30
+ answer_id = answer[:answer_id]
31
+ url = page_with_my_answer(question_id)
32
+ doc = Request.fetch url
33
+ # Log.green "question id #{question_id} | answer id #{answer_id}"
34
+ parsed_documents << DocumentParser.new(doc, question_id, answer_id)
35
+ end
36
+ parsed_documents
37
+ end
38
+
39
+ def page_with_my_answer(id)
40
+ "#{BASE_URL}/#{id}/"
41
+ end
42
+
43
+ def write_files(parsed_documents)
44
+ parsed_documents.each do |doc|
45
+ HtmlConverter.new doc if AutoPilot.configuration.format.include? :html
46
+ MarkdownConverter.new doc if AutoPilot.configuration.format.include? :md
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,81 @@
1
+ require 'ruby-stackoverflow'
2
+ module AutoPilot
3
+ class API
4
+ attr_reader :user, :options, :answers
5
+
6
+ def initialize(user = AutoPilot.configuration.user, options = {})
7
+ @user = user
8
+ @options = options
9
+ @answers = []
10
+ add_config_client_key
11
+ end
12
+
13
+ def get_answers
14
+ Log.green "fetching information for #{AutoPilot.configuration.user} via stackoverflow api"
15
+ pages.each do |page|
16
+ response = answer_response(page)
17
+ answers << response.data.first.answers
18
+ break unless response.has_more
19
+ end
20
+ filtered(answers)
21
+ end
22
+
23
+ def pages
24
+ Array(1..(AutoPilot.configuration.max_pages || 3))
25
+ end
26
+
27
+ # https://api.stackexchange.com/docs/throttle
28
+ # NOTE: While not strictly a throttle, the Stack Exchange API employs heavy caching and as such no application should make semantically identical requests more than once a minute.
29
+ def throttle
30
+ sleep(AutoPilot.configuration.throttle || 3)
31
+ yield if block_given?
32
+ end
33
+
34
+ private
35
+
36
+ def answer_response(page)
37
+ throttle { RubyStackoverflow.users_with_answers([user_id], 'page' => page) }
38
+ end
39
+
40
+ def add_config_client_key
41
+ if key = AutoPilot.configuration.key
42
+ RubyStackoverflow.configure { |config| config.client_key = key }
43
+ else
44
+ Log.yellow 'by signing up for an api key you can execute more requests - http://api.stackexchange.com/'
45
+ end
46
+ end
47
+
48
+ def user_id
49
+ throttle
50
+ if user_response.data
51
+ user_response.data.first.user_id
52
+ else
53
+ if error = user_response.error
54
+ fail "#{error.error_message} | #{error.error_name} | #{error.error_code}"
55
+ end
56
+ end
57
+ end
58
+
59
+ def user_response
60
+ @response ||= RubyStackoverflow.users(inname: user)
61
+ end
62
+
63
+ def filtered(answers)
64
+ if answers.length > 0
65
+ filtered_answers = answers.flatten.uniq.select { |answer| answer.score > 0 }
66
+ [].tap do |arr|
67
+ filtered_answers.each do |answer|
68
+ arr << { answer_id: answer.answer_id, question_id: answer.question_id }
69
+ end
70
+ end
71
+ else
72
+ fail "could not find answers for #{AutoPilot.configuration.user}"
73
+ end
74
+ end
75
+
76
+ def fail(error)
77
+ Log.red error
78
+ abort
79
+ end
80
+ end
81
+ end