auto_pilot 0.1.0

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