vnehm 1.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.
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