View Issue Details

IDProjectCategoryView StatusLast Update
0011226MMW v4Framework: Scripts/Extensionspublic2013-10-05 02:51
Reporterzvezdan Assigned To 
PriorityhighSeverityminorReproducibilityalways
Status closedResolutionfixed 
Fixed in Version4.1 
Summary0011226: ISDBSongData::RenameByMask is moving file and changing Path property without UpdateDB
DescriptionThe RenameByMask method is moving file without used UpdateDB. Here is the test script:

Option Explicit

Sub OnStartUp()
    Dim oMenuItem

    Set oMenuItem = SDB.UI.AddMenuItem(SDB.UI.Menu_Pop_TrackList, 0, 0)
    oMenuItem.Caption = "Test changes to SongData"
    oMenuItem.OnClickFunc = "Test"
    oMenuItem.UseScript = Script.ScriptPath
End Sub

Sub Test(oMenuItem)
    Dim oSongData
    Dim bMoved

    Set oSongData = SDB.SelectedSongList.Item(0)
' oSongData.Path = ""
    On Error Resume Next
    bMoved = oSongData.RenameByMask(SDB.Tools.UFText2Mask _
            ("C:\Music\<Genre>\<Album Artist>\<Album>\<Track#:2> - <Title>"))
    On Error GoTo 0
    SDB.MessageBox bMoved & vbCr & oSongData.Path, mtInformation, Array(mbOK)
    oSongData.DiscardChanges
End Sub

If I remove the comment sign from the line: oSongData.Path = "" I get the error message: "Could not find file C, it will not be moved.". I tried that line because you have this strange thing with the Path property which says: "If you don't want to do so (to move file), you can set empty string to Path property first." That error message appears even with On Error Resume Next before problematic RenameByMask.

Note that I am not using UpdateDB and even I have the new DiscardChanges method.

Actuality, I want to get the string of path with applied some mask on some song, but without moving its file and even without changing its Path value in the database.
TagsNo tags attached.
Fixed in build1662

Relationships

related to 0011121 closedLudek ISDBSongData::Path = ... is moving file and changing Path property without UpdateDB (reverted) 
related to 0011115 closedLudek Strange behavior of ISDBSongData object 

Activities

zvezdan

2013-09-16 13:11

updater   ~0037553

If you don't want to change the current behavior of this method, then please add one new method, let say ISDBSongData::PathStringByMask, which could return the same string for path as RenameByMask, but without moving files.

Here are some examples why I need this. The first one is my Export/Create Playlists script to which I want to add a possibility to replace paths in playlist files with some user-defined mask. For example, one track has database path c:\My Music\blah blah.mp3 and user want to export M3U file which should store the path for that file using e:\Music\<Genre>\<Artist>\<Title>.<Extension> mask. I cannot use the existing RenameByMask method for that because it moves files which I don't want at all.

The another example would be my RegExp Find & Replace script to which I would like to add a possibility to replace paths using some user-defined mask. If you don't know how that script looks alike - it has one dialog box similar to Auto-Organize Files dialog box with one table displaying many files with their original (Old) and New paths. I cannot do this using the existing RenameByMask method because it moves files immediately, while I want just to display the new paths in the table first and to move files only if user clicks on the Replace button.

Ludek

2013-09-17 16:40

developer   ~0037579

Last edited: 2013-09-17 16:41

Added the new ISDBSongData::PathByMask method as described/requested here: 0011121:0037561

Added in build 1659.

peke

2013-09-18 22:32

developer   ~0037603

Verified 1659

Left for Zvezdan to close it.

zvezdan

2013-09-25 23:05

updater   ~0037680

I am getting the error #438 - Object doesn't support this property or method: 'oNewSong.PathByMask' with build 1661, where oNewSong is SongData object.

By the way, you didn't update wiki about this method.

Ludek

2013-09-26 12:49

developer   ~0037688

Last edited: 2013-09-26 12:49

Documented here: http://www.mediamonkey.com/wiki/index.php/ISDBSongData::PathByMask
with working script attached.

zvezdan

2013-09-26 14:07

updater   ~0037690

It works great, thank you very much! However, I need to ask, why did you make as a property, but not as a method? If it is a method it would be more consistent with the existing RenameByMask method. Besides, I cannot remember when I last saw (if at all) some property that is write-only. There are read-only or read/write, but write-only...

Ludek

2013-09-26 14:12

developer   ~0037691

Last edited: 2013-09-26 14:25

Yes, it could be method like RenameByMask, but I personally felt it like write property (i.e. more similar to Path property).

Not a big deal one way or the other IMHO. So letting it as property.


EDIT: Also property is about "setting something" and method about "doing something", and in this case it just sets the Path, so I think that it is reasonable to left it as write property.

zvezdan

2013-09-26 14:27

updater   ~0037692

I think it is more similar to RenameByMask method (with only difference that it takes effect only after UpdateDB), than it is similar to the Path property. The Path property is a "property" of SongData object as it is Artist or Album or Title, but I cannot see how "PathByMask" could be called a "property".

Besides, if it is a method it could be used directly in some user-created VBScript expression that I am using in RegExp script. The write-only property will be much more complicated to use in such cases.

zvezdan

2013-09-26 15:20

updater   ~0037696

Here are some excerpts from MSDN's page "Choosing Between Properties and Methods" at http://msdn.microsoft.com/en-us/library/vstudio/ms229054%28v=vs.100%29.aspx:

"Properties are meant to be used like fields, meaning that properties should not be computationally complex or produce side effects."

"Do use a property, rather than a method, if the value of the property is stored in the process memory and the property would just provide access to the value."

"Do use a method, rather than a property, in the following situations.

- The operation is orders of magnitude slower than a field set would be...

- The operation is a conversion, ..." (which is obviously the case with the PathByMask)

"- The operation returns a different result each time it is called, even if the parameters do not change..." (which is possible with the PathByMask, even if a mask do not change, since it depends of the Path value as well)

"- The operation has a significant and observable side effect..." (with that logic even your implementation of Path that moves files is not correct, but we already talked about that.)

Ludek

2013-09-26 15:51

developer   ~0037697

Last edited: 2013-09-26 16:00

Sorry, but I don't understand.

1. Why using S.PathByMask = "<artist> - <title>" will be much more complicated than using S.PathByMask("<artist> - <title>") ?

2. You wrote that operation is a conversion, I don't see a conversion, it only sets Path similar like S.Title = "Title" sets title.

You are true that Path should be rather a method (because it also moves a file), but I still don't see why PathByMask should be a method if it only sets path.


Nevertless it would be for me much less time consuming to change it from property to method than keeping this bizzare discussion with you. And because I created this property especially to satisfy your needs, I am going to do it again, but if you want it to change to method then it should be called rahter SetPathByMask(...)

Ludek

2013-09-26 16:29

developer   ~0037701

Last edited: 2013-09-26 16:47

1. Was about something different than you replied
2. You are true that there is a string conversion

I added new ISDBSongData::SetPathByMask method that does the same as the current PathByMask method, documented here:
http://www.mediamonkey.com/wiki/index.php/ISDBSongData::SetPathByMask

Added in 1662.

zvezdan

2013-09-26 16:30

updater   ~0037702

1. It is not complicated for scripters, but from the program side of view. Do you want to say that:
oSongData.PathByMask = ".\$First(<Genre>,1,1)\$MovePrefix(<Artist>)\$Replace(string,what,by)\...\whatever_you _could_write_using_masks"

is not internally more complicated (i.e. computationally more complex) than:
oSongData.Title = "some_simple_string"?

2. Do you really want to say that with the first example you are not doing internally any conversion? You are right that this discussion is bizarre when you could say that.

zvezdan

2013-09-26 16:59

updater   ~0037703

I am sorry, I just posted slightly modified text before I saw your response.

1. You are right, I didn't know on what you mean by "complicated" and I will now try to explain. If you didn't see RegExp script - it has a possibility to execute user-defined VBScript expressions during run-time. For example, users could write UCase("$&") and script will convert field specified with Into combo box to upper case. Or they could write SDB.Tools.UFText2Mask("<Artist>") and script will assign Artist to the specified field (not matter how pointless is this example).

So, users could use VBScript functions and MM property values quite easily in such expression. However, setting something to some property is not a function, but a statement. You cannot write oSongData.PathByMask = "something" in RegExp because this is not an expression, it does not return value, but sets value, instead of oSongData.PathByMask("something").

If you are using statement, then you should write something like Execute("oSongData.PathByMask = ""something"""), but then you have a problem with double quotes at best, and maybe something even more complicated. I could post you some expressions that I am using where I need to use 8 double quotes instead of just one because of using several nested Execute and Eval commands.

Anyway, this new method, property or whatever you gave added, is quite welcome. Thank you again.

peke

2013-10-05 02:51

developer   ~0037772

Verified 1662