Help - Search - Members - Calendar
Full Version: foo_playlist_tree
Hydrogenaudio Forums > Hosted Forums > foobar2000 > 3rd Party Plugins - (fb2k)
Pages: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37
cwbowron
Permission problem has been fixed again. I do not know of its a problem with my hosting or if someone hacked my ftp server, but it once again is working.
noorotic
@Chris (or Mr. Bowron)... I am using PTP in my PanelsUI, regardless of whether it causes flickers or not (worth it)... but my observation last night while working with it... it seems to me that Yes, the flickering/redraw problems are largely if not entirely corrected. I really appreciate this!

emot-toot.gif

And I have read some of the mzscheme coding, and will be playing with it sometime soon. My concentration levels are frequently unhappily low, and it does take some concentration.

One final note/question, would be, is there a page or location on your wiki (I have not found one) or would it not be helpful to have it, where useful and curious queries and formatting strings could be submitted? Just a thought.

smile.gif

Thanks for your efforts.
cwbowron
QUOTE(noorotic @ Mar 25 2007, 06:26) *
One final note/question, would be, is there a page or location on your wiki (I have not found one) or would it not be helpful to have it, where useful and curious queries and formatting strings could be submitted? Just a thought.


Yes, at one point I had my wiki open, but I got a lot of advertising spam, so I closed it so only I can edit the pages. If you have queries you would like to share, you can share them here or on my forum http://www.bowron.us/smf/... If I see stuff posted here that I think will have general appeal, I will post them to the wiki myself.

Thanks.
cwbowron
Temporary backup server:

http://msu.edu/~bowronch/foobar/foo_playlist_tree.zip
ciaran
Is there any way to do bitwise operations in the CRITERIA field?

I am trying to store a DWORD type var, so I want to do:

( %FIELD% & 2 ) GREATER 0

which would let me filter out bit 1, for example.

That query doesn't work tho. Can you help?

Thx
cwbowron
QUOTE(ciaran @ Mar 31 2007, 14:39) *

Is there any way to do bitwise operations in the CRITERIA field?

I am trying to store a DWORD type var, so I want to do:

( %FIELD% & 2 ) GREATER 0


No, there's no built in way to use bitwise operations there.

If you wanted to try out the built in scheme interpreter, you would be able to do this, but it will be more complicated.
ciaran
cwboron, thx for your reply. I figured out a way to do it with the $mod function. However, something like:

$mod(%ipod_pl%,2) GREATER 0

does not work in the criteria field. Was it possible to do tagz function, or am I just behind on PT versions and it can be done now?

Thanks again
cwbowron
New Release. This adds the ability to script foobar2000 menu actions as well as interact with the playlists via the embedded scheme language. You can also assign @scheme query refreshes to buttons to automate some stuff...

QUOTE
Release 3.0beta 3

* GUID's for queries
* main menu command for refreshing @scheme queries: Library/Playlist Tree/Refresh/* (you can refresh a query, for its side effects such as creating a new playlist and playing it with the new playlist interaction commands below)
* for-each-playlist-entry can now take an integer playlist index OR a playlist name to specify which playlist
* (in-library? handle)
* (handle-test handle filter-string) - e.g. (handle-test handle "rating GREATER 3")
* (mainmenu mainmenu-fun-string)
* (playlist-contextmenu contextmenu-fn-string [playlist-index])
* (contextmenu contextmenu-fn-string handle-list)
* (playing-playlist)
* (active-playlist)
* (find-or-create-playlist name) => returns a playlist-index
* (add-to-playlist handle [playlist-index] [item-index]) => if no playlist-index is specified, active playlist is assumed.
* (clear-playlist [playlist-index])
* (activate-playlist playlist-index)
* (play-from-playlist [playlist-index] [item-index])


Examples of new features:
CODE
;;; Fill *Scheme* playlist with an hours worth
(let ((playlist-index (find-or-create-playlist "*Scheme*"))
(total-time 0))
(clear-playlist playlist-index)
(for-each-db-entry
(lambda (handle)
(let ((len (get-length handle)))
(if (< (+ len total-time) (* 60 60))
(begin
(add-to-playlist handle playlist-index)
(set! total-time (+ total-time len))))))
"rating GREATER 3"
"$rand()")
(activate-playlist playlist-index)
(play-from-playlist playlist-index))


CODE
;;; Show properties of all playlist entries
(let ((the-list (list)))
(for-each-playlist
(lambda (n)
(for-each-playlist-entry
n
(lambda (handle)
(set! the-list
(cons handle the-list))))))
(contextmenu "Properties" the-list))
gob
hey cwbowron, if enough people are interested would it be possible to have a separate font dialog box for each playlist tree panel?
bb10
I have a problem with this component.

I'm using the latest Panels UI and SCPL. I have a node for my complete database and 2 nodes for 2 musicfolders.

Normally when i click on a node it displays all the tracks of that node in SCPL. It only does now with one of the nodes (53 tracks total on that node).

The other 2 nodes (with about 6000 tracks each) don't send the tracks to SCPL when i click on them.

Can anyone help me? smile.gif


EDIT:
When i start foobar my complete database is shown in SCPL.

Also when I click a node while im in another playlist it doesn't go to my *Browser* playlist. It only does that with one node and thats the one with 53 tracks.

EDIT2:
Nvm, I found an option that limits the number of files to 5000 under "mouse and keyboard". Strange place for that option but it solved my problem. smile.gif
w00tfest99
Am I being stupid? I loaded this plugin and I don't get the panel that all of the screenshots seem to show. Is there some place I have to go to activate it? I saw somewhere that you need to activate it in Columns UI but I don't know how do do that.
noorotic
QUOTE(w00tfest99 @ Apr 8 2007, 19:01) *

Am I being stupid? I loaded this plugin and I don't get the panel that all of the screenshots seem to show. Is there some place I have to go to activate it? I saw somewhere that you need to activate it in Columns UI but I don't know how do do that.


If your main UI is ColumnsUI, any panel must be added to the panel layout, under Preferences/ColumnsUI/Layout. If you are just getting started, it does (I found, anyway) take a while of playing with that, to get what you want.

If you are instead using PanelsUI, you must, in your main PanelsUI config (also under preferences), load and show any panel, with the $panel() function.

These things apply to any panel, not specifically PTP.

Best...
Kiteroa
This looks like it i sgoing to be a very powerful component - once the scheme language is understood.


Meanwhile, I'm trying to build an index of artists which includes them twice - once as

John Smith

and once as

Smith, John


No problem getting either way (using ordinary PTP queries) but I can't seem to combine them in a single query. Any ideas?
alphaex32
Are there any good tutorials for the new scheme language you're using? I'm curious about how powerful it is. Can it, for example, rename and move files between playlists automatically?
Kiteroa
QUOTE(alphaex32 @ Apr 19 2007, 11:03) *

Are there any good tutorials for the new scheme language you're using? I'm curious about how powerful it is. Can it, for example, rename and move files between playlists automatically?


Theres a lot of stuff on the mzscheme web site but it gets very complex , very quickly! It seems very abstract and extremely powerful but I haven't found it very easy to pick up.

I'm trying to generate and activate a single playlist named with the name of the now playing track and containing all versions of the current playing track.... I've based code on the examples provided to generate most of the pieces required (- now playing details, db query, etc.) but combining them is proving to be a nightmare!

Anyone have any examples?
MiSP
I'm using a tag, INVOLVED PEOPLE LIST, to display info about all involved people (duh). The syntax I use is

name1 (role1); name2 (role2); name3 (role3);

etc. Now, I want to make a query in foo_playlist_tree that displays all the different persons. If I just use %involved people list%, I get a single record with all of the involved people for any given track, and not one record for each person. Does anybody know how I can do this? (I only want the names, not the names and the roles.)

It gets more advanced after that - I want sub"folders" with their roles, and after that, various albums or something like that. I can do the latter myself, but how do I extract what is within each parenthesis?
cwbowron
QUOTE(MiSP @ Apr 19 2007, 08:41) *

I'm using a tag, INVOLVED PEOPLE LIST, to display info about all involved people (duh). The syntax I use is

name1 (role1); name2 (role2); name3 (role3);

etc. Now, I want to make a query in foo_playlist_tree that displays all the different persons. If I just use %involved people list%, I get a single record with all of the involved people for any given track, and not one record for each person. Does anybody know how I can do this? (I only want the names, not the names and the roles.)

It gets more advanced after that - I want sub"folders" with their roles, and after that, various albums or something like that. I can do the latter myself, but how do I extract what is within each parenthesis?


Are you trying to do this using only the foobar2000 titleformatting stuff, or are you doing it in scheme?
MiSP
QUOTE(cwbowron @ Apr 19 2007, 14:09) *

Are you trying to do this using only the foobar2000 titleformatting stuff, or are you doing it in scheme?

What's scheme? Let's go for foobar2000 titleformatting. tongue.gif Unless it's impossible, of course. I'm not familiar with scheme.
cwbowron
QUOTE(MiSP @ Apr 19 2007, 10:01) *

QUOTE(cwbowron @ Apr 19 2007, 14:09) *

Are you trying to do this using only the foobar2000 titleformatting stuff, or are you doing it in scheme?

What's scheme? Let's go for foobar2000 titleformatting. tongue.gif Unless it's impossible, of course. I'm not familiar with scheme.


There's a built in Scheme interpreter in Playlist Tree these days for really advanced quieries.

I don't know that your problem can be solved using regular titleformatting, but I know that it can using scheme, as I did something similar for a user on the playlist tree forum.
FofR
I'm having problems getting this to work with PanelsUI v0.9. I've installed the component and the library dlls in the correct places and the component options are there in the preferences.

From here I go to edit my layout and include a panel using $panel and making the panel Playlist Tree. When I click OK or Apply things go crazy, CPU usage jumps to 99% and fb2k's footprint starts rising rapidly. The pop-up asking for me to join the user map appears but I cannot click yes or no on it. I try waiting a while but the memory usage hits 300mb and fb2k says it's not responding so I have to stop the process from running.

Is there a fix to this, what's the likely cause? Are there known component incompatibilities?
2Pacalypse
@fofr

i have the same problem. the pop up about the map appears, and then another one pops up and it keeps going until i ctrl alt del foobar.
cwbowron
QUOTE(FofR @ Apr 19 2007, 12:08) *

I'm having problems getting this to work with PanelsUI v0.9. I've installed the component and the library dlls in the correct places and the component options are there in the preferences.

From here I go to edit my layout and include a panel using $panel and making the panel Playlist Tree. When I click OK or Apply things go crazy, CPU usage jumps to 99% and fb2k's footprint starts rising rapidly. The pop-up asking for me to join the user map appears but I cannot click yes or no on it. I try waiting a while but the memory usage hits 300mb and fb2k says it's not responding so I have to stop the process from running.

Is there a fix to this, what's the likely cause? Are there known component incompatibilities?


There were a few issues with ghosted windows and such in PTP and Browser, but I had thought that they were fixed.

I personally don't use Panels UI so I don't really know what's going on... I test Playlist Tree with columns ui and my own foo_dock plugin.
FofR
When I go to view > dockable panels > new. Then in that panel select Playlist tree I get a massive cpu spike but then the panel loads. From there, if I load up a Playlist Tree Panel in PanelsUI I get a small CPU spike but then everything is ok.

PUI may simply not like the alert the panel throws up.
sylla
Hello, I have tried to find it myself but didn't. It's probably pretty easy to do, I hope so =)

I want the playlist tree to act as the normal playlist view, so that when i click on anything in it it shows up in my SCPL.

I also have sorted my playlists with either -s- or -a- so that it views either album view or single view. I would want it to be so in the playlist tree too.

As it is now I have to middle click and then go through context menu to add it to a real playlist and it doesn't change view if I have -a- or -s-.

Any solution?
FofR
Is there a way to send different queries to different playlists? I see that Scheme has:

CODE
(add-to-playlist handle [playlist-index] [item-index]) => if no playlist-index is specified, active playlist is assumed.


But I am not sure how I would implement that with a mouse or keyboard action.
cwbowron
QUOTE(FofR @ Apr 19 2007, 17:42) *

Is there a way to send different queries to different playlists? I see that Scheme has:

CODE
(add-to-playlist handle [playlist-index] [item-index]) => if no playlist-index is specified, active playlist is assumed.


But I am not sure how I would implement that with a mouse or keyboard action.


It's possible in scheme. And once you've gotten the scheme query written, you can assign the query refresh to a keystroke or button using the Main Menu refresh options (under libarary->Playlist Tree->Refresh).
Kiteroa
Starting to have some success with scheme queries now - it is a very subtle but powerful language!

Is it possible to access the value of a tag (e.g. artist, track, or my user-defined tag "opus") in a scheme query to use elsewhere in scheme code?
cwbowron
QUOTE(Kiteroa @ Apr 19 2007, 21:41) *

Starting to have some success with scheme queries now - it is a very subtle but powerful language!

Is it possible to access the value of a tag (e.g. artist, track, or my user-defined tag "opus") in a scheme query to use elsewhere in scheme code?


absolutely. What are you trying to do?
Kiteroa
QUOTE(cwbowron @ Apr 20 2007, 14:14) *

QUOTE(Kiteroa @ Apr 19 2007, 21:41) *

Starting to have some success with scheme queries now - it is a very subtle but powerful language!

Is it possible to access the value of a tag (e.g. artist, track, or my user-defined tag "opus") in a scheme query to use elsewhere in scheme code?


absolutely. What are you trying to do?



I'm trying to query the database to find any other tracks with the same composer and title as that playing but which has an "opus" tag.

I'm (currently) stuck on building the filter string for the query and then building the name for the playlist. (I've hard-coded them into the code for the present). I'm not sure how to build get tag values (meta-tag()? ) and build strings?

In any case, although I can run the db query with a filter of form e.g. "composer is schubert" it does not run with a filter of a longer form e.g. "composer is schubert AND title is die forelle AND NOT opus MISSING" (even when hard-coded.)

I want to make and activate a playlist with the composer, title and opus number as its name. Then I'll pick up the name of the active playlist in panels_ui and make a button to set the opus of the playing track (after checking the composer and title match)!

Here's my code ( such as it is):

CODE


(let (        (playlistname '"OPUS3")  
               (filter "(composer HAS schubert AND title has forelle)")
       )  
      (let (
            (handle (now-playing))
            )
           (let (  
                  (title (format-title handle "%composer% %title%" ) )
                 )  
            (add-to-playlist handle playlist-index)
            (add-node handle (list title)
           )
      )

    (for-each-db-entry
           (lambda (handle)
                        (begin
                              (add-node handle (list (format-title handle "DB: %title% %opus%"  )))
                        )
             )
   filter
      )

  (let (
               (playlist-index (find-or-create-playlist playlistname))
        )
        (clear-playlist playlist-index)
        (activate-playlist playlist-index)
  )



I'm learning by doing ... and enjoying it as the power of the list processing languages is amazing, but I'd be grateful for any help you can give.
FofR
QUOTE(cwbowron @ Apr 20 2007, 00:38) *

It's possible in scheme. And once you've gotten the scheme query written, you can assign the query refresh to a keystroke or button using the Main Menu refresh options (under libarary->Playlist Tree->Refresh).


Would you mind showing me the code to do this?

My current code not using scheme is:

Criteria:
%last_played% HAS 20

Format:
$cwb_datediff(%last_played%,%cwb_systemdate%) days ago|[%artist% - ]%title%

Population Order:
$num($cwb_datediff(%last_played%,%cwb_systemdate%),3)$sub(100,$substr(%last_played%,12,13))

cwbowron
QUOTE(Kiteroa @ Apr 20 2007, 00:51) *

I'm trying to query the database to find any other tracks with the same composer and title as that playing but which has an "opus" tag.

I'm (currently) stuck on building the filter string for the query and then building the name for the playlist. (I've hard-coded them into the code for the present). I'm not sure how to build get tag values (meta-tag()? ) and build strings?

In any case, although I can run the db query with a filter of form e.g. "composer is schubert" it does not run with a filter of a longer form e.g. "composer is schubert AND title is die forelle AND NOT opus MISSING" (even when hard-coded.)

I want to make and activate a playlist with the composer, title and opus number as its name. Then I'll pick up the name of the active playlist in panels_ui and make a button to set the opus of the playing track (after checking the composer and title match)!


This should get you close. I couldnt test it myself because I dont have the same tags, so there could be some errors.

BTW, I think part of the problem with your original filter string is that case is important. all the keywords such as IS, HAS, MISSING, NOT, AND must be uppercase.

CODE
(let ((playing (now-playing)))
(let ((composer (format-title playing "%composer%"))
(title (format-title playing "%title%")))
(let ((filter
(string-append "composer IS " composer
" AND title IS " title
" AND NOT opus MISSING"))
(item-found #f))
(for-each-db-entry
(lambda (handle)
(let* ((opus (format-title handle "%opus%"))
(playlist-name
(string-append composer " - " title " - " opus)))
(add-to-playlist handle
(find-or-create-playlist playlist-name))))
filter))))
cwbowron
QUOTE(FofR @ Apr 20 2007, 04:23) *

QUOTE(cwbowron @ Apr 20 2007, 00:38) *

It's possible in scheme. And once you've gotten the scheme query written, you can assign the query refresh to a keystroke or button using the Main Menu refresh options (under libarary->Playlist Tree->Refresh).


Would you mind showing me the code to do this?

<snip>


Here's the original query converted into scheme:

CODE
(for-each-db-entry
(lambda (handle)
(let ((days (format-title
handle
"$cwb_datediff(%last_played%,%cwb_systemdate%) days ago"))
(leaf
(format-title
handle
"[%artist% - ]%title%")))
(add-node handle (list days leaf))))
"%last_played% HAS 20"
"$num($cwb_datediff(%last_played%,%cwb_systemdate%),3)$sub(100,$substr(%last_played%,12,13)")


Here's a version that puts the tracks into separate playlists based on when they were last played. It only uses tracks that have been played within 2 weeks.

CODE
(let ((cleared-list ()))
(for-each-db-entry
(lambda (handle)
(let ((days (format-title
handle
"$cwb_datediff(%last_played%,%cwb_systemdate%) days ago"))
(leaf
(format-title
handle
"[%artist% - ]%title%")))
(let ((p-index (find-or-create-playlist days)))
(when (not (member days cleared-list))
(clear-playlist p-index)
(set! cleared-list (cons days cleared-list)))
(add-to-playlist handle p-index))))
"%last_played% HAS 20 AND \"$cwb_datediff(%last_played%,%cwb_systemdate%)\" LESS 14"
"%last_played%"))




FofR
Excellent smile.gif, time to play.

Is there any reason this doesn't work:

CODE
$ifgreater(2,@quote<@format<%_itemcount%>>,,VA|)


Hmm, seems this would produce some sort of recursive error
cwbowron
QUOTE(FofR @ Apr 20 2007, 11:26) *

Excellent smile.gif, time to play.

Is there any reason this doesn't work:

CODE
$ifgreater(2,@quote<@format<%_itemcount%>>,,VA|)


Hmm, seems this would produce some sort of recursive error


Where are you trying to put that?
Kiteroa
QUOTE(cwbowron @ Apr 21 2007, 01:01) *

QUOTE(Kiteroa @ Apr 20 2007, 00:51) *

I'm trying to query the database to find any other tracks with the same composer and title as that playing but which has an "opus" tag.

I'm (currently) stuck on building the filter string for the query and then building the name for the playlist. (I've hard-coded them into the code for the present). I'm not sure how to build get tag values (meta-tag()? ) and build strings?

In any case, although I can run the db query with a filter of form e.g. "composer is schubert" it does not run with a filter of a longer form e.g. "composer is schubert AND title is die forelle AND NOT opus MISSING" (even when hard-coded.)

I want to make and activate a playlist with the composer, title and opus number as its name. Then I'll pick up the name of the active playlist in panels_ui and make a button to set the opus of the playing track (after checking the composer and title match)!


This should get you close. I couldnt test it myself because I dont have the same tags, so there could be some errors.

BTW, I think part of the problem with your original filter string is that case is important. all the keywords such as IS, HAS, MISSING, NOT, AND must be uppercase.

CODE
(let ((playing (now-playing)))
(let ((composer (format-title playing "%composer%"))
(title (format-title playing "%title%")))
(let ((filter
(string-append "composer IS " composer
" AND title IS " title
" AND NOT opus MISSING"))
(item-found #f))
(for-each-db-entry
(lambda (handle)
(let* ((opus (format-title handle "%opus%"))
(playlist-name
(string-append composer " - " title " - " opus)))
(add-to-playlist handle
(find-or-create-playlist playlist-name))))
filter))))




Thanks very much - it works well, first time!

I didn't realise about needing upper-case for the query keywords - (I realised last night that I had had the full filters working OK and couldn't figure why they didn't work now. I guess I changed their case when retyping etc.) It might be useful if the wiki states that tyeh keywords must be in capitals (or maybe it does and I didn't notice).

(Looking forward to doing more with scheme: I've already built a master index - single list with artists, albums, composer in alphabetical order - I'm going to add the entries "last, first" as well as "first last" (using your strchr function) and group under initial letters!

Looking at the primitives - should there be one to delete a playlist? delete a playlist entry? etc..
MiSP
QUOTE(cwbowron @ Apr 19 2007, 15:07) *

There's a built in Scheme interpreter in Playlist Tree these days for really advanced quieries.

I don't know that your problem can be solved using regular titleformatting, but I know that it can using scheme, as I did something similar for a user on the playlist tree forum.

Thanks, but I don't quite get where the code snippets should be entered. Criteria? Or Format? I've tried both, and nothing happens. (I did of course add a tag called "credits" with the same syntax to a few test tracks.)

I don't quite get the Scheme language. I've tried looking at the Scheme code snippets here and comparing them to their TAGZ counterpart, but I don't get it. Is there a place where I can learn it in this context, a place with examples and descriptions? I especially need some syntax reference, I mean, I don't even have any idea what the "let" thing does.
MiSP
Nevermind, I made it! Originally, I had the same problem as described here. However, I made some changes and tried using variables. It worked perfectly! biggrin.gif

Here's my code (I'm using the %involved people list% tag).

Criteria:
CODE
NOT involved people list MISSING


Format:
CODE
$puts(ip,%<involved people list>%)
$substr($get(ip),1,$add($strchr($get(ip),'('),-2))|$substr($get(ip),$add($strchr($get(ip),'('),1),$add($strrchr($get(ip),')'),-1))|%title%

This way, I will firstly get the involved people, then their roles as "subfolders". I've not done anything more interesting, I just wanted to get it working. Now it works, and I'll get to polish it and make it the way I want (basically adding more subfolders, like album).

The syntax I use when entering information into INVOLVED PEOPLE LIST is
CODE
name1 (role1); name2 (role2); name3 (role3)


For anyone struggling with the same problem, here's details:

First, I created this:
CODE
$substr(%<involved people list>%,1,$strchr(%<involved people list>%,''))|%title%

This was the one that didn't work. It was supposed to take all the involved persons and include the tag value up to the first parenthesis (where the role part begins). However, I just ran into the problem I mentioned earlier.

So, I went on to defining a variable:
CODE
$puts(ip,%<involved people list>%)

I didn't know what this would actually do - would it parse the whole tag and put every matching value into the variable, or would it parse the first part of the tag (the first person), finish the subfolders here and then move on to the next part (person)? Turns out it was the latter, and thank God for that. (Sorry if that was a messy description, I'm not that good with this stuff.)

So, the rest was easy. I added another line, the complete script now looked like this:
CODE
$puts(ip,%<involved people list>%)
$substr($get(ip),1,$strchr($get(ip),'('))|%title%

This would give names such as Todd Wilson (, Mark Smith ( etc. So, I just fooled around a bit with the $add() function to remove the two latter characters (the opening parenthesis and the space before that). Now it looked like this:
CODE
$puts(ip,%<involved people list>%)
$substr($get(ip),1,$add($strchr($get(ip),'('),-2))


So, for the last part, I wanted to have roles as subfolders. I did pretty much the same here - I used $strchr() and $strrchr() to get the character position for the opening and closing parentheses, used the $add() function to remove the parentheses themselves and ended up with the result at the top of this post. Hope this helps people. smile.gif

Edit: The only drawback with my INVOLVED PEOPLE LIST formatting used in conjunction with my script, is that I can not have parentheses in names or in the roles themselves, parentheses can only be used for denoting a role. For example: If I enter
CODE
Mike (Michael) Smith (guitar)

it will show up as the name "Mike" and the role "Michael) Smith (guitar". This can be fixed in two ways - either by changing the whole syntax used for entering information (which might be an idea), or by making the script find the last occurence of the opening parenthesis, and not the first occurence like I have done here (however, the latter does still not allow parentheses inside the role string).
Kiteroa
QUOTE(cwbowron @ Apr 21 2007, 01:01) *

QUOTE(Kiteroa @ Apr 20 2007, 00:51) *

I'm trying to query the database to find any other tracks with the same composer and title as that playing but which has an "opus" tag.

I'm (currently) stuck on building the filter string for the query and then building the name for the playlist. (I've hard-coded them into the code for the present). I'm not sure how to build get tag values (meta-tag()? ) and build strings?

In any case, although I can run the db query with a filter of form e.g. "composer is schubert" it does not run with a filter of a longer form e.g. "composer is schubert AND title is die forelle AND NOT opus MISSING" (even when hard-coded.)

I want to make and activate a playlist with the composer, title and opus number as its name. Then I'll pick up the name of the active playlist in panels_ui and make a button to set the opus of the playing track (after checking the composer and title match)!


This should get you close. I couldnt test it myself because I dont have the same tags, so there could be some errors.

BTW, I think part of the problem with your original filter string is that case is important. all the keywords such as IS, HAS, MISSING, NOT, AND must be uppercase.

CODE
(let ((playing (now-playing)))
(let ((composer (format-title playing "%composer%"))
(title (format-title playing "%title%")))
(let ((filter
(string-append "composer IS " composer
" AND title IS " title
" AND NOT opus MISSING"))
(item-found #f))
(for-each-db-entry
(lambda (handle)
(let* ((opus (format-title handle "%opus%"))
(playlist-name
(string-append composer " - " title " - " opus)))
(add-to-playlist handle
(find-or-create-playlist playlist-name))))
filter))))




This is working well - but I haven't been able to get it to activate one of the generated playlists just before it exits! I'd really appreciate your showing me what to do...

I've got it activating the playlist! - using a BEGIN to group the commands. I'd be interested to see how you would have done it, if you have some time some time.
Kiteroa
QUOTE(Kiteroa @ Apr 19 2007, 10:51) *

This looks like it i sgoing to be a very powerful component - once the scheme language is understood.


Meanwhile, I'm trying to build an index of artists which includes them twice - once as

John Smith

and once as

Smith, John


No problem getting either way (using ordinary PTP queries) but I can't seem to combine them in a single query. Any ideas?


I've done this now - I can put up my code if anyone is interested .
MiSP
Upload it please, I'm interested too.
Kiteroa
QUOTE(MiSP @ May 1 2007, 20:32) *

Upload it please, I'm interested too.



This is my scheme preferences code:

(remove-whitespace, strchr & split came from CWBowron's PLT forum; strip came from the web but flip and initial-and-string are my first scheme procedures - or whatever they are called in scheme!)


CODE


(define (remove-whitespace str)
(let ((len (string-length str)))
(do ((start 0 (+ 1 start)))
((or (>= start len)
(not (char=? #\space (string-ref str start))))
(do ((end (- len 1) (- end 1)))
((or (<= end start)
(not (char=? #\space (string-ref str end))))
(substring str start (+ 1 end))))))))

(define (strchr str chr start)
(cond
((>= start (string-length str)) #f)
((char=? (string-ref str start) chr) start)
(else (strchr str chr (+ 1 start)))))

(define (split str chr)
(let ((mid (strchr str chr 0)))
(if mid
(list (remove-whitespace (substring str 0 (- mid 1)))
(split (substring str (+ mid 1) (string-length str) chr))
)
#f)))
; strip : string -> string
; remove white space from the beginning and end of a string
(define strip
(let ([r-strip (regexp "^[ \t\r]*(.*?)[ \t\r]*$")])
(lambda (s)
(cadr (regexp-match r-strip s)))))

(define (flip str chr sep )
(let ((mid (strchr str chr 0)))
(if mid
(strip (string-append (strip (substring str (+ mid 1) (string-length str)))
(if (string? sep) sep (make-string 1 sep) ) (strip (substring str 0 mid ))))
#f)))

(define (initial-and-string str)
(if (> (string-length str) 2)
(list (substring str 0 1) str)
(list str)
))



and in the query:

CODE


(define (proc-tag hp tag album title)

(if (> (string-length tag) 1)
(add-node hp (append (initial-and-string tag) (list album title)) )
(if (flip tag #\, " ")
(add-node hp (append (initial-and-string (flip tag #\, " " )) (list album title) ))
(if (flip tag #\space "," )
(add-node hp (append (initial-and-string (flip tag #\ ", " )) (list album title) ))
)
)
)
)
;----------------------------------------------------------------------------------------------------------------------------------------
(for-each-db-entry
(lambda (handle)
(let (
(album (format-title handle "[%album%]"))
(albumartist (format-title handle "$if3($trim($meta(album artist)), )"))
(title (format-title handle "%track% %title%"))
(artistfull (format-title handle "$meta_sep(artist,', ',' & ')"))
)
(add-node handle (append (initial-and-string album) (list artistfull title)))

(for-each
(lambda (composer)
(let (
(album (format-title handle "[%album%]"))
(title (format-title handle "%track% %title%"))
)
(proc-tag handle composer album title)
))
(meta-list handle "composer") )

(for-each
(lambda (artist)
(let (
(album (format-title handle "[%album%]"))
(title (format-title handle "%track% %title%"))
)
(proc-tag handle artist album title)
) )
(meta-list handle "artist"))

(for-each
(lambda (artist)
(let (
(album (format-title handle "[%album%]"))
(albumartist (format-title handle "[%album artist%]"))
(title (format-title handle "%track% %title%"))
)
(proc-tag handle albumartist album title)
) )
(meta-list handle "artist"))
)
))



The code makes a single alphabetical index (i.e. A B C etc. ) with all artists, album artists, composers and albums in it. It handles ordinary names e.g. : "John Smith" and creates "Smith, John". It respects tags the other way around e.g. "te Kanawa, Kiri" and generates "Kiri te Kanawa" as the reversal. (If the tag was "Kiri te Kanawa", the normal process would generate "Kanawa, Kiri te".) e.g. "Mozart, Wolfgang Amadeus" and generates "Wolfgang Amadeus Mozart" as the reversal. (If the tag was "Wolfgang Amadeus Mozart", the normal process would generate "Amadeus Mozart, Wolfgang".) If the tag value ends with a comma, e.g. "Dresden Orchestra," then no reversal is meant to be entered. I was relying on the fact the original name and the flipped name would be the same so that there would only be one entry in the index. This works but the entry has each track twice. I'll fix this up tomorrow and repost.

Also, I have found that selecting items from Playlist Tree sends them directly to my active playlist as well as the playlist PLT is set up to send to. Not sure what is causing this. I intend to explore further tomorrow. I'd be grateful to hear if you do or don't experience this!

Good luck.
Kiteroa
QUOTE(Kiteroa @ May 1 2007, 22:17) *

QUOTE(MiSP @ May 1 2007, 20:32) *

Upload it please, I'm interested too.



This is my scheme preferences code:

(remove-whitespace, strchr & split came from CWBowron's PLT forum; strip came from the web but flip and initial-and-string are my first scheme procedures - or whatever they are called in scheme!)


CODE


(define (remove-whitespace str)
(let ((len (string-length str)))
(do ((start 0 (+ 1 start)))
((or (>= start len)
(not (char=? #\space (string-ref str start))))
(do ((end (- len 1) (- end 1)))
((or (<= end start)
(not (char=? #\space (string-ref str end))))
(substring str start (+ 1 end))))))))

(define (strchr str chr start)
(cond
((>= start (string-length str)) #f)
((char=? (string-ref str start) chr) start)
(else (strchr str chr (+ 1 start)))))

(define (split str chr)
(let ((mid (strchr str chr 0)))
(if mid
(list (remove-whitespace (substring str 0 (- mid 1)))
(split (substring str (+ mid 1) (string-length str) chr))
)
#f)))
; strip : string -> string
; remove white space from the beginning and end of a string
(define strip
(let ([r-strip (regexp "^[ \t\r]*(.*?)[ \t\r]*$")])
(lambda (s)
(cadr (regexp-match r-strip s)))))

(define (flip str chr sep )
(let ((mid (strchr str chr 0)))
(if mid
(strip (string-append (strip (substring str (+ mid 1) (string-length str)))
(if (string? sep) sep (make-string 1 sep) ) (strip (substring str 0 mid ))))
#f)))

(define (initial-and-string str)
(if (> (string-length str) 2)
(list (substring str 0 1) str)
(list str)
))



and in the query:

CODE


(define (proc-tag hp tag album title)

(if (> (string-length tag) 1)
(add-node hp (append (initial-and-string tag) (list album title)) )
(if (flip tag #\, " ")
(add-node hp (append (initial-and-string (flip tag #\, " " )) (list album title) ))
(if (flip tag #\space "," )
(add-node hp (append (initial-and-string (flip tag #\ ", " )) (list album title) ))
)
)
)
)
;----------------------------------------------------------------------------------------------------------------------------------------
(for-each-db-entry
(lambda (handle)
(let (
(album (format-title handle "[%album%]"))
(albumartist (format-title handle "$if3($trim($meta(album artist)), )"))
(title (format-title handle "%track% %title%"))
(artistfull (format-title handle "$meta_sep(artist,', ',' & ')"))
)
(add-node handle (append (initial-and-string album) (list artistfull title)))

(for-each
(lambda (composer)
(let (
(album (format-title handle "[%album%]"))
(title (format-title handle "%track% %title%"))
)
(proc-tag handle composer album title)
))
(meta-list handle "composer") )

(for-each
(lambda (artist)
(let (
(album (format-title handle "[%album%]"))
(title (format-title handle "%track% %title%"))
)
(proc-tag handle artist album title)
) )
(meta-list handle "artist"))

(for-each
(lambda (artist)
(let (
(album (format-title handle "[%album%]"))
(albumartist (format-title handle "[%album artist%]"))
(title (format-title handle "%track% %title%"))
)
(proc-tag handle albumartist album title)
) )
(meta-list handle "artist"))
)
))



The code makes a single alphabetical index (i.e. A B C etc. ) with all artists, album artists, composers and albums in it. It handles ordinary names e.g. : "John Smith" and creates "Smith, John". It respects tags the other way around e.g. "te Kanawa, Kiri" and generates "Kiri te Kanawa" as the reversal. (If the tag was "Kiri te Kanawa", the normal process would generate "Kanawa, Kiri te".) e.g. "Mozart, Wolfgang Amadeus" and generates "Wolfgang Amadeus Mozart" as the reversal. (If the tag was "Wolfgang Amadeus Mozart", the normal process would generate "Amadeus Mozart, Wolfgang".) If the tag value ends with a comma, e.g. "Dresden Orchestra," then no reversal is meant to be entered. I was relying on the fact the original name and the flipped name would be the same so that there would only be one entry in the index. This works but the entry has each track twice. I'll fix this up tomorrow and repost.

Also, I have found that selecting items from Playlist Tree sends them directly to my active playlist as well as the playlist PLT is set up to send to. Not sure what is causing this. I intend to explore further tomorrow. I'd be grateful to hear if you do or don't experience this!

Good luck.

Kiteroa
QUOTE(Kiteroa @ May 2 2007, 15:52) *

QUOTE(Kiteroa @ May 1 2007, 22:17) *

QUOTE(MiSP @ May 1 2007, 20:32) *

Upload it please, I'm interested too.



This is my scheme preferences code:

(remove-whitespace, strchr & split came from CWBowron's PLT forum; strip came from the web but flip and initial-and-string are my first scheme procedures - or whatever they are called in scheme!)


CODE


(define (remove-whitespace str)
(let ((len (string-length str)))
(do ((start 0 (+ 1 start)))
((or (>= start len)
(not (char=? #\space (string-ref str start))))
(do ((end (- len 1) (- end 1)))
((or (<= end start)
(not (char=? #\space (string-ref str end))))
(substring str start (+ 1 end))))))))

(define (strchr str chr start)
(cond
((>= start (string-length str)) #f)
((char=? (string-ref str start) chr) start)
(else (strchr str chr (+ 1 start)))))

(define (split str chr)
(let ((mid (strchr str chr 0)))
(if mid
(list (remove-whitespace (substring str 0 (- mid 1)))
(split (substring str (+ mid 1) (string-length str) chr))
)
#f)))
; strip : string -> string
; remove white space from the beginning and end of a string
(define strip
(let ([r-strip (regexp "^[ \t\r]*(.*?)[ \t\r]*$")])
(lambda (s)
(cadr (regexp-match r-strip s)))))

(define (flip str chr sep )
(let ((mid (strchr str chr 0)))
(if mid
(strip (string-append (strip (substring str (+ mid 1) (string-length str)))
(if (string? sep) sep (make-string 1 sep) ) (strip (substring str 0 mid ))))
#f)))

(define (initial-and-string str)
(if (> (string-length str) 2)
(list (substring str 0 1) str)
(list str)
))



and in the query:

CODE


(define (proc-tag hp tag album title)

(if (> (string-length tag) 1)
(add-node hp (append (initial-and-string tag) (list album title)) )
(if (flip tag #\, " ")
(add-node hp (append (initial-and-string (flip tag #\, " " )) (list album title) ))
(if (flip tag #\space "," )
(add-node hp (append (initial-and-string (flip tag #\ ", " )) (list album title) ))
)
)
)
)
;----------------------------------------------------------------------------------------------------------------------------------------
(for-each-db-entry
(lambda (handle)
(let (
(album (format-title handle "[%album%]"))
(albumartist (format-title handle "$if3($trim($meta(album artist)), )"))
(title (format-title handle "%track% %title%"))
(artistfull (format-title handle "$meta_sep(artist,', ',' & ')"))
)
(add-node handle (append (initial-and-string album) (list artistfull title)))

(for-each
(lambda (composer)
(let (
(album (format-title handle "[%album%]"))
(title (format-title handle "%track% %title%"))
)
(proc-tag handle composer album title)
))
(meta-list handle "composer") )

(for-each
(lambda (artist)
(let (
(album (format-title handle "[%album%]"))
(title (format-title handle "%track% %title%"))
)
(proc-tag handle artist album title)
) )
(meta-list handle "artist"))

(for-each
(lambda (artist)
(let (
(album (format-title handle "[%album%]"))
(albumartist (format-title handle "[%album artist%]"))
(title (format-title handle "%track% %title%"))
)
(proc-tag handle albumartist album title)
) )
(meta-list handle "artist"))
)
))



The code makes a single alphabetical index (i.e. A B C etc. ) with all artists, album artists, composers and albums in it. It handles ordinary names e.g. : "John Smith" and creates "Smith, John". It respects tags the other way around e.g. "te Kanawa, Kiri" and generates "Kiri te Kanawa" as the reversal. (If the tag was "Kiri te Kanawa", the normal process would generate "Kanawa, Kiri te".) e.g. "Mozart, Wolfgang Amadeus" and generates "Wolfgang Amadeus Mozart" as the reversal. (If the tag was "Wolfgang Amadeus Mozart", the normal process would generate "Amadeus Mozart, Wolfgang".) If the tag value ends with a comma, e.g. "Dresden Orchestra," then no reversal is meant to be entered. I was relying on the fact the original name and the flipped name would be the same so that there would only be one entry in the index. This works but the entry has each track twice. I'll fix this up tomorrow and repost.

Also, I have found that selecting items from Playlist Tree sends them directly to my active playlist as well as the playlist PLT is set up to send to. Not sure what is causing this. I intend to explore further tomorrow. I'd be grateful to hear if you do or don't experience this!

Good luck.




This is the latest, for me final, version - somewhat more Scheme-like (I think). I've added a loop to handle the values (divided by "\") in multi-value tags separately as some multi-value tags were not being separated by the primitive.

In the scheme preferences code box:

CODE

(define (remove-whitespace str)
(let ((len (string-length str)))
(do ((start 0 (+ 1 start)))
((or (>= start len)
(not (char=? #\space (string-ref str start))))
(do ((end (- len 1) (- end 1)))
((or (<= end start)
(not (char=? #\space (string-ref str end))))
(substring str start (+ 1 end))))))))

(define (strchr str chr start)
(cond
((>= start (string-length str)) #f)
((char=? (string-ref str start) chr) start)
(else (strchr str chr (+ 1 start)))))

(define (split str chr)
(let ((mid (strchr str chr 0)))
(if mid
(list (remove-whitespace (substring str 0 (- mid 1)))
(split (substring str (+ mid 1) (string-length str) chr))
)
#f)))

;;; str-split : Apr 2006 Doug Hoyte, hcsw.org.
;;; ----
;;; Splits a string 'str into a list of strings
;;; that were separated by the delimiter character 'ch
;;; ----
;;; Efficient as possible given that we can't count on
;;; 'str being an immutable string.

(define (str-split str ch)
(let ((len (string-length str)))
(letrec
((split
(lambda (a b)
(cond
((>= b len) (if (= a b) '() (cons (substring str a b) '())))
((char=? ch (string-ref str b)) (if (= a b)
(split (+ 1 a) (+ 1 b))
(cons (substring str a b) (split b b))))
(else (split a (+ 1 b)))))))
(split 0 0))))

; strip : string -> string
; remove white space from the beginning and end of a string
(define strip
(let ([r-strip (regexp "^[ \t\r]*(.*?)[ \t\r]*$")])
(lambda (s)
(cadr (regexp-match r-strip s)))))

(define (flip str chr sep )
(let ((mid (strchr str chr 0)))
(if mid
(strip (string-append (strip (substring str (+ mid 1) (string-length str) ))
(if (string? sep) sep (string sep) )
(strip (substring str 0 mid )) ))
#f )))

(define (initial-and-string str)
(cond ( (not str) '() )
( (> (string-length str) 1) (list (substring str 0 1) str ) )
( #t (list str) )
))


In the scheme code box:

CODE

(define (proc-tag hp multivaluetag album title)
(for-each
(lambda (multivaluetag)
(for-each
(lambda (tag)
(if (not (equal? (substring tag (- (string-length tag) 1) (string-length tag) ) ",") )
(add-node hp (append (initial-and-string tag) (list album title) )) )
(cond
( (strchr tag #\, 0)
(add-node hp (append (initial-and-string (flip tag #\, " " )) (list album title) )) )
( (strchr tag #\space 0)
(add-node hp (append (initial-and-string (flip tag #\space ", " )) (list album title) )) )
)
)
(str-split multivaluetag #\\) )
)
(meta-list hp multivaluetag) )
)
;----------------------------------------------------------------------------------------------------------------------------------------
(for-each-db-entry
(lambda (handle)
(let (
(album (format-title handle "[%album%]"))
(title (format-title handle "%track% %title%"))
(artistfull (format-title handle "$meta_sep(artist,', ',' & ')"))
)
; add album
(add-node handle (append (initial-and-string album) (list artistfull title) ))

(proc-tag handle "composer" album title)
(proc-tag handle "artist" album title)
(proc-tag handle "albumartist" album title)
(proc-tag handle "album artist" album title)
)
))


4nt1
Hi - I am running the latest version of everything...

Playlist Tree 3.03
Panels UI 11.0
Foobar 0.9.4.3
Columns UI 0.1.3 b1.7

Win XP SP2

Every time I try to run Playlist Tree in either Columns or Panels it stops responding and crashes - people keep telling me to launch Playlist Tree in columns ui and then get a dialogue box popup and click ok - and then from there it will work... I simply do not get this option - I have tried adding/removing all of the versions and components and I still do not get the option...

I really want to try and use this component but it aint working sad.gif

I have just tried removing panels completly and using the default ui and using dockable panels to add playlist tree and it wont show either.. I have those other dll's in my main foobar folder as instructed.. any suggestions.. it seems not to be panels ui related any more...


----

finally got it to load left the application in default ui running the panel for about 5-10 minutes and eventually the dialogue box shows up - i hit ok and now it works inside panels...

I am guessing it takes so long to load because I have a large music collection 50,000 songs and its scanning them?

either way I am happy its working now..
The Judge
Hey guys, having a little problem with this. I installed it once and didn't like it so deleted it. Thought I'd give it another shot again today and now it just doesn't want to work. I'm not used to it so I guess I could be using it incorrectly but I don't think so. In short it won't allow me to change playlists via the tree. If I right-click on my SCPL and change via the context menu it works but no-go otherwise. It worked the other day but not now. I even deleted any other components I've installed since but it still doesn't work. Any help would be appreciated.
shakey_snake
you can only "change playlists via the tree" if the active playlist is *Browser*
(or whatever you may have changed it to)
The Judge
Thanks but that still doesn't seem to have worked sad.gif. I just noticed my 'Refresh Browser' option in the Library menu is missing too.

EDIT:Seems it's not just the Playlist Tree. I can't change playlists via the Playlist Switcher either. Argh. Lol

Looks like my CFG or Columns UI got corrupted or something. Had to do a fresh install and reconfigure everything. Luckily I'd saved all my code as text files. Now that I think about it after I installed the playlist tree I did have a crash so that may be what caused it. Don't know. Either way, just thought I'd let you know. Remember to back up all your code not just your cfg! smile.gif

I'll get round to trying this again once I take a suitable rest. Lol.
cwbowron
I'm in the process of moving my foobar2000 components and documentations to a new server. It should forward links from the old wiki.bowron.us site to the new host at bazquux.com, but I wanted users to know that the new bazquux.com site is legitimate.
Notsmart
Greetings all!

I was wondering how I can enable this plugin?=/

I put those dll's in right directions, and I saw the playlist_tree in preferences-> components, but I have no clue how to enable it? ohmy.gif

Kiteroa
QUOTE(Notsmart @ May 12 2007, 06:18) *

Greetings all!

I was wondering how I can enable this plugin?=/

I put those dll's in right directions, and I saw the playlist_tree in preferences-> components, but I have no clue how to enable it? ohmy.gif



Try main menu: Library/ Playlist Tree/ Root/ New Query
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Invision Power Board © 2001-2008 Invision Power Services, Inc.