Permalink
Browse files

insert progression records

  • Loading branch information...
technoweenie committed Jul 26, 2008
0 parents commit 1a3fc7ba600d41af34cd0f0a7a20fc839e390355
20 LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2008-* Rick Olson
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,12 @@
+require 'rubygems'
+require 'rake/gempackagetask'
+require 'spec/rake/spectask'
+
+file_list = FileList['spec/*_spec.rb']
+
+Spec::Rake::SpecTask.new('spec') do |t|
+ t.spec_files = file_list
+end
+
+desc 'Default: run specs.'
+task :default => 'spec'
@@ -0,0 +1,55 @@
+$: << File.join(File.dirname(__FILE__), '..', 'vendor', 'feed_me', 'lib')
+require 'rubygems'
+require 'open-uri'
+require 'dm-core'
+require 'feed_me'
+
+module Seinfeld
+ class User
+ include DataMapper::Resource
+ property :id, Integer, :serial => true
+ property :login, String
+ property :email, String
+ has n, :progressions, :class_name => "Seinfeld::Progression", :order => [:created_at.desc]
+
+ def update_progress
+ transaction do
+ save if new_record?
+ days = scan_for_progress
+ unless days.empty?
+ existing = progressions(:created_at => days).map { |p| p.created_at }
+ (days - existing).each do |day|
+ progressions.create(:created_at => day)
+ end
+ end
+ end
+ end
+
+ def scan_for_progress
+ feed = get_feed
+ feed.entries.inject({}) do |selected, entry|
+ if entry.title =~ %r{^#{login} committed}
+ updated = entry.updated_at
+ date = Time.utc(updated.year, updated.month, updated.day)
+ selected.update date => nil
+ else
+ selected
+ end
+ end.keys.sort
+ end
+
+ private
+ def get_feed
+ feed = nil
+ open("http://github.com/#{login}.atom") { |f| feed = FeedMe.parse(f.read) }
+ feed
+ end
+ end
+
+ class Progression
+ include DataMapper::Resource
+ property :id, Integer, :serial => true
+ property :created_at, DateTime
+ belongs_to :user, :class_name => "Seinfeld::User"
+ end
+end
@@ -0,0 +1,10 @@
+$: << File.join(File.dirname(__FILE__), '..', 'lib')
+require 'seinfeld_calendar'
+require 'ruby-debug'
+require 'ostruct'
+require 'spec'
+
+DataMapper.setup(:default, 'sqlite3::memory:')
+DataMapper.auto_migrate!
+
+Debugger.start
@@ -0,0 +1,63 @@
+require File.join( File.dirname(__FILE__), "spec_helper" )
+
+module Seinfeld
+ describe User do
+ before :all do
+ @feed = OpenStruct.new
+ @feed.entries = [
+ OpenStruct.new(:title => "bob committed something", :updated_at => Time.utc(2008, 1, 1, 22)),
+ OpenStruct.new(:title => "bob watched something"),
+ OpenStruct.new(:title => "bob committed something", :updated_at => Time.utc(2008, 1, 1, 23)),
+ OpenStruct.new(:title => "bob committed something", :updated_at => Time.utc(2008, 1, 2, 23)),
+ ]
+ end
+
+ before do
+ @user = Seinfeld::User.new :login => 'bob'
+ end
+
+ describe "#scan_for_progress" do
+ before do
+ @user.stub!(:get_feed).and_return(@feed)
+ end
+
+ it "returns array" do
+ @user.scan_for_progress.should be_kind_of(Array)
+ end
+
+ it "returns unique days" do
+ @user.scan_for_progress.should == [Time.utc(2008, 1, 1), Time.utc(2008, 1, 2)]
+ end
+
+ it "matches against login name" do
+ @user.login = 'not bob'
+ @user.scan_for_progress.should be_empty
+ end
+ end
+
+ describe "#update_progress" do
+ before do
+ @user.stub!(:get_feed).and_return(@feed)
+ User.transaction do
+ User.all.destroy!
+ Progression.all.destroy!
+ end
+ end
+
+ it "saves record if necessary" do
+ @feed.stub!(:entries).and_return([])
+ @user.update_progress
+ @user.id.should_not be_nil
+ end
+
+ it "inserts progression records" do
+ lambda { @user.update_progress }.should change { Progression.all(:user_id => @user.id).size }.by(2)
+ end
+
+ it "inserts only unique progression records" do
+ Progression.create! :user_id => @user.id, :created_at => @feed.entries.first.updated_at
+ lambda { @user.update_progress }.should change { Progression.all(:user_id => @user.id).size }.by(1)
+ end
+ end
+ end
+end
@@ -0,0 +1,19 @@
+# Redefines the mappings in order for Autotest to pick up on a merb app
+puts "loaded .autotest"
+require 'autotest/redgreen'
+
+Autotest.add_hook :initialize do |at|
+ at.clear_mappings
+ at.add_exception(/\.git/)
+
+ at.add_mapping(%r{^spec/.*_spec\.rb$}) { |filename, _| filename}
+
+ at.add_mapping(%r{^spec/spec_helper\.rb$}) { |_, m| at.files_matching %r{^spec/.*_spec\.rb$} }
+ at.add_mapping(%r{^spec/(.*)/spec_helper\.rb$}) { |_, m| at.files_matching %r{^spec/#{m[1]}/.*_spec\.rb$} }
+
+ # map root libs
+ at.add_mapping(%r{^lib/([^/]+)\.rb$}) { |_, m| at.files_matching %r{^spec/([^/]+)_spec\.rb$} }
+
+ # map libs
+ at.add_mapping(%r{^lib/[^/]+/([^/]+)\.rb$}) { |_, m| at.files_matching %r{^spec/#{m[1]}_spec\.rb$} }
+end
@@ -0,0 +1,20 @@
+Copyright (c) 2008 Jonas Nicklas
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,23 @@
+Feed Me
+=======
+
+Feed Me is a simple parser for RSS2 and Atom feed, adding other feed formats should be trivial. Feed Me is pretty minimal and basically only does translation/cleanup from different feed formats to a consistent API. It is designed to be minimal.
+
+Feed Me is built on the excellent Hpricot parser written by _why the lucky stiff.
+
+Use it like this:
+
+ file = File.read('some_feed.atom')
+
+ feed = FeedMe.parse(file)
+
+ feed.title
+ feed.author.name
+ feed.entries.each do |entry|
+ entry.title
+ entry.content
+ end
+
+Check out the specs or lib/feed_me/consts.rb for the complete API.
+
+DISCLAIMER: This is very much alpha software, use at your own risk!
@@ -0,0 +1,68 @@
+require 'rubygems'
+require 'rake/gempackagetask'
+require 'spec/rake/spectask'
+
+file_list = FileList['spec/*_spec.rb']
+
+namespace :spec do
+ desc "Run all examples with RCov"
+ Spec::Rake::SpecTask.new('rcov') do |t|
+ t.spec_files = file_list
+ t.rcov = true
+ t.rcov_dir = "doc/coverage"
+ t.rcov_opts = ['--exclude', 'spec']
+ end
+
+ desc "Generate an html report"
+ Spec::Rake::SpecTask.new('report') do |t|
+ t.spec_files = file_list
+ t.rcov_opts = ['--exclude', 'spec']
+ t.spec_opts = ["--format", "html:doc/reports/specs.html"]
+ t.fail_on_error = false
+ end
+
+end
+
+desc 'Default: run specs.'
+task :default => 'spec:rcov'
+
+PLUGIN = "feed_me"
+NAME = "feed_me"
+VERSION = "0.0.1"
+AUTHOR = "Jonas Nicklas"
+EMAIL = "jonas.nicklas@gmail.com"
+HOMEPAGE = "http://merb-plugins.rubyforge.org/feed_me/"
+SUMMARY = "Merb plugin that provides ..."
+
+spec = Gem::Specification.new do |s|
+ s.name = NAME
+ s.version = VERSION
+ s.platform = Gem::Platform::RUBY
+ s.has_rdoc = true
+ s.extra_rdoc_files = ["README", "LICENSE", 'TODO']
+ s.summary = SUMMARY
+ s.description = s.summary
+ s.author = AUTHOR
+ s.email = EMAIL
+ s.homepage = HOMEPAGE
+ s.require_path = 'lib'
+ s.autorequire = PLUGIN
+ s.files = %w(LICENSE README Rakefile TODO) + Dir.glob("{lib,specs}/**/*")
+end
+
+Rake::GemPackageTask.new(spec) do |pkg|
+ pkg.gem_spec = spec
+end
+
+task :install => [:package] do
+ sh %{sudo gem install pkg/#{NAME}-#{VERSION}}
+end
+
+namespace :jruby do
+
+ desc "Run :package and install the resulting .gem with jruby"
+ task :install => :package do
+ sh %{#{SUDO} jruby -S gem install pkg/#{NAME}-#{Merb::VERSION}.gem --no-rdoc --no-ri}
+ end
+
+end
@@ -0,0 +1,5 @@
+TODO:
+Fix LICENSE with your name
+Fix Rakefile with your name and contact info
+Add your code to lib/feed_me.rb
+Add your Merb rake tasks to lib/feed_me/merbtasks.rb
@@ -0,0 +1,33 @@
+# make sure we're running inside Merb
+if defined?(Merb::Plugins)
+ dependency 'hpricot'
+else
+ require 'rubygems'
+ require 'hpricot'
+end
+
+unless nil.respond_to? :try
+ # the ultimate duck
+ class Object
+ def try(method, *args)
+ self.send(method, *args)
+ rescue NoMethodError
+ nil
+ end
+ end
+end
+
+module FeedMe
+ def self.parse(feed)
+ FeedMe::FeedParser.parse(feed)
+ end
+
+ def self.open(file)
+ FeedMe::FeedParser.parse(file)
+ end
+end
+
+['consts', 'abstract_parser', 'feed_struct', 'simple_struct',
+ 'feed_parser', 'item_parser'].each do |f|
+ require File.join(File.dirname(__FILE__), 'feed_me', f)
+end
Oops, something went wrong.

0 comments on commit 1a3fc7b

Please sign in to comment.