plexify 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 +17 -0
- data/.plexify.yml +4 -0
- data/Gemfile +9 -0
- data/LICENSE.txt +22 -0
- data/README.md +31 -0
- data/Rakefile +1 -0
- data/bin/plexify +7 -0
- data/lib/plexify/execute.rb +170 -0
- data/lib/plexify/logger.rb +19 -0
- data/lib/plexify/media.rb +13 -0
- data/lib/plexify/media_manager.rb +88 -0
- data/lib/plexify/media_organizer.rb +71 -0
- data/lib/plexify/prepare.rb +91 -0
- data/lib/plexify/version.rb +3 -0
- data/lib/plexify.rb +23 -0
- data/plexify.gemspec +19 -0
- metadata +62 -0
data/.gitignore
ADDED
data/.plexify.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Pierre FILSTROFF
|
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,31 @@
|
|
1
|
+
# Plexify
|
2
|
+
|
3
|
+
Currently in development. Not working yet.
|
4
|
+
|
5
|
+
TODO: Write a gem description
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
gem 'plexify'
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install plexify
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
TODO: Write usage instructions here
|
24
|
+
|
25
|
+
## Contributing
|
26
|
+
|
27
|
+
1. Fork it
|
28
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
29
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
30
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
31
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/plexify
ADDED
@@ -0,0 +1,170 @@
|
|
1
|
+
module Plexify
|
2
|
+
module Execute
|
3
|
+
class Plexify
|
4
|
+
# Plexify::Execute initialize method
|
5
|
+
def initialize(args)
|
6
|
+
@args = args
|
7
|
+
@options = {}
|
8
|
+
@missing_args = []
|
9
|
+
end
|
10
|
+
|
11
|
+
# Parses the command-line arguments and execute files processing
|
12
|
+
def parse!
|
13
|
+
begin
|
14
|
+
@opts = OptionParser.new(&method(:set_opts))
|
15
|
+
@opts.parse!(@args)
|
16
|
+
check_arguments
|
17
|
+
|
18
|
+
if @args.any?
|
19
|
+
@options[:source] = @args[0] unless @options[:source]
|
20
|
+
@options[:destination] = @args[1] unless @options[:destination]
|
21
|
+
end
|
22
|
+
|
23
|
+
process_result
|
24
|
+
|
25
|
+
# Puts missing arguments
|
26
|
+
rescue OptionParser::MissingArgument => e
|
27
|
+
built_string = e.message
|
28
|
+
for arg in @missing_args
|
29
|
+
built_string += arg
|
30
|
+
unless @missing_args.last == arg
|
31
|
+
built_string += ", "
|
32
|
+
else
|
33
|
+
built_string += "\n\n"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
puts built_string
|
37
|
+
puts @opts
|
38
|
+
|
39
|
+
# Puts exception message
|
40
|
+
rescue Exception => e
|
41
|
+
raise e if @options[:trace] || e.is_a?(SystemExit)
|
42
|
+
|
43
|
+
print "\n#{e.class}: " unless e.class == RuntimeError
|
44
|
+
puts "#{e.message}"
|
45
|
+
puts " Use --trace for backtrace."
|
46
|
+
end
|
47
|
+
exit 0
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
# Check missing arguments
|
52
|
+
def check_arguments
|
53
|
+
return if @args.size == 2
|
54
|
+
|
55
|
+
@missing_args << "-s [source]" if !@options[:source] && !@args[0]
|
56
|
+
@missing_args << "-d [destination]" if !@options[:destination] && !@options[:movies_destination] && !@options[:series_destination]
|
57
|
+
@missing_args << "--movies-destination [destination]" if !@options[:destination] && !@options[:movies_destination] && !@options[:series_destination]
|
58
|
+
@missing_args << "--series-destination [destination]" if !@options[:destination] && !@options[:series_destination] && !@options[:movies_destination]
|
59
|
+
|
60
|
+
if @missing_args.any?
|
61
|
+
raise OptionParser::MissingArgument
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# Set options definition for command-line execution
|
66
|
+
def set_opts(opts)
|
67
|
+
opts.banner = "Usage: plexify -s /media/temp --movies-destination /media/Movies --series-destination /media/Series\n\n"
|
68
|
+
|
69
|
+
opts.on('-s [source]', '--source [source]', 'Source folder which includes media files. Temp folder.') do |source|
|
70
|
+
@options[:source] = source
|
71
|
+
end
|
72
|
+
|
73
|
+
opts.on('-d [destination]', '--destination [dest]', 'Destination folder to put organized.') do |destination|
|
74
|
+
@options[:destination] = destination
|
75
|
+
end
|
76
|
+
|
77
|
+
opts.on('--movies-destination [dest]', 'Destination folder to put organized movies files.') do |movies_destination|
|
78
|
+
@options[:movies_destination] = movies_destination
|
79
|
+
end
|
80
|
+
|
81
|
+
opts.on('--series-destination [dest]', 'Destination folder to put organized series files.') do |series_destination|
|
82
|
+
@options[:series_destination] = series_destination
|
83
|
+
end
|
84
|
+
|
85
|
+
opts.on_tail('-t', '--test', 'Test files name searching in media databases: only print results.') do
|
86
|
+
@options[:test] = true
|
87
|
+
end
|
88
|
+
|
89
|
+
opts.on_tail('--accept-removing-all', :NONE, 'Accept removing source files. [NOT WORKING YET]') do
|
90
|
+
@options[:accept_removing_all] = true
|
91
|
+
end
|
92
|
+
|
93
|
+
opts.on_tail("-?", "-h", "--help", "Show this message.") do
|
94
|
+
puts opts
|
95
|
+
exit
|
96
|
+
end
|
97
|
+
|
98
|
+
opts.on_tail("-v", "--version", "Print version") do
|
99
|
+
puts("Plexify #{VERSION}")
|
100
|
+
exit
|
101
|
+
end
|
102
|
+
|
103
|
+
opts.on_tail('--trace', :NONE, 'Show a full traceback on error') do
|
104
|
+
@options[:trace] = true
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
# Process result
|
109
|
+
def process_result
|
110
|
+
|
111
|
+
Logger.info("=> Preparing source folder")
|
112
|
+
source = Prepare::Source.new(@options)
|
113
|
+
source.prepare
|
114
|
+
Logger.info(" : #{source.files.size} #{source.files.size > 1 ? 'files' : 'file'} found")
|
115
|
+
|
116
|
+
unless @options[:test]
|
117
|
+
Logger.info("\n=> Preparing destination folder")
|
118
|
+
destination = Prepare::Destination.new(@options)
|
119
|
+
destination.prepare
|
120
|
+
end
|
121
|
+
|
122
|
+
media_manager = MediaManager.new
|
123
|
+
media_organizer = MediaOrganizer.new(source, destination) unless @options[:test]
|
124
|
+
|
125
|
+
files_processed_count = 0
|
126
|
+
|
127
|
+
# Process files
|
128
|
+
for file in source.files
|
129
|
+
basename = File.basename(file.path)
|
130
|
+
Logger.info("\n\n=> Analyzing '#{basename}' file...")
|
131
|
+
medias = media_manager.analyze(file)
|
132
|
+
|
133
|
+
# Choose the good media
|
134
|
+
if medias.any?
|
135
|
+
Logger.info("\nFound medias :")
|
136
|
+
|
137
|
+
# If the test argument is present, don't move files or prompt the user
|
138
|
+
if @options[:test]
|
139
|
+
for media in medias
|
140
|
+
Logger.success("\n#{media.data.name} #{media.data.released ? "(#{Date.parse(media.data.released).year})" : nil}")
|
141
|
+
end
|
142
|
+
else
|
143
|
+
Logger.success("\n0: The movie isn't in the list, go next without doing anything.")
|
144
|
+
medias.each_with_index do |media, index|
|
145
|
+
Logger.success("\n#{index+1}: #{media.data.name} #{media.data.released ? "(#{Date.parse(media.data.released).year})" : nil}")
|
146
|
+
end
|
147
|
+
|
148
|
+
Logger.success("\nChoose the movie: ")
|
149
|
+
resp = STDIN.gets.chomp.to_i-1
|
150
|
+
|
151
|
+
if resp >= 0 && resp <= medias.size
|
152
|
+
media = medias[resp]
|
153
|
+
Logger.success("\nMedia found : #{media.data.name} #{media.data.released ? "(#{Date.parse(media.data.released).year})" : nil}")
|
154
|
+
media_organizer.move_to_destination(file, media)
|
155
|
+
files_processed_count += 1
|
156
|
+
elsif resp == -1
|
157
|
+
Logger.info("Aborting...")
|
158
|
+
next
|
159
|
+
end
|
160
|
+
end
|
161
|
+
else
|
162
|
+
Logger.error("\nMedia not found")
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
Logger.info("\n\n=> Files pocessed #{files_processed_count}/#{source.files.size}") unless @options[:test]
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Plexify
|
2
|
+
# Logger class
|
3
|
+
class Logger
|
4
|
+
# print informations
|
5
|
+
def self.info(content)
|
6
|
+
print content
|
7
|
+
end
|
8
|
+
|
9
|
+
# print success in green
|
10
|
+
def self.success(content)
|
11
|
+
print content.colorize(:green)
|
12
|
+
end
|
13
|
+
|
14
|
+
# print errors in red
|
15
|
+
def self.error(content)
|
16
|
+
print content.colorize(:red)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
module Plexify
|
2
|
+
class MediaManager
|
3
|
+
# Initialize variables and load tmdb media manager
|
4
|
+
def initialize
|
5
|
+
@tmdb_api_key = nil
|
6
|
+
@tmdb_default_language = nil
|
7
|
+
load_tmdb
|
8
|
+
end
|
9
|
+
|
10
|
+
# Search for a media in the Tmdb media manager database.
|
11
|
+
def analyze(file)
|
12
|
+
name = File.basename(file.path, File.extname(file.path))
|
13
|
+
splitted_name = name.split(/\W/).map(&:downcase)
|
14
|
+
|
15
|
+
medias = analyse_names(splitted_name, {})
|
16
|
+
|
17
|
+
flattened_medias = []
|
18
|
+
medias.each_pair do |title, media|
|
19
|
+
flattened_medias << media if flattened_medias.empty?
|
20
|
+
unless flattened_medias.map(&:data).map(&:id).include?(media.data.id)
|
21
|
+
media.found_title = title
|
22
|
+
flattened_medias << media
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
return flattened_medias
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
# Load tmdb media manager
|
31
|
+
def load_tmdb
|
32
|
+
load_plexify_config
|
33
|
+
Tmdb.api_key = @tmdb_api_key
|
34
|
+
Tmdb.default_language = @tmdb_default_language
|
35
|
+
end
|
36
|
+
|
37
|
+
# Load plexify config yaml file in the home directory
|
38
|
+
# The file structure is :
|
39
|
+
# plexify:
|
40
|
+
# tmdb:
|
41
|
+
# api_key: xxxx
|
42
|
+
# default_language: en
|
43
|
+
def load_plexify_config
|
44
|
+
config_file_path = File.join(File.dirname(__FILE__), "../../.plexify.yml")
|
45
|
+
config_file = File.open config_file_path
|
46
|
+
yaml_config = YAML::load(config_file)
|
47
|
+
|
48
|
+
tmdb_config = yaml_config["plexify"]["tmdb"]
|
49
|
+
@tmdb_api_key = tmdb_config["api_key"]
|
50
|
+
@tmdb_default_language = tmdb_config["default_language"]
|
51
|
+
end
|
52
|
+
|
53
|
+
def analyse_names(list, medias)
|
54
|
+
title = String.new
|
55
|
+
|
56
|
+
list.each_with_index do |str, index|
|
57
|
+
title << " " if title.length > 0
|
58
|
+
title << str
|
59
|
+
media = find(title)
|
60
|
+
|
61
|
+
if media.empty?
|
62
|
+
if medias.any?
|
63
|
+
shift = list.shift
|
64
|
+
analyse_names(list, medias)
|
65
|
+
end
|
66
|
+
else
|
67
|
+
medias[title] = Media.new(media)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
return medias
|
71
|
+
end
|
72
|
+
|
73
|
+
# Get Levenshtein distance
|
74
|
+
def levenshtein_distance(first, second)
|
75
|
+
Text::Levenshtein.distance(first, second)
|
76
|
+
end
|
77
|
+
|
78
|
+
# Find a movie in the Tmdb database with a title and a limit of one item
|
79
|
+
def find(title)
|
80
|
+
TmdbMovie.find(:title => title, :limit => 1)
|
81
|
+
end
|
82
|
+
|
83
|
+
# Find all movies in the Tmdb database with a title
|
84
|
+
def find_all(title)
|
85
|
+
TmdbMovie.find(:title => title)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module Plexify
|
2
|
+
# Class MediaOrganizer
|
3
|
+
# It manage source and destination folders
|
4
|
+
class MediaOrganizer
|
5
|
+
attr_reader :source
|
6
|
+
attr_reader :destination
|
7
|
+
|
8
|
+
# Initialize
|
9
|
+
def initialize(source, destination)
|
10
|
+
@source = source
|
11
|
+
@destination = destination
|
12
|
+
end
|
13
|
+
|
14
|
+
# Move a file the his appropriate destination folder
|
15
|
+
def move_to_destination(file, media)
|
16
|
+
# Consider media is a movie
|
17
|
+
destination = @destination.movies_folder.path
|
18
|
+
|
19
|
+
# Create an appropriate media folder
|
20
|
+
media_folder_name = "#{media.data.name} (#{Date.parse(media.data.released).year})"
|
21
|
+
media_folder_path = File.join(destination, media_folder_name)
|
22
|
+
file_basename = File.basename(file.path)
|
23
|
+
|
24
|
+
# Create the movie folder
|
25
|
+
FileUtils.mkdir(media_folder_path) unless File.exists?(media_folder_path)
|
26
|
+
media_folder = File.open(media_folder_path)
|
27
|
+
|
28
|
+
if media_folder
|
29
|
+
renamed_file_basename = media_folder_name + File.extname(file_basename)
|
30
|
+
renamed_file_path = File.join(media_folder.path, renamed_file_basename)
|
31
|
+
|
32
|
+
# Copy the file with a progress bar
|
33
|
+
Logger.info("\nCopying file to '#{renamed_file_path}'")
|
34
|
+
copy_with_progressbar(file.path, renamed_file_path)
|
35
|
+
Logger.success("File '#{renamed_file_path}' copied") if File.exists?(renamed_file_path)
|
36
|
+
end
|
37
|
+
|
38
|
+
Logger.info("\nDo you want to remove the source file '#{file_basename}' ? (y/n) ")
|
39
|
+
resp = STDIN.gets.chomp
|
40
|
+
|
41
|
+
if resp.eql?("y")
|
42
|
+
FileUtils.rm file.path
|
43
|
+
Logger.success("File '#{file_basename}' removed")
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
# Copy a file with a great progress bar
|
50
|
+
def copy_with_progressbar(source, destination)
|
51
|
+
source_file = File.new(source, "r")
|
52
|
+
destination_file = File.new(destination, "w")
|
53
|
+
source_size = File.size(source)
|
54
|
+
batch_bytes = ( source_size / 100 ).ceil
|
55
|
+
total = 0
|
56
|
+
|
57
|
+
p_bar = ProgressBar.create(:title => "Copying '#{File.basename(source_file.path)}'", :format => '|%b>%i| %p%% %t')
|
58
|
+
buffer = source_file.sysread(batch_bytes)
|
59
|
+
|
60
|
+
while total < source_size do
|
61
|
+
destination_file.syswrite(buffer)
|
62
|
+
p_bar.progress = ((total*100)/source_size).ceil + 1
|
63
|
+
total += batch_bytes
|
64
|
+
if (source_size - total) < batch_bytes
|
65
|
+
batch_bytes = (source_size - total)
|
66
|
+
end
|
67
|
+
buffer = source_file.sysread(batch_bytes)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
module Plexify
|
2
|
+
module Prepare
|
3
|
+
# Destination class implementation
|
4
|
+
class Destination
|
5
|
+
attr_accessor :folder
|
6
|
+
attr_accessor :movies_folder
|
7
|
+
attr_accessor :series_folder
|
8
|
+
|
9
|
+
# Plexify::Execute initialize method
|
10
|
+
def initialize(options)
|
11
|
+
@destination_path = options[:destination]
|
12
|
+
@movies_destination_path = options[:movies_destination]
|
13
|
+
@series_destination_path = options[:series_destination]
|
14
|
+
end
|
15
|
+
|
16
|
+
def prepare
|
17
|
+
if @destination_path
|
18
|
+
prepare_destination
|
19
|
+
else
|
20
|
+
prepare_destinations
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
protected
|
25
|
+
# Prepare destination
|
26
|
+
def prepare_destination
|
27
|
+
# Create destination folder
|
28
|
+
destination_path = @destination_path
|
29
|
+
@folder = create_or_use_folder(destination_path)
|
30
|
+
|
31
|
+
# Create "Movies" and "TV Shows" folder
|
32
|
+
@movies_folder = create_or_use_folder(destination_path, "Movies")
|
33
|
+
@series_folder = create_or_use_folder(destination_path, "TV Shows")
|
34
|
+
end
|
35
|
+
|
36
|
+
# Prepare destinations
|
37
|
+
def prepare_destinations
|
38
|
+
# Create or use movies and series folders
|
39
|
+
movies_path = @movies_destination_path
|
40
|
+
series_path = @series_destination_path
|
41
|
+
|
42
|
+
@movies_folder = create_or_use_folder(movies_path) if movies_path
|
43
|
+
@series_folder = create_or_use_folder(series_path) if series_path
|
44
|
+
end
|
45
|
+
|
46
|
+
# Create or use a folder
|
47
|
+
def create_or_use_folder(*args)
|
48
|
+
path = args.first
|
49
|
+
|
50
|
+
if args.size > 1
|
51
|
+
name = args[1]
|
52
|
+
end
|
53
|
+
|
54
|
+
folder_path = name ? File.join(path, name) : path
|
55
|
+
|
56
|
+
if File.exists?(folder_path) && File.directory?(folder_path)
|
57
|
+
folder = File.open(folder_path)
|
58
|
+
else
|
59
|
+
Logger.info("\n=> Created missing '#{name ? name : File.basename(folder_path)}' folder in destination folder.")
|
60
|
+
FileUtils.mkdir_p folder_path
|
61
|
+
folder = File.open(folder_path) if File.exists?(folder_path)
|
62
|
+
end
|
63
|
+
|
64
|
+
folder
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# Source class implementation
|
69
|
+
class Source
|
70
|
+
attr_accessor :folder
|
71
|
+
attr_accessor :files
|
72
|
+
|
73
|
+
# Initialize
|
74
|
+
def initialize(options)
|
75
|
+
@source_path = options[:source]
|
76
|
+
@files = Array.new
|
77
|
+
end
|
78
|
+
|
79
|
+
# Prepare source folder
|
80
|
+
def prepare
|
81
|
+
@folder = File.new @source_path
|
82
|
+
|
83
|
+
if File.exists?(@folder.path) && File.directory?(@folder.path)
|
84
|
+
Dir.glob(@folder.path + "/**/*.{mkv,avi,mov}") do |file|
|
85
|
+
@files << File.open(file)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
data/lib/plexify.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'date'
|
3
|
+
require 'ruby-progressbar'
|
4
|
+
require 'optparse'
|
5
|
+
require 'colorize'
|
6
|
+
require 'ruby-tmdb'
|
7
|
+
require 'yaml'
|
8
|
+
require 'text'
|
9
|
+
|
10
|
+
Dir[File.dirname(__FILE__) + "/plexify/**/*"].each{ |file| require file }
|
11
|
+
|
12
|
+
module Plexify
|
13
|
+
class Plexify
|
14
|
+
def initialize(args)
|
15
|
+
@opts = Execute::Plexify.new(args)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Run plexify !
|
19
|
+
def run!
|
20
|
+
@opts.parse!
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/plexify.gemspec
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'plexify/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "plexify"
|
8
|
+
gem.version = Plexify::VERSION
|
9
|
+
gem.authors = ["Pierre FILSTROFF"]
|
10
|
+
gem.email = ["pfilstroff@gmail.com"]
|
11
|
+
gem.description = %q{Organize media folders to get ready with media managers}
|
12
|
+
gem.summary = %q{Media managers files organizer}
|
13
|
+
gem.homepage = ""
|
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
|
+
end
|
metadata
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: plexify
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Pierre FILSTROFF
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-12-03 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: Organize media folders to get ready with media managers
|
15
|
+
email:
|
16
|
+
- pfilstroff@gmail.com
|
17
|
+
executables:
|
18
|
+
- plexify
|
19
|
+
extensions: []
|
20
|
+
extra_rdoc_files: []
|
21
|
+
files:
|
22
|
+
- .gitignore
|
23
|
+
- .plexify.yml
|
24
|
+
- Gemfile
|
25
|
+
- LICENSE.txt
|
26
|
+
- README.md
|
27
|
+
- Rakefile
|
28
|
+
- bin/plexify
|
29
|
+
- lib/plexify.rb
|
30
|
+
- lib/plexify/execute.rb
|
31
|
+
- lib/plexify/logger.rb
|
32
|
+
- lib/plexify/media.rb
|
33
|
+
- lib/plexify/media_manager.rb
|
34
|
+
- lib/plexify/media_organizer.rb
|
35
|
+
- lib/plexify/prepare.rb
|
36
|
+
- lib/plexify/version.rb
|
37
|
+
- plexify.gemspec
|
38
|
+
homepage: ''
|
39
|
+
licenses: []
|
40
|
+
post_install_message:
|
41
|
+
rdoc_options: []
|
42
|
+
require_paths:
|
43
|
+
- lib
|
44
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
45
|
+
none: false
|
46
|
+
requirements:
|
47
|
+
- - ! '>='
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '0'
|
50
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
51
|
+
none: false
|
52
|
+
requirements:
|
53
|
+
- - ! '>='
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
requirements: []
|
57
|
+
rubyforge_project:
|
58
|
+
rubygems_version: 1.8.24
|
59
|
+
signing_key:
|
60
|
+
specification_version: 3
|
61
|
+
summary: Media managers files organizer
|
62
|
+
test_files: []
|