mediaman 0.0.1

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,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .DS_Store
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in mediaman.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Wil Gieseler
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # Mediaman
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'mediaman'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install mediaman
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/mediaman ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ lib = File.expand_path(File.dirname(__FILE__) + '/../lib')
4
+ $LOAD_PATH.unshift(lib) if File.directory?(lib) && !$LOAD_PATH.include?(lib)
5
+
6
+ require 'mediaman'
7
+ require 'mediaman/command'
8
+
9
+ Mediaman::CommandLine.start
@@ -0,0 +1,35 @@
1
+ module Mediaman
2
+
3
+ require "thor"
4
+
5
+ class CommandLine < Thor
6
+
7
+ desc "add <file>", "sorts the file according to its metadata"
8
+ method_option :library, type: :string, aliases: "-l", desc: "Media library base folder to sort into.", default: "."
9
+ method_option :batch, type: :boolean, aliases: "-b", desc: "Adds each file or folder in the passed-in folder to the library.", default: false
10
+ def add(path)
11
+ library_document = LibraryDocument.from_path path
12
+ library_document.library_path = File.expand_path options[:library]
13
+ # puts "Sidecar path:"
14
+ # puts library_document.library_sidecar_path
15
+ puts "Video:"
16
+ puts library_document.video_files
17
+ puts "Junk:"
18
+ puts library_document.junk_files
19
+ puts "Files to move:"
20
+ puts library_document.files_to_move.to_yaml
21
+ puts "moving"
22
+ library_document.move_to_library!
23
+ library_document.save_and_apply_metadata!
24
+ end
25
+
26
+ desc "metadata <file>", "returns all the metadata discoverable about this file or directory"
27
+ def metadata(path)
28
+ doc = Document.from_path(path)
29
+ doc.save_and_apply_metadata!
30
+ puts "Metadata and image saved to #{doc.extras_path}"
31
+ end
32
+
33
+ end
34
+
35
+ end
@@ -0,0 +1,206 @@
1
+ require 'yaml'
2
+ require 'mini_subler'
3
+ require "open-uri"
4
+
5
+ module Mediaman
6
+
7
+ # Represents an on-disk folder or file representation
8
+ # of some kind of media.
9
+
10
+ class Document
11
+
12
+ def self.from_path(path)
13
+ f = self.new
14
+ f.path = File.expand_path path
15
+ f
16
+ end
17
+
18
+ attr_accessor :path
19
+
20
+ def rebase!(path)
21
+ self.path = path
22
+ @primary_video_file = nil
23
+ @junk_files = nil
24
+ @video_files = nil
25
+ end
26
+
27
+ def save_and_apply_metadata!
28
+ extract_metadata!
29
+ save_sidecar!
30
+ download_image!
31
+ add_metadata_to_file!
32
+ # Rewrap mkv to mp4.
33
+ end
34
+
35
+ def add_metadata_to_file!
36
+ h = metadata.to_subler_hash
37
+ h[:artwork] = artwork_path if File.exists?(artwork_path)
38
+ puts "Primary: #{primary_video_file}"
39
+ puts h.to_s
40
+ MiniSubler::Command.vendored.set_metadata primary_video_file, h
41
+ rescue
42
+ puts "Exception while adding metadata to file."
43
+ end
44
+
45
+ def download_image!
46
+ if !File.exists?(artwork_path) && metadata.canonical_image_url.present?
47
+ FileUtils.mkdir_p(File.dirname(artwork_path))
48
+ open(metadata.canonical_image_url) {|f|
49
+ File.open(artwork_path, "wb") do |file|
50
+ file.puts f.read
51
+ end
52
+ }
53
+ end
54
+ end
55
+
56
+ def artwork_path
57
+ extra_path "Artwork#{metadata.canonical_image_url.present? ? File.extname(metadata.canonical_image_url) : ".jpg"}"
58
+ end
59
+
60
+ def metadata
61
+ @metadata ||= begin
62
+ metadata = {}
63
+ metadata.merge!(local_metadata || {})
64
+ metadata.merge!(remote_metadata || {})
65
+ metadata.reject!{|k, v| v.blank?}
66
+ Metadata.new(metadata)
67
+ end
68
+ end
69
+ alias_method :extract_metadata!, :metadata
70
+
71
+ def local_metadata
72
+ @local_metadata ||= begin
73
+ metadata = {}
74
+ metadata.merge!(filename_metadata || {})
75
+ metadata.merge!(video_metadata || {})
76
+ metadata.merge!(sidecar_metadata || {})
77
+ metadata.reject!{|k, v| v.blank?}
78
+ Metadata.new(metadata)
79
+ end
80
+ end
81
+
82
+ def local_metadata_fetched?
83
+ @local_metadata.present?
84
+ end
85
+
86
+ def remote_metadata
87
+ @remote_metadata ||= begin
88
+ if local_metadata['movie']
89
+ Metadata.new({'movie_details' => Trakt::Movie.new(title: local_metadata['name'], year: local_metadata['year'])})
90
+ elsif local_metadata['tv']
91
+ tv = Trakt::TVEpisode.new show_title: local_metadata['name'], season_number: local_metadata['season_number'], episode_number: local_metadata['episode_number']
92
+ Metadata.new({'episode_details' => tv.to_hash, 'show_details' => tv.show.to_hash})
93
+ end
94
+ end
95
+ end
96
+
97
+ def filename
98
+ File.basename(self.path, '.*')
99
+ end
100
+
101
+ def filename_metadata
102
+ @filename_metadata ||= MediaFilename.new(self.filename).to_hash.try(:stringify_keys)
103
+ end
104
+
105
+ def video_metadata
106
+ @video_metadata ||= MiniSubler::Command.vendored.get_metadata(self.video_files.first).try(:stringify_keys)
107
+ end
108
+
109
+ def standalone_extras_path
110
+ File.join(File.dirname(self.path), File.basename(self.path, '.*') + " Extras")
111
+ end
112
+
113
+ def library_extras_path
114
+ File.join(File.dirname(self.path), "Extras", File.basename(self.path, '.*'))
115
+ end
116
+
117
+ def extras_paths
118
+ [library_extras_path, standalone_extras_path]
119
+ end
120
+
121
+ def extras_path
122
+ d = nil
123
+ for path in extras_paths.uniq
124
+ d = path if File.exists?(path)
125
+ end
126
+ d = extras_paths.last if d.nil?
127
+ d
128
+ end
129
+
130
+ def extra_path(file)
131
+ File.join extras_path, file
132
+ end
133
+
134
+ def extra_paths(file)
135
+ extras_paths.uniq.map do |x|
136
+ File.join x, file
137
+ end
138
+ end
139
+
140
+ def sidecar_metadata
141
+ @sidecar_metadata ||= begin
142
+ y = {}
143
+ extra_paths("Metadata.yml").each do |path|
144
+ if File.exists?(path)
145
+ y.merge! YAML::load(File.open(path))
146
+ end
147
+ end
148
+ y.stringify_keys
149
+ end
150
+ end
151
+
152
+ def save_sidecar!(path = extra_path("Metadata.yml"))
153
+ FileUtils.mkdir_p(File.dirname(path))
154
+ File.open(path, 'w') {|f| f.write(self.metadata.stringify_keys.to_yaml) }
155
+ end
156
+
157
+ def video_files
158
+ sort_junk! unless @video_files
159
+ @video_files
160
+ end
161
+
162
+ def secondary_video_files
163
+ if video_files && primary_video_file
164
+ v = video_files.dup
165
+ v.delete primary_video_file
166
+ v
167
+ else
168
+ []
169
+ end
170
+ end
171
+
172
+ def primary_video_file
173
+ sort_junk! unless @video_files
174
+ @primary_video_file ||= @video_files.sort{|a, b| File.size?(a) <=> File.size?(b) }.first
175
+ end
176
+
177
+ def junk_files
178
+ sort_junk! unless @junk_files
179
+ @junk_files
180
+ end
181
+
182
+ private
183
+
184
+ def sort_junk!
185
+ junk_files = []
186
+ video_files = []
187
+ if File.directory?(self.path)
188
+ Dir.glob File.join(self.path, "*") do |file|
189
+ filepath = file
190
+ case File.extname(file)[1..-1]
191
+ when /mov|mp4|m4v|avi|wmv|mkv/i then
192
+ video_files << filepath
193
+ else
194
+ junk_files << filepath
195
+ end
196
+ end
197
+ else
198
+ video_files << self.path
199
+ end
200
+ @video_files = video_files
201
+ @junk_files = junk_files
202
+ end
203
+
204
+ end
205
+
206
+ end
@@ -0,0 +1,82 @@
1
+ module Mediaman
2
+
3
+ # Represents an on-disk folder or file representation
4
+ # of some kind of media.
5
+ #
6
+ # This type is part of a "library" folder strucure.
7
+
8
+ class LibraryDocument < Document
9
+
10
+ attr_accessor :library_path
11
+
12
+ def move_to_library!
13
+ files_to_move.each do |original_file, new_file|
14
+ FileUtils.mkdir_p(File.dirname(new_file))
15
+ FileUtils.move(original_file, new_file)
16
+ end
17
+ rebase! library_file_path
18
+ FileUtils.mkdir_p library_extras_path
19
+ end
20
+
21
+ def files_to_move
22
+ files = {}
23
+ files[primary_video_file] = library_file_path if primary_video_file
24
+ for file in junk_files + secondary_video_files
25
+ files[file] = File.join desired_library_junk_path, File.basename(file)
26
+ end
27
+ files
28
+ end
29
+
30
+ def library_filename
31
+ if metadata.tv? && metadata.canonical_show_name
32
+ s = "#{metadata.canonical_show_name}/Season #{metadata.season_number}/#{metadata.episode_id}"
33
+ s << " - #{metadata.canonical_episode_name}" if metadata.canonical_episode_name.present?
34
+ s
35
+ elsif metadata.year.present?
36
+ "#{metadata.canonical_movie_title.gsub(":", " - ")} (#{metadata.year})"
37
+ else
38
+ metadata.name
39
+ end
40
+ end
41
+
42
+ def library_versioned_filename(n = 1)
43
+ extension = File.extname(primary_video_file)[1..-1]
44
+ old_filename = File.basename(primary_video_file, '.*')
45
+ v = ""
46
+ v = " v#{n}" if n > 1
47
+ if library_filename.present?
48
+ "#{library_filename}#{v}.#{extension}"
49
+ else
50
+ "#{old_filename}#{v}.#{extension}"
51
+ end
52
+ end
53
+
54
+ def library_file_path
55
+ @library_file_path ||= begin
56
+ base_path = File.join File.expand_path(library_path), metadata.library_category
57
+ i = 1
58
+ dup = true
59
+ while dup == true
60
+ path = File.join base_path, library_versioned_filename(i)
61
+ if File.exists?(path) || File.directory?(path)
62
+ i = i + 1
63
+ dup = true
64
+ else
65
+ dup = false
66
+ end
67
+ end
68
+ path
69
+ end
70
+ end
71
+
72
+ def desired_library_extras_path
73
+ File.join File.dirname(library_file_path), "Extras", File.basename(library_file_path, '.*')
74
+ end
75
+
76
+ def desired_library_junk_path
77
+ File.join desired_library_extras_path, "Junk"
78
+ end
79
+
80
+ end
81
+
82
+ end
@@ -0,0 +1,152 @@
1
+ module Mediaman
2
+
3
+ class MediaFilename
4
+
5
+ attr_accessor :filename
6
+
7
+ def initialize(filename)
8
+ self.filename = filename
9
+ parse_name!
10
+ formatted_name # To init year
11
+ end
12
+
13
+ def to_hash
14
+ {
15
+ filename: self.filename,
16
+ name: self.formatted_name,
17
+ raw_name: self.raw_name,
18
+ year: self.year,
19
+ tv: self.tv?,
20
+ movie: self.movie?,
21
+ season_number: self.season,
22
+ episode_number: self.episode,
23
+ hd: self.hd?,
24
+ hd_format: self.hd_format
25
+ }
26
+ end
27
+
28
+ def parse_name!
29
+ name = self.filename + ".mov"
30
+
31
+ # Normal matching
32
+ normal_matches = name.match(/^([a-zA-Z0-9.]*)\.S([0-9]{1,2})E([0-9]{1,2}).*$/i)
33
+ if normal_matches
34
+ @item_name = normal_matches[1]
35
+ @season = normal_matches[2].to_i
36
+ @episode = normal_matches[3].to_i
37
+ end
38
+
39
+ unless @item_name && @season && @episode
40
+ # Mythbusters hack
41
+ mythbusters_matches = name.match(/(myth.*)([0-9][0-9])([0-9][0-9])/i)
42
+ if mythbusters_matches && mythbusters_matches[1].downcase.include?("myth")
43
+ @item_name = "Mythbusters"
44
+ @season = mythbusters_matches[2].to_i
45
+ @episode = mythbusters_matches[3].to_i
46
+ end
47
+ end
48
+
49
+ end
50
+
51
+ def raw_name
52
+ @item_name || self.filename
53
+ end
54
+
55
+ def formatted_name
56
+ perioded_name = []
57
+
58
+ name =
59
+
60
+ name_string = raw_name.gsub("'", "")
61
+ name_string = raw_name.gsub(";", "")
62
+
63
+ splitsies = name_string.split(/[ -.\[\]]/)
64
+ splitsies.each_index do |i|
65
+ x = splitsies[i].split(" ")
66
+ x = x.split("+")
67
+ x = x.split("_")
68
+ x = x.split("[")
69
+ x = x.split("]")
70
+ splitsies[i] = x
71
+ end
72
+
73
+ name_done = false
74
+ i = 0
75
+ for item in splitsies.flatten
76
+ int = item.to_i
77
+ if (1900..Time.now.year + 3).cover?(int) && i > 0
78
+ @year = int
79
+ name_done = true
80
+ elsif item == "720p"
81
+ name_done = true
82
+ else
83
+ perioded_name << item unless name_done
84
+ end
85
+ i += 1
86
+ end
87
+ name = perioded_name.join(" ")
88
+
89
+ # Hacks
90
+ name.gsub! /Extended( Version)/i, ""
91
+
92
+ name
93
+ end
94
+
95
+ def title_slug
96
+ slug = formatted_name.parameterize
97
+
98
+ #Hacks
99
+ slug = "the-newsroom-2012" if slug == "the-newsroom"
100
+
101
+ slug
102
+ end
103
+
104
+ def season
105
+ @season
106
+ end
107
+
108
+ def episode
109
+ @episode
110
+ end
111
+
112
+ def tv?
113
+ episode.present? && season.present?
114
+ end
115
+
116
+ def year
117
+ @year
118
+ end
119
+
120
+ def movie?
121
+ !tv? && year.present?
122
+ end
123
+
124
+ def hd?
125
+ self.filename.include?("720p") || self.filename.include?("1080p") || self.filename.include?("HDTV") || self.filename.include?("HDRip")
126
+ end
127
+
128
+ def h264?
129
+ (self.filename =~ /m4v|mp4|h264|x264/i).present?
130
+ end
131
+
132
+ def hd_format
133
+ return "SD" unless hd?
134
+ if self.filename.include?("720p")
135
+ "720p"
136
+ elsif self.filename.include?("1080p")
137
+ "1080p"
138
+ else
139
+ "HD"
140
+ end
141
+ end
142
+
143
+ def to_s
144
+ formatted_name
145
+ end
146
+
147
+ def debug
148
+ "name: #{name}, formatted_name: #{formatted_name}, slug: #{slug}, season: #{season}, episode: #{episode}, hd?: #{hd?}, tv?: #{tv?}, string: #{string}"
149
+ end
150
+
151
+ end
152
+ end
@@ -0,0 +1,90 @@
1
+ require 'hashie'
2
+ require 'digest/md5'
3
+
4
+ module Mediaman
5
+
6
+ class Metadata < Hashie::Mash
7
+
8
+ def canonical_show_name
9
+ show_details.try(:title).presence || name.presence || raw_name.presence
10
+ end
11
+
12
+ def canonical_episode_name
13
+ episode_details.title.presence
14
+ end
15
+
16
+ def canonical_movie_title
17
+ movie_details.try(:title).presence || name.presence || raw_name.presence
18
+ end
19
+
20
+ def episode_id
21
+ "#{season_number}x#{"%02d" % episode_number}"
22
+ end
23
+
24
+ def library_category
25
+ return "TV Shows" if tv?
26
+ return "Movies" if movie?
27
+ "Other Media"
28
+ end
29
+
30
+ def canonical_image_url
31
+ if tv?
32
+ episode_details.try(:[], "images").try(:first).try(:last)
33
+ else
34
+ movie_details.try(:[], "poster").presence
35
+ end
36
+ end
37
+
38
+ def canonical_description
39
+ if tv?
40
+ episode_details.try(:[], "overview").presence
41
+ else
42
+ movie_details.try(:[], "overview").presence
43
+ end
44
+ end
45
+
46
+ def canonical_director
47
+ if movie?
48
+ d = movie_details.try(:[], "people").try(:[], "directors").presence
49
+ d.map{|director| director.name}.join ", "
50
+ end
51
+ end
52
+
53
+ def canonical_rating
54
+ movie_details.try(:[], "certification").presence
55
+ end
56
+
57
+ def canonical_year
58
+ movie_details.try(:[], "year").presence || year.presence
59
+ end
60
+
61
+ def uuid
62
+ movie_details.try(:[], "imdb_id") || Digest::MD5.hexdigest("#{filename}")
63
+ end
64
+
65
+ def to_subler_hash
66
+ h = {}
67
+ if movie?
68
+ h[:name] = canonical_movie_title
69
+ h[:media_kind] = "Movie"
70
+ h[:rating] = canonical_rating if canonical_rating
71
+ h[:year] = canonical_year if canonical_year
72
+ end
73
+ if tv?
74
+ h[:name] = canonical_episode_name
75
+ h[:tv_show] = canonical_show_name
76
+ h[:album] = canonical_show_name
77
+ h[:tv_episode_id] = episode_id
78
+ h[:tv_episode_number] = episode_number
79
+ h[:tv_season] = season_number
80
+ h[:track_number] = "#{episode_number}/0"
81
+ h[:media_kind] = "TV Show"
82
+ end
83
+ h[:description] = canonical_description if canonical_description.present?
84
+ h[:hd_video] = true if hd?
85
+ h
86
+ end
87
+
88
+ end
89
+
90
+ end
@@ -0,0 +1,23 @@
1
+ module Mediaman
2
+
3
+ class TemporaryDocument < Document
4
+
5
+ def self.from_name(name)
6
+ f = self.new
7
+ f.path = name
8
+ f
9
+ end
10
+
11
+ def metadata
12
+ @metadata ||= begin
13
+ metadata = {}
14
+ metadata.merge!(filename_metadata || {})
15
+ metadata.merge!(remote_metadata || {})
16
+ metadata.reject!{|k, v| v.blank?}
17
+ Metadata.new(metadata)
18
+ end
19
+ end
20
+
21
+ end
22
+
23
+ end
@@ -0,0 +1,66 @@
1
+ require 'httparty'
2
+
3
+ module Mediaman
4
+
5
+ module Trakt
6
+
7
+ attr_accessor :api_key
8
+ def self.api_key=(key)
9
+ @@api_key = key
10
+ end
11
+
12
+ def self.api_key
13
+ defined?(@@api_key) ? @@api_key : ENV['TRAKT_API_KEY']
14
+ end
15
+
16
+ class Fetcher < Hash
17
+ include HTTParty
18
+ format :json
19
+
20
+ def self.from_hash(hash = {})
21
+ f = self.new()
22
+ f.merge!(hash) if hash.present?
23
+ f
24
+ end
25
+
26
+ def initialize(options = {})
27
+ self.options = options
28
+ self.merge!(fetch! || {}) if self.respond_to?(:fetch!)
29
+ end
30
+ attr_accessor :options
31
+ attr_accessor :response
32
+
33
+ end
34
+
35
+ class Movie < Fetcher
36
+
37
+ def slug
38
+ "#{options[:title].parameterize}-#{options[:year].to_s.parameterize}"
39
+ end
40
+
41
+ def fetch!
42
+ Movie.get("http://api.trakt.tv/movie/summary.json/#{Trakt.api_key}/#{slug}")
43
+ end
44
+
45
+ end
46
+
47
+ class TVEpisode < Fetcher
48
+
49
+ attr_accessor :show
50
+
51
+ def fetch!
52
+ url = "http://api.trakt.tv/show/episode/summary.json/#{Trakt.api_key}/#{options[:show_title].parameterize}/#{options[:season_number]}/#{options[:episode_number]}"
53
+ self.response = r = self.class.get(url)
54
+ self.show = Trakt::TVShow.from_hash self.response['show']
55
+ self.response['episode']
56
+ end
57
+
58
+ end
59
+
60
+ class TVShow < Fetcher
61
+
62
+ end
63
+
64
+ end
65
+
66
+ end
@@ -0,0 +1,3 @@
1
+ module Mediaman
2
+ VERSION = "0.0.1"
3
+ end
data/lib/mediaman.rb ADDED
@@ -0,0 +1,13 @@
1
+ # Dependencies
2
+ require 'active_support/all'
3
+
4
+ # Helpers
5
+ require "mediaman/version"
6
+ require "mediaman/media_filename"
7
+ require "mediaman/trakt"
8
+
9
+ # Models
10
+ require "mediaman/metadata"
11
+ require "mediaman/document"
12
+ require "mediaman/temporary_document"
13
+ require "mediaman/library_document"
data/mediaman.gemspec ADDED
@@ -0,0 +1,29 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'mediaman/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "mediaman"
8
+ gem.version = Mediaman::VERSION
9
+ gem.authors = ["Wil Gieseler"]
10
+ gem.email = ["supapuerco@gmail.com"]
11
+ gem.description = "Helps you organize your media!"
12
+ gem.summary = "Helps you organize your media!"
13
+ gem.homepage = "http://github.com/supapuerco/mediaman"
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.add_dependency 'activesupport', '>=3.0.0'
21
+ gem.add_dependency 'thor'
22
+ gem.add_dependency 'mini_subler'
23
+ gem.add_dependency 'httparty'
24
+ gem.add_dependency 'hashie'
25
+
26
+ gem.add_development_dependency "rake"
27
+ gem.add_development_dependency "rspec"
28
+
29
+ end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+
3
+ describe Mediaman::MediaFilename do
4
+
5
+ def parse(filename)
6
+ Mediaman::MediaFilename.new(filename).to_hash
7
+ end
8
+
9
+ describe "correctly parses" do
10
+
11
+ it "The Descendants" do
12
+ h = parse("The Descendants")
13
+ h[:name].should == "The Descendants"
14
+ end
15
+
16
+ it "The.Newsroom.S01E01.COOOLNESS" do
17
+ h = parse("The.Newsroom.S01E01.COOOLNESS")
18
+ h[:name].should == "The Newsroom"
19
+ h[:tv].should be_true
20
+ h[:episode_number].should == 1
21
+ end
22
+
23
+ it "John.Adams.S01E01.720p.HDTV.x264" do
24
+ h = parse("John.Adams.S01E01.720p.HDTV.x264")
25
+ h[:name].should == "John Adams"
26
+ end
27
+
28
+ it "John Adams.S01E01.720p.HDTV.x264" do
29
+ h = parse("John Adams.S01E01.720p.HDTV.x264")
30
+ h[:name].should == "John Adams"
31
+ end
32
+
33
+ end
34
+
35
+
36
+ end
@@ -0,0 +1,13 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # Require this file using `require "spec_helper.rb"` to ensure that it is only
4
+ # loaded once.
5
+ #
6
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
7
+ RSpec.configure do |config|
8
+ config.treat_symbols_as_metadata_keys_with_true_values = true
9
+ config.run_all_when_everything_filtered = true
10
+ config.filter_run :focus
11
+ end
12
+
13
+ require_relative "../lib/mediaman"
metadata ADDED
@@ -0,0 +1,150 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mediaman
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.1
6
+ platform: ruby
7
+ authors:
8
+ - Wil Gieseler
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2012-08-20 00:00:00 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: activesupport
17
+ prerelease: false
18
+ requirement: &id001 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 3.0.0
24
+ type: :runtime
25
+ version_requirements: *id001
26
+ - !ruby/object:Gem::Dependency
27
+ name: thor
28
+ prerelease: false
29
+ requirement: &id002 !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: "0"
35
+ type: :runtime
36
+ version_requirements: *id002
37
+ - !ruby/object:Gem::Dependency
38
+ name: mini_subler
39
+ prerelease: false
40
+ requirement: &id003 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: "0"
46
+ type: :runtime
47
+ version_requirements: *id003
48
+ - !ruby/object:Gem::Dependency
49
+ name: httparty
50
+ prerelease: false
51
+ requirement: &id004 !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ type: :runtime
58
+ version_requirements: *id004
59
+ - !ruby/object:Gem::Dependency
60
+ name: hashie
61
+ prerelease: false
62
+ requirement: &id005 !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: "0"
68
+ type: :runtime
69
+ version_requirements: *id005
70
+ - !ruby/object:Gem::Dependency
71
+ name: rake
72
+ prerelease: false
73
+ requirement: &id006 !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: "0"
79
+ type: :development
80
+ version_requirements: *id006
81
+ - !ruby/object:Gem::Dependency
82
+ name: rspec
83
+ prerelease: false
84
+ requirement: &id007 !ruby/object:Gem::Requirement
85
+ none: false
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: "0"
90
+ type: :development
91
+ version_requirements: *id007
92
+ description: Helps you organize your media!
93
+ email:
94
+ - supapuerco@gmail.com
95
+ executables:
96
+ - mediaman
97
+ extensions: []
98
+
99
+ extra_rdoc_files: []
100
+
101
+ files:
102
+ - .gitignore
103
+ - .rspec
104
+ - Gemfile
105
+ - LICENSE.txt
106
+ - README.md
107
+ - Rakefile
108
+ - bin/mediaman
109
+ - lib/mediaman.rb
110
+ - lib/mediaman/command.rb
111
+ - lib/mediaman/document.rb
112
+ - lib/mediaman/library_document.rb
113
+ - lib/mediaman/media_filename.rb
114
+ - lib/mediaman/metadata.rb
115
+ - lib/mediaman/temporary_document.rb
116
+ - lib/mediaman/trakt.rb
117
+ - lib/mediaman/version.rb
118
+ - mediaman.gemspec
119
+ - spec/mediaman/media_filename_spec.rb
120
+ - spec/spec_helper.rb
121
+ homepage: http://github.com/supapuerco/mediaman
122
+ licenses: []
123
+
124
+ post_install_message:
125
+ rdoc_options: []
126
+
127
+ require_paths:
128
+ - lib
129
+ required_ruby_version: !ruby/object:Gem::Requirement
130
+ none: false
131
+ requirements:
132
+ - - ">="
133
+ - !ruby/object:Gem::Version
134
+ version: "0"
135
+ required_rubygems_version: !ruby/object:Gem::Requirement
136
+ none: false
137
+ requirements:
138
+ - - ">="
139
+ - !ruby/object:Gem::Version
140
+ version: "0"
141
+ requirements: []
142
+
143
+ rubyforge_project:
144
+ rubygems_version: 1.8.15
145
+ signing_key:
146
+ specification_version: 3
147
+ summary: Helps you organize your media!
148
+ test_files:
149
+ - spec/mediaman/media_filename_spec.rb
150
+ - spec/spec_helper.rb