I want to build a search engine for my collection of DVDs

I have a few of them.

It is getting more viable to search them than try to remember which ones I have.

Bog standard text file.

So I would like to search them.
They are NOT in ALPHABETICAL order.
Rather, ordered as they are on the shelf.
(good? bad? Dunno.)

There are indexes that tell me which shelf.
So then I would count the lines after the index and that would be the horizontal position.

Possible?

I would look at doing that with a database.. e.g mysql

Its doable with a text file but it will take longer in the long run

1 Like

Yeah.... I should get back into databases.

I'm talking with chatgpt just now on ideas.

A librarian in the 1870's developed a system to find books in a library his name was Dewey, Maybe you could do something similar.

1 Like

I have a semi working index/text file.

Mr Chat GPT has just helped me convert that into a JSON format and load it into NR as flow context.

Now we are working on how to search the list.

(Wish me luck.)

:wink:

Sorry - Off on a bit of a tangent. What I did was uploaded all my music CDs to a RPi-4B on one of my home servers, then purchased a licence for MyMedia (GBP ÂŁ7.50 plus taxes)

So now I can ask Alexa things like...

  • Alexa, ask My Media to play the album {Album}
  • Alexa, ask My Media to play {TrackName}
  • Alexa, ask My Media to play the track {TrackName}
  • Alexa, ask My Media to play the song {TrackName}
  • Alexa, ask My Media to play {TrackName} by {Artist}
  • Alexa, ask My Media to play the track {TrackName} by {Artist}
  • Alexa, ask My Media to play the song {TrackName} by {Artist}
  • Alexa, ask My Media to play {Music} by {Artist}
  • Alexa, ask My Media to play {Artist}
  • Alexa, ask My Media to play the artist {Artist}
  • Alexa, ask My Media to play my {Playlist} playlist
  • Alexa, ask My Media to play {Genre} {Music}

Great fun and so very, very easy.

1 Like

I'm not sure it is for that I want it, but more for curiosity how to search for things.

I know how I"m doing it is clunky, but sometimes you have to do things the wrong way to appreciate the better/right way.

Not sure just yet. :wink:

Really depends on how much spare time you have to devote to the task. Another alternative is to use Spotify (either a free or paid accout). My EV has Spotify built-in which means I can take my music with me.

This would be my recommendation as well. Index your collection by groups that represent something semantically, like genre, and then by column and row. Each shelf can be a group, to make your search easier. Then subdivide it again by row and column. Your db table columns would look like this

uuid | name | shelf | row | column

  • make shelf, row, column unique composed key

Then you can find a dvd position by

SELECT * FROM my_table_name as t WHERE t.name LIKE "%movie_name%" 

Thanks.

I'm not sure how big a hole I'm digging for myself here.
:wink:

I have about...... (a lot) of DVDs.
Grouping them and all that would be a lot of time.
I have a sort of working list with all (well, most) DVDs listed in the order they are on the shelves.

What I've got now does seem to work.
Though I haven't checked it for box sets with a lot of DVDs called the same thing.
But being a boxed set.......

It is (to me) mind blowing how good (well, to me) chatgpt is at bashing out code that is close to what I want and only a couple of Yeah, but.....'s it gets it working.

If you want to have fun, train an AI to locate your dvd given it pictures and a name. Then build an app and point it to your shelves after providing the name of the movie. Let the model highlight the dvd for you

Totally!

And while a database for this would be good. Unless you have MILLIONS, you might want to try without to begin with.

Other things that might be extensions beyond a simple start would be:

  • using a PHOTO or several of your CD shelves along with the text. Not too hard to be able to get a visual pointer or highlight for a searched CD.
  • Integrating with bar-code scanning.
  • Integrating with any mp3 versions of your CD's if you have them.

If you ended up with an ARRAY, you will need the filter function. No databases need to be harmed in the making of this. :smiley:

1 Like

One key feature of 'My Media' (and similar offerings) is it automatically catalogues the whole of my music library by artist, genre, title, etc. So I can say... "Play 'Bridge Over Troubled Water' " and it will play that track or "Play music by 'Fleetwood Mac' " and it will play all the tracks it can find.
When I purchase a new CD, I can have it uploaded to my server and get My Media to re-catalogue the whole library in 5 minutes or so.

Ok, thanks all.

This is where I'm at now.

function node:

let searchTerm = msg.searchtitle.trim().toLowerCase(); // Normalize the search term to lowercase

if (!searchTerm) {
    node.warn("Search term is empty.");
    msg.payload = "Please enter a search term.";
    return msg;
}

// Assuming the dvdIndex is set properly and contains an array of DVD objects
let dvdIndex = flow.get("dvdIndex");

if (!dvdIndex || !Array.isArray(dvdIndex) || dvdIndex.length === 0) {
    node.warn("No DVD data found in flow context.");
    msg.payload = "No DVDs available to search.";
    return msg;
}

let results = dvdIndex.filter((dvd) => {
    // Check if the search term is in the title (case insensitive)
    return dvd.title.toLowerCase().includes(searchTerm);
});

// If no results are found
if (results.length === 0) {
    msg.payload = "No search results found.";
    return msg;
}

let output = "";

// Loop through the matching results and format the output
results.forEach((result) => {
    // Ensure we have a valid result object and location data
    if (result.location) {
        output += `Found: "${result.title}" Location: ${result.location.location},\n section ${result.location.box}, Row: ${result.location.row}, Position: ${result.location.position}\n\n`;
    } else {
        // If no location found, indicate it in the output
        output += `Found: "${result.title}" but no location information available.\n\n`;
    }
});

msg.payload = output.trim();
return msg;

I'm wanting to split the output so it is over 2 lines.
This is what I get now:
Found: "Tomorrow - when the war began" Location: Above Bookcase, section 1, Row: front, Position: 26

I want something like:

Found: "Tomorrow - when the war began" Location: Above Bookcase,
 section 1, Row: front, Position: 26

Piccie to help.

Ah!

I needed <br> not \n.

Yes?

How would I make the output field TALLER for when it gets multiple matches?

Flow:

[{"id":"change-set-searchtitle","type":"change","z":"b8111f78dd481d81","name":"Set search title","rules":[{"t":"set","p":"searchtitle","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":4640,"y":290,"wires":[["function-search-and-format"]]},{"id":"38f453df81316559","type":"ui_text_input","z":"b8111f78dd481d81","name":"","label":"Input","tooltip":"","group":"42f742fbc1b5a034","order":1,"width":0,"height":0,"passthru":true,"mode":"text","delay":"00","topic":"topic","sendOnBlur":false,"className":"","topicType":"msg","x":4480,"y":290,"wires":[["change-set-searchtitle"]]},{"id":"183d4cc6e4f63f21","type":"inject","z":"b8111f78dd481d81","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"toy story","payloadType":"str","x":4490,"y":340,"wires":[["change-set-searchtitle"]]},{"id":"6684929d5c688330","type":"inject","z":"b8111f78dd481d81","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"tomorrow","payloadType":"str","x":4490,"y":380,"wires":[["change-set-searchtitle"]]},{"id":"58e262b80987dd9e","type":"inject","z":"b8111f78dd481d81","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"unfindable","payloadType":"str","x":4490,"y":420,"wires":[["change-set-searchtitle"]]},{"id":"function-search-and-format","type":"function","z":"b8111f78dd481d81","name":"Search and format results","func":"let searchTerm = msg.searchtitle.trim().toLowerCase(); // Normalize the search term to lowercase\n\nif (!searchTerm) {\n    node.warn(\"Search term is empty.\");\n    msg.payload = \"Please enter a search term.\";\n    return msg;\n}\n\n// Assuming the dvdIndex is set properly and contains an array of DVD objects\nlet dvdIndex = flow.get(\"dvdIndex\");\n\nif (!dvdIndex || !Array.isArray(dvdIndex) || dvdIndex.length === 0) {\n    node.warn(\"No DVD data found in flow context.\");\n    msg.payload = \"No DVDs available to search.\";\n    return msg;\n}\n\nlet results = dvdIndex.filter((dvd) => {\n    // Check if the search term is in the title (case insensitive)\n    return dvd.title.toLowerCase().includes(searchTerm);\n});\n\n// If no results are found\nif (results.length === 0) {\n    msg.payload = \"No search results found.\";\n    return msg;\n}\n\nlet output = \"\";\n\n// Loop through the matching results and format the output\nresults.forEach((result) => {\n    // Ensure we have a valid result object and location data\n    if (result.location) {\n        output += `Found: \"${result.title}\" Location: ${result.location.location},<br>section ${result.location.box}, Row: ${result.location.row}, Position: ${result.location.position}<br><br>`;\n    } else {\n        // If no location found, indicate it in the output\n        output += `Found: \"${result.title}\" but no location information available.<br><br>`;\n    }\n});\n\nmsg.payload = output.trim();\nreturn msg;\n","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":4860,"y":290,"wires":[["96bf171221f663ea"]]},{"id":"96bf171221f663ea","type":"ui_text","z":"b8111f78dd481d81","group":"42f742fbc1b5a034","order":2,"width":"0","height":"0","name":"","label":"result","format":"{{msg.payload}}","layout":"row-spread","className":"","x":5050,"y":290,"wires":[]},{"id":"42f742fbc1b5a034","type":"ui_group","name":"DVD search","tab":"9e1ed5e519ff655f","order":4,"disp":true,"width":"10","collapse":false,"className":""},{"id":"9e1ed5e519ff655f","type":"ui_tab","name":"TEST2","icon":"dashboard","order":39,"disabled":false,"hidden":false}]

(Forgive the inject nodes. They're for testing)

(it's 23:36 here... I'm tired. See you tomorrow!)
And again: Thanks for the replies.

Sorry Andrew - just re-read the title of your post and seen it says DVDs.
For some reason I thought it said CDs - must get my eyesight checked.
That means you can ignore all my comments about My Media (as that product is for CDs).

Well you could load json into context/memory, use alasql (converts into a in-memory database) and then you can perform sql queries (if sql has the preference), then again storing an array/json object into memory context and searching using javascript is extremely fast for a million large javascript objects.

(Don't fret it. I know the feeling.)

What I wrote (well... Chatgpt and I) seems to be working ok.

Just need to get the output area bigger.

I seem to have found the way to adjust the vertical size.

Not the best as it is now a FIXED height.

Would using DB-2 have better options for this problem?

No.

This is down to an understanding of HTML/CSS layouts. With DB2, you are already constrained to specific layouts - which work well in the majority of cases. Beyond that, you need to use bespoke styling.

I'm not sure how you are using DB2, I could only suggest how I would go about it when using plain HTML/CSS. And I would most likely be looking to use either a grid or flex layout. I'd have to see the HTML to know which and I haven't done that. But both would enable flexible heights. But again, you may hit constraints of DB1/2 overall layouts - I don't use them so I can't really comment on that.

1 Like