showfeature 0.1.0

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.
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ #ignore les fichier temporaire généré par linux
2
+ *.*~
3
+ *~
4
+ #ignore ceux généré par emacs
5
+ \#*
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'http://rubygems.org/'
2
+
3
+ gem "mime-types"
data/Gemfile.lock ADDED
@@ -0,0 +1,10 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ mime-types (1.19)
5
+
6
+ PLATFORMS
7
+ ruby
8
+
9
+ DEPENDENCIES
10
+ mime-types
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Allan Seymour
2
+
3
+ Permission is hereby granted, free of charge, to any person
4
+ obtaining a copy of this software and associated documentation
5
+ files (the "Software"), to deal in the Software without
6
+ restriction, including without limitation the rights to use,
7
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the
9
+ Software is furnished to do so, subject to the following
10
+ conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,20 @@
1
+ ## ShowFeature ##
2
+
3
+ A library to find distinguishable features in a tv show filename as it
4
+ was downloaded
5
+ (e.g. [name].S[season]E[episode].hdtv-[team].avi)
6
+
7
+ # Usage
8
+
9
+ ```ruby
10
+ require 'showfeature'
11
+ sf = ShowFeature::Processor.new('foo.125.x264-bar.mkv')
12
+ sf.parse
13
+ puts sf.to_hsh
14
+ ```
15
+
16
+ **Author :** Allan Seymour
17
+ **Version :** 0.1.0
18
+ **Release Date :** December 04, 2012
19
+ **Copyright :** MIT License
20
+
@@ -0,0 +1,7 @@
1
+ $:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
2
+
3
+ module ShowFeature
4
+ TypeError = Class.new (TypeError)
5
+ NotParsedError = Class.new (StandardError)
6
+ ArgumentError = Class.new(ArgumentError)
7
+ end
@@ -0,0 +1,90 @@
1
+ $:.unshift File.join(File.dirname(__FILE__), '..')
2
+ require 'showfeature'
3
+ require 'mime/types'
4
+
5
+ module ShowFeature
6
+
7
+ # The main processor class is in charge of the parsing of tv show filename
8
+ class Processor
9
+
10
+ attr_reader :id, :name, :team, :episode, :season, :raw_name, :parsed
11
+
12
+ # Pattern used for the parsing process
13
+ PATTERN = /(^[\w\.\(\)]+)\.(\d{3}|s?\d{1,2}[ex]?\d{2})\..*-(.*)\.[\d\w]{3}$/i
14
+
15
+ ##
16
+ # Creates a new Processor instance for +raw_name+ parsing
17
+ #
18
+ # An ArgumentError is raised if +raw_name+'s mime type does not
19
+ # match the type of a video file
20
+ def initialize(raw_name)
21
+ raise ShowFeature::ArgumentError, 'argument does not match a video file type' unless
22
+ ShowFeature::Processor.video_file_type? raw_name
23
+ @raw_name = raw_name
24
+ @parsed = false
25
+ end
26
+
27
+ ##
28
+ # Parses the tv show filename looking for relevant element
29
+ def parse
30
+ proc = Proc.new do |position, proc|
31
+ tmp = @raw_name[PATTERN,position]
32
+ tmp.nil? ? nil : proc.call(tmp)
33
+ end
34
+ @name = proc.call(1, lambda{|x| x.downcase.tr_s('.',' ')})
35
+ @season = proc.call(2, lambda{|x| "%02d" % x[/(\d+).?(\d{2}$)/,1].to_i})
36
+ @episode = proc.call(2, lambda{|x| "%02d" % x[/(\d+).?(\d{2}$)/,2].to_i})
37
+ @team = proc.call(3, lambda{|x| x.downcase})
38
+ @parsed = true
39
+ end
40
+
41
+ ##
42
+ # Checks if the tv show filename has already been parsed
43
+ def parsed?
44
+ @parsed
45
+ end
46
+
47
+ ##
48
+ # Returns hash filled with all parsed element
49
+ def to_hsh
50
+ hash = Hash.new
51
+ hash.merge!( { :name =>@name,
52
+ :season => @season,
53
+ :episode => @episode,
54
+ :team => @team } ) unless [@name,@season,@episode, @team].all? {|x| x.eql?nil}
55
+ hash
56
+ end
57
+
58
+ ##
59
+ # Checks if +str+'s mime type matches a video file type
60
+ def self.video_file_type?(str)
61
+ MIME::Types.of(str).any? do |x| x.to_s =~/^video/ end
62
+ end
63
+
64
+ ##
65
+ # Checks if the mime type of the current processed show matches a video file type
66
+ def video_file_type?
67
+ MIME::Types.of(@raw_name).any? do |x| x.to_s =~/^video/ end
68
+ end
69
+
70
+
71
+ def replace(arg)
72
+ raise ShowFeature::TypeError, 'argument must be of type String or Hash' unless
73
+ [String, Hash].any?{|type| arg.kind_of? type}
74
+ raise ShowFeature::NotParsedError, 'showfeature cannot complete replace if show is not parsed' unless parsed?
75
+ if arg.kind_of? String
76
+ @raw_name = arg if ShowFeature::Processor.video_file_type?(arg)
77
+ else
78
+ hash = {
79
+ :name =>@name,
80
+ :season => @season,
81
+ :episode => @episode,
82
+ :team => @team }.merge(arg) {|k,v1,v2| k.eql?(:episode) ? "%02d"%v2 : v2}
83
+ hash.each do |key, value|
84
+ @raw_name.sub! self.send("#{key}").gsub(' ','.'), value
85
+ instance_variable_set("@#{key}", value)
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,3 @@
1
+ module ShowFeature
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,7 @@
1
+ module ShowFeature
2
+ ROOT = File.expand_path(File.dirname(__FILE__))
3
+ Dir.glob(File.join(ROOT, "showfeature",'*.rb')).
4
+ each do |file|
5
+ require file
6
+ end
7
+ end
@@ -0,0 +1,15 @@
1
+ require File.expand_path('../lib/showfeature/version', __FILE__)
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = "showfeature"
5
+ spec.version= ShowFeature::VERSION
6
+ spec.summary = 'This library allows to find the relevant features in a tv show filename (e.g. [name].S[season]E[episode].hdtv-[team].avi)'
7
+ spec.description = "This library allows to find the relevant features in a tv show filename (e.g. [name].S[season]E[episode].hdtv-[team].avi)"
8
+ spec.homepage = "https://github.com/stonebanks/showfeature/"
9
+ spec.author = "Allan Seymour"
10
+ spec.email = "banks.the.megalithic.stone@gmail.com"
11
+ spec.require_paths = ['lib']
12
+ spec.files = `git ls-files`.split("\n")
13
+ spec.required_ruby_version = '>= 1.9.1'
14
+ spec.test_files = `git ls-files -- spec `.split("\n")
15
+ end
@@ -0,0 +1,136 @@
1
+ $:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
2
+
3
+ require 'minitest/spec'
4
+ require 'minitest/autorun'
5
+ require 'showfeature'
6
+ require 'erb'
7
+
8
+ Output = Struct.new(:name, :episode, :season, :team, :raw_name)
9
+
10
+ def create_a_show
11
+ t = ([('a'..'z'),(0..9)].map{|i| i.to_a}).flatten
12
+ r = (Array.new(t)<<['(',')','.']).flatten
13
+ output = Output.new
14
+ output.name = (0..30).map{r.sample}.join
15
+ output.team = (0..4).map {t.sample}.join
16
+ nb = ERB.new (['s<%="%02d"%output.season %>e<%="%02d"%output.episode%>',
17
+ '<%="%01d"%output.season %><%="%02d"%output.episode%>',
18
+ '<%="%02d"%output.season %>x<%="%02d"%output.episode%>',
19
+ '<%="%01d"%output.season %>X<%="%02d"%output.episode%>'].sample)
20
+ output.season = (1..99).map{|s| s}.sample.to_s
21
+ output.episode = (1..99).map{|s| s}.sample.to_s
22
+ output.raw_name = output.name+"."+ nb.result(binding) + ".hdtv-"+output.team+[".avi",".mp4",".mkv"].sample
23
+ output
24
+ end
25
+
26
+ describe ShowFeature::Processor do
27
+ before do
28
+ @output = create_a_show
29
+ @show = @output.raw_name
30
+ end
31
+
32
+ it "can be created with a string argument" do
33
+ ShowFeature::Processor.new(@show).raw_name.must_equal @show
34
+ end
35
+
36
+ it "must raised an ArgumentError if mime type does not match a video file type" do
37
+ result = lambda{ ShowFeature::Processor.new('show')}
38
+ result.must_raise ShowFeature::ArgumentError
39
+ error = result.call rescue $!
40
+ error.message.must_equal 'argument does not match a video file type'
41
+ end
42
+
43
+
44
+ describe "when asked to be hashed" do
45
+ before do
46
+ @sf = ShowFeature::Processor.new(@show)
47
+ end
48
+ it "must return an hash" do
49
+ @sf.parse
50
+ @sf.to_hsh.must_be_instance_of Hash
51
+ end
52
+ it "must filled the hash correctly " do
53
+ @sf.parse
54
+ @sf.to_hsh.must_equal({ :name => @output.name.gsub('.', ' '),
55
+ :season => @output.season,
56
+ :episode => @output.episode,
57
+ :team => @output.team })
58
+ end
59
+ it "must return an empty hash if showfeature is not parsed yet" do
60
+ @sf.to_hsh.must_be_empty
61
+ end
62
+ end
63
+
64
+ describe "when asked to parse the show name" do
65
+ before do
66
+ @sf = ShowFeature::Processor.new(@show)
67
+ @sf.parse
68
+ end
69
+ it "must retrieve the element" do
70
+ assert_block do
71
+ [:name, :episode, :team, :raw_name].
72
+ all? {|stuff|
73
+ @output.send(stuff).eql? @sf.send(stuff).gsub(' ','.')
74
+ }
75
+ @output.season.to_i.must_equal @sf.season.to_i
76
+ end
77
+ end
78
+ end
79
+
80
+ describe "when asked if parsed" do
81
+ before do
82
+ @sf = ShowFeature::Processor.new(@show)
83
+ end
84
+ it "must return true if parsed" do
85
+ @sf.parsed?.wont_equal true
86
+ @sf.parse
87
+ @sf.parsed?.must_equal true
88
+ end
89
+ end
90
+
91
+ describe "when asked to replace an element" do
92
+ before do
93
+ @sf = ShowFeature::Processor.new(@show)
94
+ end
95
+ it "must replace raw_name by default when a string is passed" do
96
+ @sf.parse
97
+ @sf.replace("foo.s01e01.hdtv-bar.mp4")
98
+ @sf.raw_name.must_equal "foo.s01e01.hdtv-bar.mp4"
99
+ end
100
+ it "must replace the wanted attributes" do
101
+ @sf.parse
102
+ @sf.replace(name: "foo", season: '01', episode: 1, team: "bar")
103
+ @sf.raw_name.must_match /foo.*01.?01.*bar/
104
+ end
105
+ it "must raised if not parsed yet" do
106
+ result = lambda{ @sf.replace(:name => "foo")}
107
+ result.must_raise ShowFeature::NotParsedError
108
+ error = result.call rescue $!
109
+ error.message.must_equal 'showfeature cannot complete replace if show is not parsed'
110
+ end
111
+ it "must raised if the given argument is not of type String or Hash" do
112
+ result = lambda{ @sf.replace([])}
113
+ result.must_raise ShowFeature::TypeError
114
+ error = result.call rescue $!
115
+ error.message.must_equal 'argument must be of type String or Hash'
116
+ end
117
+
118
+ it "wont do anything if argument has not a video filename when a String is passed" do
119
+ @sf.parse
120
+ @sf.replace 'foo'
121
+ @sf.raw_name.must_equal @output.raw_name
122
+ end
123
+ end
124
+
125
+ describe "when asked if it is a video file" do
126
+ before do
127
+ @sf = ShowFeature::Processor.new(@show)
128
+ end
129
+ it "must be true or false" do
130
+ assert_block do
131
+ [TrueClass,FalseClass].any? {|elt| @sf.video_file_type?.instance_of? elt}
132
+ end
133
+ end
134
+ end
135
+
136
+ end
metadata ADDED
@@ -0,0 +1,58 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: showfeature
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Allan Seymour
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-12-04 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: This library allows to find the relevant features in a tv show filename
15
+ (e.g. [name].S[season]E[episode].hdtv-[team].avi)
16
+ email: banks.the.megalithic.stone@gmail.com
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - .gitignore
22
+ - Gemfile
23
+ - Gemfile.lock
24
+ - LICENSE
25
+ - README.md
26
+ - lib/showfeature.rb
27
+ - lib/showfeature/exception.rb
28
+ - lib/showfeature/processor.rb
29
+ - lib/showfeature/version.rb
30
+ - showfeature.gemspec
31
+ - spec/showfeature_spec.rb
32
+ homepage: https://github.com/stonebanks/showfeature/
33
+ licenses: []
34
+ post_install_message:
35
+ rdoc_options: []
36
+ require_paths:
37
+ - lib
38
+ required_ruby_version: !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: 1.9.1
44
+ required_rubygems_version: !ruby/object:Gem::Requirement
45
+ none: false
46
+ requirements:
47
+ - - ! '>='
48
+ - !ruby/object:Gem::Version
49
+ version: '0'
50
+ requirements: []
51
+ rubyforge_project:
52
+ rubygems_version: 1.8.23
53
+ signing_key:
54
+ specification_version: 3
55
+ summary: This library allows to find the relevant features in a tv show filename (e.g.
56
+ [name].S[season]E[episode].hdtv-[team].avi)
57
+ test_files:
58
+ - spec/showfeature_spec.rb