OpusCustomFields Script Command (Feedback Needed)

Hi
I've been using this command for a few weeks and while I have not found any issues, it definitively needs more thorough testing in different scenarios before being released.

Anyone who might find this useful and want to be a tester? PM me or write below.

OpusCustomFields is a command that lets you define and set custom fields in Directory Opus. Now you can create your own custom metadata with ease!

Main Features:

  • Allows you to define custom fields through an easy-to-use interface. You can set the keyword, label, and data type the field will store.
  • You can set values in previously defined fields using the same command, making it possible to use it programmatically and from other commands/external programs.
  • You can copy, move, or delete the file containing the metadata. This makes it easy to transfer entire metadata sets between files or even create backups.
  • Supports files/folders on NTFS drives and other storage types, even outside the filesystem (ZIP, FTP, MTP, etc.).

How It Works:

When reading or setting values, the command tries to read/store data in the following order:

  1. In an ADS within the same file.
  2. In a separate file in a user-specified folder.
  3. In a file in the same directory as the target file.

If the file is in the filesystem but not on an NTFS drive, only the last two options are used.
If the file is outside the filesystem, only the second option is used.

The data is available in Opus as regular script columns, so they can be used wherever available.
Data can be written using the command itself, with a syntax similar to SetAttr META.

Sign me up

I'm interested in this. Can I get to use it? Thank you.

Hi @errante, am very glad to see your attempt at this, it sounds very promising.
We had a back and forth, a few months back, about this script's subject.

Am very interested for sure, and am I would like to test it.

If I may two specific questions.
Regarding;

Are these two methods similar and compatible with voids implementation? I ask as I am looking for a solution that would be compatible with Everything 1.5. Reading your description of it, it seems to be.

With NTFS ADS being a pain and limiting, I am only interested in method 3;

Does OpusCustomFields address the issue of orphans? ie when you copying or moving files, OpusCustomFields ensures the metadata is moved or copied along with its file?

Cheers.

Thanks for the interest.
However, a long time ago I decided to put this aside and keep it for personal use. Mainly because I couldn't meet the standards I was looking for regarding Everything support, and because, as it is, it can fulfill my needs, so I got lazy about it and called it a day.

No. I talked to void a couple of times about the possibility of implementing some more practical way of adding Everything support for companion files, but that was about it. I remember that some weeks after I finished the test script, void came up with metadata.efu support. But as far as I understand, its implementation isn't meant for custom fields, but rather for already-defined properties. I do think about making it compatible at some point, mainly because I want those fields to be instantly searchable so badly. But as I said, I was lazy about it, and also, as I said, metadata.efu doesn't look like it's meant for custom fields.
At the moment, those two options are basically the same files that are stored in the ADS stream, so they're companions per-file instead of per-folder.

No, because the event designed for this doesn't support it. You can check more about it here:

It does support rename operations, which is the only thing I could add support for.

I'm very open to new ideas about this though, especially when it comes to some kind of Everything integration :grinning_face:. Regarding the format and everything else, currently the companion files are just a JSON schema that stores the value and internal name, with all your custom fields in the same file. So it's easier for DOpus to retrieve them, but probably not so much for other tools like Everything.


FWIW, although it looks kind of off-topic, have you ever used Calibre? What about .OPF files?

In Calibre, you can also define and set custom fields. Although it's meant for ebooks, you can basically add those companion .OPF files to any file. Since I'm an avid book reader, I do have a lot of ebooks (mostly in Calibre and Kavita), so a while ago I was thinking about how cool it would be to access all that metadata from Opus.
So that add-in also exists :sweat_smile:. It can parse any .epub, .pdf, and .cb* natively, with support for parsing .opf files as well. So in theory, you could also use those files for custom metadata.

I was just waiting for 13.25.1 to be out and see what changes related to thumbnailers it would bring, so I could act accordingly (Currently that add-in can also let you add cover previews, as an external tool). So feel free to test it once it's released.

I've been thinking about this for the past month. A few weeks ago, I made a prototype of OpusCustomFields that uses a sqlite database, and I definitely think that's the way to go. At least for me, it's been quite useful in practice, and having an actual database makes searches much faster (e.g. I was moving my labels and tags, set unmovable timestamps to files, .etc).

In this case, I need some testers to help out before I simply release it, since it could end up changing the design itself. I may have overlooked something, etc. Once it's published, it'll be harder to make those kinds of changes. Anyone interested?

FEATURES:

  • Manage custom fields through an easy-to-use interface.
  • Almost any item can have custom fields, including FTP, MTP, items inside archives, etc.
  • Full support for all data types supported by Opus.
  • Custom fields can be used as regular script columns, e.g. for searching, filtering, etc.
  • Built-in support for setting values in registered fields.
  • Officially, these are the first user columns in Opus that aren't read-only!
  • Support for exporting/importing custom fields.
  • Support for advanced actions: PULL, PUSH, FLUSH, .etc.
  • Seamless data management using a sqlite database.
  • Support for directly searching the database, including an advanced mode using SQL SELECT syntax.

MANAGING CUSTOM FIELDS:

To use this script, you first need to have some fields enabled. This can be done from the Configuration window.

To manage your custom fields, you can access it:

  • From the Script Management window
  • Using the OPUSCUSTOMFIELDS CONFIG command

You can disable fields. Their data will remain in the database, but they won't be accessible through any command (their status is changed to inactive in the database).

You can customize various properties for a column, including adding a short description.

Once you've made your changes, you need to press Save to apply them (including to the database).

NOTE 1: When creating a custom field, you'll be asked for a name and a data type. These CANNOT be changed later due to the difficulty involved in changing the data type in the database.

NOTE 2: When configuring the fields, the fields reported by the database and those stored in your Opus configuration are synced to keep both sides in sync. No columns are deleted during this process.

NOTE 3: Deleting a column from the Configuration window IS A DESTRUCTIVE PROCESS. It means DELETING the column from the database ALONG WITH ALL OF ITS DATA.


AVAILABLE COMMANDS:

Set:

Allows you to set values for any active fields. Its syntax is similar to how Opus's SET META command works.

Pull:

Creates a copy of all custom fields and their values for a given file.

Push:

Sets values for active fields by reading the data from a file.

Flush:

Removes values from active fields for a given file.

Find:

Searches directly using the database. It supports a simple syntax based on the field data types, as well as an advanced mode using SQL SELECT syntax.

Purge:

Cleans up orphaned data in the database, or removes data for files matching a given wildcard. It can also run the SQL VACUUM command.


NOTES:

  • It is NOT possible to track a file when it is moved/deleted if it has data in the database. To mitigate this limitation, the script uses:

    • The unique file ID of each file (for local filesystem files only) is stored in the database, so if a file is moved within the same drive, it can theoretically be found and updated automatically.
    • There is an option (which must be enabled in the script's Options window) to save a copy to an ADS and/or a .dopcf file next to the file whenever the database is modified, when possible (local filesystem files only).
    • There is a column that is always enabled and shows the number of fields for a given file. This can be useful if you plan to move the file somewhere else, so you can first use the PULL command to create a copy.
    • There is a column that is always enabled and shows the last time the data was saved to the database.
  • Custom fields can be used in regular Opus searches, although this obviously means using the database indirectly.

  • Datetime, date, and time values are always stored in UTC using ISO-8601 format, but are transparently converted back to the local time zone when used through any method (except PULL, where they retain their original format).

  • When setting data (PUSH and SET), you can use placeholders for any property available in Opus for a file, including script/Evalautor column values. To invoke a placeholder, enclose it in $_value_$.
    Example: OpusCustomFields SET "mytags:$_keywords_$;other tag" "timestamp:$_created_$" sets values for mytags and timestamp on the selected files in the source file display, retrieving the keywords and creation date of each file at runtime.
    If a value is set to empty, that field is removed for the given file (similar to how SET META works).

  • You can use FLUSH to remove fields more easily. Example: OpusCustomFields FLUSH=mytags,timestamp.

  • The schema for PUSH is a simple JSON object with key:value pairs.

  • Valid values according to the data type are:

    • Text: Any string value.
    • Datetime: "now" or formatted as ISO-8601, with optional milliseconds when a time component is present.
    • Date: "now" or formatted as ISO-8601.
    • Time: "now" or formatted as ISO-8601, with optional milliseconds.
    • Number: Any positive integer.
    • Number,signed: Any integer.
    • Double: Any double number.
    • Boolean: true|yes|1 are equivalent to true. Anything else is converted to false.
    • Stars: Integer between 0 and 5.
    • Percent|Graph: Integer between 0 and 100.
    • Duration: Integer or string in the format xd HH:mm:ss. Days, hours, and minutes are optional.
    • Durationh: Integer or string in the format xd HH:mm:ss. Days are optional.
    • Size: Integer or a numeric string.
  • Some values may be converted if they don't follow the guidelines above.

  • No command can CREATE or DELETE fields, or modify fields marked as inactive. Use the Configuration window for those operations.

  • Column import is currently only available from the Configuration window.

I'm definitely interested in this.

Ok, let me add support for 2 more things.

Btw, do you think the database should be encrypted using Windows tools, so that it only allows access to one specific user and the script?
The user would add their own password but it would still be linked to the current Windows user. Personally, I don't think I need that, but maybe it's common for many users to keep super private things in the db?

I would not make that the default at least. I think that for many users, it's just useless and could lead to information loss if they forget the password.
And if the password is stored in the script configuration, it kind of defeats the protection ... at least partially.

I'm sorry I do not really have time at the moment to go into testing this, but it surely looks promising. Great idea!

No, you don't need to enter your password everytime (only when creating the db and if you decide to export your database later). And the script doesn't save the password either, since that would obviously be pointless. In fact, it uses the Windows Data Protection API, so you end up with your key file that the helper automatically uses to access the database, plus its own salt, so it is the only one with that permission. Everything is linked to your Windows user credentials, so additional steps are needed to move the database to another machine. So, this is clearly a minus in terms of portability. And since the helper runs on demand, it adds a slight tiny delay after each startup, which is a bit annoying, especially when populating the columns. So yes, I guess it's not something that would survive to tests versions.

I don't think I need this either.

OK, I think it's ready for testing.

I've finished adding two things I've been wanting for a long time, and since this script has its own FIND command, they can be implemented now: Set and Array column types.

For DOpus, they're just like regular strings, but internally they're actual arrays (the difference being that Set doesn't support duplicate values). So when doing a simple search, you can use CONTAINS/NOT CONTAINS:

timestamp == thisweek AND myarray CONTAINS "some value"

And in ADVANCED FIND, you can do even more since SQL supports JSON parsing.

@MG250 I'll send you the script as soon as finish some basic usage explanation. But remember, this is for testing purposes.