Work in progress - Modify Play Counter via script

Download and get help for different MediaMonkey for Windows 4 Addons.

Moderators: Peke, Gurus

Pablo
Posts: 554
Joined: Sun Feb 22, 2004 2:59 am

Work in progress - Modify Play Counter via script

Post by Pablo »

Hi, here is my second version of the scripts. Now it is actually two scripts: one lets the user choose a new Play Counter for selected files (ChangePlayCounter) and the other resets all the Play Counters in the database to 0 (ResetPlayCounter). There's also a third script listed but I haven't implemented it yet.

You have to save the following code as: PlayCounter.vbs

Code: Select all

Sub ChangePlayCounter

  ' Define variables
  Dim list, itm, i, newPlayCounter, mb, progress
  
  'Get a new value for the Play Counter from the user

  newPlayCounter = InputBox("Enter the new value for the Played field", "Modify Play Counter")
  
  'If Canceled, exit
  If  newPlayCounter = "" Then
  	Exit Sub
  End If
  
  'Check that the text entered is a valid parameter. Inform user if it isn't.
  If Not IsNumeric(newPlayCounter) Then
  	mb = MsgBox("You did not enter a number. Please try again.",0,"Error")
  	Exit Sub
  ElseIf newPlayCounter < 0 Then
  	mb = MsgBox("Only positive numbers or 0 are allowed. Please try again.",0,"Error")
  	Exit Sub
    End If

  ' Get list of selected tracks from MediaMonkey
  Set list = SDB.SelectedSongList 
  If list.count=0 Then 
  	Set list = SDB.AllVisibleSongList 
  End If  
  
  'No songs selected?
  If list.count = 0 Then
  	mb = MsgBox("No songs were selected. Please select some songs and try again",0,"Error")
  	Exit Sub
  End If
  
  'Set up progress
  Set Progress = SDB.Progress
  Progress.Text = "Changing Play Counters..."
  Progress.MaxValue = list.count

  'Process all selected tracks
  For i=0 To list.count-1
    Set itm = list.Item(i)
    'Set the Play Counter
    itm.PlayCounter = newPlayCounter
    itm.UpdateDB
    Progress.value = i+1
    If Progress.terminate Then
    	Exit For
    End if	
  Next
  
  Set Progress =  nothing
  
End Sub

Sub ResetPlayCounter
	
	'This is drastic, so require confirmation from user
	
	Dim yesimsure

	yesimsure = InputBox("Are you sure you want to reset the play counter for all tracks in the Library? Write YES to proceed.", "Reset Play Counter")
	
	If yesimsure <> "YES" Then
		Exit Sub
	End If

	'Reset the counter...
	SDB.Database.ExecSQL("UPDATE SONGS SET PLAYCOUNTER = 0 WHERE TRUE=TRUE")

End Sub

Sub RestorePlayCounter

	Dim mb
	mb = MsgBox("This script has not been implemented yet.")
	

End Sub
You will also need to add the following to your scripts.ini file:

Code: Select all

[ChangePlayCounter]
FileName=PlayCounter.vbs
ProcName=ChangePlayCounter
Order=20
DisplayName=Change Play Counter
Description=Change the play counter of the selected files
Language=VBScript
ScriptType=0

[ResetPlayCounter]
FileName=PlayCounter.vbs
ProcName=ResetPlayCounter
Order=21
DisplayName=Reset Play Counter
Description=Reset the play counter of all files in the library
Language=VBScript
ScriptType=0
I'm working on improving and extending these scripts. Needless to say, backup your database since these scripts (especially reset) introduce substantial changes to it.

Pablo
Pablo
Posts: 554
Joined: Sun Feb 22, 2004 2:59 am

Post by Pablo »

Here is an update. Now you can:

* Set the play counter of selected tracks to whatever you want (Use "Scripts | Set Play Counter").
* Reset all play counters in the DB to 0 (Use "Scripts | Reset Play Counter").
* Restore all play counters to the actual number of times each track was played in MM (Use "Scripts | Restore Play Counter").

All these scripts alter the database, and although they seem to work (so you should be able to restore your counters after playing with the other two options) I can't guarantee it so back up your database!

Copy and paste the following code into a file called "PlayCounter.vbs" in your scripts folder:

Code: Select all


Sub SetPlayCounter

  ' Define variables
  Dim list, itm, i, newPlayCounter, mb, progress
  
  'Get a new value for the Play Counter from the user

  newPlayCounter = InputBox("Enter the new value for the Played field", "Set Play Counter")
  
  'If Canceled, exit
  If  newPlayCounter = "" Then
  	Exit Sub
  End If
  
  'Check that the text entered is a valid parameter. Inform user if it isn't.
  If Not IsNumeric(newPlayCounter) Then
  	mb = MsgBox("You did not enter a number. Please try again.",0,"Error")
  	Exit Sub
  ElseIf newPlayCounter < 0 Then
  	mb = MsgBox("Only positive numbers or 0 are allowed. Please try again.",0,"Error")
  	Exit Sub
  End If

  ' Get list of selected tracks from MediaMonkey
  Set list = SDB.SelectedSongList 
  If list.count=0 Then 
  	Set list = SDB.AllVisibleSongList 
  End If  
  
  'No songs selected?
  If list.count = 0 Then
  	mb = MsgBox("No songs were selected. Please select some songs and try again",0,"Error")
  	Exit Sub
  End If
  
  'Set up progress
  Set Progress = SDB.Progress
  Progress.Text = "Writing New Play Counters..."
  Progress.MaxValue = list.count

  'Process all selected tracks
  For i=0 To list.count-1
    Set itm = list.Item(i)
    'Set the Play Counter
    itm.PlayCounter = newPlayCounter
    itm.UpdateDB
    Progress.value = i+1
    If Progress.terminate Then
    	Exit For
    End if	
  Next
  
  Set Progress =  nothing
  
End Sub

Sub ResetPlayCounter
	
	'This is drastic, so require confirmation from user
	
	Dim yesimsure

	yesimsure = InputBox("Are you sure you want to reset the play counter for all tracks in the Library? Write YES to proceed. Note: You will have to refresh the view (F5) in order to see the changes.", "Reset Play Counter")
	
	If yesimsure <> "YES" Then
		Exit Sub
	End If

	'Reset the counter...
	SDB.Database.ExecSQL("UPDATE SONGS SET PLAYCOUNTER = 0 WHERE TRUE=TRUE")

End Sub

Sub RestorePlayCounter

	'This is drastic, so require confirmation from user
	
	Dim yesimsure

	yesimsure = InputBox("Are you sure you want to restore the play counter to the number of times each track was played in MediaMonkey? Write YES to proceed. Note: You will have to refresh the view (F5) in order to see the changes.", "Restore Play Counter")
	
	If yesimsure <> "YES" Then
		Exit Sub
	End If

	Dim Str1, Str2, Str3, Str4, Str5
	
	'Create a temporary table which stores song IDs and the number of times each song was played
	Str1 = "SELECT Songs.ID, timesPlayed INTO updateCounter "
	Str2 = "FROM Songs, [SELECT Played.idSong as SID, Count(Played.idSong) AS timesPlayed  FROM Played GROUP BY Played.idSong]. AS subq "
	Str3 = "WHERE Songs.Id =subq.SID"
	
	SDB.Database.ExecSQL(Str1 & Str2 & Str3)
	
	'Use the table just created to update the playCounter field in the songs table
	Str4 = "UPDATE Songs, updateCounter SET songs.playcounter = updateCounter.timesPlayed "
	Str5= "WHERE songs.id=updateCounter.id"
	
	SDB.Database.ExecSQL(Str4 & Str5)
	
	'Delete temporary table 
	SDB.Database.ExecSQL("DROP TABLE updateCounter")
	

End Sub
You will have to add the following lines to your scripts.ini file for this to work:

Code: Select all


[SetPlayCounter]
FileName=PlayCounter.vbs
ProcName=SetPlayCounter
Order=20
DisplayName=Set Play Counter
Description=Set the play counter of the selected files to whatever value you want
Language=VBScript
ScriptType=0

[ResetPlayCounter]
FileName=PlayCounter.vbs
ProcName=ResetPlayCounter
Order=21
DisplayName=Reset Play Counter
Description=Reset the play counter of all files in the library
Language=VBScript
ScriptType=0

[RestorePlayCounter]
FileName=PlayCounter.vbs
ProcName=RestorePlayCounter
Order=22
DisplayName=Restore Play Counter
Description=Restore the play counter of all files in the library
Language=VBScript
ScriptType=0

Let me know if this works and any ideas/suggestions! :o

The next step will be to allow the user to enter two dates and set the play counter to the number of times track were played in that period (useful if you wonder what you were listening to 1 year ago, or if you find that tracks that you don't like anymore are still high in the ranking and therefore decide to limit yourself to the last 3 months).

Pablo
roylayer
Posts: 85
Joined: Tue Feb 25, 2003 12:44 am

Post by roylayer »

Looks good, Pablo! There are a couple of things that I would do in addition:

1) Make a simplified version of SetPlayCounter that doesn't ask the user for a value. It would simply increment the PlayCounter column by 1. I would use that version of your script 99.99% of the time.

2) I am also a bit concerned that the LastPlayed column is not being updated. I do not know everything that MM does with LastPlayed and PlayCounter, so it might be safer to maintain them in pairs. For example, if the PlayCounter is not zero and the LastPlayed date is blank, could that cause a problem for MM somewhere if it is expecting a LastPlayed date to be set for a non-zero PlayCounter?

That type of unknown (to us, at least) internal data consistency logic is one of the dangers of updating the database outside of the existing MM user interface. I think we'd be pretty safe in this case, though.

Thanks for all of your efforts!
Happy user of MediaMonkey Gold version 2.5.5.998
Computer: p4, 2.5 ghz, 3 gb ram, win xp
Lowlander
Posts: 56572
Joined: Sat Sep 06, 2003 5:53 pm
Location: MediaMonkey 5

Post by Lowlander »

I don't think it matters that the two fields are inconsistent. My guess it is just used for playlists and searches.
We'll see what they say. I have asked in an other forum for a scripting guide once MM 2.2 is out there. This would give as some needed inside in MM, codes and thus expand scripting possibilities for us!
jiri
Posts: 5419
Joined: Tue Aug 14, 2001 7:00 pm
Location: Czech Republic
Contact:

Post by jiri »

You can modify these two fields without any danger.

Btw, there's also 'Played' table that contains information about any track played in the history. Actually the two fields in Songs table are redundant and are there only for performance reasons. The 'Played' table is used in 'write-only' mode currently (no information used for it), but it may be used in the future. Maybe this info could be useful for you...

Jiri
Lowlander
Posts: 56572
Joined: Sat Sep 06, 2003 5:53 pm
Location: MediaMonkey 5

Post by Lowlander »

So MM remembers every track ever played and its time? Isn't there a risk that the DB will grow to be enormous storing all this information?
jiri
Posts: 5419
Joined: Tue Aug 14, 2001 7:00 pm
Location: Czech Republic
Contact:

Post by jiri »

I don't think so, each entry requires only very little space. Anyway, there'll be options to empty the table once it's better utilized.

Jiri
Lowlander
Posts: 56572
Joined: Sat Sep 06, 2003 5:53 pm
Location: MediaMonkey 5

Post by Lowlander »

Ok, that's cool


How will this information eventually be used?
jiri
Posts: 5419
Joined: Tue Aug 14, 2001 7:00 pm
Location: Czech Republic
Contact:

Post by jiri »

There's a couple of options, e.g. some statistics, evaluation of listening habits, etc.

Jiri
Lowlander
Posts: 56572
Joined: Sat Sep 06, 2003 5:53 pm
Location: MediaMonkey 5

Post by Lowlander »

Cool, very cool. Some very powerful analysis could be done based on this data.
Pablo
Posts: 554
Joined: Sun Feb 22, 2004 2:59 am

Post by Pablo »

In fact, my script uses the played table to restore the Player Counter to the "correct" value once it's been modified. I think the redundance is good, because it allows to modify the player counter to suit the user preferences (for example, reset it) without losing information about played songs.

And I plan to do some kind of statistics in whe spirit Jiri mentions. Of course, it would be nice to have those as part of the MM interface :) .

Pablo
Lowlander
Posts: 56572
Joined: Sat Sep 06, 2003 5:53 pm
Location: MediaMonkey 5

Post by Lowlander »

Certainly, I can't wait for statistics. And not only numbers maybe some graphics too.

But we'll see that would be low priority, just has a huge coolness factor!
Pablo
Posts: 554
Joined: Sun Feb 22, 2004 2:59 am

A more advanced Set Play Counter script

Post by Pablo »

Hi, thanks for the suggestions. I wrote a far more flexible script to change the play counter. Instead of a number, the user can enter a formula and use the current value of the counter (denoted by C).
Examples:

0 ---> Set counter of selected files to 0.
C+1 ---> Increases counter of selected files by 1.
Max(C,1) ---> If counter is 0, move it to 1; otherwise don't modify it.
Sqr(C) ---> Takes the square root of C. Useful if you want to keep the relative order of play counters but make the numbers smaller (Sqr(C) will usually not be an integer but the program rounds to the nearest integer automatically).
Min(C,50) ---> Cap all counters at 50.

To use this script, add the following code to the existing playcounter.vbs file:

Code: Select all

Function Min(x, y)
	If x<y Then
		Min = x
	Else
		Min = y
	End If
End Function
			
Function Max(x, y)
	If x>y Then
		Max = x
	Else
		Max = y
	End If
End Function

Sub SetPlayCounterAdvanced

  ' Define variables
  Dim list, itm, i, userInput, newC , mb, progress, C
  
  'Get a new value for the Play Counter from the user

  userInput = InputBox("Enter a formula for the new play counter. Use C to refer to the current value. Examples: 0, C+1, Max(1,C).", "Set Play Counter (Advanced)")
  
  'If Canceled, exit
  If  userInput = "" Then
  	Exit Sub
  End If
  

  ' Get list of selected tracks from MediaMonkey
  Set list = SDB.SelectedSongList 
  If list.count=0 Then 
  	Set list = SDB.AllVisibleSongList 
  End If  
  
  'No songs selected?
  If list.count = 0 Then
  	mb = MsgBox("No songs were selected. Please select some songs and try again",0,"Error")
  	Exit Sub
  End If
  
  'Set up progress
  Set Progress = SDB.Progress
  Progress.Text = "Writing New Play Counters..."
  Progress.MaxValue = list.count

  'Process all selected tracks
  For i=0 To list.count-1
  
    Set itm = list.Item(i)
    C = itm.playCounter
    'Evaluate user input
    newC = Eval(userInput)
    
    'Set the Play Counter
    itm.PlayCounter = newC
    itm.UpdateDB
    Progress.value = i+1
    If Progress.terminate Then
    	Exit For
    End if	
  Next
  
  Set Progress =  nothing
  
End Sub
Add the following to the scripts.ini file:

Code: Select all

[SetPlayCounterAdvanced]
FileName=PlayCounter.vbs
ProcName=SetPlayCounterAdvanced
Order=20
DisplayName=Set Play Counter (Advanced)
Description=Modify the play counter by setting it to a numerical value or a formula depending on the current value
Language=VBScript
ScriptType=0
This script does no error checking, so if VBscript is not able to make sense of your formula you'll get an error message directly from the VBscript engine.

As usual, backup your database (but remember you can restore the play counter with one of the scripts).

Pablo
roylayer
Posts: 85
Joined: Tue Feb 25, 2003 12:44 am

Post by roylayer »

Pablo, are you sure that your scripts are actually updating the PlayCounter in the database? The reason I ask is that I wrote an alternate version of your script to do just the simple incrementing that I need without having to prompt the user, but the script doesn't actually update the database. Here's the script:

Code: Select all

'increments play counter

Option Explicit

Sub IncrPlayCntr
  ' Define variables
  Dim list, itm, i

  ' Get list of selected tracks from MediaMonkey
  Set list = SDB.SelectedSongList 
  If list.count=0 Then 
    Set list = SDB.AllVisibleSongList 
  End If  

  ' Process all selected tracks
  For i=0 To list.count-1
    Set itm = list.Item(i)
    itm.PlayCounter = itm.PlayCounter + 1

    ' Update the changes in DB
    itm.UpdateDB
  Next
End Sub
This script is almost identical to FixTrkNo, a script that I posted earlier. (As a matter of fact I began coding this script by first cloning that one.) The only difference is that FixTrkNo updates TrackOrder, and it works; whereas, this one updates PlayCounter, and it doesn't work. It looks like it works when looking in the tracklist pane. The proper value is even displayed inside of the script when I display it via a Msgbox. But when I leave the node and come back, the PlayCounter is unchanged. I also verify that it is unchanged by checking the record in the Access database.

So, I conclude that the UpdateDB method of the Item object does not update PlayCounter.

Can you check to see if yours is really working? If it is, I need to figure out what you're doing right and what I'm doing wrong! Thanks.
Happy user of MediaMonkey Gold version 2.5.5.998
Computer: p4, 2.5 ghz, 3 gb ram, win xp
Pablo
Posts: 554
Joined: Sun Feb 22, 2004 2:59 am

Post by Pablo »

Roylayer,

You're right! My Set Counter and Set Counter (advanced) scripts DO NOT update the database. Maybe the playCounter field was somehow implemented as read-only...

However, the reset/restore scripts do work, because they execute SQL (they don't go through updateDB). So to make my and your script work, we only have to replace itm.playCounter =... and itm.updateDB by an explicit SQL call that does the same; i.e:

Code: Select all


   SDB.database.execSQL("UPDATE Songs SET PlayCounter=" & newValue & " WHERE Id=" & itm.songID)

Here newValue is the new desired value for the play counter (in your case, newValue = itm.PlayCounter+1).

I did this to one of my scripts and now it works (you'll have to refresh the view to see the new values).

Thanks for finding out this! :o

Pablo
Last edited by Pablo on Fri Mar 12, 2004 10:14 pm, edited 2 times in total.
Post Reply