delicious-cli 0.1.1
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.
- data/LICENSE +20 -0
- data/README.rdoc +63 -0
- data/bin/dels +6 -0
- data/lib/delicious-cli/api.rb +36 -0
- data/lib/delicious-cli/db.rb +113 -0
- data/lib/delicious-cli/display.rb +51 -0
- data/lib/delicious-cli/log.rb +7 -0
- data/lib/delicious-cli/settings.rb +60 -0
- data/lib/delicious-cli.rb +156 -0
- data/test/delicious-cli_test.rb +7 -0
- data/test/test_helper.rb +10 -0
- metadata +93 -0
    
        data/LICENSE
    ADDED
    
    | @@ -0,0 +1,20 @@ | |
| 1 | 
            +
            Copyright (c) 2009 Chris Gahan
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            Permission is hereby granted, free of charge, to any person obtaining
         | 
| 4 | 
            +
            a copy of this software and associated documentation files (the
         | 
| 5 | 
            +
            "Software"), to deal in the Software without restriction, including
         | 
| 6 | 
            +
            without limitation the rights to use, copy, modify, merge, publish,
         | 
| 7 | 
            +
            distribute, sublicense, and/or sell copies of the Software, and to
         | 
| 8 | 
            +
            permit persons to whom the Software is furnished to do so, subject to
         | 
| 9 | 
            +
            the following conditions:
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            The above copyright notice and this permission notice shall be
         | 
| 12 | 
            +
            included in all copies or substantial portions of the Software.
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
         | 
| 15 | 
            +
            EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
         | 
| 16 | 
            +
            MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
         | 
| 17 | 
            +
            NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
         | 
| 18 | 
            +
            LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
         | 
| 19 | 
            +
            OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
         | 
| 20 | 
            +
            WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
         | 
    
        data/README.rdoc
    ADDED
    
    | @@ -0,0 +1,63 @@ | |
| 1 | 
            +
            = delicious-cli
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            Locally mirror your delicious links, then search them. Example:
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                dels <search query>
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            == Installation
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                gem sources --add http://gemcutter.org
         | 
| 10 | 
            +
                gem install delicious-cli
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            == Example:
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            === Setting your delicious username/password:
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                epi@fizz$ dels -c
         | 
| 17 | 
            +
                
         | 
| 18 | 
            +
                Delicious login info
         | 
| 19 | 
            +
                ---------------------------
         | 
| 20 | 
            +
                
         | 
| 21 | 
            +
                Username: mydeliciouslogin
         | 
| 22 | 
            +
                Password: mypassword
         | 
| 23 | 
            +
                
         | 
| 24 | 
            +
                User: "mydeliciouslogin" | Pass: "mypassword"
         | 
| 25 | 
            +
                Is this correct? [y/N] y
         | 
| 26 | 
            +
                
         | 
| 27 | 
            +
                * Checking that login/password works...
         | 
| 28 | 
            +
                  |_ Login successful! Saving config...
         | 
| 29 | 
            +
             | 
| 30 | 
            +
             | 
| 31 | 
            +
            === Downloading all your delicious links:
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                epi@fizz$ dels -r
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                * Redownloading database...
         | 
| 36 | 
            +
                * Retrieving all links... (3465 links found)
         | 
| 37 | 
            +
                * Inserting links into database...done!
         | 
| 38 | 
            +
             | 
| 39 | 
            +
            === Downloading new links (since last sync):
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                epi@fizz$ dels -s
         | 
| 42 | 
            +
                
         | 
| 43 | 
            +
                * Synchronizing database...
         | 
| 44 | 
            +
                * Retrieving new links... (5 links found)
         | 
| 45 | 
            +
                * Inserting links into database...done!
         | 
| 46 | 
            +
             | 
| 47 | 
            +
            == Commandline options:
         | 
| 48 | 
            +
             | 
| 49 | 
            +
            Usage: dels [options] <search query>
         | 
| 50 | 
            +
             | 
| 51 | 
            +
            Specific options:
         | 
| 52 | 
            +
                -d, --debug                      Debug info
         | 
| 53 | 
            +
                -s, --sync                       Synchronize links
         | 
| 54 | 
            +
                -r, --redownload                 Erase database and redownload all links
         | 
| 55 | 
            +
                -c, --config                     Configure app (set delicious username/password)
         | 
| 56 | 
            +
                -t, --test-auth                  Test that authentication info works
         | 
| 57 | 
            +
             | 
| 58 | 
            +
            Common options:
         | 
| 59 | 
            +
                -h, --help                       Show this message
         | 
| 60 | 
            +
             | 
| 61 | 
            +
            == Copyright
         | 
| 62 | 
            +
             | 
| 63 | 
            +
            Copyright (c) 2009 Chris Gahan. See LICENSE for details.
         | 
    
        data/bin/dels
    ADDED
    
    
| @@ -0,0 +1,36 @@ | |
| 1 | 
            +
            require 'httparty'
         | 
| 2 | 
            +
            require 'delicious-cli/settings'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            # Documentation:
         | 
| 5 | 
            +
            #   http://delicious.com/help/api
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            class Delicious
         | 
| 8 | 
            +
              include HTTParty
         | 
| 9 | 
            +
              base_uri 'api.del.icio.us:443/v1'
         | 
| 10 | 
            +
              format :xml
         | 
| 11 | 
            +
             | 
| 12 | 
            +
              def self.posts_update
         | 
| 13 | 
            +
                result = get('/posts/update')
         | 
| 14 | 
            +
                if result["update"]
         | 
| 15 | 
            +
                  result["update"]["time"]
         | 
| 16 | 
            +
                else
         | 
| 17 | 
            +
                  nil
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
              end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
              def self.posts_all(options={})
         | 
| 22 | 
            +
                result = get('/posts/all', :query=>options)
         | 
| 23 | 
            +
                [result["posts"]["post"]].flatten  # ensure it's an array
         | 
| 24 | 
            +
              end
         | 
| 25 | 
            +
              
         | 
| 26 | 
            +
              def self.posts_since(time)
         | 
| 27 | 
            +
                $log.debug "Retrieving links newer than #{time}"
         | 
| 28 | 
            +
                results = posts_all(:fromdt=>time)
         | 
| 29 | 
            +
                results.select { |r| r["time"] != time }
         | 
| 30 | 
            +
              end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
              def self.valid_auth?
         | 
| 33 | 
            +
                not posts_update.nil?
         | 
| 34 | 
            +
              end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
            end
         | 
| @@ -0,0 +1,113 @@ | |
| 1 | 
            +
            require 'sequel'
         | 
| 2 | 
            +
            require 'sequel/extensions/blank'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            require 'delicious-cli/settings'
         | 
| 5 | 
            +
            require 'delicious-cli/api'
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            #################################################################
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            $log.debug "Loading database..."
         | 
| 10 | 
            +
            DB = Sequel.sqlite(configfile('delicious.db'))
         | 
| 11 | 
            +
            $log.debug "done."
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            #################################################################
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            =begin
         | 
| 16 | 
            +
            Sample record:
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            {
         | 
| 19 | 
            +
              "href"=>"http://guru.com/",
         | 
| 20 | 
            +
              "time"=>"2009-04-24T06:06:37Z",
         | 
| 21 | 
            +
              "hash"=>"80e9a5f0bccb7f9e9dfd2e309eabd7de",
         | 
| 22 | 
            +
              "tag"=>"jobs business freelance employment outsourcing exchanges networking",
         | 
| 23 | 
            +
              "meta"=>"485e955fe2937fbef85390623ad0984c",
         | 
| 24 | 
            +
              "description"=>"Guru.com",
         | 
| 25 | 
            +
              "extended"=>"Worldwide freelancer marketplace."
         | 
| 26 | 
            +
            }
         | 
| 27 | 
            +
            =end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
            #################################################################
         | 
| 30 | 
            +
             | 
| 31 | 
            +
            class Database
         | 
| 32 | 
            +
              @@posts = DB[:posts]
         | 
| 33 | 
            +
             | 
| 34 | 
            +
              def self.init!
         | 
| 35 | 
            +
                create_posts! unless DB.table_exists?(:posts)
         | 
| 36 | 
            +
              end  
         | 
| 37 | 
            +
             | 
| 38 | 
            +
              def self.clear!
         | 
| 39 | 
            +
                DB.drop_table(:posts)
         | 
| 40 | 
            +
                create_posts!
         | 
| 41 | 
            +
              end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
              def self.create_posts!
         | 
| 44 | 
            +
                DB.create_table :posts do
         | 
| 45 | 
            +
                  primary_key :id
         | 
| 46 | 
            +
                  
         | 
| 47 | 
            +
                  string :href
         | 
| 48 | 
            +
                  string :time
         | 
| 49 | 
            +
                  string :tag
         | 
| 50 | 
            +
                  string :description
         | 
| 51 | 
            +
                  text :extended
         | 
| 52 | 
            +
                  string :hash
         | 
| 53 | 
            +
                  string :meta
         | 
| 54 | 
            +
                  
         | 
| 55 | 
            +
                  index :hash, {:unique=>true}
         | 
| 56 | 
            +
                  index [:description, :extended, :tag]
         | 
| 57 | 
            +
                end
         | 
| 58 | 
            +
              end
         | 
| 59 | 
            +
              
         | 
| 60 | 
            +
              def self.sync(all=false)
         | 
| 61 | 
            +
                all = true if @@posts.empty?
         | 
| 62 | 
            +
                
         | 
| 63 | 
            +
                if all
         | 
| 64 | 
            +
                  print "* Retrieving all links..."
         | 
| 65 | 
            +
                  STDOUT.flush
         | 
| 66 | 
            +
                  posts = Delicious.posts_all
         | 
| 67 | 
            +
                else
         | 
| 68 | 
            +
                  print "* Retrieving new links..."
         | 
| 69 | 
            +
                  STDOUT.flush
         | 
| 70 | 
            +
                  posts = Delicious.posts_since(most_recent_time)
         | 
| 71 | 
            +
                end      
         | 
| 72 | 
            +
                
         | 
| 73 | 
            +
                $log.debug "sync: got #{posts.size} posts"
         | 
| 74 | 
            +
                
         | 
| 75 | 
            +
                puts " (#{posts.size} links found)"
         | 
| 76 | 
            +
                
         | 
| 77 | 
            +
                return if posts.empty?
         | 
| 78 | 
            +
                
         | 
| 79 | 
            +
                print "* Inserting links into database..."
         | 
| 80 | 
            +
                
         | 
| 81 | 
            +
                counter = 0
         | 
| 82 | 
            +
                for post in posts
         | 
| 83 | 
            +
                  counter += 1
         | 
| 84 | 
            +
                  begin
         | 
| 85 | 
            +
                    add post
         | 
| 86 | 
            +
                  rescue Sequel::DatabaseError => e
         | 
| 87 | 
            +
                    $log.debug "error: #{e} adding #{post.inspect}"
         | 
| 88 | 
            +
                  end
         | 
| 89 | 
            +
                  
         | 
| 90 | 
            +
                  if counter % 37 == 0
         | 
| 91 | 
            +
                    print "."
         | 
| 92 | 
            +
                    STDOUT.flush
         | 
| 93 | 
            +
                  end
         | 
| 94 | 
            +
                end
         | 
| 95 | 
            +
                
         | 
| 96 | 
            +
                puts "done!"
         | 
| 97 | 
            +
              end
         | 
| 98 | 
            +
              
         | 
| 99 | 
            +
              def self.most_recent_time
         | 
| 100 | 
            +
                @@posts.order(:time.desc).limit(1).first[:time]
         | 
| 101 | 
            +
              end
         | 
| 102 | 
            +
              
         | 
| 103 | 
            +
              def self.add(params)
         | 
| 104 | 
            +
                @@posts << params
         | 
| 105 | 
            +
              end
         | 
| 106 | 
            +
              
         | 
| 107 | 
            +
              def self.find(query)
         | 
| 108 | 
            +
                query = "%#{query}%" if query.is_a? String
         | 
| 109 | 
            +
                @@posts.filter(:extended.like(query) | :description.like(query) | :tag.like(query)).order(:time)
         | 
| 110 | 
            +
              end
         | 
| 111 | 
            +
              
         | 
| 112 | 
            +
              
         | 
| 113 | 
            +
            end
         | 
| @@ -0,0 +1,51 @@ | |
| 1 | 
            +
            require 'date'
         | 
| 2 | 
            +
            require 'colorize'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            #################################################################
         | 
| 5 | 
            +
            ## Load the colorize gem, and define the "hilite" function
         | 
| 6 | 
            +
            begin
         | 
| 7 | 
            +
              require 'rubygems'
         | 
| 8 | 
            +
              require 'colorize'
         | 
| 9 | 
            +
              # Colourized hilite...
         | 
| 10 | 
            +
              class String
         | 
| 11 | 
            +
                def hilite(query, color=:white)
         | 
| 12 | 
            +
                  query = Regexp.new( Regexp.escape(query), Regexp::IGNORECASE )
         | 
| 13 | 
            +
                  self.to_s.send(color).gsub(/(.*)(#{query})(.*)/) { $1.send(color) + $2.black.on_yellow + $3.send(color)}
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
            rescue LoadError
         | 
| 17 | 
            +
              STDERR.puts "Note: You should install the 'colorize' gem for extra prettiness.\n"
         | 
| 18 | 
            +
              # Monochrome hilite does nothing...
         | 
| 19 | 
            +
              class String
         | 
| 20 | 
            +
                def hilite(query); self; end
         | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
            end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
            #################################################################
         | 
| 25 | 
            +
             | 
| 26 | 
            +
            def formatdate(date, width=11)
         | 
| 27 | 
            +
              dt = DateTime.parse(date)
         | 
| 28 | 
            +
              time = "%l:%M%P"
         | 
| 29 | 
            +
              date = "%d %b %g"
         | 
| 30 | 
            +
              #dt.strftime("#{date} #{time}")
         | 
| 31 | 
            +
              result = dt.strftime(date)
         | 
| 32 | 
            +
              
         | 
| 33 | 
            +
              result.ljust(width).light_yellow
         | 
| 34 | 
            +
            end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
             | 
| 37 | 
            +
            def display(post, query, indent_size=11)
         | 
| 38 | 
            +
              indent = " " * indent_size
         | 
| 39 | 
            +
             | 
| 40 | 
            +
              date   = formatdate(post[:time], indent_size)
         | 
| 41 | 
            +
              desc   = post[:description].hilite(query, :light_white)
         | 
| 42 | 
            +
              ext    = post[:extended].hilite(query, :white)
         | 
| 43 | 
            +
              url    = post[:href].hilite(query, :light_blue)
         | 
| 44 | 
            +
              tags   = post[:tag].hilite(query, :light_cyan)
         | 
| 45 | 
            +
             | 
| 46 | 
            +
              puts date + desc
         | 
| 47 | 
            +
              puts indent + ext if post[:extended].any?
         | 
| 48 | 
            +
              puts indent + url
         | 
| 49 | 
            +
              puts indent + "(".cyan + tags + ")".cyan
         | 
| 50 | 
            +
              puts
         | 
| 51 | 
            +
            end
         | 
| @@ -0,0 +1,60 @@ | |
| 1 | 
            +
            require 'fileutils'
         | 
| 2 | 
            +
            require 'yaml'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            require 'delicious-cli/log'
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            #################################################################
         | 
| 7 | 
            +
            HOMEDIR    = File.expand_path("~")
         | 
| 8 | 
            +
            CONFIGDIR  = File.join(HOMEDIR, ".delicious")
         | 
| 9 | 
            +
            #################################################################
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            #################################################################
         | 
| 12 | 
            +
            class FileNotFound < IOError; end
         | 
| 13 | 
            +
            #################################################################
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            #################################################################
         | 
| 16 | 
            +
            def configfile(filename, check=false)
         | 
| 17 | 
            +
              path = File.join(CONFIGDIR, filename)
         | 
| 18 | 
            +
              
         | 
| 19 | 
            +
              if check and not File.exists? path
         | 
| 20 | 
            +
                raise FileNotFound, path
         | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
              
         | 
| 23 | 
            +
              path
         | 
| 24 | 
            +
            end
         | 
| 25 | 
            +
            #################################################################
         | 
| 26 | 
            +
             | 
| 27 | 
            +
             | 
| 28 | 
            +
             | 
| 29 | 
            +
            #################################################################
         | 
| 30 | 
            +
             | 
| 31 | 
            +
            unless File.exists? CONFIGDIR
         | 
| 32 | 
            +
              $log.info "* Creating new config directory: #{CONFIGDIR}"
         | 
| 33 | 
            +
              FileUtils.mkdir_p CONFIGDIR 
         | 
| 34 | 
            +
            end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
            class Settings
         | 
| 37 | 
            +
              
         | 
| 38 | 
            +
              def self.settings
         | 
| 39 | 
            +
                @settings ||= {}
         | 
| 40 | 
            +
              end
         | 
| 41 | 
            +
              
         | 
| 42 | 
            +
              def self.[](key)
         | 
| 43 | 
            +
                settings[key]
         | 
| 44 | 
            +
              end
         | 
| 45 | 
            +
              
         | 
| 46 | 
            +
              def self.[]=(key, val)
         | 
| 47 | 
            +
                settings[key] = val
         | 
| 48 | 
            +
              end  
         | 
| 49 | 
            +
              
         | 
| 50 | 
            +
              def self.load!
         | 
| 51 | 
            +
                @settings = YAML::load_file( configfile('settings.yml') )
         | 
| 52 | 
            +
              end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
              def self.save!
         | 
| 55 | 
            +
                open( configfile('settings.yml'), "w" ) do |f|
         | 
| 56 | 
            +
                  f.write YAML::dump(settings)
         | 
| 57 | 
            +
                end
         | 
| 58 | 
            +
              end
         | 
| 59 | 
            +
              
         | 
| 60 | 
            +
            end
         | 
| @@ -0,0 +1,156 @@ | |
| 1 | 
            +
            #!/usr/bin/env ruby
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            #################################################################
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            require "delicious-cli/log"
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            libs = %w[
         | 
| 8 | 
            +
              rubygems
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              optparse
         | 
| 11 | 
            +
              optparse/time
         | 
| 12 | 
            +
              ostruct
         | 
| 13 | 
            +
             | 
| 14 | 
            +
              delicious-cli/db
         | 
| 15 | 
            +
              delicious-cli/display
         | 
| 16 | 
            +
              delicious-cli/api
         | 
| 17 | 
            +
              delicious-cli/settings
         | 
| 18 | 
            +
            ]
         | 
| 19 | 
            +
             | 
| 20 | 
            +
            libs.each do |lib|
         | 
| 21 | 
            +
              #$log.debug "loading #{lib}"
         | 
| 22 | 
            +
              require lib
         | 
| 23 | 
            +
            end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
            #################################################################
         | 
| 26 | 
            +
             | 
| 27 | 
            +
            def search(query)
         | 
| 28 | 
            +
              matches = Database.find(query)
         | 
| 29 | 
            +
              matches.each { |match| display(match, query) }
         | 
| 30 | 
            +
            end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
            def sync
         | 
| 33 | 
            +
              puts "* Synchronizing database..."
         | 
| 34 | 
            +
              Database.sync
         | 
| 35 | 
            +
            end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
            def redownload
         | 
| 38 | 
            +
              puts "* Redownloading database..."
         | 
| 39 | 
            +
              Database.clear!
         | 
| 40 | 
            +
              Database.sync
         | 
| 41 | 
            +
            end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
            def config
         | 
| 44 | 
            +
              # prompt user and stuff
         | 
| 45 | 
            +
              puts "Delicious login info"
         | 
| 46 | 
            +
              puts "---------------------------"
         | 
| 47 | 
            +
              puts
         | 
| 48 | 
            +
              print "Username: "
         | 
| 49 | 
            +
              username = gets.strip
         | 
| 50 | 
            +
              print "Password: "
         | 
| 51 | 
            +
              password = gets.strip
         | 
| 52 | 
            +
              
         | 
| 53 | 
            +
              puts
         | 
| 54 | 
            +
              puts "User: #{username.inspect} | Pass: #{password.inspect}"
         | 
| 55 | 
            +
              print "Is this correct? [y/N] "
         | 
| 56 | 
            +
              answer = gets.strip
         | 
| 57 | 
            +
              if answer =~ /^[Yy]$/
         | 
| 58 | 
            +
                puts 
         | 
| 59 | 
            +
                
         | 
| 60 | 
            +
                puts "* Checking that login/password works..."
         | 
| 61 | 
            +
                Delicious.basic_auth(username, password)
         | 
| 62 | 
            +
                if Delicious.valid_auth?    
         | 
| 63 | 
            +
                  puts "  |_ Login successful! Saving config..."
         | 
| 64 | 
            +
                  Settings["username"] = username
         | 
| 65 | 
            +
                  Settings["password"] = password
         | 
| 66 | 
            +
                  Settings.save!
         | 
| 67 | 
            +
                else
         | 
| 68 | 
            +
                  puts "  |_ Login failed! (Please check your credentials or network.)"
         | 
| 69 | 
            +
                end
         | 
| 70 | 
            +
                puts
         | 
| 71 | 
            +
              else
         | 
| 72 | 
            +
                puts "Aborting..."
         | 
| 73 | 
            +
              end
         | 
| 74 | 
            +
            end
         | 
| 75 | 
            +
             | 
| 76 | 
            +
             | 
| 77 | 
            +
            #################################################################
         | 
| 78 | 
            +
             | 
| 79 | 
            +
            def main
         | 
| 80 | 
            +
             | 
| 81 | 
            +
              # In it!
         | 
| 82 | 
            +
              
         | 
| 83 | 
            +
              Database.init!
         | 
| 84 | 
            +
              Settings.load!
         | 
| 85 | 
            +
              
         | 
| 86 | 
            +
              Delicious.basic_auth(Settings["username"], Settings["password"])
         | 
| 87 | 
            +
             | 
| 88 | 
            +
              # Parse de opts
         | 
| 89 | 
            +
              
         | 
| 90 | 
            +
              ARGV.push("--help") if ARGV.empty?
         | 
| 91 | 
            +
              
         | 
| 92 | 
            +
              options = OpenStruct.new
         | 
| 93 | 
            +
              OptionParser.new do |opts|
         | 
| 94 | 
            +
                opts.banner = "Usage: dels [options] <search query>"
         | 
| 95 | 
            +
                opts.separator ""
         | 
| 96 | 
            +
                opts.separator "Specific options:"
         | 
| 97 | 
            +
                
         | 
| 98 | 
            +
                opts.on("-d", "--debug", "Debug info") do |opt|
         | 
| 99 | 
            +
                  options.debug = true
         | 
| 100 | 
            +
                end
         | 
| 101 | 
            +
              
         | 
| 102 | 
            +
                opts.on("-s", "--sync", "Synchronize links") do |opt|
         | 
| 103 | 
            +
                  options.sync = true
         | 
| 104 | 
            +
                end
         | 
| 105 | 
            +
              
         | 
| 106 | 
            +
                opts.on("-r", "--redownload", "Erase database and redownload all links") do |opt|
         | 
| 107 | 
            +
                  options.redownload = true
         | 
| 108 | 
            +
                end
         | 
| 109 | 
            +
              
         | 
| 110 | 
            +
                opts.on("-c", "--config", "Configure app (set delicious username/password)") do |opt|
         | 
| 111 | 
            +
                  options.config = true
         | 
| 112 | 
            +
                end
         | 
| 113 | 
            +
             | 
| 114 | 
            +
                opts.on("-t", "--test-auth", "Test that authentication info works") do |opt|
         | 
| 115 | 
            +
                  options.test_auth = true 
         | 
| 116 | 
            +
                end
         | 
| 117 | 
            +
             | 
| 118 | 
            +
             | 
| 119 | 
            +
                opts.separator ""
         | 
| 120 | 
            +
                opts.separator "Common options:"
         | 
| 121 | 
            +
             | 
| 122 | 
            +
                # No argument, shows at tail.  This will print an options summary.
         | 
| 123 | 
            +
                # Try it and see!
         | 
| 124 | 
            +
                opts.on_tail("-h", "--help", "Show this message") do
         | 
| 125 | 
            +
                  puts opts
         | 
| 126 | 
            +
                  puts
         | 
| 127 | 
            +
                  exit
         | 
| 128 | 
            +
                end
         | 
| 129 | 
            +
                
         | 
| 130 | 
            +
              end.parse!
         | 
| 131 | 
            +
              
         | 
| 132 | 
            +
              
         | 
| 133 | 
            +
              # Handle options
         | 
| 134 | 
            +
             | 
| 135 | 
            +
              $log.level = Logger::DEBUG if options.debug
         | 
| 136 | 
            +
               
         | 
| 137 | 
            +
              if options.test_auth
         | 
| 138 | 
            +
                puts "Logging in as '#{Settings["username"]}': #{Delicious.valid_auth? ? "success!" : "fail!"}"
         | 
| 139 | 
            +
              elsif options.config 
         | 
| 140 | 
            +
                config
         | 
| 141 | 
            +
              elsif options.redownload
         | 
| 142 | 
            +
                redownload
         | 
| 143 | 
            +
              elsif options.sync
         | 
| 144 | 
            +
                sync
         | 
| 145 | 
            +
              else
         | 
| 146 | 
            +
                exit 1 unless query = ARGV[0]
         | 
| 147 | 
            +
                query = ARGV[0]
         | 
| 148 | 
            +
                search(query)
         | 
| 149 | 
            +
              end
         | 
| 150 | 
            +
              
         | 
| 151 | 
            +
            end
         | 
| 152 | 
            +
             | 
| 153 | 
            +
             | 
| 154 | 
            +
            if $0 == __FILE__
         | 
| 155 | 
            +
              main
         | 
| 156 | 
            +
            end
         | 
    
        data/test/test_helper.rb
    ADDED
    
    
    
        metadata
    ADDED
    
    | @@ -0,0 +1,93 @@ | |
| 1 | 
            +
            --- !ruby/object:Gem::Specification 
         | 
| 2 | 
            +
            name: delicious-cli
         | 
| 3 | 
            +
            version: !ruby/object:Gem::Version 
         | 
| 4 | 
            +
              version: 0.1.1
         | 
| 5 | 
            +
            platform: ruby
         | 
| 6 | 
            +
            authors: 
         | 
| 7 | 
            +
            - epitron
         | 
| 8 | 
            +
            autorequire: 
         | 
| 9 | 
            +
            bindir: bin
         | 
| 10 | 
            +
            cert_chain: []
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            date: 2009-08-29 00:00:00 -04:00
         | 
| 13 | 
            +
            default_executable: dels
         | 
| 14 | 
            +
            dependencies: 
         | 
| 15 | 
            +
            - !ruby/object:Gem::Dependency 
         | 
| 16 | 
            +
              name: sequel
         | 
| 17 | 
            +
              type: :runtime
         | 
| 18 | 
            +
              version_requirement: 
         | 
| 19 | 
            +
              version_requirements: !ruby/object:Gem::Requirement 
         | 
| 20 | 
            +
                requirements: 
         | 
| 21 | 
            +
                - - ">="
         | 
| 22 | 
            +
                  - !ruby/object:Gem::Version 
         | 
| 23 | 
            +
                    version: "0"
         | 
| 24 | 
            +
                version: 
         | 
| 25 | 
            +
            - !ruby/object:Gem::Dependency 
         | 
| 26 | 
            +
              name: httparty
         | 
| 27 | 
            +
              type: :runtime
         | 
| 28 | 
            +
              version_requirement: 
         | 
| 29 | 
            +
              version_requirements: !ruby/object:Gem::Requirement 
         | 
| 30 | 
            +
                requirements: 
         | 
| 31 | 
            +
                - - ">="
         | 
| 32 | 
            +
                  - !ruby/object:Gem::Version 
         | 
| 33 | 
            +
                    version: "0"
         | 
| 34 | 
            +
                version: 
         | 
| 35 | 
            +
            - !ruby/object:Gem::Dependency 
         | 
| 36 | 
            +
              name: colorize
         | 
| 37 | 
            +
              type: :runtime
         | 
| 38 | 
            +
              version_requirement: 
         | 
| 39 | 
            +
              version_requirements: !ruby/object:Gem::Requirement 
         | 
| 40 | 
            +
                requirements: 
         | 
| 41 | 
            +
                - - ">="
         | 
| 42 | 
            +
                  - !ruby/object:Gem::Version 
         | 
| 43 | 
            +
                    version: "0"
         | 
| 44 | 
            +
                version: 
         | 
| 45 | 
            +
            description: A commandline tool which lets you download all your delicious.com links into a local SQLite database and search them (with pretty color-coded results).
         | 
| 46 | 
            +
            email: chris@ill-logic.com
         | 
| 47 | 
            +
            executables: 
         | 
| 48 | 
            +
            - dels
         | 
| 49 | 
            +
            extensions: []
         | 
| 50 | 
            +
             | 
| 51 | 
            +
            extra_rdoc_files: 
         | 
| 52 | 
            +
            - LICENSE
         | 
| 53 | 
            +
            - README.rdoc
         | 
| 54 | 
            +
            files: 
         | 
| 55 | 
            +
            - lib/delicious-cli.rb
         | 
| 56 | 
            +
            - lib/delicious-cli/api.rb
         | 
| 57 | 
            +
            - lib/delicious-cli/db.rb
         | 
| 58 | 
            +
            - lib/delicious-cli/display.rb
         | 
| 59 | 
            +
            - lib/delicious-cli/log.rb
         | 
| 60 | 
            +
            - lib/delicious-cli/settings.rb
         | 
| 61 | 
            +
            - LICENSE
         | 
| 62 | 
            +
            - README.rdoc
         | 
| 63 | 
            +
            has_rdoc: true
         | 
| 64 | 
            +
            homepage: http://github.com/epitron/delicious-cli
         | 
| 65 | 
            +
            licenses: []
         | 
| 66 | 
            +
             | 
| 67 | 
            +
            post_install_message: 
         | 
| 68 | 
            +
            rdoc_options: 
         | 
| 69 | 
            +
            - --charset=UTF-8
         | 
| 70 | 
            +
            require_paths: 
         | 
| 71 | 
            +
            - lib
         | 
| 72 | 
            +
            required_ruby_version: !ruby/object:Gem::Requirement 
         | 
| 73 | 
            +
              requirements: 
         | 
| 74 | 
            +
              - - ">="
         | 
| 75 | 
            +
                - !ruby/object:Gem::Version 
         | 
| 76 | 
            +
                  version: "0"
         | 
| 77 | 
            +
              version: 
         | 
| 78 | 
            +
            required_rubygems_version: !ruby/object:Gem::Requirement 
         | 
| 79 | 
            +
              requirements: 
         | 
| 80 | 
            +
              - - ">="
         | 
| 81 | 
            +
                - !ruby/object:Gem::Version 
         | 
| 82 | 
            +
                  version: "0"
         | 
| 83 | 
            +
              version: 
         | 
| 84 | 
            +
            requirements: []
         | 
| 85 | 
            +
             | 
| 86 | 
            +
            rubyforge_project: 
         | 
| 87 | 
            +
            rubygems_version: 1.3.3
         | 
| 88 | 
            +
            signing_key: 
         | 
| 89 | 
            +
            specification_version: 3
         | 
| 90 | 
            +
            summary: Delicious.com commandline interface
         | 
| 91 | 
            +
            test_files: 
         | 
| 92 | 
            +
            - test/delicious-cli_test.rb
         | 
| 93 | 
            +
            - test/test_helper.rb
         |