From c9fccb475f2ef2d899841a56f4fc9b0e1b5cae52 Mon Sep 17 00:00:00 2001 From: marguerite Date: Sun, 16 Nov 2014 02:16:56 +0800 Subject: [PATCH] save/load playlist --- BiliConfig.rb | 7 +-- BiliPlaylist.rb | 117 +++++++++++++++++++++++++++++++++++++++++++++ BiliUrlsHandler.rb | 40 ---------------- BiliWidgets.rb | 81 +++++++++++++++++++++++++------ ChangeLog | 3 ++ TODO | 20 +++++++- 6 files changed, 209 insertions(+), 59 deletions(-) create mode 100644 BiliPlaylist.rb delete mode 100644 BiliUrlsHandler.rb diff --git a/BiliConfig.rb b/BiliConfig.rb index a0d89ae..689bd62 100644 --- a/BiliConfig.rb +++ b/BiliConfig.rb @@ -2,10 +2,11 @@ module BiliConfig class Biliconf - @@userHome = `echo $HOME`.gsub(/\n/,"") - @@configPath = File.join(@@userHome,".config/BiliGui") + $userHome = `echo $HOME`.gsub(/\n/,"") + $configPath = File.join($userHome,".config/BiliGui") + p "Config Path: #{$configPath}" - def initialize(name="biligui.conf", path=@@configPath) + def initialize(name="biligui.conf", path=$configPath) @name = name @path = path diff --git a/BiliPlaylist.rb b/BiliPlaylist.rb new file mode 100644 index 0000000..8e49c23 --- /dev/null +++ b/BiliPlaylist.rb @@ -0,0 +1,117 @@ +module BiliPlaylist + + class BiliPlaylist + + def initialize(videos="") + @videos = videos + @videosHash = {} + + videosSplit + end + + def videosSplit + + unless @videos.empty? then + + @videos.split(/\n/).each do |video| + + unless video.index("http://") then + next + end + + + videoHashKey = "av" + video.gsub(/^.*\/av/,"").gsub(/\//,"") + videoHashValue = video + + @videosHash[videoHashKey] = videoHashValue + + end + + end + + end + + def hash + return @videosHash + end + + def save(filename="") + + require 'fileutils' + + playlist = filename + + default_playlist = "#{$configPath}/biliplaylist.m3u8" + + if playlist.empty? then + playlist = default_playlist + end + + old_playlist = playlist + ".old" + + if File.exist?(playlist) then + FileUtils.mv playlist, old_playlist + else + io = File.open(playlist,"w") + io.puts "#EXTM3U" + + @videosHash.to_a.each do |video| + io.puts "#EXTINF:#{video[0]}" + io.puts video[1] + end + + io.close + end + end + + def load(playlist="") + + playlistHash = {} + + default_playlist = "#{$configPath}/biliplaylist.m3u8" + + if playlist.empty? && File.exist?(default_playlist) then + playlist = default_playlist + end + + + if playlist.empty? then + p "[ERR] No playlist available!" + else + + io = File.open(playlist, 'r') + + validArray = [] + i = 0 + + io.each_line do |line| + + line.chomp! + + i += 1 + + unless line.index("http://") then + next + end + + unless line.index("bilibili") then + p "#{line} doesn't seem to be a Bilibili URL!" + else + p line + validArray[i] = line + end + + end + + if validArray.empty? then + p "This playlist has no URL we support!" + end + + io.close + end + + end + + end + +end diff --git a/BiliUrlsHandler.rb b/BiliUrlsHandler.rb deleted file mode 100644 index e25ebe4..0000000 --- a/BiliUrlsHandler.rb +++ /dev/null @@ -1,40 +0,0 @@ -module BiliUrlsHandler - class BiliUrls - - def initialize(urls) - - @urlBlock = urls - @urlHash = {} - - urlSplit - - end - - def urlSplit - - unless @urlBlock.empty? then - urls = @urlBlock.split(/\n/) - urls.each do |url| - - # validation codes here - unless url.index("http://") then - puts "Url invalid: #{url}" - next - end - - urlHashValue = url - urlHashKey = urlHashValue.gsub(/^.*\/av/,"").gsub(/\//,"") - @urlHash[urlHashKey] = urlHashValue - end - else - puts "No Urls!" - end - - end - - def urlBlockHash - return @urlHash - end - - end -end diff --git a/BiliWidgets.rb b/BiliWidgets.rb index e92aec4..e2c14be 100644 --- a/BiliWidgets.rb +++ b/BiliWidgets.rb @@ -1,7 +1,7 @@ require 'Qt' require 'qtwebkit' require_relative 'BiliConfig' -require_relative 'BiliUrlsHandler' +require_relative 'BiliPlaylist' class BiliGuiConfig @@ -20,20 +20,30 @@ def load end -class BiliGuiUrls +class BiliGuiPlaylist - include BiliUrlsHandler + include BiliPlaylist - def initialize(urls) + def initialize(videoURLs="") - @urls = urls + @videos = videoURLs + + @videosHash = BiliPlaylist.new(@videos) end def hash - urlHash = BiliUrls.new(@urls) - return urlHash.urlBlockHash + return @videosHash.hash + end + + def save(filename="") + @videosHash.save(filename) end + + def load(playlist="") + BiliPlaylist.new.load(playlist) + end + end class BiliGui < Qt::Widget @@ -42,6 +52,8 @@ class BiliGui < Qt::Widget slots 'clear()' slots 'bilidanChoose()' slots 'biliWeb()' + slots 'biliSave()' + slots 'biliLoad()' Width = 800 Height = 400 @@ -97,18 +109,39 @@ def init_ui biliWebButton = Qt::PushButton.new 'Visit bilibili.tv (experimental)', playlistTab @urlArea = Qt::TextEdit.new playlistTab @messageLabel = Qt::Label.new "", playlistTab - @messageLabel.setStyleSheet("color: #ff0000;") + @messageLabel.setStyleSheet("color: #ff0000;") + ctlPanel = Qt::Widget.new playlistTab okButton = Qt::PushButton.new 'Play', playlistTab clearButton = Qt::PushButton.new 'Clear', playlistTab grid_Playlist.addWidget biliUrlLabel, 0, 0, 1, 1 grid_Playlist.addWidget biliWebButton, 0, 1, 1, 1 grid_Playlist.addWidget @urlArea, 1, 0, 1, 4 + grid_Playlist.addWidget ctlPanel, 1, 4, 1, 1 grid_Playlist.addWidget @messageLabel, 2, 0, 1, 2 grid_Playlist.addWidget okButton, 2, 2, 1, 1 grid_Playlist.addWidget clearButton, 2, 3, 1, 1 grid_Playlist.setColumnStretch 0, 0 + + connect biliWebButton, SIGNAL('clicked()'), self, SLOT('biliWeb()') + connect okButton, SIGNAL('clicked()'), self, SLOT('bilidan()') + connect clearButton, SIGNAL('clicked()'), self, SLOT('clear()') + + ## controlPanel layout + grid_ctlPanel = Qt::GridLayout.new ctlPanel + + ctlLoadButton = Qt::PushButton.new 'Load', ctlPanel + ctlSaveButton = Qt::PushButton.new 'Save', ctlPanel + ctlBlank = Qt::Label.new ctlPanel + + grid_ctlPanel.addWidget ctlLoadButton, 0, 0, 1, 1 + grid_ctlPanel.addWidget ctlSaveButton, 1, 0, 1, 1 + grid_ctlPanel.addWidget ctlBlank, 2, 0, 3, 2 + + connect ctlLoadButton, SIGNAL('clicked()'), self, SLOT('biliLoad()') + connect ctlSaveButton, SIGNAL('clicked()'), self, SLOT('biliSave()') + # Settings Tab grid_Settings = Qt::GridLayout.new settingsTab bilidanPathLabel = Qt::Label.new "Please enter your bilidan's path:", settingsTab @@ -124,9 +157,6 @@ def init_ui grid_Settings.setColumnStretch 0, 0 connect bilidanButton, SIGNAL('clicked()'), self, SLOT('bilidanChoose()') - connect biliWebButton, SIGNAL('clicked()'), self, SLOT('biliWeb()') - connect okButton, SIGNAL('clicked()'), self, SLOT('bilidan()') - connect clearButton, SIGNAL('clicked()'), self, SLOT('clear()') end def bilidan @@ -134,7 +164,7 @@ def bilidan require 'open3' urlText = @urlArea.toPlainText() - urlTextHash = BiliGuiUrls.new(urlText).hash + urlTextHash = BiliGuiPlaylist.new(urlText).hash pathText = @bilidanPath.text() # validate bilidan.py path @@ -151,6 +181,8 @@ def bilidan urlTextHash.each_value do |hashvalue| + p "Now Playing: #{hashvalue}" + command = "#{pathText} #{hashvalue}" Open3.popen3(command) do |stdin, stdout, stderr, wait_thr| stderr.each_line do |line| @@ -158,6 +190,9 @@ def bilidan unless line.index("99%") then @messageLabel.setText(line) end + + stdout.each_line {|line| p line} + end unless wait_thr.value.success?() then @@ -178,8 +213,7 @@ def clear end def bilidanChoose - userHome = `echo $HOME`.gsub(/\n/,"") - bilidanBin = Qt::FileDialog.getOpenFileName(self, "Please choose your bilidan.py", "#{userHome}", "Python files (*.py)") + bilidanBin = Qt::FileDialog.getOpenFileName(self, "Please choose your bilidan.py", "#{$userHome}", "Python files (*.py)") unless bilidanBin == nil then if bilidanBin.index("bilidan.py") then @bilidanPath.setText(bilidanBin) @@ -198,4 +232,23 @@ def biliWeb end + def biliLoad + playlist = Qt::FileDialog.getOpenFileName(self, "Please choose your playlist", "#{$configPath}", "Playlist file (*.m3u8)") + unless playlist == nil then + BiliGuiPlaylist.new.load(playlist) + end + end + + def biliSave + if @urlArea.toPlainText().empty? then + p "No video URL can be saved at all!" + else + filename = Qt::FileDialog.getSaveFileName(self, "Please choose save location", "#{$configPath}", "Playlist file (*.m3u8)") + unless filename == nil then + playlist = BiliGuiPlaylist.new(@urlArea.toPlainText()) + playlist.save(filename) + end + end + end + end diff --git a/ChangeLog b/ChangeLog index e97eb4d..a275fbc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,6 @@ +0.0.5 +* switch to Tab layout for future features +* load/save bilibili playlist file. 0.0.4 * multl URLs support * fix: click cancel in BilidanChoose will clear biligui.conf diff --git a/TODO b/TODO index 88355b0..6d9db0d 100644 --- a/TODO +++ b/TODO @@ -1,3 +1,19 @@ -* load URLs from a file and save currently pasted URLs to a file * let error message fade out -* rework the GUI to use tabs for bilibili website +* autoload playlists +* capture more useful informations from console output +* more error detecting +* Bangou (avXXXX) paste support +* custom look and feel +* play history + +future: + +* download videos +** use aria2 +* upload videos +* rewrite a native ruby Bilidan +* fetch URL and extract stuff to fill bilibili.tv tab +** develop a cache system, to compare timestamp, background update, etc +* a navigation menu on bilibili tab and by default display top 10 videos with their link and preview image +* rearrange the video URLs, if it's not played yet, then update the stack. +* random play