diff --git a/.travis.yml b/.travis.yml index 5965653..1d6f7fe 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,10 +4,10 @@ sudo: false before_install: - gem update --system + # Update bundler to the latest + - gem install bundler rvm: - - 2.2 - - 2.3 - 2.4 - 2.5 - jruby-head diff --git a/lib/user_agent/browsers.rb b/lib/user_agent/browsers.rb index 2206ace..33b6629 100644 --- a/lib/user_agent/browsers.rb +++ b/lib/user_agent/browsers.rb @@ -13,6 +13,7 @@ require 'user_agent/browsers/playstation' require 'user_agent/browsers/podcast_addict' require 'user_agent/browsers/vivaldi' +require 'user_agent/browsers/pocket_casts' class UserAgent module Browsers @@ -28,6 +29,7 @@ module Browsers Opera, WechatBrowser, Vivaldi, + PocketCasts, Chrome, ITunes, PlayStation, diff --git a/lib/user_agent/browsers/pocket_casts.rb b/lib/user_agent/browsers/pocket_casts.rb new file mode 100644 index 0000000..1a25da1 --- /dev/null +++ b/lib/user_agent/browsers/pocket_casts.rb @@ -0,0 +1,98 @@ +class UserAgent + module Browsers + # Pocket Casts BMID/E678F58F21 + # PocketCasts/1.0 (Pocket Casts Feed Parser; +http://pocketcasts.com/) + # Shifty Jelly Pocket Casts, Android v4.5.3 + # Shifty Jelly Pocket Casts, iOS v4.3 + # Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Pocket Casts/1.1 Pocket Casts/1.1 + class PocketCasts < Base + ANDROID_REGEX = /Android/ + IOS_REGEX = /iOS/ + POCKETCASTS_REGEX = /PocketCasts/ + POCKET_CASTS_REGEX = /Pocket Casts/ + POCKET_CASTS_SLASH_REGEX = /Pocket Casts\// + WINDOWS_REGEX = /Windows/ + WINDOWS_NT_REGEX = /Windows NT/ + + def self.extend?(agent) + agent.detect { |useragent| POCKETCASTS_REGEX.match?(useragent.product) } || POCKET_CASTS_REGEX.match?(agent.to_s) + end + + def browser + 'Pocket Casts' + end + + # Gets the right application + def application + detect_product('PocketCasts') + end + + # Gets the operating system + # + # @return [String] the os + def os + app = reject { |agent| agent.comment.nil? || agent.comment.empty? }.first + return if app.nil? + + if WINDOWS_NT_REGEX.match?(app.comment[0]) + OperatingSystems.normalize_os(app.comment[0]) + elsif app.comment[2].nil? + OperatingSystems.normalize_os(app.comment[1]) + elsif ANDROID_REGEX.match?(app.comment[1]) + OperatingSystems.normalize_os(app.comment[1]) + elsif (os_string = app.comment.detect { |c| OperatingSystems::IOS_VERSION_REGEX.match?(c) }) + OperatingSystems.normalize_os(os_string) + end + end + + # Gets the platform + # + # @return [String] the platform + def platform + app = reject { |agent| agent.comment.nil? || agent.comment.empty? }.first + + if app + return 'Windows' if WINDOWS_REGEX.match?(app.comment[0]) + return 'BlackBerry' if app.comment[0] == 'BB10' + return 'Android' if app.comment.any? { |c| ANDROID_REGEX.match?(c) } + end + + ua = self.to_s + if ANDROID_REGEX.match?(ua) + 'Android' + elsif IOS_REGEX.match?(ua) + 'iPhone' + end + end + + # Gets the version + # + # @return [String] + def version + if application && application.version + version = application.version.to_s + return version.index('/') ? normalize_version(version.split('/')[-1]) : normalize_version(application.version) + end + + ua = self.to_s + if pos = ua =~ ANDROID_REGEX + normalize_version(ua[pos..-1].split[1]) + elsif pos = ua =~ IOS_REGEX + normalize_version(ua[pos..-1].split[1]) + elsif POCKET_CASTS_SLASH_REGEX.match?(ua) + normalize_version(detect_product('Casts').version) + end + end + + private + + # Normalize the version string + # - remove starting 'v' + def normalize_version(version) + version = version.to_s + return version[1..-1] if version.downcase.start_with?('v') + version + end + end + end +end diff --git a/spec/browsers/pocket_casts_user_agent_spec.rb b/spec/browsers/pocket_casts_user_agent_spec.rb new file mode 100644 index 0000000..a5097d8 --- /dev/null +++ b/spec/browsers/pocket_casts_user_agent_spec.rb @@ -0,0 +1,81 @@ +require 'user_agent' + +shared_examples 'Pocket Casts' do + it "returns 'Pocket Casts' as its browser" do + expect(useragent.browser).to eq('Pocket Casts') + end +end + +describe "UserAgent: Pocket Casts BMID/E678F58F21" do + let!(:useragent) { UserAgent.parse("Pocket Casts BMID/E678F58F21") } + + it_behaves_like 'Pocket Casts' + + it "should return nil as its version" do + expect(useragent.version).to be_nil + end + + it "should return nil as its platform" do + expect(useragent.platform).to be_nil + end +end + +describe "UserAgent: PocketCasts/1.0 (Pocket Casts Feed Parser; +http://pocketcasts.com/)" do + let!(:useragent) { UserAgent.parse("PocketCasts/1.0 (Pocket Casts Feed Parser; +http://pocketcasts.com/)") } + + it_behaves_like 'Pocket Casts' + + it "should return '1.0' as its version" do + expect(useragent.version).to eq('1.0') + end + + it "should return nil as its platform" do + expect(useragent.platform).to be_nil + end +end + +describe "UserAgent: Shifty Jelly Pocket Casts, Android v4.5.3" do + let!(:useragent) { UserAgent.parse("Shifty Jelly Pocket Casts, Android v4.5.3") } + + it_behaves_like 'Pocket Casts' + + it "should return '4.5.3' as its version" do + expect(useragent.version).to eq('4.5.3') + end + + it "should return 'Android' as its platform" do + expect(useragent.platform).to eq('Android') + end +end + +describe "UserAgent: Shifty Jelly Pocket Casts, iOS v4.3" do + let!(:useragent) { UserAgent.parse("Shifty Jelly Pocket Casts, iOS v4.3") } + + it_behaves_like 'Pocket Casts' + + it "should return '4.3' as its version" do + expect(useragent.version).to eq('4.3') + end + + it "should return 'iPhone' as its platform" do + expect(useragent.platform).to eq('iPhone') + end +end + +describe "UserAgent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Pocket Casts/1.1 Pocket Casts/1.1" do + let!(:useragent) { UserAgent.parse("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Pocket Casts/1.1 Pocket Casts/1.1") } + + it_behaves_like 'Pocket Casts' + + it "should return '1.1' as its version" do + expect(useragent.version).to eq('1.1') + end + + it "should return 'Windows' as its platform" do + expect(useragent.platform).to eq('Windows') + end + + it "should return 'Windows 10' as its os" do + expect(useragent.os).to eq('Windows 10') + end +end