rack-newsstand 0.0.3

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: 6593b8cd8b161d5fb3d31a895e8064de2fab51b2
4
+ data.tar.gz: d3db244673a496ca0a39a38331ecabaf9a3a5f5e
5
+ SHA512:
6
+ metadata.gz: 2e92b50f238e90aaabbacbaceafc2da5f3d608345fba365ebb186ebad2322796057188fb77b00d97f8128740058d455a07bb09339c8f256b87f9a6da451f9c37
7
+ data.tar.gz: 60209b4a09d4b6a37fdcc2aa907401890a6e44e3ae2cce94edc45f3426552ddf4bef6b15415372b466a507e9f6c4f2980d5cd77ce1efc71019937467230f5612
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,42 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ rack-newsstand (0.0.3)
5
+ builder (>= 3.0)
6
+ plist (~> 3.1)
7
+ rack (~> 1.4)
8
+ sequel (~> 3.37)
9
+ sinatra (~> 1.3)
10
+
11
+ GEM
12
+ remote: https://rubygems.org/
13
+ specs:
14
+ builder (3.2.0)
15
+ diff-lcs (1.2.4)
16
+ plist (3.1.0)
17
+ rack (1.5.2)
18
+ rack-protection (1.5.0)
19
+ rack
20
+ rake (10.0.4)
21
+ rspec (2.13.0)
22
+ rspec-core (~> 2.13.0)
23
+ rspec-expectations (~> 2.13.0)
24
+ rspec-mocks (~> 2.13.0)
25
+ rspec-core (2.13.1)
26
+ rspec-expectations (2.13.0)
27
+ diff-lcs (>= 1.1.3, < 2.0)
28
+ rspec-mocks (2.13.1)
29
+ sequel (3.47.0)
30
+ sinatra (1.4.2)
31
+ rack (~> 1.5, >= 1.5.2)
32
+ rack-protection (~> 1.4)
33
+ tilt (~> 1.3, >= 1.3.4)
34
+ tilt (1.4.0)
35
+
36
+ PLATFORMS
37
+ ruby
38
+
39
+ DEPENDENCIES
40
+ rack-newsstand!
41
+ rake
42
+ rspec
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2013 Mattt Thompson (http://mattt.me/)
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,92 @@
1
+ # Rack::Newsstand
2
+
3
+ Newsstand was introduced in iOS 5 to give publishers a common framework to syndicate content. `Rack::Newsstand` provides webservice endpoints for issue data, as well as a Newsstand Atom feed.
4
+
5
+ ## Requirements
6
+
7
+ - PostgreSQL 9.1 running locally ([Postgres.app](http://postgresapp.com) is the easiest way to get a Postgres server running on your Mac)
8
+
9
+ ## Example Usage
10
+
11
+ Rack::Newsstand can be run as Rack middleware or as a single web application. All that is required is a connection to a Postgres database.
12
+
13
+ ### Gemfile
14
+
15
+ ```ruby
16
+ source "https://rubygems.org"
17
+
18
+ gem 'rack-newsstand'
19
+ gem 'pg'
20
+ ```
21
+
22
+ ### config.ru
23
+
24
+ ```ruby
25
+ require 'bundler'
26
+ Bundler.require
27
+
28
+ run Rack::Newsstand
29
+ ```
30
+
31
+ An example application can be found in the `/example` directory of this repository.
32
+
33
+ ### `GET /issues` (`Accept: application/x-plist`)
34
+
35
+ ```xml
36
+ <?xml version="1.0" encoding="UTF-8"?>
37
+ <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
38
+ <plist version="1.0">
39
+ <array>
40
+ <dict>
41
+ <key>name</key>
42
+ <string>magazine-1</string>
43
+ <key>title</key>
44
+ <string>Magazine Issue 1</string>
45
+ <key>summary</key>
46
+ <string>Lorem ipsum dolar sit amet</string>
47
+ <key>date</key>
48
+ <date>2013-04-19T12:00:00Z</date>
49
+ <key>covers</key>
50
+ <dict>
51
+ <key>SOURCE</key>
52
+ <string>http://example.com/assets/covers/magazine-1.png</string>
53
+ </dict>
54
+ <key>content</key>
55
+ <array>
56
+ <string>http://example.com/assets/content/magazine-1.pdf</string>
57
+ </array>
58
+ </dict>
59
+ </array>
60
+ </plist>
61
+ ```
62
+
63
+ ### `GET /issues` (`Accept: application/application/atom+xml`)
64
+
65
+ ```xml
66
+ <?xml version="1.1" encoding="UTF-8"?>
67
+ <feed xmlns="http://www.w3.org/2005/Atom" xmlns:news="http://itunes.apple.com/2011/Newsstand">
68
+ <updated>
69
+ </updated>
70
+ <entry>
71
+ <id>magazine-0</id>
72
+ <summary/>
73
+ <updated>2013-04-30 09:59:54 -0700</updated>
74
+ <published>2013-04-30 09:59:54 -0700</published>
75
+ <news:cover_art_icons>
76
+ <news:cover_art_icon size="SOURCE" src="http://example.com/assets/covers/magazine-1.png"/>
77
+ </news:cover_art_icons>
78
+ </entry>
79
+ </feed>
80
+ ```
81
+
82
+ ## Contact
83
+
84
+ Mattt Thompson
85
+
86
+ - http://github.com/mattt
87
+ - http://twitter.com/mattt
88
+ - m@mattt.me
89
+
90
+ ## License
91
+
92
+ Rack::Newsstand is available under the MIT license. See the LICENSE file for more info.
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler"
2
+ Bundler.setup
3
+
4
+ gemspec = eval(File.read("rack-newsstand.gemspec"))
5
+
6
+ task :build => "#{gemspec.full_name}.gem"
7
+
8
+ file "#{gemspec.full_name}.gem" => gemspec.files + ["rack-newsstand.gemspec"] do
9
+ system "gem build rack-newsstand.gemspec"
10
+ end
@@ -0,0 +1,77 @@
1
+ require 'rack'
2
+ require 'sinatra/base'
3
+ require 'sequel'
4
+
5
+ module Rack
6
+ class Newsstand < Sinatra::Base
7
+ autoload :Issue, 'rack/newsstand/models/issue'
8
+
9
+ disable :raise_errors, :show_exceptions
10
+
11
+ configure do
12
+ Sequel.extension :core_extensions, :migration, :pg_array, :pg_hstore, :pg_hstore_ops
13
+
14
+ if ENV['DATABASE_URL']
15
+ DB = Sequel.connect(ENV['DATABASE_URL'])
16
+ DB.extend Sequel::Postgres::PGArray::DatabaseMethods
17
+ DB.extend Sequel::Postgres::HStore::DatabaseMethods
18
+
19
+ Sequel::Migrator.run(DB, ::File.join(::File.dirname(__FILE__), "newsstand/migrations"), table: 'newsstand_schema_info')
20
+ end
21
+ end
22
+
23
+ get '/issues' do
24
+ @issues = Issue.order(:published_at).all
25
+
26
+ request.accept.each do |type|
27
+ case type.to_s
28
+ when 'application/atom+xml', 'application/xml', 'text/xml'
29
+ content_type 'application/x-plist'
30
+ return builder :atom
31
+ when 'application/x-plist'
32
+ content_type 'application/x-plist'
33
+ return @issues.to_plist
34
+ when 'application/json'
35
+ pass
36
+ end
37
+ end
38
+
39
+ halt 406
40
+ end
41
+
42
+ get '/issues/:name' do
43
+ pass unless request.accept? 'application/x-plist'
44
+ content_type 'application/x-plist'
45
+
46
+ param :name, String, empty: false
47
+
48
+ Issue.find(name: params[:name]).to_plist
49
+ end
50
+
51
+ template :atom do
52
+ <<-EOF
53
+ xml.instruct! :xml, :version => '1.1'
54
+ xml.feed "xmlns" => "http://www.w3.org/2005/Atom",
55
+ "xmlns:news" => "http://itunes.apple.com/2011/Newsstand" do
56
+
57
+ xml.updated { @issues.first.updated_at rescue Time.now }
58
+
59
+ @issues.each do |issue|
60
+ xml.entry do
61
+ xml.id issue.name
62
+ xml.summary issue.summary
63
+ xml.updated issue.updated_at
64
+ xml.published issue.published_at
65
+ xml.tag!("news:end_date"){ issue.expires_at } if issue.expires_at
66
+ xml.tag!("news:cover_art_icons") do
67
+ issue.cover_urls.each do |size, url|
68
+ xml.tag!("news:cover_art_icon", size: size, src: url)
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
74
+ EOF
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,28 @@
1
+ Sequel.migration do
2
+ up do
3
+ run %{CREATE EXTENSION IF NOT EXISTS hstore;}
4
+
5
+ create_table :newsstand_issues do
6
+ primary_key :id
7
+
8
+ column :name, :varchar, unique: true, empty: false
9
+ column :title, :varchar, empty: false
10
+ column :summary, :varchar, empty: false
11
+ column :tags, :'text[]'
12
+ column :metadata, :hstore
13
+ column :cover_urls, :hstore
14
+ column :asset_urls, :'text[]'
15
+ column :created_at, :timestamp
16
+ column :updated_at, :timestamp
17
+ column :published_at, :timestamp
18
+ column :expires_at, :timestamp
19
+
20
+ index :name
21
+ index :published_at
22
+ end
23
+ end
24
+
25
+ down do
26
+ drop_table :newsstand_issues
27
+ end
28
+ end
@@ -0,0 +1,34 @@
1
+ require 'plist'
2
+
3
+ module Rack
4
+ class Newsstand
5
+ class Issue < Sequel::Model
6
+ plugin :json_serializer, naked: true, except: :id
7
+ plugin :validation_helpers
8
+ plugin :timestamps, force: true, update_on_create: true
9
+ plugin :schema
10
+ plugin :typecast_on_load
11
+
12
+ self.dataset = :newsstand_issues
13
+ self.strict_param_setting = false
14
+ self.raise_on_save_failure = false
15
+
16
+ def to_plist_node
17
+ {
18
+ name: self.name,
19
+ title: self.title,
20
+ date: self.published_at,
21
+ covers: self.cover_urls.to_hash,
22
+ assets: self.asset_urls.to_a
23
+ }.to_plist(false)
24
+ end
25
+
26
+ def validate
27
+ super
28
+
29
+ validates_presence [:name, :published_at]
30
+ validates_unique :name
31
+ end
32
+ end
33
+ end
34
+ end
Binary file
Binary file
@@ -0,0 +1,28 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "rack-newsstand"
6
+ s.license = "MIT"
7
+ s.authors = ["Mattt Thompson"]
8
+ s.email = "m@mattt.me"
9
+ s.homepage = "http://mattt.me"
10
+ s.version = "0.0.3"
11
+ s.platform = Gem::Platform::RUBY
12
+ s.summary = "Rack::Newsstand"
13
+ s.description = "Automatically generate webservice endpoints for Newsstand"
14
+
15
+ s.add_dependency "rack", "~> 1.4"
16
+ s.add_dependency "sinatra", "~> 1.3"
17
+ s.add_dependency "sequel", "~> 3.37"
18
+ s.add_dependency "plist", "~> 3.1"
19
+ s.add_dependency "builder", ">= 3.0"
20
+
21
+ s.add_development_dependency "rspec"
22
+ s.add_development_dependency "rake"
23
+
24
+ s.files = Dir["./**/*"].reject { |file| file =~ /\.\/(bin|example|log|pkg|script|spec|test|vendor)/ }
25
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
26
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
27
+ s.require_paths = ["lib"]
28
+ end
metadata ADDED
@@ -0,0 +1,152 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rack-newsstand
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ platform: ruby
6
+ authors:
7
+ - Mattt Thompson
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-05-03 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rack
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.4'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.4'
27
+ - !ruby/object:Gem::Dependency
28
+ name: sinatra
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '1.3'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '1.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: sequel
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '3.37'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '3.37'
55
+ - !ruby/object:Gem::Dependency
56
+ name: plist
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '3.1'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: '3.1'
69
+ - !ruby/object:Gem::Dependency
70
+ name: builder
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ! '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '3.0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ! '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '3.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ! '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ! '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rake
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ! '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ! '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ description: Automatically generate webservice endpoints for Newsstand
112
+ email: m@mattt.me
113
+ executables: []
114
+ extensions: []
115
+ extra_rdoc_files: []
116
+ files:
117
+ - ./Gemfile
118
+ - ./Gemfile.lock
119
+ - ./lib/rack/newsstand/migrations/001_base_schema.rb
120
+ - ./lib/rack/newsstand/models/issue.rb
121
+ - ./lib/rack/newsstand.rb
122
+ - ./LICENSE
123
+ - ./rack-newsstand-0.0.1.gem
124
+ - ./rack-newsstand-0.0.2.gem
125
+ - ./rack-newsstand.gemspec
126
+ - ./Rakefile
127
+ - ./README.md
128
+ homepage: http://mattt.me
129
+ licenses:
130
+ - MIT
131
+ metadata: {}
132
+ post_install_message:
133
+ rdoc_options: []
134
+ require_paths:
135
+ - lib
136
+ required_ruby_version: !ruby/object:Gem::Requirement
137
+ requirements:
138
+ - - ! '>='
139
+ - !ruby/object:Gem::Version
140
+ version: '0'
141
+ required_rubygems_version: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ! '>='
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ requirements: []
147
+ rubyforge_project:
148
+ rubygems_version: 2.0.3
149
+ signing_key:
150
+ specification_version: 4
151
+ summary: Rack::Newsstand
152
+ test_files: []