evernotable 1.0.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.
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in evernotable.gemspec
4
+ gemspec
@@ -0,0 +1,57 @@
1
+ = Evernotable
2
+
3
+ * https://github.com/kmuthupa/evernotable
4
+
5
+ == Description
6
+
7
+ A simple commandline task manager that uses Evernote note store. This automatically creates a new distinct Evernote notebook for persistance of tasks. Users can add new tasks, list them and remove existing tasks.
8
+
9
+ == Usage
10
+
11
+ # authenticate
12
+ evernotable auth login
13
+ evernotable auth logout
14
+
15
+ # add a new task
16
+ evernotable task add 'shave my beard!'
17
+
18
+ # list all existing tasks
19
+ evernotable task list
20
+
21
+ # remove an existing task
22
+ evernotable task remove #2 => removes task listed #2
23
+
24
+ == Dependencies
25
+
26
+ * evernote
27
+ * thrift
28
+ * thrift_client
29
+ * encrypted_strings
30
+ * highline
31
+
32
+ == Installation
33
+
34
+ * gem install evernotable
35
+
36
+ == License
37
+
38
+ Copyright 2012 Karthik Muthupalaniappan
39
+
40
+ Permission is hereby granted, free of charge, to any person obtaining
41
+ a copy of this software and associated documentation files (the
42
+ 'Software'), to deal in the Software without restriction, including
43
+ without limitation the rights to use, copy, modify, merge, publish,
44
+ distribute, sublicense, and/or sell copies of the Software, and to
45
+ permit persons to whom the Software is furnished to do so, subject to
46
+ the following conditions:
47
+
48
+ The above copyright notice and this permission notice shall be
49
+ included in all copies or substantial portions of the Software.
50
+
51
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
52
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
53
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
54
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
55
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
56
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
57
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,3 @@
1
+ # start up the CLI
2
+ require "evernotable/cli"
3
+ Evernotable::CLI.start(*ARGV)
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "evernotable/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "evernotable"
7
+ s.version = Evernotable::VERSION
8
+ s.authors = ["Karthik Muthupalaniappan"]
9
+ s.email = ["karthik.m@imaginea.com"]
10
+ s.homepage = "http://intellisenze.wordpress.com"
11
+ s.summary = %q{A simple commandline task manager that uses Evernote note store}
12
+ s.description = %q{A simple commandline task manager that uses Evernote note store. This automatically creates a new distinct Evernote notebook for persistance of these task notes.}
13
+
14
+ s.rubyforge_project = "evernotable"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_dependency "thrift"
22
+ s.add_dependency "thrift_client"
23
+ s.add_dependency "evernote"
24
+ s.add_dependency "highline"
25
+ s.add_dependency "encrypted_strings"
26
+ s.add_development_dependency "rspec"
27
+ end
@@ -0,0 +1,4 @@
1
+ require 'evernote'
2
+
3
+ module Evernotable
4
+ end
@@ -0,0 +1,13 @@
1
+ require "evernotable"
2
+ require "evernotable/command"
3
+ require "highline"
4
+
5
+ class Evernotable::CLI
6
+
7
+ def self.start(*args)
8
+ command = args.shift.strip rescue "help"
9
+ Evernotable::Command.load
10
+ Evernotable::Command.run(command, args)
11
+ end
12
+
13
+ end
@@ -0,0 +1,8 @@
1
+ module Evernotable
2
+ module Client
3
+
4
+ class ClientException < RuntimeError
5
+ end
6
+
7
+ end
8
+ end
@@ -0,0 +1,30 @@
1
+ require 'evernote'
2
+ require 'evernotable/client'
3
+ require 'yaml'
4
+
5
+ class Evernotable::Client::Base
6
+ attr_reader :config
7
+ attr_reader :current_user
8
+ attr_reader :client_token
9
+
10
+ def initialize(params={})
11
+ @config = params[:config] || nil
12
+ @current_user = params[:current_user] || nil
13
+ @client_token = params[:client_token] || nil
14
+ end
15
+
16
+ protected
17
+
18
+ def wrap_method(message, &block)
19
+ yield @client_token
20
+ rescue Exception => ex
21
+ raise Evernotable::Client::ClientException, "#{message}: #{ex.message}"
22
+ end
23
+
24
+ attr_writer :current_user
25
+ attr_writer :client_token
26
+ end
27
+
28
+
29
+
30
+
@@ -0,0 +1,69 @@
1
+ require 'evernotable/client/base'
2
+ require 'evernotable/utilities'
3
+
4
+ class Evernotable::Client::Note < Evernotable::Client::Base
5
+ include Evernotable::Utilities
6
+ attr_reader :notebook_guid
7
+
8
+ def initialize(params={})
9
+ super(params)
10
+ @api = @config["note_api"]["sandbox"] #TODO: variablize the api env
11
+ @notebook_name = @config["notebook"]["name"]
12
+ @notebook_guid = nil
13
+ @instance = Evernote::NoteStore.new("#{@api}#{params[:user_shard]}")
14
+ end
15
+
16
+ def add_notebook
17
+ wrap_method('attempt to create new notebook') do |client_token|
18
+ @notebook_guid = @instance.createNotebook(client_token, Evernote::EDAM::Type::Notebook.new({:name => @notebook_name})).guid
19
+ end
20
+ end
21
+
22
+ def add_note(note_text)
23
+ self.add_notebook unless notebook_exists?
24
+ wrap_method('attempt to create a new note') do |client_token|
25
+ @instance.createNote(client_token, Evernote::EDAM::Type::Note.new({:title => note_text, :content => wrap_enml(note_text), :notebookGuid => @notebook_guid}))
26
+ end
27
+ end
28
+
29
+ def remove_note(note_guid)
30
+ return unless notebook_exists?
31
+ wrap_method('attempt to remove a note') { |client_token| @instance.deleteNote(client_token, note_guid) }
32
+ end
33
+
34
+ def list_notes
35
+ return unless notebook_exists?
36
+ wrap_method('attempt to list notes') do |client_token|
37
+ @instance.findNotes(client_token, Evernote::EDAM::NoteStore::NoteFilter.new({:notebookGuid => @notebookGuid}), 0, 100).notes
38
+ end
39
+ end
40
+
41
+ def list_notebooks
42
+ wrap_method('attempt to list notebooks') { |client_token| @instance.listNotebooks(client_token) }
43
+ end
44
+
45
+ def expunge_notebook
46
+ return unless notebook_exists?
47
+ wrap_method('attempt to expunge the evernotable notebook') do |client_token|
48
+ @instance.expungeNotebook(client_token, @notebook_guid)
49
+ end
50
+ end
51
+
52
+ def expunge_trashed_notes
53
+ wrap_method('attempt to expunge all trashed notes') do |client_token|
54
+ @instance.expungeInactiveNotes(client_token)
55
+ end
56
+ end
57
+
58
+ def notebook_exists?
59
+ notebooks = list_notebooks
60
+ notebooks.each do |notebook|
61
+ if notebook.name == 'evernotable'
62
+ @notebook_guid = notebook.guid
63
+ return true
64
+ end
65
+ end
66
+ return false
67
+ end
68
+
69
+ end
@@ -0,0 +1,27 @@
1
+ require 'evernotable/client/base'
2
+
3
+ class Evernotable::Client::User < Evernotable::Client::Base
4
+
5
+ def initialize(params={})
6
+ super
7
+ api = @config["user_api"]["sandbox"] #TODO: variablize the api env
8
+ @instance = Evernote::UserStore.new(api, {:username => params[:user], :password => params[:password], :consumer_key => @config["api_credentials"]["consumer_key"], :consumer_secret => @config["api_credentials"]["consumer_secret"]})
9
+ end
10
+
11
+ def authenticate
12
+ self.wrap_method('attempt to authenticate the user') do
13
+ auth_result = @instance.authenticate
14
+ self.current_user = auth_result.user
15
+ self.client_token = auth_result.authenticationToken
16
+ end
17
+ end
18
+
19
+ def refresh_authentication
20
+ self.wrap_method('attempt to refresh auth token') {|client_token| self.client_token = @instance.refreshAuthentication(client_token).authenticationToken}
21
+ end
22
+
23
+ def valid_version?
24
+ self.wrap_method('attempt to check API version') { @instance.version_valid? }
25
+ end
26
+
27
+ end
@@ -0,0 +1,49 @@
1
+ require 'evernotable/utilities'
2
+
3
+ module Evernotable
4
+ module Command
5
+
6
+ extend Evernotable::Utilities
7
+
8
+ class CommandFailed < RuntimeError
9
+ end
10
+
11
+ def self.load
12
+ @@commands = []
13
+ Dir[File.join(File.dirname(__FILE__), "command", "*.rb")].each do |file|
14
+ require file
15
+ @@commands << File.basename(file, '.*')
16
+ end
17
+ end
18
+
19
+ def self.commands
20
+ @@commands ||= []
21
+ end
22
+
23
+ def self.valid?(cmd)
24
+ @@commands.include?(cmd)
25
+ end
26
+
27
+ def self.run(cmd, arguments=[])
28
+ if cmd.nil? || cmd.empty?
29
+ output_with_bang("Use *evernotable help* for additional information.")
30
+ exit(1)
31
+ end
32
+ unless valid?(cmd)
33
+ output_with_bang("*#{cmd}* is not a valid evernotable command.")
34
+ output_with_bang("Use *evernotable help* for additional information.")
35
+ exit(1)
36
+ else
37
+ #instantiate command and invoke method on it
38
+ method = arguments.shift || :help
39
+ obj = eval("Evernotable::Command::#{cmd.capitalize}").new(arguments)
40
+ obj.send(method)
41
+ end
42
+ rescue CommandFailed => ex
43
+ error "#{ex.message}"
44
+ rescue Interrupt => e
45
+ error "\n[command canceled]"
46
+ end
47
+
48
+ end
49
+ end
@@ -0,0 +1,33 @@
1
+ require "evernotable/command/base"
2
+
3
+ class Evernotable::Command::Auth < Evernotable::Command::Base
4
+
5
+ def login
6
+ user = [] << @highline.ask("Enter your Evernote username: ")
7
+ user << @highline.ask("Enter your Evernote password: ") { |q| q.echo = "*" }
8
+ authenticate_user(user)
9
+ write_to_file credentials_file, user.join('/')
10
+ display "You were successfully authenticated."
11
+ end
12
+
13
+ def logout
14
+ if File.exist?(credentials_file)
15
+ File.delete(credentials_file)
16
+ display "You were successfully logged out."
17
+ else
18
+ output_with_bang "You are not logged in."
19
+ end
20
+ end
21
+
22
+ def method_missing(method_name, *args)
23
+ case method_name
24
+ when :help then
25
+ display '--------------------------------------------'
26
+ display '# authenticate
27
+ evernotable auth login
28
+ evernotable auth logout'
29
+ display '--------------------------------------------'
30
+ end
31
+ end
32
+
33
+ end
@@ -0,0 +1,47 @@
1
+ require "evernotable/command"
2
+ require "evernotable/client/user"
3
+ require "evernotable/client/note"
4
+ require 'evernotable/utilities'
5
+
6
+ class Evernotable::Command::Base
7
+
8
+ include Evernotable::Utilities
9
+
10
+ def initialize(params=[])
11
+ @config = YAML.load(File.read('lib/evernotable_config.yml'))
12
+ @args = params.map {|p| p.strip}
13
+ @highline = HighLine.new
14
+ end
15
+
16
+ def authenticate_user(user=[])
17
+ user = read_from_file(credentials_file).split('/') if user.empty?
18
+ @user_client = Evernotable::Client::User.new({:user => user.first, :password => user.last, :config => @config})
19
+ begin
20
+ @user_client.authenticate
21
+ rescue Evernotable::Client::ClientException => ex
22
+ raise Evernotable::Command::CommandFailed, "Invalid Evernote credentials."
23
+ end
24
+ end
25
+
26
+ def note_client
27
+ authenticate_user
28
+ Evernotable::Client::Note.new({:user_shard => @user_client.current_user.shardId, :client_token => @user_client.client_token, :config => @config})
29
+ end
30
+
31
+ def invoke_client
32
+ begin
33
+ yield
34
+ rescue Evernotable::Client::ClientException => ex
35
+ raise Evernotable::Command::CommandFailed, "Oops. That didn't work."
36
+ end
37
+ end
38
+
39
+ def method_missing(method_name, *args)
40
+ end
41
+
42
+ protected
43
+
44
+ def credentials_file
45
+ @config["credentials_file"]["path"]
46
+ end
47
+ end
@@ -0,0 +1,24 @@
1
+ require "evernotable/command/base"
2
+
3
+ class Evernotable::Command::Help < Evernotable::Command::Base
4
+
5
+ def method_missing(method_name, *args)
6
+ case method_name
7
+ when :help then
8
+ display 'Evernotable is a simple commandline task/todo manager that uses Evernote note store.'
9
+ display 'This automatically creates a new distinct Evernote notebook for persistance of tasks. Users can add new tasks, list them and remove existing tasks after authenticating using their Evernote credentials.'
10
+ display '--------------------------------------------'
11
+ display '# authenticate
12
+ evernotable auth login
13
+ evernotable auth logout'
14
+ display '# add a new task
15
+ evernotable task add shave my beard!'
16
+ display '# list all existing tasks
17
+ evernotable task list'
18
+ display '# remove an existing task
19
+ evernotable task remove #2 => removes task listed #2'
20
+ display '--------------------------------------------'
21
+ end
22
+ end
23
+
24
+ end
@@ -0,0 +1,39 @@
1
+ require "evernotable/command/base"
2
+
3
+ class Evernotable::Command::Task < Evernotable::Command::Base
4
+
5
+ def add
6
+ invoke_client do
7
+ note_client.add_note(@args.first)
8
+ display 'Done.'
9
+ end
10
+ end
11
+
12
+ def list
13
+ invoke_client do
14
+ notes = note_client.list_notes
15
+ notes.collect{|n| n.title}.each_with_index{|n, i| display "#{i+1}. #{n}"}
16
+ end
17
+ end
18
+
19
+ def remove
20
+ invoke_client do
21
+ note_client.remove_note(@args.first)
22
+ display 'Done.'
23
+ end
24
+ end
25
+
26
+ def method_missing(method_name, *args)
27
+ case method_name
28
+ when :help then
29
+ display '--------------------------------------------'
30
+ display '# add a new task
31
+ evernotable task add shave my beard!'
32
+ display '# list all existing tasks
33
+ evernotable task list'
34
+ display '# remove an existing task
35
+ evernotable task remove #2 => removes task listed #2'
36
+ display '--------------------------------------------'
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,48 @@
1
+ require 'encrypted_strings'
2
+
3
+ module Evernotable
4
+ module Utilities
5
+
6
+ def format_with_bang(message)
7
+ return '' if message.to_s.strip == ""
8
+ "! " + message.split("\n").join("\n ! ")
9
+ end
10
+
11
+ def output_with_bang(message="", new_line=true)
12
+ return if message.to_s.strip == ""
13
+ display(format_with_bang(message), new_line)
14
+ end
15
+
16
+ def display(msg="", new_line=true)
17
+ if new_line
18
+ STDOUT.puts(msg)
19
+ else
20
+ STDOUT.print(msg)
21
+ STDOUT.flush
22
+ end
23
+ end
24
+
25
+ def error(msg)
26
+ STDERR.puts(format_with_bang(msg))
27
+ exit(1)
28
+ end
29
+
30
+ def wrap_enml(content)
31
+ "<?xml version='1.0' encoding='UTF-8'?><!DOCTYPE en-note SYSTEM 'http://xml.evernote.com/pub/enml2.dtd'><en-note>#{content}</en-note>"
32
+ end
33
+
34
+ def write_to_file(file, content)
35
+ File.open(file, 'w') {|f| f.write(content.encrypt(:symmetric, :password => encrypt_key))}
36
+ end
37
+
38
+ def read_from_file(file)
39
+ File.exist?(file) ? File.read(file).decrypt(:symmetric, :password => encrypt_key) : ''
40
+ end
41
+
42
+ def encrypt_key
43
+ config = YAML.load(File.read('lib/evernotable_config.yml'))
44
+ return config["encryption"]["key"]
45
+ end
46
+
47
+ end
48
+ end
@@ -0,0 +1,3 @@
1
+ module Evernotable
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,17 @@
1
+ api_credentials:
2
+ consumer_key: kswamin
3
+ consumer_secret: dbd87f40e8507b16
4
+ user_api:
5
+ sandbox: https://sandbox.evernote.com/edam/user
6
+ production: https://www.evernote.com/edam/user
7
+ note_api:
8
+ sandbox: http://sandbox.evernote.com/edam/note/
9
+ production: http://www.evernote.com/edam/note/
10
+ notebook:
11
+ name: evernotable
12
+ credentials_file:
13
+ path: /tmp/evernotable
14
+ encryption:
15
+ key: 'evern0te'
16
+
17
+
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+ require 'evernotable/client/base'
3
+
4
+ describe Evernotable::Client::Base do
5
+ before(:all) do
6
+ @config = YAML.load(File.read('lib/evernotable_config.yml'))
7
+ end
8
+
9
+ it 'should appropriately be initialized' do
10
+ base_client = Evernotable::Client::Base.new({:config => @config})
11
+ base_client.should_not be_nil
12
+ base_client.current_user.should be_nil
13
+ base_client.config.should_not be_nil
14
+ base_client.config["api_credentials"]["consumer_key"].should == 'kswamin'
15
+ base_client.config["api_credentials"]["consumer_secret"].should == 'dbd87f40e8507b16'
16
+ end
17
+ end
@@ -0,0 +1,64 @@
1
+ require 'spec_helper'
2
+ require 'evernotable/client/note'
3
+
4
+ describe Evernotable::Client::Note do
5
+
6
+ before(:all) do
7
+ @config = YAML.load(File.read('lib/evernotable_config.yml'))
8
+ @user_client = Evernotable::Client::User.new({:user => 'kswamin', :password => 'dumbass', :config => @config})
9
+ @user_client.authenticate
10
+ @note_client = Evernotable::Client::Note.new({:user_shard => @user_client.current_user.shardId, :client_token => @user_client.client_token, :config => @config})
11
+ #@note_client.expunge_notebook #TODO: doesn't work for some weird reason, investigate
12
+ end
13
+
14
+ it 'should appropriately be initialized' do
15
+ @note_client.should_not be_nil
16
+ @note_client.config.should_not be_nil
17
+ @note_client.notebook_guid.should be_nil
18
+ end
19
+
20
+ it 'should add a new notebook successfully' do
21
+ lambda { @note_client.add_notebook }.should_not raise_error
22
+ @note_client.notebook_guid.should_not be_nil
23
+ end
24
+
25
+ it 'should list notebooks successfully' do
26
+ list = []
27
+ lambda {list = @note_client.list_notebooks}.should_not raise_error
28
+ list.size.should == 2
29
+ list.collect {|n| n.name}.include?('evernotable').should be_true
30
+ end
31
+
32
+ it 'should check if the notebook exists?' do
33
+ @note_client.notebook_exists?.should be_true
34
+ end
35
+
36
+ it 'should add a note successfully' do
37
+ notes = nil
38
+ lambda {notes = @note_client.list_notes}.should_not raise_error
39
+ notes.size.should == 0
40
+ lambda { @note_client.add_note('note 1') }.should_not raise_error
41
+ lambda { @note_client.add_note('note 2') }.should_not raise_error
42
+ lambda { @note_client.add_note('note 3') }.should_not raise_error
43
+ lambda {notes = @note_client.list_notes}.should_not raise_error
44
+ notes.size.should == 3
45
+ end
46
+
47
+ it 'should list notes successfully' do
48
+ notes = nil
49
+ lambda {notes = @note_client.list_notes}.should_not raise_error
50
+ notes.size.should == 3
51
+ notes.collect{|n| n.title}.should == ['note 1', 'note 2', 'note 3']
52
+ end
53
+
54
+ it 'should remove a note successfully' do
55
+ note = nil
56
+ lambda { note = @note_client.add_note('note 4') }.should_not raise_error
57
+ count = @note_client.list_notes.size
58
+ count.should == 4
59
+ lambda { @note_client.remove_note(note.guid) }.should_not raise_error
60
+ count = @note_client.list_notes.size
61
+ count.should == 3
62
+ end
63
+
64
+ end
@@ -0,0 +1,56 @@
1
+ require 'spec_helper'
2
+ require 'evernotable/client/user'
3
+
4
+ describe Evernotable::Client::User do
5
+
6
+ before(:all) do
7
+ @config = YAML.load(File.read('lib/evernotable_config.yml'))
8
+ end
9
+
10
+ it 'should appropriately be initialized' do
11
+ user_client = Evernotable::Client::User.new({:user => 'kswamin', :password => 'dumbass', :config => @config})
12
+ user_client.should_not be_nil
13
+ user_client.config.should_not be_nil
14
+ end
15
+
16
+ describe '#authenticate' do
17
+ it 'should authenticate the user successfully' do
18
+ user_client = Evernotable::Client::User.new({:user => 'kswamin', :password => 'dumbass', :config => @config})
19
+ user_client.should_not be_nil
20
+ user_client.authenticate
21
+ user_client.current_user.should_not be_nil
22
+ user_client.client_token.should_not be_nil
23
+ end
24
+ it 'should not authenticate the user successfully' do
25
+ user_client = Evernotable::Client::User.new({:user => 'kswamin', :password => 'thewrongpassword', :config => @config})
26
+ user_client.should_not be_nil
27
+ lambda { user_client.authenticate }.should raise_error(Evernotable::Client::ClientException)
28
+ user_client.current_user.should be_nil
29
+ user_client.client_token.should be_nil
30
+ end
31
+ end
32
+
33
+ describe '#refresh authentication' do
34
+ before(:all) do
35
+ @user_client = Evernotable::Client::User.new({:user => 'kswamin', :password => 'dumbass', :config => @config})
36
+ @user_client.authenticate
37
+ end
38
+ it 'should refresh the authentication for the user successfully' do
39
+ prev_token = @user_client.client_token
40
+ @user_client.refresh_authentication
41
+ @user_client.client_token.should_not be_nil
42
+ new_token = @user_client.client_token
43
+ prev_token.should_not == new_token
44
+ end
45
+ end
46
+
47
+ describe '#check valid version' do
48
+ before(:all) do
49
+ @user_client = Evernotable::Client::User.new({:user => 'kswamin', :password => 'dumbass', :config => @config})
50
+ end
51
+ it 'should check if the version is valid' do
52
+ @user_client.valid_version?.should be_true
53
+ end
54
+ end
55
+
56
+ end
@@ -0,0 +1,55 @@
1
+ require 'spec_helper'
2
+ require 'evernotable/command/auth'
3
+
4
+ describe Evernotable::Command::Auth do
5
+ it 'displays relevant information when help is invoked' do
6
+ auth_command = Evernotable::Command::Auth.new
7
+ auth_command.should_not be_nil
8
+ STDOUT.should_receive(:puts).exactly(3).times.with(any_args())
9
+ lambda {auth_command.send(:help)}.should_not raise_error(Evernotable::Command::CommandFailed)
10
+ end
11
+
12
+ describe '#login' do
13
+ pending 'TODO: fix auth login specs'
14
+ # it 'should log the user in successfully using user input' do
15
+ # user_mock = mock("Evernotable::Client::User")
16
+ # Evernotable::Client::User.stub(:new).and_return(user_mock)
17
+ # user_mock.stub!(:read_from_file).and_return(nil)
18
+ # highline = mock("HighLine")
19
+ # HighLine.stub(:new).and_return(highline)
20
+ # highline.stub!(:ask).and_return('kswamin', 'dumbass')
21
+ # user_mock.stub!(:authenticate).and_return(true)
22
+ # user_mock.stub!(:write_to_file).and_return(true)
23
+ # STDOUT.should_receive(:puts).exactly(1).times.with('You were successfully authenticated.')
24
+ # auth_command = Evernotable::Command::Auth.new
25
+ # lambda {auth_command.send(:login)}.should_not raise_error(Evernotable::Command::CommandFailed)
26
+ # end
27
+
28
+ # it 'should fail authenticating the user' do
29
+ # user_mock = mock("Evernotable::Client::User")
30
+ # Evernotable::Client::User.stub(:new).and_return(user_mock)
31
+ # File.stub!(:exist?).and_return(true)
32
+ # File.stub!(:read).and_return('kswamin/wrongpass')
33
+ # user_mock.stub!(:authenticate).and_raise(Evernotable::Client::ClientException)
34
+ # auth_command = Evernotable::Command::Auth.new
35
+ # lambda {auth_command.send(:login)}.should raise_error(Evernotable::Command::CommandFailed)
36
+ # end
37
+ end
38
+
39
+ describe '#logout' do
40
+ it 'should log the user out successfully' do
41
+ File.stub!(:exist?).and_return(true)
42
+ File.stub!(:delete).and_return(true)
43
+ STDOUT.should_receive(:puts).exactly(1).times.with('You were successfully logged out.')
44
+ auth_command = Evernotable::Command::Auth.new
45
+ lambda {auth_command.send(:logout)}.should_not raise_error(Evernotable::Command::CommandFailed)
46
+ end
47
+
48
+ it 'should not log out if the user is not logged in already' do
49
+ File.stub!(:exist?).and_return(false)
50
+ STDOUT.should_receive(:puts).exactly(1).times.with(any_args())
51
+ auth_command = Evernotable::Command::Auth.new
52
+ lambda {auth_command.send(:logout)}.should_not raise_error(Evernotable::Command::CommandFailed)
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+ require 'evernotable/command/base'
3
+
4
+ describe Evernotable::Command::Base do
5
+ it 'should appropriately be initialized' do
6
+ base_command = Evernotable::Command::Base.new(['remove', '2'])
7
+ base_command.should_not be_nil
8
+ end
9
+
10
+ it 'should log the user in successfully using user input' do
11
+ user_mock = mock("Evernotable::Client::User")
12
+ Evernotable::Client::User.stub(:new).and_return(user_mock)
13
+ user_mock.stub!(:authenticate).and_return(true)
14
+ base_command = Evernotable::Command::Base.new
15
+ lambda {base_command.authenticate_user(['kswamin', 'dumbass'])}.should_not raise_error(Evernotable::Command::CommandFailed)
16
+ end
17
+
18
+ it 'should fail authenticating the user' do
19
+ user_mock = mock("Evernotable::Client::User")
20
+ Evernotable::Client::User.stub(:new).and_return(user_mock)
21
+ user_mock.stub!(:authenticate).and_raise(Evernotable::Client::ClientException)
22
+ base_command = Evernotable::Command::Base.new
23
+ lambda {base_command.authenticate_user(['kswamin', 'wrongpass'])}.should raise_error(Evernotable::Command::CommandFailed)
24
+ end
25
+
26
+ describe '#invoke client' do
27
+ it 'should invoke the client method without exceptions' do
28
+ base_command = Evernotable::Command::Base.new
29
+ base_command.invoke_client do
30
+ true
31
+ end.should_not raise_error(Evernotable::Command::CommandFailed)
32
+ end
33
+
34
+ it 'should invoke the client method resulting in exception' do
35
+ base_command = Evernotable::Command::Base.new
36
+ lambda do
37
+ base_command.invoke_client do
38
+ raise Evernotable::Client::ClientException
39
+ end
40
+ end.should raise_error(Evernotable::Command::CommandFailed)
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+ require 'evernotable/command/help'
3
+
4
+ describe Evernotable::Command::Help do
5
+ it 'displays useful information when help is invoked' do
6
+ help_command = Evernotable::Command::Help.new
7
+ help_command.should_not be_nil
8
+ STDOUT.should_receive(:puts).with(/Evernotable is a simple commandline/)
9
+ STDOUT.should_receive(:puts).with(/This automatically creates/)
10
+ lambda {help_command.send(:help)}.should_not raise_error(Evernotable::Command::CommandFailed)
11
+ end
12
+ end
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+ require 'evernotable/command/task'
3
+
4
+ describe Evernotable::Command::Task do
5
+ before(:all) do
6
+ @task_command = Evernotable::Command::Task.new(['dude!'])
7
+ end
8
+
9
+ it 'displays relevant information when help is invoked' do
10
+ @task_command.should_not be_nil
11
+ STDOUT.should_receive(:puts).exactly(5).times.with(any_args())
12
+ lambda {@task_command.send(:help)}.should_not raise_error(Evernotable::Command::CommandFailed)
13
+ end
14
+
15
+ it 'should add note successfully' do
16
+ mock_note_client = mock('Evernotable::Client::Note')
17
+ mock_note_client.stub!(:add_note).and_return(true)
18
+ @task_command.stub!(:note_client).and_return(mock_note_client)
19
+ STDOUT.should_receive(:puts).exactly(1).times.with('Done.')
20
+ lambda {@task_command.add}.should_not raise_error(Evernotable::Command::CommandFailed)
21
+ end
22
+
23
+ it 'should list notes successfully' do
24
+ mock_note_client = mock('Evernotable::Client::Note')
25
+ mock_note_client.stub!(:list_notes).and_return(['note1', 'note2'])
26
+ @task_command.stub!(:note_client).and_return(mock_note_client)
27
+ lambda {@task_command.list}.should_not raise_error(Evernotable::Command::CommandFailed)
28
+ end
29
+
30
+ it 'should remove note successfully' do
31
+ mock_note_client = mock('Evernotable::Client::Note')
32
+ mock_note_client.stub!(:remove_note).and_return(true)
33
+ @task_command.stub!(:note_client).and_return(mock_note_client)
34
+ STDOUT.should_receive(:puts).exactly(1).times.with('Done.')
35
+ lambda {@task_command.remove}.should_not raise_error(Evernotable::Command::CommandFailed)
36
+ end
37
+ end
@@ -0,0 +1,69 @@
1
+ require 'spec_helper'
2
+ require 'evernotable/command'
3
+
4
+ describe Evernotable::Command do
5
+ before(:all) do
6
+ Evernotable::Command.load
7
+ end
8
+
9
+ it 'should raise command failed error' do
10
+ begin
11
+ raise Evernotable::Command::CommandFailed, 'testing commandfailed'
12
+ rescue Evernotable::Command::CommandFailed => ex
13
+ ex.message.should == 'testing commandfailed'
14
+ ex.is_a?(Evernotable::Command::CommandFailed).should be_true
15
+ end
16
+ end
17
+
18
+ it 'should load all the commands successfully' do
19
+ Evernotable::Command::Base.should_not be_nil
20
+ Evernotable::Command::Auth.should_not be_nil
21
+ Evernotable::Command::Task.should_not be_nil
22
+ end
23
+
24
+ it 'should build the list of commands available' do
25
+ Evernotable::Command.commands.should =~ ['auth', 'base', 'task', 'help']
26
+ end
27
+
28
+ it 'should test valid' do
29
+ Evernotable::Command.valid?('auth').should be_true
30
+ Evernotable::Command.valid?('task').should be_true
31
+ Evernotable::Command.valid?('wrong-one').should be_false
32
+ end
33
+
34
+ describe '#run' do
35
+ it 'should display errors and exit on invalid command' do
36
+ STDOUT.should_receive(:puts).with("! *uncommand* is not a valid evernotable command.")
37
+ STDOUT.should_receive(:puts).with("! Use *evernotable help* for additional information.")
38
+ lambda { Evernotable::Command.run('uncommand') }.should raise_error(SystemExit)
39
+ end
40
+ it 'should display error and exit on blank command' do
41
+ STDOUT.should_receive(:puts).with("! Use *evernotable help* for additional information.")
42
+ lambda { Evernotable::Command.run('') }.should raise_error(SystemExit)
43
+ end
44
+ it 'should display error and exit on nil command' do
45
+ STDOUT.should_receive(:puts).with("! Use *evernotable help* for additional information.")
46
+ lambda { Evernotable::Command.run(nil) }.should raise_error(SystemExit)
47
+ end
48
+ it 'should instantiate the right command and invoke the appropriate method on it' do
49
+ auth_mock = mock("Evernotable::Command::Auth")
50
+ task_mock = mock("Evernotable::Command::Task")
51
+ help_mock = mock("Evernotable::Command::Help")
52
+ Evernotable::Command::Auth.stub(:new).and_return(auth_mock)
53
+ Evernotable::Command::Task.stub(:new).and_return(task_mock)
54
+ Evernotable::Command::Help.stub(:new).and_return(help_mock)
55
+ auth_mock.should_receive(:login).with(no_args())
56
+ auth_mock.should_receive(:logout).with(no_args())
57
+ lambda { Evernotable::Command.run('auth', ['login']) }.should_not raise_error(SystemExit)
58
+ lambda { Evernotable::Command.run('auth', ['logout']) }.should_not raise_error(SystemExit)
59
+ task_mock.should_receive(:add)
60
+ task_mock.should_receive(:remove)
61
+ task_mock.should_receive(:help)
62
+ help_mock.should_receive(:help)
63
+ lambda { Evernotable::Command.run('task', ['add', 'do this right away!']) }.should_not raise_error(SystemExit)
64
+ lambda { Evernotable::Command.run('task', ['remove', '3']) }.should_not raise_error(SystemExit)
65
+ lambda { Evernotable::Command.run('task') }.should_not raise_error(SystemExit)
66
+ lambda { Evernotable::Command.run('help') }.should_not raise_error(SystemExit)
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,48 @@
1
+ module DisplayMatcher
2
+
3
+ def display_message(command, message)
4
+ DisplayMessageMatcher::DisplayMessage.new command, message
5
+ end
6
+
7
+ class DisplayMessage
8
+ def initialize(command, message)
9
+ @command = command
10
+ @message = message
11
+ end
12
+
13
+ def matches?(given_proc)
14
+ displayed_expected_message = false
15
+ @given_messages = []
16
+
17
+ @command.should_receive(:display).
18
+ any_number_of_times do |message, newline|
19
+ @given_messages << message
20
+ displayed_expected_message = displayed_expected_message ||
21
+ message == @message
22
+ end
23
+
24
+ given_proc.call
25
+ displayed_expected_message
26
+ end
27
+
28
+ def failure_message
29
+ "expected #{ @command } to display the message #{ @message.inspect } but #{ given_messages }"
30
+ end
31
+
32
+ def negative_failure_message
33
+ "expected #{ @command } to not display the message #{ @message.inspect } but it was displayed"
34
+ end
35
+
36
+ private
37
+
38
+ def given_messages
39
+ if @given_messages.empty?
40
+ 'no messages were displayed'
41
+ else
42
+ formatted_given_messages = @given_messages.map(&:inspect).join ', '
43
+ "the following messages were displayed: #{ formatted_given_messages }"
44
+ end
45
+ end
46
+
47
+ end
48
+ end
@@ -0,0 +1,16 @@
1
+ $stdin = File.new("/dev/null")
2
+
3
+ require "rubygems"
4
+ require "bundler/setup"
5
+ require "rspec"
6
+ require 'highline'
7
+ require "display_matcher"
8
+
9
+ def fail_command(message)
10
+ raise_error(Evernotable::Command::CommandFailed, message)
11
+ end
12
+
13
+ RSpec.configure do |config|
14
+ config.color_enabled = true
15
+ config.include DisplayMatcher
16
+ end
@@ -0,0 +1,39 @@
1
+ require 'evernotable/utilities'
2
+
3
+ describe Evernotable::Utilities do
4
+ include Evernotable::Utilities
5
+ it 'should test format message with bang' do
6
+ format_with_bang('').should == ''
7
+ format_with_bang('hello there').should == '! hello there'
8
+ format_with_bang("hello there\nWhats up?").should == "! hello there\n ! Whats up?"
9
+ end
10
+
11
+ it 'should test display message' do
12
+ STDOUT.should_receive(:puts).with("hello there")
13
+ display('hello there', true)
14
+ STDOUT.should_receive(:print).with("hello there")
15
+ display('hello there', false)
16
+ end
17
+
18
+ it 'should test output with bang' do
19
+ STDOUT.should_receive(:puts).with("! hello there is a problem")
20
+ output_with_bang('hello there is a problem')
21
+ STDOUT.should_receive(:print).with("! hello there")
22
+ output_with_bang('hello there', false)
23
+ end
24
+
25
+ it 'should test error display' do
26
+ STDERR.should_receive(:puts).with('')
27
+ lambda {error(nil)}.should raise_error(SystemExit)
28
+ STDERR.should_receive(:puts).with("! error thrown")
29
+ lambda {error('error thrown')}.should raise_error(SystemExit)
30
+ end
31
+
32
+ it 'should wrap enml content around a string' do
33
+ wrap_enml('test').should == "<?xml version='1.0' encoding='UTF-8'?><!DOCTYPE en-note SYSTEM 'http://xml.evernote.com/pub/enml2.dtd'><en-note>test</en-note>"
34
+ end
35
+
36
+ it 'should return encrypt_key' do
37
+ encrypt_key.should_not be_nil
38
+ end
39
+ end
@@ -0,0 +1,8 @@
1
+ require "spec_helper"
2
+ require "evernotable/version"
3
+
4
+ describe Evernotable do
5
+ it 'returns the correct version of the gem' do
6
+ Evernotable::VERSION.should == '1.0.0'
7
+ end
8
+ end
metadata ADDED
@@ -0,0 +1,158 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: evernotable
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Karthik Muthupalaniappan
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-02-29 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: thrift
16
+ requirement: &70349991702640 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70349991702640
25
+ - !ruby/object:Gem::Dependency
26
+ name: thrift_client
27
+ requirement: &70349991702220 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70349991702220
36
+ - !ruby/object:Gem::Dependency
37
+ name: evernote
38
+ requirement: &70349991701800 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :runtime
45
+ prerelease: false
46
+ version_requirements: *70349991701800
47
+ - !ruby/object:Gem::Dependency
48
+ name: highline
49
+ requirement: &70349991701380 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :runtime
56
+ prerelease: false
57
+ version_requirements: *70349991701380
58
+ - !ruby/object:Gem::Dependency
59
+ name: encrypted_strings
60
+ requirement: &70349991700960 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :runtime
67
+ prerelease: false
68
+ version_requirements: *70349991700960
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: &70349991700540 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *70349991700540
80
+ description: A simple commandline task manager that uses Evernote note store. This
81
+ automatically creates a new distinct Evernote notebook for persistance of these
82
+ task notes.
83
+ email:
84
+ - karthik.m@imaginea.com
85
+ executables:
86
+ - evernotable
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - .gitignore
91
+ - Gemfile
92
+ - README.rdoc
93
+ - Rakefile
94
+ - bin/evernotable
95
+ - evernotable.gemspec
96
+ - lib/evernotable.rb
97
+ - lib/evernotable/cli.rb
98
+ - lib/evernotable/client.rb
99
+ - lib/evernotable/client/base.rb
100
+ - lib/evernotable/client/note.rb
101
+ - lib/evernotable/client/user.rb
102
+ - lib/evernotable/command.rb
103
+ - lib/evernotable/command/auth.rb
104
+ - lib/evernotable/command/base.rb
105
+ - lib/evernotable/command/help.rb
106
+ - lib/evernotable/command/task.rb
107
+ - lib/evernotable/utilities.rb
108
+ - lib/evernotable/version.rb
109
+ - lib/evernotable_config.yml
110
+ - spec/client/base_spec.rb
111
+ - spec/client/note_spec.rb
112
+ - spec/client/user_spec.rb
113
+ - spec/command/auth_spec.rb
114
+ - spec/command/base_spec.rb
115
+ - spec/command/help_spec.rb
116
+ - spec/command/task_spec.rb
117
+ - spec/command_spec.rb
118
+ - spec/display_matcher.rb
119
+ - spec/spec_helper.rb
120
+ - spec/utilities_spec.rb
121
+ - spec/version_spec.rb
122
+ homepage: http://intellisenze.wordpress.com
123
+ licenses: []
124
+ post_install_message:
125
+ rdoc_options: []
126
+ require_paths:
127
+ - lib
128
+ required_ruby_version: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ! '>='
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ required_rubygems_version: !ruby/object:Gem::Requirement
135
+ none: false
136
+ requirements:
137
+ - - ! '>='
138
+ - !ruby/object:Gem::Version
139
+ version: '0'
140
+ requirements: []
141
+ rubyforge_project: evernotable
142
+ rubygems_version: 1.8.10
143
+ signing_key:
144
+ specification_version: 3
145
+ summary: A simple commandline task manager that uses Evernote note store
146
+ test_files:
147
+ - spec/client/base_spec.rb
148
+ - spec/client/note_spec.rb
149
+ - spec/client/user_spec.rb
150
+ - spec/command/auth_spec.rb
151
+ - spec/command/base_spec.rb
152
+ - spec/command/help_spec.rb
153
+ - spec/command/task_spec.rb
154
+ - spec/command_spec.rb
155
+ - spec/display_matcher.rb
156
+ - spec/spec_helper.rb
157
+ - spec/utilities_spec.rb
158
+ - spec/version_spec.rb