apple-news 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (115) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +4 -0
  5. data/Gemfile +4 -0
  6. data/README.md +138 -0
  7. data/Rakefile +6 -0
  8. data/apple-news.gemspec +28 -0
  9. data/bin/console +14 -0
  10. data/bin/setup +8 -0
  11. data/lib/apple-news.rb +41 -0
  12. data/lib/apple-news/addition.rb +7 -0
  13. data/lib/apple-news/additions/base.rb +15 -0
  14. data/lib/apple-news/additions/link.rb +9 -0
  15. data/lib/apple-news/animation.rb +7 -0
  16. data/lib/apple-news/animations/appear.rb +7 -0
  17. data/lib/apple-news/animations/base.rb +17 -0
  18. data/lib/apple-news/animations/fade_in.rb +8 -0
  19. data/lib/apple-news/animations/move_in.rb +8 -0
  20. data/lib/apple-news/animations/scale_fade.rb +8 -0
  21. data/lib/apple-news/article.rb +33 -0
  22. data/lib/apple-news/behavior.rb +7 -0
  23. data/lib/apple-news/behaviors/background_motion.rb +7 -0
  24. data/lib/apple-news/behaviors/background_parallax.rb +7 -0
  25. data/lib/apple-news/behaviors/base.rb +15 -0
  26. data/lib/apple-news/behaviors/motion.rb +7 -0
  27. data/lib/apple-news/behaviors/parallax.rb +8 -0
  28. data/lib/apple-news/behaviors/springy.rb +7 -0
  29. data/lib/apple-news/channel.rb +40 -0
  30. data/lib/apple-news/component.rb +28 -0
  31. data/lib/apple-news/component_layout.rb +9 -0
  32. data/lib/apple-news/components/audio.rb +16 -0
  33. data/lib/apple-news/components/author.rb +8 -0
  34. data/lib/apple-news/components/banner_advertisement.rb +14 -0
  35. data/lib/apple-news/components/base.rb +17 -0
  36. data/lib/apple-news/components/body.rb +8 -0
  37. data/lib/apple-news/components/byline.rb +8 -0
  38. data/lib/apple-news/components/caption.rb +8 -0
  39. data/lib/apple-news/components/chapter.rb +10 -0
  40. data/lib/apple-news/components/container.rb +8 -0
  41. data/lib/apple-news/components/divider.rb +8 -0
  42. data/lib/apple-news/components/embed_web_video.rb +12 -0
  43. data/lib/apple-news/components/figure.rb +8 -0
  44. data/lib/apple-news/components/gallery.rb +8 -0
  45. data/lib/apple-news/components/header.rb +7 -0
  46. data/lib/apple-news/components/heading.rb +8 -0
  47. data/lib/apple-news/components/illustrator.rb +8 -0
  48. data/lib/apple-news/components/image.rb +14 -0
  49. data/lib/apple-news/components/instagram.rb +9 -0
  50. data/lib/apple-news/components/intro.rb +8 -0
  51. data/lib/apple-news/components/logo.rb +8 -0
  52. data/lib/apple-news/components/medium_rectangle_advertisement.rb +7 -0
  53. data/lib/apple-news/components/mosaic.rb +8 -0
  54. data/lib/apple-news/components/music.rb +8 -0
  55. data/lib/apple-news/components/photo.rb +8 -0
  56. data/lib/apple-news/components/photographer.rb +8 -0
  57. data/lib/apple-news/components/portrait.rb +8 -0
  58. data/lib/apple-news/components/pullquote.rb +8 -0
  59. data/lib/apple-news/components/quote.rb +8 -0
  60. data/lib/apple-news/components/scalable_image.rb +14 -0
  61. data/lib/apple-news/components/section.rb +8 -0
  62. data/lib/apple-news/components/text.rb +13 -0
  63. data/lib/apple-news/components/title.rb +8 -0
  64. data/lib/apple-news/components/tweet.rb +9 -0
  65. data/lib/apple-news/components/video.rb +12 -0
  66. data/lib/apple-news/configuration.rb +12 -0
  67. data/lib/apple-news/document.rb +22 -0
  68. data/lib/apple-news/document/attachments.rb +24 -0
  69. data/lib/apple-news/document/metadata.rb +43 -0
  70. data/lib/apple-news/document/persistence.rb +42 -0
  71. data/lib/apple-news/layout.rb +8 -0
  72. data/lib/apple-news/links.rb +19 -0
  73. data/lib/apple-news/metadata.rb +15 -0
  74. data/lib/apple-news/multipart_post_patch.rb +29 -0
  75. data/lib/apple-news/properties.rb +87 -0
  76. data/lib/apple-news/properties/advertising_layout.rb +7 -0
  77. data/lib/apple-news/properties/advertising_settings.rb +7 -0
  78. data/lib/apple-news/properties/anchor.rb +15 -0
  79. data/lib/apple-news/properties/base.rb +7 -0
  80. data/lib/apple-news/properties/caption_descriptor.rb +8 -0
  81. data/lib/apple-news/properties/color_stop.rb +8 -0
  82. data/lib/apple-news/properties/content_inset.rb +7 -0
  83. data/lib/apple-news/properties/gallery_item.rb +7 -0
  84. data/lib/apple-news/properties/margin.rb +7 -0
  85. data/lib/apple-news/properties/offset.rb +7 -0
  86. data/lib/apple-news/property.rb +7 -0
  87. data/lib/apple-news/request.rb +6 -0
  88. data/lib/apple-news/requests/get.rb +28 -0
  89. data/lib/apple-news/requests/post.rb +57 -0
  90. data/lib/apple-news/resource.rb +25 -0
  91. data/lib/apple-news/scene.rb +7 -0
  92. data/lib/apple-news/scenes/base.rb +15 -0
  93. data/lib/apple-news/scenes/fading_sticky_header.rb +8 -0
  94. data/lib/apple-news/scenes/parallax_scale_header.rb +7 -0
  95. data/lib/apple-news/section.rb +27 -0
  96. data/lib/apple-news/security.rb +46 -0
  97. data/lib/apple-news/style.rb +10 -0
  98. data/lib/apple-news/styles/base.rb +7 -0
  99. data/lib/apple-news/styles/border.rb +7 -0
  100. data/lib/apple-news/styles/component.rb +7 -0
  101. data/lib/apple-news/styles/component_text.rb +9 -0
  102. data/lib/apple-news/styles/document.rb +7 -0
  103. data/lib/apple-news/styles/drop_cap.rb +9 -0
  104. data/lib/apple-news/styles/fill.rb +11 -0
  105. data/lib/apple-news/styles/gradient_fill.rb +12 -0
  106. data/lib/apple-news/styles/image_fill.rb +11 -0
  107. data/lib/apple-news/styles/inline_text.rb +7 -0
  108. data/lib/apple-news/styles/linear_gradient_fill.rb +9 -0
  109. data/lib/apple-news/styles/shadow.rb +8 -0
  110. data/lib/apple-news/styles/stroke.rb +7 -0
  111. data/lib/apple-news/styles/text.rb +8 -0
  112. data/lib/apple-news/styles/text_stroke.rb +8 -0
  113. data/lib/apple-news/styles/video_fill.rb +12 -0
  114. data/lib/apple-news/version.rb +3 -0
  115. metadata +241 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 703b6211a92ccabe31c718641e2cb15d79782614
4
+ data.tar.gz: 8f10ed6f53c56d308aa0d028b78c4590b11007c7
5
+ SHA512:
6
+ metadata.gz: 4e24363fdc8a83fa956528471e6452d925cc67766f14d0f6b757f0221acb5ef8e9b5e35f45f89a0c373b1e834fcb7588a1bc1d8af3f7e09a00e60f08c3753820
7
+ data.tar.gz: b9d5d00d7c16762cddefb3fb7830ee350ad9ef758367421b31947f7d69be22ea38b0d3191f640de81bb30f77e9e72da843b095d6e2de031d829f06bdda071756
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ test.rb
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.3.0
4
+ before_install: gem install bundler -v 1.11.2
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in apple-news.gemspec
4
+ gemspec
@@ -0,0 +1,138 @@
1
+ # Apple News
2
+
3
+ A fully featured gem for building Apple News documents and interfacing with the Apple News API.
4
+
5
+ **NOTE:** this is very much a work in progress. There are a lot of things that don't work yet, and some things will probbaly change (even drastically), but the basics are here. You can create and fetch articles, and fetch information about channels and sections.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'apple-news'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install apple-news
22
+
23
+ ## Configuration
24
+
25
+ In order to work with the Apple News API, we have to set a couple of configuration params that are available from [News Publisher](https://www.icloud.com/#newspublisher).
26
+
27
+ ``` ruby
28
+ AppleNews.config.channel_id = "63aFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF"
29
+ AppleNews.config.api_key_id = "379FFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF"
30
+ AppleNews.config.api_key_secret = "miJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
31
+ ```
32
+
33
+ ## Fetching Data
34
+
35
+ ### Channels
36
+
37
+ You can fetch the Channel information by calling:
38
+
39
+ ``` ruby
40
+ channel = AppleNews::Channel.current
41
+ ```
42
+
43
+ Because each channel has a separate API key, there is only ever one channel that you can fetch.
44
+
45
+ ### Sections
46
+
47
+ You can either fetch sections by their ID, or by fetching all of them through the Channel object.
48
+
49
+ ``` ruby
50
+ section = AppleNews::Section.new(section_id)
51
+
52
+ # or
53
+ channel = AppleNews::Channel.current
54
+ channel.default_section # for the default section
55
+ channel.sections # for all the sections
56
+ ```
57
+
58
+ ### Articles
59
+
60
+ You can fetch articles either by their ID, their channel, or their section.
61
+
62
+ ``` ruby
63
+ article = AppleNews::Article.new(article_id)
64
+
65
+ # or
66
+ channel = AppleNews::Channel.current
67
+ channel.articles # all articles in the channel
68
+ channel.default_section.articles # all articles in the default section
69
+ ```
70
+
71
+ ## Submitting Articles
72
+
73
+ Apple News articles are submitted as "bundles", with the article content and attached files together in one request. Because of this, we have the concept of a Document. The Document is the high-level abstraction that contains all of the contents for submission to the Apple News API, as well as the extra metadata that lets us control things like setting whether the article is just a preview or if it's sponsored.
74
+
75
+ ### Building Articles
76
+
77
+ Articles are built using the `AppleNews::Article` class. All articles must have an identifier (a string generated by you to determine article uniqueness, not the ID returned from the Apple News API), title, layout, components, and a default component text style.
78
+
79
+ In order to maintain idiomatic Ruby, all properties are accessed/set via the underscore version of the actual Apple News API property. For example, `componentTextStyles` becomes `component_text_styles`.
80
+
81
+ ``` ruby
82
+ article = AppleNews::Article.new
83
+ article.identifier = "1234"
84
+ article.title = "Test Article"
85
+ article.layout = AppleNews::Layout.new(columns: 1, width: 1024)
86
+ article.component_text_styles[:default] = AppleNews::Style::ComponentText.new(
87
+ font_name: 'Georgia',
88
+ font_size: 14,
89
+ text_color: '#000000'
90
+ )
91
+
92
+ article.components << AppleNews::Component::Heading.new(text: "Test Article")
93
+ article.components << AppleNews::Component::Body.new(text: "Just testing out this Ruby gem!")
94
+ ```
95
+
96
+ Every component, style, property, etc. as defined by the [API documentation](https://developer.apple.com/library/ios/documentation/General/Conceptual/Apple_News_Format_Ref/index.html) has its own class. Each property can be set either by the constructor, or by calling the accessor method on the object. For example:
97
+
98
+ ``` ruby
99
+ AppleNews::Component::Instagram.new(url: 'https://www.instagram.com/p/BB7mr0hsS4U/')
100
+
101
+ # or
102
+
103
+ component = AppleNews::Component::Instagram.new
104
+ component.url = "https://www.instagram.com/p/BB7mr0hsS4U/"
105
+ ```
106
+
107
+ ### Creating a Document
108
+
109
+ A document must have an article. Once it's created, you can set metadata flags and add files to the document bundle.
110
+
111
+ ``` ruby
112
+ document = AppleNews::Document.new(article)
113
+ document.is_preview = true
114
+
115
+ # There are 3 different ways you can add a file to the document
116
+ document.add_file(File.new("/path/to/image.jpg"))
117
+ document.add_file_at_path("/path/to/image.jpg")
118
+ document.add_string_as_file("image.jpg", image_contents, "image/jpeg")
119
+ ```
120
+
121
+ ### Saving a Document
122
+
123
+ Once you have your document built, you can submit it to the API.
124
+
125
+ ```
126
+ document.save!
127
+ ```
128
+
129
+ ## Development
130
+
131
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
132
+
133
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
134
+
135
+ ## Contributing
136
+
137
+ Bug reports and pull requests are welcome on GitHub at https://github.com/hodinkee/apple-news-rb.
138
+
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'apple-news/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "apple-news"
8
+ spec.version = AppleNews::VERSION
9
+ spec.authors = ["Ryan LeFevre"]
10
+ spec.email = ["ryan@hodinkee.com"]
11
+
12
+ spec.summary = %q{Fully-featured library for working with the Apple News API.}
13
+ spec.description = %q{Fully-featured library for fetching and creating content with the Apple News API.}
14
+ spec.homepage = "https://github.com/hodinkee/apple-news-rb"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
+ spec.bindir = "exe"
18
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.11"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+ spec.add_development_dependency "rspec", "~> 3.0"
24
+
25
+ spec.add_dependency "activesupport"
26
+ spec.add_dependency "multipart-post"
27
+ spec.add_dependency "mime-types", ">= 3.0"
28
+ end
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "apple/news"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,41 @@
1
+ require 'active_support/core_ext/hash/indifferent_access'
2
+ require "active_support/concern"
3
+ require "active_support/core_ext/class/attribute"
4
+ require "active_support/core_ext/string/inflections"
5
+
6
+ require "base64"
7
+ require "json"
8
+ require 'net/http/post/multipart'
9
+ require 'apple-news/multipart_post_patch'
10
+ require "mime/types"
11
+
12
+ require "apple-news/version"
13
+ require "apple-news/properties"
14
+ require "apple-news/addition"
15
+ require "apple-news/animation"
16
+ require "apple-news/behavior"
17
+ require "apple-news/component"
18
+ require "apple-news/component_layout"
19
+ require "apple-news/layout"
20
+ require "apple-news/metadata"
21
+ require "apple-news/property"
22
+ require "apple-news/scene"
23
+ require "apple-news/style"
24
+
25
+ require "apple-news/resource"
26
+ require "apple-news/links"
27
+ require "apple-news/configuration"
28
+ require "apple-news/document"
29
+ require "apple-news/article"
30
+ require "apple-news/channel"
31
+ require "apple-news/request"
32
+ require "apple-news/section"
33
+ require "apple-news/security"
34
+
35
+ module AppleNews
36
+ extend self
37
+
38
+ def config
39
+ @config ||= Configuration.new
40
+ end
41
+ end
@@ -0,0 +1,7 @@
1
+ require 'apple-news/additions/base'
2
+ Dir["#{File.dirname(__FILE__)}/additions/*.rb"].each { |path| require path }
3
+
4
+ module AppleNews
5
+ module Addition
6
+ end
7
+ end
@@ -0,0 +1,15 @@
1
+ module AppleNews
2
+ module Addition
3
+ class Base
4
+ include Properties
5
+
6
+ def self.type(val = nil)
7
+ val.nil? ? _required_property_map[:type] : required_property(:type, val)
8
+ end
9
+
10
+ def type
11
+ self.class.type
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,9 @@
1
+ module AppleNews
2
+ module Addition
3
+ class Link < Base
4
+ type "link"
5
+ required_properties :range_length, :range_start, :url
6
+ property_inflection :url, 'URL'
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,7 @@
1
+ require 'apple-news/animations/base'
2
+ Dir["#{File.dirname(__FILE__)}/animations/*.rb"].each { |path| require path }
3
+
4
+ module AppleNews
5
+ module Animation
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module AppleNews
2
+ module Animation
3
+ class Appear < Base
4
+ type "appear"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,17 @@
1
+ module AppleNews
2
+ module Animation
3
+ class Base
4
+ include Properties
5
+
6
+ optional_property :user_controllable
7
+
8
+ def self.type(val = nil)
9
+ val.nil? ? _required_property_map[:type] : required_property(:type, val)
10
+ end
11
+
12
+ def type
13
+ self.class.type
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,8 @@
1
+ module AppleNews
2
+ module Animation
3
+ class FadeIn < Base
4
+ type "fade_in"
5
+ optional_property :initial_alpha
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ module AppleNews
2
+ module Animation
3
+ class MoveIn < Base
4
+ type "move_in"
5
+ optional_property :preferred_starting_position
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ module AppleNews
2
+ module Animation
3
+ class ScaleFade < Base
4
+ type "scale_fade"
5
+ optional_properties :initial_alpha, :initial_scale
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,33 @@
1
+ module AppleNews
2
+ class Article
3
+ include Resource
4
+ include Properties
5
+
6
+ attr_reader :id
7
+
8
+ required_properties :identifier, :title, :layout
9
+ required_property :components, []
10
+ required_property :component_text_styles, {}
11
+
12
+ required_property :version, "1.1"
13
+ required_property :language, "en"
14
+
15
+ optional_properties :advertising_settings, :subtitle, :metadata, :document_style,
16
+ :text_styles, :component_layouts, :component_styles
17
+
18
+ def initialize(id = nil, opts = nil)
19
+ super(opts)
20
+
21
+ @id = id
22
+ @url = "/articles/#{id}"
23
+ @metadata = Metadata.new((opts || {}).fetch(:metadata, {}))
24
+
25
+ hydrate! if !id.nil? && opts.nil?
26
+ end
27
+
28
+ def persisted?
29
+ !@id.nil?
30
+ end
31
+ alias_method :saved?, :persisted?
32
+ end
33
+ end
@@ -0,0 +1,7 @@
1
+ require 'apple-news/behaviors/base'
2
+ Dir["#{File.dirname(__FILE__)}/behaviors/*.rb"].each { |path| require path }
3
+
4
+ module AppleNews
5
+ module Behavior
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module AppleNews
2
+ module Behavior
3
+ class BackgroundMotion < Base
4
+ type "background_motion"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module AppleNews
2
+ module Behavior
3
+ class BackgroundParallax < Base
4
+ type "background_parallax"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,15 @@
1
+ module AppleNews
2
+ module Behavior
3
+ class Base
4
+ include Properties
5
+
6
+ def self.type(val = nil)
7
+ val.nil? ? _required_property_map[:type] : required_property(:type, val)
8
+ end
9
+
10
+ def type
11
+ self.class.type
12
+ end
13
+ end
14
+ end
15
+ end