irecorder 0.0.4-linux → 0.0.5-linux

Sign up to get free protection for your applications and to get access to all the features.
data/README CHANGED
@@ -1,10 +1,18 @@
1
1
  BBC iPlayer like audio recorder with KDE GUI.
2
2
  You can browse BBC Radio programmes and click to download stream file.
3
- file will be converted mp3 files automatically.
4
- iplayer allow to play without any other browser or play on your prefered browser.
3
+ files will be converted to mp3 files automatically.
4
+ irecorder allow to play without any other browser or play on your prefered browser.
5
5
 
6
- Installation
7
- ============
6
+ == KDE ruby
7
+ ==============
8
+ irecorder require kdebindings.
9
+ please check your distro package to install it.
10
+ or you can compile from source.
11
+ http://download.kde.org/download.php?url=stable/4.5.0/src/kdebindings-4.5.0.tar.bz2
12
+
13
+
14
+ == Installation
15
+ ==================
8
16
  install most important package kdebindings4.
9
17
  on Mandriva Linux use urpmi command.
10
18
 
@@ -28,8 +36,8 @@ launch irecorder just type irecorder.rb
28
36
  # irecorder.rb
29
37
 
30
38
 
31
- Build Gem
32
- ============
39
+ == Build Gem
40
+ =================
33
41
  if you want to gem package from source, use rake command.
34
42
 
35
43
  # rake gem
data/Rakefile CHANGED
@@ -6,9 +6,10 @@ require 'rake/gempackagetask'
6
6
 
7
7
  spec = Gem::Specification.new do |s|
8
8
  s.name = "irecorder"
9
- s.version = "0.0.4"
9
+ s.version = "0.0.5"
10
10
  s.author = "ruby.twiddler"
11
11
  s.email = "ruby.twiddler at gmail.com"
12
+ s.homepage = "http://wiki.github.com/rubytwiddler/irecorder/"
12
13
  s.platform = "linux"
13
14
  s.summary = "BBC iPlayer like audio recorder with KDE GUI."
14
15
  s.files = FileList["{bin,lib}/**/*"].to_a
@@ -22,12 +23,9 @@ spec = Gem::Specification.new do |s|
22
23
  BBC iPlayer like audio recorder with KDE GUI.
23
24
  You can browse BBC Radio programmes and click to download stream file.
24
25
  files will be converted to mp3 files automatically.
25
- iplayer allow to play without any other browser or on your prefered media player
26
+ irecorder allow to play without any other browser or play on your prefered browser.
26
27
  like mplayer.
27
28
  irecorder require kdebindings.
28
- svn://anonsvn.kde.org/home/kde/branches/KDE/4.4/kdebindings
29
- http://websvn.kde.org/branches/KDE/4.4/kdebindings/
30
- please check your distro package to install it.
31
29
  EOF
32
30
  s.has_rdoc = false
33
31
  s.extra_rdoc_files = ["README"]
@@ -65,3 +63,11 @@ task :install4rpm do
65
63
  installToDir('bin/irecorder', prefix, :mode => 0755)
66
64
  end
67
65
 
66
+
67
+ resouce_files = [ 'resources/irecorder.qrc' ] + FileList['resources/images/*.png']
68
+ desc "package resources"
69
+ file 'lib/irecorder_resource.rb' => resouce_files do
70
+ %x{ rbrcc resources/irecorder.qrc >lib/irecorder_resource.rb }
71
+ end
72
+
73
+ task :resource => 'lib/irecorder_resource.rb'
@@ -2,8 +2,8 @@
2
2
  #
3
3
  # 2010 by ruby.twiddler@gmail.com
4
4
  #
5
- # IPlayer interface
6
- # record real/wma (rtsp/mms) audio/video stream
5
+ # iPlayer interface
6
+ # record real/wma (rtsp/mms) audio stream
7
7
  #
8
8
 
9
9
  $KCODE = 'UTF8'
@@ -12,7 +12,7 @@ require 'ftools'
12
12
  APP_NAME = File.basename(__FILE__).sub(/\.rb/, '')
13
13
  APP_DIR = File::dirname(File.expand_path(File.dirname(__FILE__)))
14
14
  LIB_DIR = File::join(APP_DIR, "lib")
15
- APP_VERSION = "0.0.3"
15
+ APP_VERSION = "0.0.5"
16
16
 
17
17
  # standard libs
18
18
  require 'rubygems'
@@ -32,207 +32,16 @@ require 'qtwebkit'
32
32
  # my libraries and programs
33
33
  #
34
34
  $:.unshift(LIB_DIR)
35
+ require "irecorder_resource"
35
36
  require "bbcnet"
36
37
  require "mylibs"
37
38
  require "logwin"
38
39
  require "taskwin"
39
40
  require "download"
41
+ require "programmewin"
40
42
  require "settings"
41
43
 
42
44
 
43
-
44
-
45
-
46
- #---------------------------------------------------------------------------------------------
47
- #---------------------------------------------------------------------------------------------
48
-
49
-
50
-
51
-
52
-
53
- #---------------------------------------------------------------------------------------------
54
- #
55
- #
56
- class ProgrammeTableWidget < Qt::TableWidget
57
- slots 'filterChanged(const QString &)'
58
-
59
- #
60
- #
61
- class Programme
62
- attr_reader :titleItem, :categoriesItem, :updatedItem
63
- attr_reader :content, :link
64
-
65
- def initialize(title, categories, updated, content, link)
66
- @titleItem = Item.new(title)
67
- @categoriesItem = Item.new(categories)
68
- @updatedItem = Item.new(updated)
69
- @content = content
70
- @link = link
71
- end
72
-
73
- def title
74
- @titleItem.text
75
- end
76
-
77
- def categories
78
- @categoriesItem.text
79
- end
80
-
81
- def updated
82
- @updatedItem.text
83
- end
84
- end
85
-
86
- #
87
- #
88
- class Item < Qt::TableWidgetItem
89
- def initialize(text)
90
- super(text)
91
- self.flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled
92
- self.toolTip = text
93
- end
94
- end
95
-
96
-
97
- #------------------------------------------------------------------------
98
- #
99
- #
100
- attr_accessor :mediaFilter
101
-
102
- def initialize()
103
- super(0, 3)
104
-
105
- setHorizontalHeaderLabels(['Title', 'Category', 'Updated'])
106
- self.horizontalHeader.stretchLastSection = true
107
- self.selectionBehavior = Qt::AbstractItemView::SelectRows
108
- self.alternatingRowColors = true
109
- self.sortingEnabled = true
110
- sortByColumn(2, Qt::DescendingOrder )
111
-
112
- @mediaFilter = ''
113
-
114
- # Hash table : key column_0_item => Programme entry.
115
- @table = Hash.new
116
- end
117
-
118
- def addEntry( row, title, categories, updated, content, link )
119
- entry = Programme.new(title, categories, updated, content, link)
120
- setItem( row, 0, entry.titleItem )
121
- setItem( row, 1, entry.categoriesItem )
122
- setItem( row, 2, entry.updatedItem )
123
- @table[entry.titleItem] = entry
124
- end
125
-
126
- # return Programme object.
127
- def [](row)
128
- @table[item(row,0)]
129
- end
130
-
131
-
132
- #
133
- # slot : called when filterLineEdit text is changed.
134
- #
135
- public
136
-
137
- def filterChanged(text)
138
- return unless text
139
-
140
- text += ' ' + @mediaFilter unless @mediaFilter.empty?
141
-
142
- regxs = text.split(/[,\s]+/).map do |w|
143
- /#{Regexp.escape(w.strip)}/i
144
- end
145
- rowCount.times do |r|
146
- i0 = item(r,0)
147
- i1 = item(r,1)
148
- i2 = item(r,2)
149
- txt = ((i0 && i0.text) || '') + ((i1 && i1.text) || '') + ((i2 && i2.text) || '')
150
- if regxs.all? do |rx| rx =~ txt end then
151
- showRow(r)
152
- else
153
- hideRow(r)
154
- end
155
- end
156
- end
157
-
158
- GroupName = "ProgrammeTable"
159
- def writeSettings
160
- config = $config.group(GroupName)
161
- config.writeEntry('Header', horizontalHeader.saveState)
162
- end
163
-
164
- def readSettings
165
- config = $config.group(GroupName)
166
- horizontalHeader.restoreState(config.readEntry('Header', horizontalHeader.saveState))
167
- end
168
-
169
- protected
170
- def contextMenuEvent(e)
171
- item = itemAt(e.pos)
172
- menu = createPopup
173
- execPopup(menu, e.globalPos, item)
174
- end
175
-
176
- def createPopup()
177
- menu = Qt::Menu.new
178
- insertPlayerActions(menu)
179
- menu
180
- end
181
-
182
- def execPopup(menu, pos, item)
183
- action = menu.exec(pos)
184
- if action then
185
- action.data
186
- # $log.code { "execute : '#{action.vData}'" }
187
- cmd, exe = action.vData.split(/@/, 2)
188
- # $log.code { "cmd(#{cmd}), exe(#{exe})" }
189
- case cmd
190
- when 'play'
191
- playMedia(exe, item)
192
- else
193
- # self.method(cmd).call(item)
194
- end
195
- end
196
- menu.deleteLater
197
- end
198
-
199
- def insertPlayerActions(menu)
200
- Mime::services('.wma').each do |s|
201
- if s.exec then
202
- exeName = s.exec[/\w+/]
203
- a = menu.addAction(KDE::Icon.new(exeName), 'Play with ' + exeName)
204
- a.setVData('play@' + s.exec)
205
- end
206
- end
207
- end
208
-
209
- def playMedia(exe, item)
210
- begin
211
- prog = self[item.row]
212
- url = prog.content[UrlRegexp] # String[] method extract only 1st one.
213
-
214
- $log.info { "episode Url : #{url}" }
215
- minfo = BBCNet::MetaInfo.get(url).update
216
- url = minfo.wma.url
217
-
218
- cmd, args = exe.split(/\s+/, 2)
219
- args = args.split(/\s+/).map do |a|
220
- a.gsub(/%\w/, url)
221
- end
222
- # $log.debug { "execute cmd '#{cmd}', args '#{args.inspect}'" }
223
- proc = Qt::Process.new(self)
224
- proc.start(cmd, args)
225
-
226
- rescue => e
227
- $log.error { e }
228
- KDE::MessageBox::information(self, i18n("There is not direct stream for this programme."))
229
- end
230
- end
231
- end
232
-
233
-
234
-
235
-
236
45
  #---------------------------------------------------------------------------------------------
237
46
  #---------------------------------------------------------------------------------------------
238
47
  #
@@ -295,7 +104,7 @@ class MainWindow < KDE::MainWindow
295
104
  reloadStyleAction.setShortcut(KDE::Shortcut.new('Ctrl+R'))
296
105
  clearStyleAction = KDE::Action.new(KDE::Icon.new('list-remove'), i18n('&Clear StyleSheet'), self)
297
106
  clearStyleAction.setShortcut(KDE::Shortcut.new('Ctrl+L'))
298
- quitAction = KDE::Action.new(KDE::Icon.new('exit'), i18n('&Quit'), self)
107
+ quitAction = KDE::Action.new(KDE::Icon.new('application-exit'), i18n('&Quit'), self)
299
108
  quitAction.setShortcut(KDE::Shortcut.new('Ctrl+Q'))
300
109
  fileMenu = KDE::Menu.new('&File', self)
301
110
  fileMenu.addAction(recordAction)
@@ -534,6 +343,7 @@ BBC iPlayer like audio (mms/rtsp) stream recorder.
534
343
  )
535
344
  end
536
345
  )
346
+ vbxw.addWidget( @listTitleLabel = Qt::Label.new('') )
537
347
  vbxw.addWidget(@programmeTable)
538
348
 
539
349
  # 'Start Download' Button
@@ -552,12 +362,14 @@ BBC iPlayer like audio (mms/rtsp) stream recorder.
552
362
  connect( w, SIGNAL(:clicked), self, SLOT(:mediaFilterChanged) )
553
363
  end
554
364
 
555
- playBtn = KDE::PushButton.new( KDE::Icon.new('media-playback-start'), i18n("Play")) do |w|
365
+ playIcon = KDE::Icon.new(':images/play-22.png')
366
+ playBtn = KDE::PushButton.new( playIcon, i18n("Play")) do |w|
556
367
  w.objectName = 'playButton'
557
368
  connect( w, SIGNAL(:clicked), self, SLOT(:playProgramme) )
558
369
  end
559
370
 
560
- downloadBtn = KDE::PushButton.new( KDE::Icon.new('arrow-down'), i18n("Download")) do |w|
371
+ downloadIcon = KDE::Icon.new(':images/download-22.png')
372
+ downloadBtn = KDE::PushButton.new( downloadIcon, i18n("Download")) do |w|
561
373
  w.objectName = 'downloadButton'
562
374
  connect( w, SIGNAL(:clicked), self, SLOT(:startDownload) )
563
375
  end
@@ -621,6 +433,7 @@ BBC iPlayer like audio (mms/rtsp) stream recorder.
621
433
  def closeEvent(event)
622
434
  writeSettings
623
435
  super(event)
436
+ $config.sync # important! qtruby can't invoke destructor properly.
624
437
  end
625
438
 
626
439
  def readSettings
@@ -628,6 +441,7 @@ BBC iPlayer like audio (mms/rtsp) stream recorder.
628
441
  @mainTabPage.restoreState(config.readEntry('MainTabPageState', @mainTabPage.saveState))
629
442
  @progTableFrame.restoreState(config.readEntry('ProgTableFrame',
630
443
  @progTableFrame.saveState))
444
+ @channelTypeToolBox.currentIndex = config.readEntry('ChannelType', @channelTypeToolBox.currentIndex)
631
445
 
632
446
  @programmeTable.readSettings
633
447
  @taskWin.readSettings
@@ -637,9 +451,20 @@ BBC iPlayer like audio (mms/rtsp) stream recorder.
637
451
  config = $config.group(GroupName)
638
452
  config.writeEntry('MainTabPageState', @mainTabPage.saveState)
639
453
  config.writeEntry('ProgTableFrame', @progTableFrame.saveState)
454
+ config.writeEntry('ChannelType', @channelTypeToolBox.currentIndex)
640
455
 
641
456
  @programmeTable.writeSettings
642
457
  @taskWin.writeSettings
458
+ # dumpConfig(GroupName)
459
+ end
460
+
461
+ def dumpConfig(group)
462
+ puts "dump #{group} config"
463
+ entries = KDE::Global.config.entryMap(group)
464
+ confGroup = KDE::Global.config.group(group)
465
+ entries.each do |key, val|
466
+ puts " key(#{key}) = #{val.inspect}"
467
+ end
643
468
  end
644
469
 
645
470
  # ------------------------------------------------------------------------
@@ -664,6 +489,9 @@ BBC iPlayer like audio (mms/rtsp) stream recorder.
664
489
  color = "#%06x" % (@programmeSummaryWebView.palette.color(Qt::Palette::Text).rgb & 0xffffff)
665
490
 
666
491
  html = <<-EOF
492
+ <style type="text/css">
493
+ img { float: left; margin: 4px; }
494
+ </style>
667
495
  <font color="#{color}">
668
496
  #{prog.content}
669
497
  </font>
@@ -733,7 +561,7 @@ BBC iPlayer like audio (mms/rtsp) stream recorder.
733
561
  url = prog.content[UrlRegexp] # String[] method extract only 1st one.
734
562
 
735
563
  $log.info { "episode Url : #{url}" }
736
- minfo = BBCNet::MetaInfo.get(url).update
564
+ minfo = BBCNet::CacheMetaInfoDevice.read(url)
737
565
  $log.debug { "#{minfo.inspect}" }
738
566
  url = minfo.wma.url
739
567
 
@@ -762,13 +590,15 @@ BBC iPlayer like audio (mms/rtsp) stream recorder.
762
590
  $log.info{ "feeding from '#{feedAdr}'" }
763
591
 
764
592
  begin
765
- makeTablefromRss( BBCNet.read(feedAdr) )
593
+ makeTablefromRss( CacheRssDevice.read(feedAdr) )
766
594
  rescue IOError, OpenURI::HTTPError => e
767
595
  $log.error { e }
768
596
  end
769
597
  mediaFilterChanged
598
+ setListTitle
770
599
  end
771
600
 
601
+
772
602
  #
773
603
  # get feed address
774
604
  #
@@ -794,15 +624,31 @@ BBC iPlayer like audio (mms/rtsp) stream recorder.
794
624
 
795
625
  return nil if channelStr.nil?
796
626
 
797
- list = %w[ list highlights popular ][@listTypeGroup.checkedId]
627
+ @listType = @listTypeGroup.checkedId
628
+ list = %w[ list highlights popular ][@listType]
798
629
 
799
630
  "http://feeds.bbc.co.uk/iplayer/#{channelStr}/#{list}"
800
631
  end
801
632
 
802
633
 
634
+ def getCategoryTitle
635
+ CategoryRssTbl[ @channelIndex ][0]
636
+ end
637
+
638
+ def setListTitle
639
+ names = []
640
+ if getChannelTitle
641
+ names << getChannelTitle
642
+ else
643
+ names << CategoryRssTbl[ @channelIndex ][0]
644
+ end
645
+ names << %w[ All Highlights Popular ][@listType]
646
+ @listTitleLabel.text = names.join(' / ')
647
+ end
648
+
803
649
  protected
804
- def makeTablefromRss(rssRaw)
805
- rss = RSS::Parser.parse(rssRaw)
650
+ def makeTablefromRss(rss)
651
+ # rss = RSS::Parser.parse(rssRaw)
806
652
  sortFlag = @programmeTable.sortingEnabled
807
653
  @programmeTable.sortingEnabled = false
808
654
  @programmeTable.hide
@@ -816,7 +662,8 @@ BBC iPlayer like audio (mms/rtsp) stream recorder.
816
662
  title = i.title.content.to_s
817
663
  updated = i.updated.content.to_s
818
664
  contents = i.content.content
819
- link = i.links.find do |l| l.rel == 'self' end.href
665
+ linkItem = i.links.find do |l| l.rel == 'self' end
666
+ link = linkItem ? linkItem.href : nil
820
667
  categories = i.categories.map do |c| c.term end.join(',')
821
668
  $log.misc { title }
822
669
  @programmeTable.addEntry( r, title, categories, updated, contents, link )
@@ -858,7 +705,7 @@ BBC iPlayer like audio (mms/rtsp) stream recorder.
858
705
  url = prog.content[UrlRegexp] # String[] method extract only 1st one.
859
706
 
860
707
  $log.info { "episode Url : #{url}" }
861
- minfo = BBCNet::MetaInfo.get(url).update
708
+ minfo = BBCNet::CacheMetaInfoDevice.read(url)
862
709
  url = minfo.wma.url
863
710
 
864
711
  fName = getSaveName(prog, 'wma')
@@ -913,7 +760,7 @@ BBC iPlayer like audio (mms/rtsp) stream recorder.
913
760
 
914
761
  # channel [BBC Radio 4, ..]
915
762
  def getChannelName
916
- title = getChannelTitle
763
+ getChannelTitle
917
764
  end
918
765
 
919
766
  def getChannelTitle
@@ -980,6 +827,7 @@ end
980
827
  #
981
828
 
982
829
  about = KDE::AboutData.new(APP_NAME, APP_NAME, KDE::ki18n(APP_NAME), APP_VERSION)
830
+ about.setProgramIconName(':images/irecorder-22.png')
983
831
  KDE::CmdLineArgs.init(ARGV, about)
984
832
  # options = KDE::CmdLineOptions.new()
985
833
  # options.add( "+url", KDE::ki18n( "The url to record)" ),"")