propre 0.1.1 → 0.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e8d4f8827aec0bc2ce9ff3581aa69e2b46973790
4
- data.tar.gz: a7a6f9ec7d86dac0d7344e5666189e305bbf0fdf
3
+ metadata.gz: 1966bbf10fe1b01355b2a2ab9cf14472b994a12e
4
+ data.tar.gz: 1be84abd1cb76629138b985d65447a0744c36aa8
5
5
  SHA512:
6
- metadata.gz: fd7ceed35a8411953d75aa74a088349c16649786b4ad4fb933cf247792665e8896deac8d9bd4855f85cdf12260be6d14b0a4f188057620cda4b572cf560115dc
7
- data.tar.gz: b56cfb345dd0888fa1ecfe176757bd0ce3a9967db5c38508b9836a786e77276c047f484d6e59563f77d1468e075b5536b27d63acafb59e9cda264411b0b68f4c
6
+ metadata.gz: 5c7b3a04b21448056a138f033264c32ff1ec3460acb39f2c2d45365f8d45c00a5ab9fdd969dd035833dc205c1dabd378b3b5d206a4388a8f58bb9d2ea551143d
7
+ data.tar.gz: 9b6a4e71a02ade3b95b61d5c341664fc6bab239dd15c065e814ebe5cd03fe1e3644bff0df6f745dbe47f899f45e3faf80deca32d8ab4a1ac1332976a2134ffec
data/README.md CHANGED
@@ -7,29 +7,29 @@ Propre
7
7
 
8
8
  ##Introduction
9
9
 
10
- **Propre** is a handy tool written in Ruby to bulk rename your movies using [TheMovieDB](https://www.themoviedb.org/) API.
10
+ **Propre** is a handy tool written in Ruby to bulk rename your movies.
11
11
 
12
- Propre will extract the title of a movie from it's filename and then rename it based on search result from TMDB.
12
+ Propre will extract the title of a movie from it's filename and then rename it by removing any useless part.
13
13
 
14
14
  ##Installation
15
15
 
16
16
  gem install propre
17
17
 
18
- To use Propre, you need an API Key from TheMovieDB. Get your API key [here](https://www.themoviedb.org/account).
19
-
20
18
  ##Usage
21
19
 
22
- Usage: propre [OPTION]... SOURCE...
23
- -i, --interactive Run interactively
24
- -R, --recursive Run recursively
25
- -V, --video-only Search for video files only
26
- -s, --sanitize Sanitize filename before search
27
- -d, --dotfile Don't ignore .dotfile
28
- -v, --version Show version information about this program and quit.
29
- -h, --help, --usage Show this help message and quit.
20
+ Commands:
21
+ propre --version, -v # Show version information about this program and quit.
22
+ propre help [COMMAND] # Describe available commands or one specific command
23
+ propre lint [FILENAME...] # Sanitize the specified file. Use --dry for dry run
24
+ propre metadata [FILENAME] # Show metadata about the specified movie or episode
30
25
 
31
26
  ##Changelog
32
27
 
28
+ ### 0.2.0
29
+
30
+ - Complete rewrite with Thor
31
+ - Removing the use of TMDB since search result wasn't successful
32
+
33
33
  ### 0.1.1
34
34
 
35
35
  - Fix bug when no movie was found
data/bin/propre CHANGED
@@ -1,72 +1,44 @@
1
1
  #!/usr/bin/env ruby
2
+ require 'thor'
2
3
 
3
4
  lib = File.expand_path(File.dirname(__FILE__) + '/../lib')
4
5
  $LOAD_PATH.unshift(lib) if File.directory?(lib) && !$LOAD_PATH.include?(lib)
5
6
 
6
- require 'optparse'
7
7
  require 'propre'
8
-
9
- options = {}
10
- OptionParser.new do |opt|
11
- opt.banner = "Usage: #{ File.basename($0) } [OPTION]... SOURCE..."
12
-
13
- opt.on('-i', '--interactive', 'Run interactively') do |v|
14
- options[:interactive] = v
15
- end
16
-
17
- opt.on('-R', '--recursive', 'Run recursively') do |v|
18
- options[:recursive] = v
19
- end
20
-
21
- opt.on('-V', '--video-only', 'Search for video files only') do |v|
22
- options[:videonly] = v
23
- end
24
-
25
- opt.on('-s', '--sanitize', 'Sanitize filename before search') do |v|
26
- options[:sanitize] = v
27
- end
28
-
29
- opt.on('-d', '--dotfile', 'Don\'t ignore .dotfile') do |v|
30
- options[:dotfile] = v
31
- end
32
-
33
- opt.on_tail("-v", "--version", "Show version information about this program and quit.") do
34
- puts "#{Propre} - v#{Propre::VERSION}"
35
- exit
8
+ require 'propre/version'
9
+
10
+ class CLI < Thor
11
+ include Propre
12
+ desc 'lint [FILENAME...]', 'Sanitize the specified file. Use --dry for dry run'
13
+ option :dry, type: :boolean
14
+ option :color, type: :boolean, default: true
15
+ def lint(*args)
16
+ String.disable_colorization(true) unless options[:color]
17
+ args.each do |filename|
18
+ basename, newname, metadata = Propre.basename_newname_metadata(filename)
19
+ if options[:dry]
20
+ unchanged = basename == newname ? :green : :yellow
21
+ puts "#{filename} -> #{newname}#{File.extname(filename)}".colorize(unchanged)
22
+ else
23
+ File.rename(filename, "#{newname}#{File.extname(filename)}")
24
+ end
25
+ end
36
26
  end
27
+ default_task :lint
37
28
 
38
- opt.on_tail("-h", "--help", "--usage", "Show this help message and quit.") do |v|
39
- puts opt.help
40
- exit
29
+ desc 'metadata [FILENAME]', 'Show metadata about the specified movie or episode'
30
+ option :format, default: 'json'
31
+ def metadata(filename)
32
+ basename, newname, metadata = Propre.basename_newname_metadata(filename)
33
+ metadata[:title] = newname
34
+ puts metadata.to_json
41
35
  end
42
36
 
43
- options[:help] = opt.help
44
-
45
- end.parse!
46
-
47
- def main(options)
48
- if ARGV.size < 1
49
- puts options[:help]
50
- else
51
- propre = Propre.new(options)
52
- if File.directory?(ARGV[0])
53
- puts "Searching for movies in directory..."
54
- propre.crawlDirectory(ARGV[0])
55
- end
56
-
57
- if File.file?(ARGV[0])
58
- puts "Searching for movie title..."
59
- if !propre.searchMovieFromFile(ARGV[0])
60
- puts "No movie found for #{ARGV[0]}"
61
- end
62
- end
37
+ map %w(--version -v) => :__version
38
+ desc '--version, -v', 'Show version information about this program and quit.'
39
+ def __version
40
+ puts "#{Propre} - v#{Version::VERSION}"
63
41
  end
64
42
  end
65
43
 
66
- begin
67
- main(options)
68
- rescue Interrupt
69
- puts "\nExiting..."
70
- rescue StandardError => e
71
- puts e
72
- end
44
+ CLI.start(ARGV)
@@ -0,0 +1,12 @@
1
+ module Blacklist
2
+ WORDS = %w(
3
+ dvd
4
+ rip
5
+ xvid
6
+ hdtv
7
+ bluray
8
+ fastsub
9
+ vostfr
10
+ ac3
11
+ )
12
+ end
@@ -1,3 +1,3 @@
1
1
  module Version
2
- VERSION = "0.1.1"
2
+ VERSION = "0.2.0"
3
3
  end
data/lib/propre.rb CHANGED
@@ -1,97 +1,72 @@
1
- require 'propre/prompt'
2
- require 'propre/settings'
3
- require 'propre/version'
1
+ require 'json'
2
+ require 'colorize'
4
3
 
5
- require 'fileutils'
6
- require 'themoviedb'
7
- require 'mime/types'
8
- require 'similar_text'
4
+ require 'propre/blacklist'
9
5
 
10
- class Propre
11
- include Prompt
12
- include Version
6
+ module Propre
7
+ def self.propify(arg)
8
+ ban_words(ban_chars(sanitize(remove_patterns(arg.downcase)))).split.map(&:capitalize).join(' ')
9
+ end
13
10
 
14
- def initialize(options)
15
- @options = options
16
- @settings = Settings.new("#{Dir.home}/.config/Propre/settings.yaml")
17
- if @settings.get('apikey').nil?
18
- puts "It's seem you didn't set your TMDB API Key (stored in ~/.config/Propre/settings.yaml) \nPlease tell me: "
19
- @settings.set('apikey', STDIN.gets.chomp())
20
- puts "Thanks !"
21
- end
22
- Tmdb::Api.key(@settings.get('apikey'))
23
- Tmdb::Api.language(@settings.get('locale') ? @settings.get('locale') : 'en')
11
+ def self.find_urls(arg)
12
+ arg = arg.match '((([A-Za-z]{3,9}:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[.\!\/\\w]*))?)'
13
+ arg.to_s
24
14
  end
25
15
 
26
- def crawlDirectory(path)
27
- Dir.foreach(path) do |item|
28
- next if item == '.' or item == '..'
29
- if File.directory?(File.join(path, item))
30
- if @options[:recursive] then self.crawlDirectory(File.join(path, item)) end
31
- else
32
- self.searchMovieFromFile(File.join(path, item))
33
- end
34
- end
16
+ def self.find_years(arg)
17
+ arg = arg.match '((19|20)\d\d)'
18
+ arg.to_s
35
19
  end
36
20
 
37
- def searchMovieFromFile(file)
38
- @file = file
39
- filename = File.basename(file,File.extname(file))
40
- if @options[:videonly] && !video?(file)
41
- return
42
- end
43
- if !@options[:dotfile] && filename.start_with?('.')
44
- return
45
- end
46
- if @options[:sanitize] then filename = self.sanitize(filename) end
47
- begin
48
- @movies = Tmdb::Movie.find(filename)
49
- rescue
50
- if Tmdb::Api.response['code'] === 401
51
- abort("Error: Did you set you're API Key ? (401)")
52
- end
53
- end
54
- if @movies.empty? then return false end
55
- @movies = @movies.sort { |a,b| b.release_date <=> a.release_date }
56
- movie = @movies.max_by {|v| filename.similar(v.title)}
57
- @movies.delete(@movies.index(movie))
58
- @movies.unshift(movie)
59
- if self.confirm
60
- File.rename(file, File.join(File.dirname(file), self.format(@selected)))
61
- end
21
+ def self.find_episode(arg)
22
+ arg = arg.match '(s\d{1,2}e\d{2,3})'
23
+ arg.to_s
62
24
  end
63
25
 
64
- def confirm()
65
- @selected = false
66
- @movies.each do |movie|
67
- answer = Prompt.yesno("#{File.basename(@file)} -> #{self.format(movie)}")
68
- if answer === false; next ; elsif answer === 'skip'; puts "Skipping..."; return end
69
- @selected = movie
70
- break
71
- end
72
- if @selected then @selected end
26
+ def self.remove_patterns(arg)
27
+ arg.slice! find_urls(arg)
28
+ arg.slice! find_years(arg)
29
+ arg.slice! find_episode(arg)
30
+ arg
31
+ end
32
+
33
+ def self.sanitize(arg)
34
+ arg.gsub('.', ' ').strip
73
35
  end
74
36
 
75
- def format(movie)
76
- year = !movie.release_date.empty? ? Date.strptime(movie.release_date, "%Y-%m-%d").year : false
77
- title = year ? "#{movie.title} (#{year})" : "#{movie.title}"
78
- title.gsub! ':','-'
79
- return "#{title}#{File.extname(@file).downcase}"
37
+ def self.ban_chars(arg)
38
+ arg.tr('^A-Za-z0-9 ', '').strip
80
39
  end
81
40
 
82
- def sanitize(filename)
83
- filename.downcase!
84
- filename.gsub!(/\(.*\)/, '')
85
- filename.gsub!("_", ' ')
86
- filename.gsub!(".", ' ')
87
- filename.sub!(/(19|20)\d{2}/, '')
88
- filename.strip!
89
- warez = ["truefrench","brrip", "ac3-funky", "fansub","bluray","720", "720p", "x264","french", "fr", "divx","hdcam","xvid","appz","bdrip","board","cam","dvd","dvd-r","dvdrip","dupecheck","fake","fs","gamez","hddvd","hddvdrip","hdrip","hdtv","pdtv","internal","int","keygen","leecher","limited","nuke","proper","repack","retail","rip","rip","screener","serial","subforced","hardsub","stv","telecine","telesync","tvrip","unrated","vhsrip","vo","vost","vostfr","workprint","french","wp","subbed","unsubbed", "r5", "r6", "md"]
90
- (filename.split - warez).join(' ')
41
+ def self.ban_words(arg)
42
+ arg.split.each do |word|
43
+ Blacklist::WORDS.select do |e|
44
+ arg.slice! word if word.include? e
45
+ end
46
+ end
47
+ arg.squeeze(' ')
91
48
  end
92
49
 
93
- def video?(file)
94
- MIME::Types[/^video/].include? MIME::Types.of(file)
50
+ def self.metadata(arg)
51
+ arg = arg.downcase
52
+ {
53
+ year: find_years(arg),
54
+ episode: find_episode(arg).upcase,
55
+ website: find_urls(arg)
56
+ }
95
57
  end
96
58
 
97
- end
59
+ def self.format(newname, metadata)
60
+ metadata[:newname] = newname
61
+ metadata[:year] = "(#{metadata[:year]})" unless metadata[:year].empty?
62
+
63
+ format = '%{newname} %{episode} %{year}'
64
+ formated = format % metadata
65
+ formated.strip.squeeze(' ')
66
+ end
67
+
68
+ def self.basename_newname_metadata(arg)
69
+ basename = File.basename(arg, File.extname(arg))
70
+ [basename, format(propify(basename), metadata(basename)), metadata(basename)]
71
+ end
72
+ end
data/propre.gemspec CHANGED
@@ -4,24 +4,21 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
  require 'propre/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
- spec.authors = ["Felix Yadomi"]
8
- spec.email = ["dev.yadomi@gmail.com"]
7
+ spec.authors = ['Felix Yadomi']
8
+ spec.email = ['dev.yadomi@gmail.com']
9
9
 
10
- spec.name = "propre"
10
+ spec.name = 'propre'
11
11
  spec.version = Version::VERSION
12
- spec.summary = %q{CLI tool to rename movies using TheMovieDB API }
12
+ spec.summary = 'CLI tool to sanitize movies filename'
13
13
 
14
- spec.files = `git ls-files`.split($\)
14
+ spec.files = `git ls-files`.split($ORS)
15
15
  spec.executables = ['propre']
16
- spec.require_paths = ["lib"]
17
-
18
- spec.add_dependency "parseconfig", "~> 1.0.6"
19
- spec.add_dependency "themoviedb", "~> 0.0.24"
20
- spec.add_dependency "mime-types", "~> 2.4.3"
21
- spec.add_dependency "highline", "~> 1.6.21"
22
- spec.add_dependency "similar_text", "~> 0.0.4"
16
+ spec.require_paths = ['lib']
23
17
 
24
- spec.add_development_dependency "bundler", "~> 1.7"
25
- spec.add_development_dependency "rake", "~> 10.0"
18
+ spec.add_dependency 'thor', '~> 0.19.1'
19
+ spec.add_dependency 'json', '~> 1.8.3'
20
+ spec.add_dependency 'colorize', '~> 0.7.7'
26
21
 
22
+ spec.add_development_dependency 'bundler', '~> 1.7'
23
+ spec.add_development_dependency 'rake', '~> 10.0'
27
24
  end
metadata CHANGED
@@ -1,111 +1,83 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: propre
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Felix Yadomi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-01-04 00:00:00.000000000 Z
11
+ date: 2015-11-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: parseconfig
14
+ name: thor
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 1.0.6
19
+ version: 0.19.1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 1.0.6
26
+ version: 0.19.1
27
27
  - !ruby/object:Gem::Dependency
28
- name: themoviedb
28
+ name: json
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ~>
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 0.0.24
33
+ version: 1.8.3
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ~>
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 0.0.24
40
+ version: 1.8.3
41
41
  - !ruby/object:Gem::Dependency
42
- name: mime-types
42
+ name: colorize
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ~>
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 2.4.3
47
+ version: 0.7.7
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ~>
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 2.4.3
55
- - !ruby/object:Gem::Dependency
56
- name: highline
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ~>
60
- - !ruby/object:Gem::Version
61
- version: 1.6.21
62
- type: :runtime
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ~>
67
- - !ruby/object:Gem::Version
68
- version: 1.6.21
69
- - !ruby/object:Gem::Dependency
70
- name: similar_text
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ~>
74
- - !ruby/object:Gem::Version
75
- version: 0.0.4
76
- type: :runtime
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ~>
81
- - !ruby/object:Gem::Version
82
- version: 0.0.4
54
+ version: 0.7.7
83
55
  - !ruby/object:Gem::Dependency
84
56
  name: bundler
85
57
  requirement: !ruby/object:Gem::Requirement
86
58
  requirements:
87
- - - ~>
59
+ - - "~>"
88
60
  - !ruby/object:Gem::Version
89
61
  version: '1.7'
90
62
  type: :development
91
63
  prerelease: false
92
64
  version_requirements: !ruby/object:Gem::Requirement
93
65
  requirements:
94
- - - ~>
66
+ - - "~>"
95
67
  - !ruby/object:Gem::Version
96
68
  version: '1.7'
97
69
  - !ruby/object:Gem::Dependency
98
70
  name: rake
99
71
  requirement: !ruby/object:Gem::Requirement
100
72
  requirements:
101
- - - ~>
73
+ - - "~>"
102
74
  - !ruby/object:Gem::Version
103
75
  version: '10.0'
104
76
  type: :development
105
77
  prerelease: false
106
78
  version_requirements: !ruby/object:Gem::Requirement
107
79
  requirements:
108
- - - ~>
80
+ - - "~>"
109
81
  - !ruby/object:Gem::Version
110
82
  version: '10.0'
111
83
  description:
@@ -116,14 +88,13 @@ executables:
116
88
  extensions: []
117
89
  extra_rdoc_files: []
118
90
  files:
119
- - .gitignore
91
+ - ".gitignore"
120
92
  - Gemfile
121
93
  - README.md
122
94
  - Rakefile
123
95
  - bin/propre
124
96
  - lib/propre.rb
125
- - lib/propre/prompt.rb
126
- - lib/propre/settings.rb
97
+ - lib/propre/blacklist.rb
127
98
  - lib/propre/version.rb
128
99
  - propre.gemspec
129
100
  homepage:
@@ -135,18 +106,18 @@ require_paths:
135
106
  - lib
136
107
  required_ruby_version: !ruby/object:Gem::Requirement
137
108
  requirements:
138
- - - '>='
109
+ - - ">="
139
110
  - !ruby/object:Gem::Version
140
111
  version: '0'
141
112
  required_rubygems_version: !ruby/object:Gem::Requirement
142
113
  requirements:
143
- - - '>='
114
+ - - ">="
144
115
  - !ruby/object:Gem::Version
145
116
  version: '0'
146
117
  requirements: []
147
118
  rubyforge_project:
148
- rubygems_version: 2.4.5
119
+ rubygems_version: 2.4.6
149
120
  signing_key:
150
121
  specification_version: 4
151
- summary: CLI tool to rename movies using TheMovieDB API
122
+ summary: CLI tool to sanitize movies filename
152
123
  test_files: []
data/lib/propre/prompt.rb DELETED
@@ -1,16 +0,0 @@
1
- require 'highline/import'
2
-
3
- module Prompt
4
-
5
- def Prompt.yesno(prompt = 'Continue?', default = false)
6
- a = ''
7
- s = default ? '[Y/n/s]' : '[y/N/s]'
8
- d = default ? 'y' : 'n'
9
- until %w[y n s].include? a
10
- a = ask("#{prompt} #{s} ") { |q| q.limit = 1; q.case = :downcase }
11
- a = d if a.length == 0
12
- end
13
- if a == 'y'; true elsif a == 's'; 'skip' else false end
14
- end
15
-
16
- end
@@ -1,25 +0,0 @@
1
- require 'yaml'
2
- require 'parseconfig'
3
-
4
- class Settings
5
-
6
- def initialize(path)
7
- @path = path
8
- if !File.exist?(path)
9
- FileUtils.mkdir_p("#{Dir.home}/.config/Propre/")
10
- FileUtils.touch(path)
11
- end
12
- conf = YAML.load_file(path)
13
- @settings = conf ? conf : Hash.new
14
- end
15
-
16
- def get(key)
17
- @settings[key]
18
- end
19
-
20
- def set(key, value)
21
- @settings[key] = value
22
- File.open(@path, 'w') { |f| YAML.dump(@settings, f) }
23
- end
24
-
25
- end