Page 1 of 5

New *basic* Script to insert fake plays from iPod

Posted: Tue Mar 11, 2008 10:39 am
by brianon
Ok. This has bugged me for ages and I just managed to get a basic version of what I want working.

The problem:
You have a track that has a Play Count of 10. However in the Played table it shows only 5 entries. So you played the track 5 times in MM and 5 times on your iPod/MP3 player.
What happens is that this can screw up your charts. especially noticed in the great PlayHistory/Stat node script.

Solution: To add fake plays for missing Played entries.

The script:
Determines how many plays are missing. Adds entries into the Played table to make up the difference. Has super simple/basic logic for the dates to give to each entry.

Example: Track A has a PlayCounter of 2 and only 1 entry in the Played table. The track was added on the 1st of March. Todays date is 10th March. It will add a fake play for the 5th of March.

So while the script can NEVER be accurate (no way of actually telling when a track was played on your iPod) it trys to guess.

Its a very quick and dirty and nasty.

One thing it does do if that it creates its own little table and once you add a fake plays for a track it stores that date. So the next time you try to add fake plays for a track it will use THAT date and not the Track Added date. Should keep things more accurate.

Here is the script. Would be great if someone could make it better/more accurate/faster etc...

Code: Select all

' MediaMonkey Script
' NAME: Fake Plays
' AUTHOR: Brianon
' Start Date : 29-03-2008
' ------------------------------------------------------------------------------------------------------------
' Ver 1.10 (11 Mar 2008)

Sub FakePlays
  Dim DB            : Set DB     = SDB.Database
  Dim list, itm, i
  Dim trackPlayCount, trackPlayDates, fakePlaysToCreate
  Dim strSQL, sqlQry
  Dim formattedAddedDate, dateToInsert
  Dim daysDiff
	Dim lastSyncDate
  Dim bHasSyncDate
  'Create any temp tables we want and remove any from previous release if required.
  'DB.ExecSQL("DROP TABLE tmpLastFakeSync")
   'Set up progress
  Set Progress = SDB.Progress

  ' Get list of selected tracks from MediaMonkey
  Set list = SDB.CurrentSongList
  If list.Count=0 Then
    Exit Sub
  End If
  Progress.Text = "Processing tracks..."
  ' Process all selected tracks
  For i=0 To list.count-1
      Set itm = list.Item(i)
         ' Get the start (BEGIN) date
       strSQL = "select tmpLastFakeSync.SyncDate AS LastSyncDate from tmpLastFakeSync where tmpLastFakeSync.SongId = " & itm.ID
        Set sqlQry = SDB.Database.OpenSQL(strSQL)
         lastSyncDate = sqlQry.StringByName("LastSyncDate")
         If lastSyncDate = "" Then
            'mb1 = MsgBox("Track has no previous entry so we will use the Added date...", 0, "Error")
            bHasSyncDate = false
            ' here we get the date this track was added to the library
           strSQL = "select Songs.DateAdded AS TrackAddedDate from Songs where Songs.ID = " & itm.ID
           Set sqlQry = SDB.Database.OpenSQL(strSQL)
            lastSyncDate = sqlQry.StringByName("TrackAddedDate")
            formattedSyncDate = FormatDateTime(lastSyncDate,2)
            'mb2 = MsgBox("Last sync for this track was..." &lastSyncDate, 0, "Error")
            bHasSyncDate = true
            formattedSyncDate = FormatDateTime(lastSyncDate,2)
         End If
      ' here we get the playcount of the current track
      trackPlayCount = itm.PlayCounter
      ' here we get the number of time/date entries for this track from SQL query
       strSQL = "select Count(Played.IdSong) AS CountOfPlays from Played where Played.IdSong = " & itm.ID
       Set sqlQry = SDB.Database.OpenSQL(strSQL)
       trackPlayDates = sqlQry.StringByName("CountOfPlays")
      ' get the difference
      fakePlaysToCreate = trackPlayCount - trackPlayDates
      ' only continue if we have fake plays to create
      ' **TODO: could increment/decrement playcounter to match actual plays ?
      If fakePlaysToCreate > 0 Then
         ' now we need to determine how many days we should add to our starting date each time
         ' we add a fake entry
         daysToAdd = calcDaysToSub(formattedSyncDate, fakePlaysToCreate)
         'mb3 = MsgBox("Fake plays required for this track are..." &fakePlaysToCreate, 0, "Error")
          'mb4 = MsgBox("Todays Date is " &Now(), 0, "Error")
          dateToInsert = Now()
         ' now create 'X' fake plays. For each play missing, add a 'dummy'
         For x=0 To fakePlaysToCreate-1

              dateToInsert = DateAdd("d",daysToAdd, dateToInsert)
              'mb5 = MsgBox("dateToInsert: " &dateToInsert, 0, "Error")
           DB.ExecSQL("insert into Played (IdSong, PlayDate) values (" &itm.ID & ",'" &Cdbl(dateToInsert) & "')")

         ' now update our FakeSynList or add a new entry
         If bHasSyncDate = true Then
         	DB.ExecSQL("Update tmpLastFakeSync Set SyncDate = '" & Now() &"' where SongId = " &itm.ID)
          'mb6 = MsgBox("Updating SyncDate to " &Now(), 0, "Error")
         	DB.ExecSQL("INSERT INTO tmpLastFakeSync (SongId, SyncDate) values ("& itm.ID &", '" & Now() &"')")
         	'mb7 = MsgBox("Inserting SyncDate " &Now(), 0, "Error")
         End If
       End If
  Set Progress =  nothing
End Sub

Function calcDaysToSub(addedDate, playsToCreate)

   Dim modDiff
   Dim tmp
   ' determine how many days since this track was added
  daysDiff = DateDiff("d",addedDate, Date)
  'mb8 = MsgBox("calDaysToAdd() --> Days Difference is : " &daysDiff, 0, "Error")
  ' now get the days we must add for each fake play
  If daysDiff = 0 Then
     ' added today so just add all fake plays for today
       daysToAdd = 0
       'mb9 = MsgBox("1: calDaysToAdd() --> daysToAdds : " &daysToAdd, 0, "Error")
    ElseIf daysDiff = playsToCreate Then
       daysToAdd = 1
       'mb10 = MsgBox("2: calDaysToAdd() --> daysToAdds : " &daysToAdd, 0, "Error")
  ElseIf daysDiff > playsToCreate Then
     daysToAdd = daysDiff / (playsToCreate+1)
     'mb11 = MsgBox("3.1: calDaysToAdd() --> daysToAdds : " &daysToAdd, 0, "Error")
  ElseIf daysDiff < daysToAdd Then
     ' ok this isn't very accurate but for most cases it won't be too far off the mark
     ' and should suffice for what I want.
     daysToAdd = 1
     'mb12 = MsgBox("4: calDaysToAdd() --> daysToAdds : " &daysToAdd, 0, "Error")
      daysToAdd = 1
      mb13 = MsgBox("5: We missed some scenario. Defaulting to 1", 0, "Error")
   End If
  ' make the number a negative
  daysToAdd = daysToAdd - (DaysToAdd*2)
  calcDaysToSub = daysToAdd
  'mb114 = MsgBox("X: calDaysToAdd() --> daysToAdds : " &daysToAdd, 0, "Error")
End Function
EDIT: Strange. The code is really badly formatted above. Looks ok for me in UltraEdit.

Posted: Tue Mar 11, 2008 11:54 am
by Christoph
I tried your script but got an error in line 56.
He doesn't accept the function FormatDateTime or one of its parameters. It seems the second doesn't work.
I have .NET Framework 1.1, 2.0, 3.0 & 3.5 installed.


Posted: Tue Mar 11, 2008 11:59 am
by brianon
Works fine for me here. I will try it on another PC tonight.

Line 56: formattedSyncDate = FormatDateTime(lastSyncDate,2)

I got the FormatDateTime() function from ... tetime.asp so it should be good.

Posted: Tue Mar 11, 2008 12:04 pm
by Christoph
Yes, there's the problem.
Could you post how to install the script proper? Maybe, there's the mistake.


Posted: Tue Mar 11, 2008 12:31 pm
by brianon
To install...

Just copy/paste the code into a file. Call it FakePlays.vbs and put int eh scripts fir of Media Monkey.

Edit scripts.ini and add ...

Code: Select all

DisplayName=Fake Plays
Description=Create Fake Plays
Modify Order accordingly.

To try it out you just highlight a track(s). Then Tools->Script->Fake Plays.


Posted: Tue Mar 11, 2008 12:38 pm
by brianon
Christoph. Just one thing. What MM version you using?

No idea if it makes any difference but I am using the latest beta.

Posted: Tue Mar 11, 2008 12:51 pm
by Teknojnky
I'm gonna guess that is mm 2, which won't support the sqlite functions...

Posted: Tue Mar 11, 2008 1:07 pm
by Christoph
I'm also using the latest MM3 beta.
@Teknojnky: No, it's just a normal VB function that throws the error.


Posted: Tue Mar 11, 2008 3:20 pm
by brianon
just home now so will try it out on pc here.

Posted: Tue Mar 11, 2008 3:39 pm
by brianon
Ok. Tried it there.

I get a different error :)

There was a problem querying the database:
Error executirng SQL statement "INSERT INTO tmpLastFakeSync (SongId, SyncDate) Values(47179, '39518.8576388889')" : constraint failed (19, 19)

Anyone any ideas ?

Table is created like so...

The date in the insert is "Cdbl(Now())"

Ok. That wasn't the problem. Updated the script...see 1st post.

Working fine for me now :D

Posted: Tue Mar 11, 2008 6:08 pm
by Christoph
this line solves my problem:

Code: Select all

formattedSyncDate = FormatDateTime(lastSyncDate,vbshorttime)
A short addition:
I think your script should also set the last played date if it's empty.


Posted: Tue Mar 11, 2008 6:46 pm
by brianon
good idea.

Posted: Wed Mar 12, 2008 1:12 am
by Christoph
A little correction of my last suggestion:
It should set the last played date when the existing is smaller than the last added fake play date.
E.g. if the last played date is 2008-01-03 10:33:33 and the script inserts a play date at 2008-03-01 9:10:12 this should be also the last played date.


Posted: Wed Mar 12, 2008 3:13 am
by Christoph
Forget my script correction. Then the script works but it creates wrong dates.
I don't know why the parameter "2" doesn't work because "4" which is the same as vbshorttime I think, works.

I implemented the "last played" already and can show you the updated code when I found a solution for the formatdatetime problem.


Posted: Wed Mar 12, 2008 3:19 am
by Christoph
ok, got it. :)
I found the solution in another thread. It is related to the "." and "," in the lastSyncDate.

Here is the updated script. Seems to work well on my computer.


Edit: Another update.
If no additional plays were added the script checks whether the last play is also the "last time played" of the songs db.

Edit2: Old code removed.