rack-newsstand 0.0.3

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.
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: []