vnehm 1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5b6058a8c80449c3eb2d1082100d0c657f6e018e
4
+ data.tar.gz: 3606d661f256f70b0b16dbc45f6ec6f5ac584d7f
5
+ SHA512:
6
+ metadata.gz: 1a9aef70122a2fb74b9f04ea1d20bc9bcd524689d7de585155d7db46185e96a007b52bb9a9d5e308b1ebaf4c952e64d2f0bdea4994de8294e2333cdd33dccc66
7
+ data.tar.gz: 186b817bc5a138651b9ceed8bf27195c5f3854b900d1c7ac2e0b25f03646623121eaf2cced5188ef641308d77edb676e46bdc20603ebc7ad179f97784ee0ed75
data/.gitignore ADDED
@@ -0,0 +1,12 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ .DS_Store
11
+ *.swp
12
+ *.gem
data/CHANGELOG.md ADDED
@@ -0,0 +1,8 @@
1
+ # История изменений vnehm
2
+
3
+ ## 1.1
4
+ * Команда `select` переименована в `list`
5
+ * Исправлена ошибка `uninitialized constant Vnehm::TrackManager::UserManager`
6
+
7
+ ## 1.0
8
+ * Первый релиз
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in vnehm.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2015 Albert Nigmatzianov
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,84 @@
1
+ # vnehm
2
+
3
+ *vnehm* - это консольная утилита, которая скачивает (и добавляет в Вашу библиотеку iTunes) аудиозаписи из ВКонтакте
4
+
5
+ ## ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ
6
+
7
+ ***Используйте эту программу только для личного пользования***
8
+
9
+ ***Разработчик vnehm не несет ответственности за любое нелегальное использование данной программы***
10
+
11
+ ## Установка
12
+
13
+ **1. [Установите Ruby](https://www.ruby-lang.org/ru/downloads/)**
14
+
15
+ **2. Установите библиотеку `taglib`**
16
+
17
+ **Для Mac OS X:**
18
+
19
+ `brew install taglib`
20
+
21
+ or
22
+
23
+ `sudo port install taglib`
24
+
25
+ **Для Linux:**
26
+
27
+ Debian/Ubuntu: `sudo apt-get install libtag1-dev`
28
+
29
+ Fedora/RHEL: `sudo yum install taglib-devel`
30
+
31
+ **3. Установите `vnehm`**
32
+
33
+ `gem install vnehm`
34
+
35
+ ## Перед использованием
36
+
37
+ Если Вы только что установили `vnehm`, напишите любую команду для первоначальной инициализации
38
+
39
+ Например, `vnehm help`
40
+
41
+ `vnehm` должен ответить примерно так:
42
+ ```
43
+ Прежде чем использовать vnehm, Вам нужно его настроить
44
+ Введите путь в желаемую директорию скачиваемых аудио...
45
+ ```
46
+ А дальше следуйте инструкциям, которые вам предложит `vnehm`
47
+
48
+ ## Примеры использования
49
+
50
+ Используйте `vnehm help` для списка всех доступных команд или `vnehm help КОМАНДА` для определенной команды
51
+
52
+ Команды и аргументы (но **НЕ** опции) могут быть сокращены, насколько они могут быть однозначны
53
+
54
+ #### Скачать в директорию по умолчанию и добавить в iTunes Вашу последнюю аудиозапись
55
+
56
+ `$ vnehm get` = `$ vnehm g`
57
+
58
+ #### Скачать и добавить в iTunes несколько последних аудиозаписей
59
+
60
+ `$ vnehm get 3` = `$ vnehm g 3`
61
+
62
+ #### Просто скачать аудиозапись
63
+
64
+ `$ vnehm dl` = `$ vnehm d`
65
+
66
+ #### Скачать аудиозапись в другую директорию
67
+
68
+ `$ vnehm g to ~/Downloads` or `$ vnehm d to .`
69
+
70
+ #### Скачать и добавить трек в другой плейлист iTunes
71
+
72
+ `$ vnehm g pl MyPlaylist`
73
+
74
+ #### Вывести список Ваших аудиозаписей и скачать выбранные
75
+
76
+ `$ vnehm list` = `$ vnehm l`
77
+
78
+ #### Найти треки по запросу и скачать выбранные
79
+
80
+ `$ vnehm search kanye west` = `$ vnehm s kanye west`
81
+
82
+ ## Лицензия
83
+
84
+ Лицензия MIT
data/Rakefile ADDED
@@ -0,0 +1,70 @@
1
+ require 'bundler'
2
+ require 'colored'
3
+ require 'vnehm/ui'
4
+ require 'rake'
5
+
6
+ Bundler::GemHelper.install_tasks
7
+ task default: %w(install)
8
+
9
+ file = 'pkg/vnehm-' + Vnehm::VERSION + '.gem'
10
+
11
+ ##
12
+ # Push to rubygems
13
+
14
+ task :push => :build do
15
+ `gem push #{file}`
16
+ end
17
+
18
+ ##
19
+ # Add command with boilerplate code
20
+ #
21
+ # For example, you want to add 'get' command
22
+ # For that you should input 'rake nc[get]'
23
+
24
+ task :nc, [:cmd] do |_, args|
25
+ cmd = args[:cmd]
26
+ cmd_file = "lib/vnehm/commands/#{cmd}_command.rb"
27
+
28
+ puts "Making #{cmd} command..."
29
+
30
+ code = <<-EOF
31
+ module Vnehm
32
+
33
+ ##
34
+ # Write here description for command
35
+
36
+ class #{cmd.capitalize}Command < Command
37
+
38
+ ##
39
+ # Add all command's options in 'initialize' method
40
+
41
+ def initialize
42
+ super
43
+ end
44
+
45
+ def execute
46
+ end
47
+
48
+ def arguments
49
+ end
50
+
51
+ def program_name
52
+ 'vnehm #{cmd}'
53
+ end
54
+
55
+ def summary
56
+ end
57
+
58
+ def usage
59
+ end
60
+
61
+ end
62
+ end
63
+ EOF
64
+
65
+ # Write to file
66
+ File.open(cmd_file, 'w') { |f| f.write(code) }
67
+
68
+ Vnehm::UI.success "Successfully made #{cmd} command!"
69
+ Vnehm::UI.warning "Don't forget to add the name of command to CommandManager::COMMANDS"
70
+ end
data/bin/vnehm ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ vnehm_dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ $LOAD_PATH.unshift(vnehm_dir) unless $LOAD_PATH.include?(vnehm_dir)
4
+ require 'vnehm'
5
+
6
+ $stderr = STDOUT
7
+
8
+ begin
9
+ Vnehm.start(ARGV)
10
+ rescue Interrupt # SIGINT
11
+ Vnehm::UI.term
12
+ # rescue StandardError, Timeout::Error => ex
13
+ # Vnehm::UI.term "While executing vnehm ... (#{ex.class})\n #{ex}"
14
+ end
@@ -0,0 +1,29 @@
1
+ module Vnehm
2
+
3
+ ##
4
+ # AppleScript module calls all AppleScript scripts and returns results
5
+
6
+ module AppleScript
7
+
8
+ def self.add_track_to_playlist(track_path, playlist_name)
9
+ `osascript \"#{script_path(:add_track_to_playlist)}\" \"#{track_path}\" \"#{playlist_name}\" > /dev/null`
10
+ end
11
+
12
+ def self.list_of_playlists
13
+ output = `osascript \"#{script_path(:list_of_playlists)}\"`
14
+ output.chomp.split(', ')
15
+ end
16
+
17
+ def self.music_master_library
18
+ `osascript \"#{script_path(:music_master_library)}\"`
19
+ end
20
+
21
+ module_function
22
+
23
+ def script_path(script_name)
24
+ applescripts_path = File.expand_path(File.join(File.dirname(__FILE__), 'applescripts'))
25
+ File.join(applescripts_path, "#{script_name}.applescript")
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/osascript
2
+ on run argv
3
+ set posixFile to first item of argv
4
+ set playlistName to second item of argv
5
+
6
+ tell application "iTunes"
7
+ set p to posixFile
8
+ set a to (p as POSIX file)
9
+ add a to playlist playlistName
10
+ end tell
11
+ end run
@@ -0,0 +1,3 @@
1
+ tell application "iTunes"
2
+ get name of playlists
3
+ end tell
@@ -0,0 +1,3 @@
1
+ tell application "iTunes"
2
+ get name of first playlist whose special kind is Music
3
+ end tell
data/lib/vnehm/cfg.rb ADDED
@@ -0,0 +1,47 @@
1
+ require 'yaml'
2
+
3
+ module Vnehm
4
+
5
+ ##
6
+ # Cfg module manipulates with nehm's config file (~/.vnehmconfig)
7
+
8
+ module Cfg
9
+
10
+ FILE_PATH = File.join(ENV['HOME'], '.vnehmconfig')
11
+
12
+ def self.[](key)
13
+ config_hash[key.to_s]
14
+ end
15
+
16
+ def self.[]=(key, value)
17
+ config_hash[key.to_s] = value
18
+ write
19
+ end
20
+
21
+ def self.create
22
+ File.new(FILE_PATH, 'w+')
23
+ end
24
+
25
+ def self.exist?
26
+ File.exist?(FILE_PATH)
27
+ end
28
+
29
+ def self.key?(key)
30
+ config_hash.key?(key.to_s)
31
+ end
32
+
33
+ module_function
34
+
35
+ def config_hash
36
+ @config_hash ||= YAML.load_file(FILE_PATH)
37
+ @config_hash ||= {} unless @config_hash
38
+
39
+ @config_hash
40
+ end
41
+
42
+ def write
43
+ IO.write(FILE_PATH, config_hash.to_yaml)
44
+ end
45
+
46
+ end
47
+ end
@@ -0,0 +1,54 @@
1
+ require 'certifi'
2
+ require 'vkontakte_api'
3
+
4
+ require 'vnehm/token_manager'
5
+
6
+ module Vnehm
7
+
8
+ ##
9
+ # Client module contains all VK API interaction methods
10
+
11
+ module Client
12
+
13
+ ##
14
+ # VK API client ID
15
+
16
+ CLIENT_ID = 5144754
17
+
18
+ ##
19
+ # VK API client object
20
+
21
+ VkontakteApi.configure do |config|
22
+ config.log_requests = false
23
+ config.log_errors = false
24
+ end
25
+
26
+ VK_CLIENT = VkontakteApi::Client.new(TokenManager.token)
27
+
28
+ ##
29
+ # SSL certificate file path
30
+
31
+ ENV['SSL_CERT_FILE'] = Certifi.where
32
+
33
+ def self.authorization_url
34
+ VkontakteApi.authorization_url(type: :client,
35
+ scope: [:audio, :offline],
36
+ client_id: CLIENT_ID,
37
+ redirect_uri: 'http://api.vkontakte.ru/blank.html')
38
+ end
39
+
40
+ ##
41
+ # Returns raw array of likes or posts (depends on argument 'type')
42
+
43
+ def self.tracks(count, offset)
44
+ VK_CLIENT.audio.get(count: count, offset: offset)
45
+ end
46
+
47
+ def self.search(query, limit, offset)
48
+ VK_CLIENT.audio.search(q: query,
49
+ count: limit,
50
+ offset: offset)
51
+ end
52
+
53
+ end
54
+ end
@@ -0,0 +1,108 @@
1
+ require 'vnehm/option_parser'
2
+
3
+ module Vnehm
4
+
5
+ ##
6
+ # Base class for all Vnehm commands. When creating a new vnehm command, define
7
+ # #initialize, #execute, #arguments, #program_name, #summary and #usage
8
+ # (as appropriate)
9
+ # See the above mentioned methods for details
10
+
11
+ class Command
12
+
13
+ ##
14
+ # Hash with options of the command
15
+
16
+ attr_accessor :options
17
+
18
+ ##
19
+ # Hash with descriptions of each option
20
+
21
+ attr_accessor :options_descs
22
+
23
+ ##
24
+ # In 'initialize' should be defined all options by method 'add_option'
25
+ # See get_command.rb as example
26
+
27
+ def initialize
28
+ @options = {}
29
+ @options_descs = {}
30
+ end
31
+
32
+ ##
33
+ # Invoke the command with the given list of arguments
34
+
35
+ def invoke(args)
36
+ handle_options(args)
37
+ execute
38
+ end
39
+
40
+ ##
41
+ # Handle the given list of arguments by parsing them and recording the
42
+ # results
43
+
44
+ def handle_options(args)
45
+ parser = OptionParser.new(args, self)
46
+ parser.parse
47
+ end
48
+
49
+ ##
50
+ # Override to provide command handling
51
+ #
52
+ # #options will be filled in with your parsed options, unparsed options will
53
+ # be left in #options[:args]
54
+
55
+ def execute
56
+ end
57
+
58
+ ##
59
+ # Override to provide details of the arguments a command takes
60
+ #
61
+ # For example:
62
+ #
63
+ # def usage
64
+ # "#{program_name} COMMAND"
65
+ # end
66
+ #
67
+ # def arguments
68
+ # ['COMMAND', 'name of command to show help']
69
+ # end
70
+
71
+ def arguments
72
+ {}
73
+ end
74
+
75
+ ##
76
+ # The name of the command for command-line invocation
77
+
78
+ def program_name
79
+ end
80
+
81
+ ##
82
+ # Override to display a short description of what this command does
83
+
84
+ def summary
85
+ end
86
+
87
+ ##
88
+ # Override to display the usage for an individual vnehm command
89
+ #
90
+ # The text "[options]" is automatically appended to the usage text
91
+
92
+ def usage
93
+ end
94
+
95
+ ##
96
+ # Add a command-line option
97
+ #
98
+ # Vnehm don't use options with dashes to be more user-friendly
99
+ #
100
+ # See 'get_command.rb' as example
101
+
102
+ def add_option(option, usage, desc)
103
+ @options[option] = nil
104
+ @options_descs[usage] = desc
105
+ end
106
+
107
+ end
108
+ end
@@ -0,0 +1,57 @@
1
+ require 'vnehm/command'
2
+
3
+ module Vnehm
4
+
5
+ ##
6
+ # The command manager contains information about all vnehm commands
7
+ # It also find and run them
8
+
9
+ module CommandManager
10
+
11
+ COMMANDS = [
12
+ :authorize,
13
+ :configure,
14
+ :dl,
15
+ :get,
16
+ :help,
17
+ :list,
18
+ :search,
19
+ :version
20
+ ]
21
+
22
+ ##
23
+ # Run the command specified by 'args'
24
+
25
+ def self.run(args)
26
+ cmd_name = args.shift.downcase
27
+ cmd = find_command(cmd_name)
28
+ cmd.invoke(args)
29
+ end
30
+
31
+ def self.find_command(cmd_name)
32
+ possibilities = find_command_possibilities(cmd_name)
33
+
34
+ if possibilities.size > 1
35
+ UI.term "Неоднозначная команда #{cmd_name} соответствует [#{possibilities.join(', ')}]"
36
+ elsif possibilities.empty?
37
+ UI.term "Команда #{cmd_name} неизвестна"
38
+ end
39
+
40
+ command_instance(possibilities.first)
41
+ end
42
+
43
+ def self.find_command_possibilities(cmd_name)
44
+ len = cmd_name.length
45
+ COMMANDS.select { |command| command[0, len] == cmd_name }
46
+ end
47
+
48
+ def self.command_instance(command_name)
49
+ command_name = command_name.to_s
50
+ const_name = command_name.capitalize << 'Command'
51
+
52
+ require "vnehm/commands/#{command_name}_command"
53
+ Vnehm.const_get(const_name).new
54
+ end
55
+
56
+ end
57
+ end
@@ -0,0 +1,46 @@
1
+ module Vnehm
2
+ class ConfigureCommand < Command
3
+
4
+ def execute
5
+ loop do
6
+ show_info
7
+ UI.newline
8
+ show_menu
9
+ UI.sleep
10
+ end
11
+ end
12
+
13
+ def program_name
14
+ 'vnehm configure'
15
+ end
16
+
17
+ def summary
18
+ 'Настройка приложения'
19
+ end
20
+
21
+ def usage
22
+ 'vnehm configure'
23
+ end
24
+
25
+ private
26
+
27
+ def show_info
28
+ dl_path = PathManager.default_dl_path
29
+ UI.say "Директория скачанных аудиозаписей: #{dl_path.magenta}" if dl_path
30
+
31
+ if OS.mac?
32
+ playlist = PlaylistManager.default_playlist
33
+ UI.say "Плейлист iTunes: #{playlist.to_s.cyan}" if playlist
34
+ end
35
+ end
36
+
37
+ def show_menu
38
+ UI.menu do |menu|
39
+ menu.choice(:inc, 'Изменить путь для скачиваемых аудиозаписей'.freeze) { PathManager.set_dl_path }
40
+ menu.choice(:inc, 'Изменить плейлист iTunes'.freeze) { PlaylistManager.set_playlist } if OS.mac?
41
+ menu.choice(:inc, 'Авторизация'.freeze) { TokenManager.authorize }
42
+ end
43
+ end
44
+
45
+ end
46
+ end
@@ -0,0 +1,36 @@
1
+ module Vnehm
2
+ class DlCommand < Command
3
+
4
+ def initialize
5
+ super
6
+
7
+ add_option(:to, 'to ПУТЬ',
8
+ 'Скачать аудиозапись(и) в ПУТЬ')
9
+ end
10
+
11
+ def execute
12
+ @options[:dl] = 'yes'
13
+
14
+ get_cmd = CommandManager.command_instance('get')
15
+ get_cmd.options = @options
16
+ get_cmd.execute
17
+ end
18
+
19
+ def arguments
20
+ { 'ЧИСЛО' => '(Необязательно) Скачать последние ЧИСЛО Ваших аудиозаписей' }
21
+ end
22
+
23
+ def program_name
24
+ 'vnehm dl'
25
+ end
26
+
27
+ def summary
28
+ 'Загрузка Ваших аудиозаписей из VK'
29
+ end
30
+
31
+ def usage
32
+ "#{program_name} [ЧИСЛО] [ОПЦИИ]"
33
+ end
34
+
35
+ end
36
+ end
@@ -0,0 +1,53 @@
1
+ module Vnehm
2
+ class GetCommand < Command
3
+
4
+ FIRST_TRACK = [1, 0]
5
+
6
+ def initialize
7
+ super
8
+
9
+ add_option(:to, 'to ПУТЬ',
10
+ 'Скачать аудиозапись(и) в ПУТЬ')
11
+
12
+ add_option(:pl, 'pl ПЛЕЙЛИСТ',
13
+ 'Добавлять аудиозапись(и) в плейлист iTunes с именем ПЛЕЙЛИСТ')
14
+ end
15
+
16
+ def execute
17
+ track_manager = TrackManager.new(@options)
18
+
19
+ UI.say 'Получение информации об аудиозаписи(ях)'
20
+ arg = @options[:args].pop
21
+ tracks =
22
+ case arg
23
+ when /^\d$/ # If arg is number
24
+ track_manager.tracks(arg, 0)
25
+ when nil
26
+ track_manager.tracks(*FIRST_TRACK)
27
+ else
28
+ UI.term "Введен некорректный аргумент"
29
+ end
30
+
31
+ UI.term 'У Вас ещё нет аудиозаписей' if tracks.nil?
32
+
33
+ track_manager.process_tracks(tracks)
34
+ end
35
+
36
+ def arguments
37
+ { 'ЧИСЛО' => '(Необязательно) Скачать последние ЧИСЛО ваших аудиозаписей' }
38
+ end
39
+
40
+ def program_name
41
+ 'vnehm get'
42
+ end
43
+
44
+ def summary
45
+ 'Загрузка и добавление треков из VK в Вашу библиотеку iTunes'
46
+ end
47
+
48
+ def usage
49
+ "#{program_name} [ЧИСЛО] [ОПЦИИ]"
50
+ end
51
+
52
+ end
53
+ end