Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > top 10 last played mp3's

Reply
Thread Tools

top 10 last played mp3's

 
 
Robin Wagenaar
Guest
Posts: n/a
 
      10-13-2007
Hello everyone,

My level of ruby-experience has just slightly passed hello-world, I'm
quite new to this programming language; I hope I don't bother all of you
too much by posting my low-level question here.

I would like to make a program that iterates recursively trough my music
directory, and selects the top-10 of most recently played tracks.

I try to use File.atime(path) to check if the current file is accessed
recently enough to get into my top-10, but my problem is that I don't
know how to (correctly) compare a date to the return value of
File.atime.

I'm sure you can give me some simple hints, or a small push in the right
direction. Thanks in advance.



this is what I have so far:

require 'find'
require 'date'

dir = "/share/music"

Find.find(dir) do |path|

if File.directory?(path)
next
else
if path.match(".*mp3") != nil
print File.atime(path)," : "
print path,"\n"
end
end

end
--
Posted via http://www.ruby-forum.com/.

 
Reply With Quote
 
 
 
 
Andreas S.
Guest
Posts: n/a
 
      10-13-2007
Robin Wagenaar wrote:
> My level of ruby-experience has just slightly passed hello-world, I'm
> quite new to this programming language; I hope I don't bother all of you
> too much by posting my low-level question here.
>
> I would like to make a program that iterates recursively trough my music
> directory, and selects the top-10 of most recently played tracks.
>
> I try to use File.atime(path) to check if the current file is accessed
> recently enough to get into my top-10, but my problem is that I don't
> know how to (correctly) compare a date to the return value of
> File.atime.


File.atime returns a Time object, you can compare it to another Time
object, for example:

if File.atime(path) > (Time.now - 60*60)
# file has been accessed in the last hout
end

But you can also solve the whole problem much easier:

Dir['/share/music/**/*.mp3', '/share/music/*.mp3'].sort_by{|f|
File.atime}.reverse[0,10]
--
Posted via http://www.ruby-forum.com/.

 
Reply With Quote
 
 
 
 
Konrad Meyer
Guest
Posts: n/a
 
      10-13-2007
--nextPart1463448.0sYXGqbxM8
Content-Type: text/plain;
charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

Quoth Andreas S.:
> Robin Wagenaar wrote:
> > My level of ruby-experience has just slightly passed hello-world, I'm
> > quite new to this programming language; I hope I don't bother all of you
> > too much by posting my low-level question here.
> >=20
> > I would like to make a program that iterates recursively trough my music
> > directory, and selects the top-10 of most recently played tracks.
> >=20
> > I try to use File.atime(path) to check if the current file is accessed
> > recently enough to get into my top-10, but my problem is that I don't
> > know how to (correctly) compare a date to the return value of
> > File.atime.

>=20
> File.atime returns a Time object, you can compare it to another Time=20
> object, for example:
>=20
> if File.atime(path) > (Time.now - 60*60)
> # file has been accessed in the last hout
> end
>=20
> But you can also solve the whole problem much easier:
>=20
> Dir['/share/music/**/*.mp3', '/share/music/*.mp3'].sort_by{|f|=20
> File.atime}.reverse[0,10]


Or, if it's deeper than two levels:

require 'find'

Find.find("/share/music/").sort_by { |f| f.atime }.reverse[0...10]

I'm glad you (the OP) are interested in learning more about ruby.

Regards,
=2D-=20
Konrad Meyer <(E-Mail Removed)> http://konrad.sobertillnoon.com/

--nextPart1463448.0sYXGqbxM8
Content-Type: application/pgp-signature; name=signature.asc
Content-Description: This is a digitally signed message part.

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (GNU/Linux)

iD8DBQBHEU9vCHB0oCiR2cwRAkCNAKC2vO8oIgkHPzGcE61doM DxmNe0FgCg0J3F
4JW3gQn+01oF69LPuv53sw4=
=xQMx
-----END PGP SIGNATURE-----

--nextPart1463448.0sYXGqbxM8--

 
Reply With Quote
 
SpringFlowers AutumnMoon
Guest
Posts: n/a
 
      10-13-2007
Andreas S. wrote:
>
> Dir['/share/music/**/*.mp3', '/share/music/*.mp3'].sort_by{|f|
> File.atime}.reverse[0,10]


this one seems to work

a = Dir['E:/Music/*.mp3'].sort_by{|f| File.atime(f)}.reverse[0,10]
a.each {|f| p f, File.atime(f)}

except on Windows Vista, I noticed 2 things:

1) The filenames with internation characters come out as ?????.mp3
and therefore File.atime(f) will fails afterwards.

2) The access time of .mp3 or .txt or .txt is unchanged even after the
file is played, or run (such as by ruby test_dir.rb), or looked at by
Notepad.




--
Posted via http://www.ruby-forum.com/.

 
Reply With Quote
 
Justin Collins
Guest
Posts: n/a
 
      10-13-2007
Robin Wagenaar wrote:
> Hello everyone,
>
> My level of ruby-experience has just slightly passed hello-world, I'm
> quite new to this programming language; I hope I don't bother all of you
> too much by posting my low-level question here.
>
> I would like to make a program that iterates recursively trough my music
> directory, and selects the top-10 of most recently played tracks.
>
> I try to use File.atime(path) to check if the current file is accessed
> recently enough to get into my top-10, but my problem is that I don't
> know how to (correctly) compare a date to the return value of
> File.atime.
>
> I'm sure you can give me some simple hints, or a small push in the right
> direction. Thanks in advance.
>
>
>
> this is what I have so far:
>
> require 'find'
> require 'date'
>
> dir = "/share/music"
>
> Find.find(dir) do |path|
>
> if File.directory?(path)
> next
> else
> if path.match(".*mp3") != nil
> print File.atime(path)," : "
> print path,"\n"
> end
> end
>
> end
>


Your original question has been answered already, but just a small note:
puts and string interpolation is generally a lot simpler to use for output:

puts "#{File.atime(path)} : #{path}"

That will also add the "\n" or "\r\n" as appropriate, so you do not need to.

-Justin

 
Reply With Quote
 
Brian Adkins
Guest
Posts: n/a
 
      10-14-2007
On Oct 13, 7:06 pm, Konrad Meyer <(E-Mail Removed)> wrote:
> require 'find'
>
> Find.find("/share/music/").sort_by { |f| f.atime }.reverse[0...10]


Doesn't Find.find() require a block? And doesn't it pass a string to
the block, not a File ?

 
Reply With Quote
 
Andreas S.
Guest
Posts: n/a
 
      10-14-2007
Konrad Meyer wrote:
> Quoth Andreas S.:
>> > know how to (correctly) compare a date to the return value of

>>
>> Dir['/share/music/**/*.mp3', '/share/music/*.mp3'].sort_by{|f|
>> File.atime}.reverse[0,10]

>
> Or, if it's deeper than two levels:


'**' takes care of that.
--
Posted via http://www.ruby-forum.com/.

 
Reply With Quote
 
Brian Adkins
Guest
Posts: n/a
 
      10-14-2007
On Oct 13, 8:35 pm, "Andreas S." <(E-Mail Removed)>
wrote:
> Konrad Meyer wrote:
> > Quoth Andreas S.:
> >> > know how to (correctly) compare a date to the return value of

>
> >> Dir['/share/music/**/*.mp3', '/share/music/*.mp3'].sort_by{|f|
> >> File.atime}.reverse[0,10]

>
> > Or, if it's deeper than two levels:

>
> '**' takes care of that.


Ah, you're right! I missed that also (even though the ** line is
highlighted in the pickaxe now that I bother to read Dir#glob ).

Before reading your explanation, I put the following together. It
might be a little friendlier for handling multiple extensions I
suppose, especially since the glob pattern isn't a real regex.

require 'pp'
require 'find'

def n_recent_files n = 1, path = '.', exts = nil
paths = []
Find.find(path) do |p|
if File.file?(p) &&
( exts.nil? ||
( (ext = File.extname(p)) &&
!ext.empty? &&
exts.include?(ext) ) )
paths << p
end
end
paths.sort! {|a,b| File.atime(b) <=> File.atime(a) }[0,n]
end

pp n_recent_files(10, '/home/brian/temp', '.mp3')
pp n_recent_files(10, '/home/brian/temp', ['.mp3', '.ogg'])

Some notes for the OP:
1) Welcome to Ruby!
2) Enumerable#sort_by can be slow in some cases, and by using sort (or
sort! in this case), the comparison can be reversed to avoid calling
Array#reverse on the entire array later.
3) It exhibits a benefit of 'duck typing' since both String and Array
define include? the caller can pass in a single string or an array of
strings for the extension parameter w/ no extra effort in the
function.
4) Although the if expression is complicated, it has the advantage of
only computing the file extension when necessary.

Brian

 
Reply With Quote
 
Brian Adkins
Guest
Posts: n/a
 
      10-14-2007
Hmm.. it just occurred to me that many of the solutions presented here
have the flaw of potentially calling File.atime() multiple times for
the same file which would require unnecessary calls to the operating
system to get the access time of the file.

Better to compute atime only once and then sort on the result. In the
case below, I then extract the file name back out of the resulting
array, but in actuality, there may be some value in providing that to
the caller in case they could make use of the access time values.

require 'pp'
require 'find'

def n_recent_files n = 1, path = '.', exts = nil
paths = []
Find.find(path) do |p|
if File.file?(p) &&
( exts.nil? ||
( (ext = File.extname(p)) &&
!ext.empty? &&
exts.include?(ext) ) )
paths << [ p, File.atime(p).to_i ]
end
end
paths.sort! {|a,b| b[1] <=> a[1] }[0,n].map {|x| x[0]}
end

pp n_recent_files(10, '/home/brian/temp', '.rb')
pp n_recent_files(10, '/home/brian/temp', ['.rb', '.txt'])

 
Reply With Quote
 
Konrad Meyer
Guest
Posts: n/a
 
      10-14-2007
--nextPart5013869.Pj8XuXjaph
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

Quoth Brian Adkins:
> On Oct 13, 7:06 pm, Konrad Meyer <(E-Mail Removed)> wrote:
> > require 'find'
> >
> > Find.find("/share/music/").sort_by { |f| f.atime }.reverse[0...10]

>=20
> Doesn't Find.find() require a block? And doesn't it pass a string to
> the block, not a File ?


Sorry, don't know anything about it, I was just going by the usage put fort=
h=20
by the guy in front of me.

=2D-=20
Konrad Meyer <(E-Mail Removed)> http://konrad.sobertillnoon.com/

--nextPart5013869.Pj8XuXjaph
Content-Type: application/pgp-signature; name=signature.asc
Content-Description: This is a digitally signed message part.

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (GNU/Linux)

iD8DBQBHEZEfCHB0oCiR2cwRAvd9AKDOBtOgOWF/fL0V34GIy76bBJrB3QCgmwYH
iWDv1hck8h8EDXhcPrVR+PA=
=+L9L
-----END PGP SIGNATURE-----

--nextPart5013869.Pj8XuXjaph--

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
I have played enough with this. I need help. =?Utf-8?B?Q2hyaXM=?= ASP .Net 3 11-11-2004 08:46 PM
Is the sport of Eddierox baiting only played at weekends or can it be played during the week? Typh0n MCSE 67 04-07-2004 12:40 AM
dvd's from e80h have some distortion when played on PC readers news.bellatlantic.net DVD Video 1 12-04-2003 11:41 AM
dvd played by media player Wouter DVD Video 2 10-21-2003 07:36 PM
Every played tennis? Nevs Computer Support 3 09-12-2003 09:13 PM



Advertisments