Showing posts with label batch processing. Show all posts
Showing posts with label batch processing. Show all posts

Automate moving measures between Power BI files .pbix, renaming and finding and replacing strings in DAX formula\expression

Yesterday I had to accomplish a task that got me thinking: this is going to take a hell of a lot of time to finish.

The user story is this: I have a Power BI .pbix file that is used somewhat as a staging\debugging file to try and test measures. Once the job is done I usually move things over to the final\main Power BI file which will be handed in to the client. Note that this final Power BI file already has report pages implemented. That's way I try things in a different file since the work can be done in a cleaner\faster model.
The problem this time was that I had to create\move lots of measures and so I'd have to do this measure by measure from the debugging file to the main file. It would take me about 1 hour to finish. Unfortunately Power BI has no built in copy\paste of measures between files as of today in its version 2.72.5556.801 64-bit (August 2019). At least we can copy and paste the visuals from one file to the other.

OK. Problem defined. Let's Google for a solution. The solution found was this awesome post titled Bulk measure handling (copy between reports/format changes). In this post the guy mentions the tool Tabular Editor. Well that was what I was looking for, really.

Just downloaded it directly from its GitHub repo here.

Followed the steps on that post and voilá: I could get more than 30 measures copied from one .pbix file to another. Great! This took me about 10 minutes to get done. 1\6 of the time previously estimated for that cumbersome\manual work. Check the following printscreen:

1st printscreen - measures moved from one Power BI file (on the left) to the other Power BI file (on the right)

2nd printscreen - batch renaming selected formulas in blue
There was another task that needed to be accomplished and it was a little bit different: needed to duplicate those copied measures. Tabular Editor makes it easy too. Just select all of them, right click and pick Duplicate # measures. Boom! You have all measures duplicated as seen in the printscreen on the right. Note that it adds a "copy" word to the measure name. So once the measures are duplicated we need to rename them and that's easy too. Select all duplicated measures, right click and pick Batch rename.

Just replaced the uppercase U in each formula name to a uppercase C as seen in the second printscreen above. Repeated the process and replaced " copy" with a blank string. That's it. Measures duplicated and renamed accordingly. Nonetheless there's still a missing step before theses measures are ready to go: change a table column name in the DAX formula\expression in each of these measures that got duplicated and renamed. How to get this done using Tabular Editor? Well, reading through its docs we can find this Advanced Scripting section. If you look at the first printscreen above you'll note that I wrote some C# code there that does exactly what is needed. See the code below:

Selected.Measures.ForEach(m => {
    var e = m.Expression;
   
    if(e.Contains("[Unit]"))
    {       
        e = e.Replace("[Unit]", "[Company]");
       
        // For debugging purposes
        //e.Output();
       
       
m.Expression = e;     
    }
});


What this piece of code is doing is that for each of the selected measures in blue on the left (see printscreens above), the measure DAX formula\expression is stored in a variable called e. I then check if this formula contains the word [Unit] that is the table column name that needs to be replaced. If the expression\formula contains this word it gets replaced with the word [Company] that refers to the other column name that is to be used in these duplicated formulas. After that the modified DAX formula is assigned back to the measure.

When finished with Tabular Editor, click Save. Return to Power BI and hit the Refresh button to reload the model.

This post is just a sample that showcases the power of Tabular Editor. You can manage and play with measures in any way imaginable.

I hope it helps someone that wants to accomplish trivial things in a more actionable way instead of having to copy\paste, rename and replace manually because that sucks.

Note: when trying to save back the modifications done in Tabular Editor an error was being displayed. Something along this line:

Failed to save modifications to the server. Error returned: 'Unexpected column name: Received column 'ObjectID.Expression' in rowset 'ObjectTranslations'. Expected column 'ObjectID.Set'.'.

I did the following to get rid of the nasty error message: opened Tabular Editor File menu and selected Preferences... checked "Allow unsupported Power BI features (experimental)". When we do this a new Translations folder appear in the Model tree. I just deleted the en-US that was under this folder (see printscreen below). Then tried saving again and it worked.

3rd printscreen - enabling Allow unsupported Power BI features (experimental) in Tabular Editor

Prevent JavaScript code blocking the UI thread with setTimeout + a handy stopWatch to profile JS code

In early January of this year I was implementing some JavaScript code that does a lot of processing on the client side with the help of jQuery. It’s part of a project where my customer asked for the possibility of answering a questionnaire in two ways: using a Wizard (one question at a time) and Listing (all questions at once) in a single form. The client side code for the Listing is the culprit and the subject of this post. It’s also related to this question I posted at StackOverflow on February 19:

Why ASP.NET MVC default Model Binder is slow? It's taking a long time to do its work

That question on SO is the inverse part, that is, the server receiving the client side data, but that’s just the other “part” of the problem which I also managed to solve. I really hope that this post helps you understand the problem with the client side part at least…

One of the things that I didn’t like in that JavaScript code was that while the questions were being processed to be rendered subsequently by the JavaScript/jQuery client side code, the browser UI thread hung/froze a lot of times – I think it’s worth mentioning here that I didn’t get Firefox’s warning prompt for "Unresponsive script". Anyway, the simple fact that the page freezes gives the user and me the developer a feeling that something is wrong with the code. As users we expect things to be fluid – we expect a good UI experience and seeing your browser freezing while loading a web page is not the best impression one may have of your software product.

I’m more experienced with server side code and haven’t ever seen any of my JavaScript code run slow on the client. I then started searching on Google why this was happening and just stumbled on this really helpful and insightful article at O’Reilly Answers:

Yielding with JavaScript Timers

Read it carefully to get a grasp of the concepts involved. I read it maybe thrice at least to understand the code and adapt it to the problem at hand. It fitted so well in my situation that the result I got after adapting the code was mind blowing.

The part that really got my attention was the Timed Code section - way bellow that O’Reilly article. It tells us that batch processing items (questions in my case) instead processing everything once or one at a time is more efficient to avoid blocking the UI.

JavaScript UI Queue and UI Thread lanes depicted: timed code is intercalated taking turnsFigure 1 - JavaScript UI Queue and UI Thread lanes depicted: timed code is intercalated taking turns

The JavaScript code I implemented processes a bunch of questions I receive from the server to prepare them to be shown to the user. Using a AJAX GET request’s success callback I dumped all the questions (usually 100 up to more than 200 sometimes and each one formatted with the help of a ASP.NET partial view) inside a div element $("#questions") like this:

// Loading Questions for the Chapter selected...
function loadQuestions(chapterId)
{
    $("#questions").fadeOut('slow').empty();

    $.ajax({
        type: "GET",
        url: "@Url.Action(MVC.UserAssessment.ActionNames.List, MVC.UserAssessment.Name)",
        data: { assessmentId: @Model.AssessmentId, chapterId : chapterId },
        cache: false,
        success: function(questions)
        {           
            $("#questions").html(questions);
            
            setUpQuestions();
        },
        error: function()
        {
            alert("@Html.Raw(Localization.UnknownErrorAjax)");
        }
    });
}

With this I had all the questions’ HTML beautifully inserted on the page but I needed to process this HTML before showing it to the user. That’s where the setUpQuestions(); method played its role. It does the heavy lifting and was where the whole thingy just got screwed up – the browser hung from time to time while inside that method… How did I discover that the problem was inside that method? I used Firebug’s Console and the JavaScript’s Date object as shown in that O’Reilly article. In setUpQuestions I use jQuery’s find, setup form fields validation with jQuery validation plugin, disable/enable fields, apply CSS styles to the questions, etc and all of this was tackled all at once by the poor browser JavaScript engine.

To profile setUpQuestions I created a stopWatch JavaScript method that receives setUpQuestions method as the func parameter:

function stopWatch(func)
{
    var start = +new Date(), stop;

    func();

    stop = +new Date();
if (stop - start < 50)
{
//alert("Just about right.");
console.log("Just about right.");
} else
{
//alert("Taking too long.");
console.log(“Taking too long.");
} }

According to that O’Reilly article, the author recommends never letting any Javascript code execute for longer than 50 milliseconds continuously, just to make sure the code never gets close to affecting the user experience – blocking the UI thread.

When I ran the code selecting different chapters with varying number of questions I kept getting “Taking too long” and then I found where the problem was. I knew it was time to adapt the code presented in the Timed Code section of that O’Reilly article. So here it is and commented where appropriate to make understanding it a little bit easier:

/// More about it here: http://answers.oreilly.com/topic/1506-yielding-with-javascript-timers/
function
timedProcessArray(items, process, callback) { var todo = $.makeArray(items); // The first call to setTimeout() creates a timer to process the first item in the array. setTimeout(function () { var start = +new Date(); do { // Calling todo.shift() returns the first item and also removes it from the array. process(todo.shift()); } // After processing the item, a check is made to determine whether there are more items to process and if the time hasn't exceeded the threshold of 50 milliseconds while (todo.length > 0 && (+new Date() - start < 50)); if (todo.length > 0) { // Because the next timer needs to run the same code as the original, arguments.callee is passed in as the first argument. setTimeout(arguments.callee, 25); }
else { //If there are no further items to process, then a callback() function is called. if (callback) { callback(items); } } }, 25); }

This code made the whole thing fluid and now the user has a much better experience while interacting with the page despite it having a lot of form controls. What it basically does is: process a batch of items/questions and then allows the UI thread to take some processing time and then it repeats until there’s no more questions left in the todo array. The process method is actually the setUpQuestions method that gets passed as a parameter called process.

In my specific case, each question has 4 HTML input elements (input/text, select, etc). If the user selects a Manual’s Chapter to answer and this Chapter contains 230 questions for example, the <form> element will contain about 920 controls = 4 x 230.That's a lot of controls to be processed by the JavaScript code inside the setUpQuestions method. Now no matter how many controls are present in the HTML code. timedProcessArray will handle this easily allowing the UI thread to breath from time to time.

This is the modified version of the loadQuestions method that makes use of this life saving timedProcessArray method where setTimeout shines:

// Loading Questions for the Chapter selected...
function loadQuestions(chapterId)
{
    $("#questions").empty();

    $.ajax({
        type: "GET",
        url: "@Url.Action(MVC.SAvE.UserAssessment.ActionNames.Answer, MVC.SAvE.UserAssessment.Name)",
        data: { assessmentId: '@Model.AssessmentId', chapterId : chapterId, format: '@Assessment.Format.List' },
        cache: false,
        success: function(data)
        {
            var questions = $(data);

            questions.hide().appendTo("#questions");

            //stopWatch(function(){ return timedProcessArray(questions, setupQuestion, stats)});

            timedProcessArray(questions, setupQuestion);

            //stats(questions);
}, error: function() { alert("@Html.Raw(Localization.UnknownErrorAjax)"); } }); }

I didn’t pass a callback function to timedProcessArray but that’s up to you.

Hope it helps you take the most out of your highly intensive processing JavaScript code.

As a last note, with the arrival of HTML5 we now have Web Workers but browser support is still limited. Things are getting better for us developers. Smile In the near future this will be standard for sure but till then we must find a way to solve the problem with the proven tools/code. setTimeout is one of them.

Mp3tag and its useful actions like Replace with regular expression and Guess values

Every once in a while I’m in a situation where I need to refresh my mind about how to work with regular expressions and guess values in Mp3tag to batch process lots of MP3 in a single shot… I’ll try to keep this post as a reference for the artifices I use with Mp3tag so that I can get back here and see what and how I did to format my MP3 tags the way they should be.

Mp3tag - The Universal Tag EditorMp3tag is IMHO the best MP3 tag editor out there. I’m so satisfied with it that I stopped trying to find a better tool. Nonetheless, I’m open to recommendations…

Mp3tag is a powerful and yet easy-to-use tool to edit metadata of common audio formats where it supports ID3v1, ID3v2.3, ID3v2.4, iTunes MP4, WMA, Vorbis Comments and APE Tags.

It can rename files based on the tag information, replace characters or words in tags and filenames, import/export tag information, create playlists and more.

I’ve been writing about MP3 in this blog. If you’re interested, you can check past posts here

As I commented above, to refresh my mind I tend to look for this post I wrote some time ago: More MP3 guessing pattern with Mp3tag in Mac OS but I decided to compile future endeavors in this area in a single post. I hope you enjoy.

This time I’m using Mp3tag in the Windows 8 side inside a Parallels Desktop virtual machine.

OK. After some formalities, let’s complete these five basic steps needed in every use case I’ll present in this post:

1 - Click the change directory button and navigate to the folder where you store the MP3s you want to edit.

Mp3tag Change Directory button

2 - Select the files you want to edit. I just press Ctrl + A to select all the files. You can also hold Ctrl to select file by file.

3 - Click the Actions (Quick) button.

Mp3tag Actions (Quick) button

4 - Follow the use cases…

Removing year between parenthesis from file name

Guessing values for Artist and Title from file name

5 - DO NOT FORGET to click the Save button after executing the actions of each use case so that the changes get applied to the files; otherwise you’ll lose the edits. Confused smile

Mp3tag Save button

Use cases

Removing year between parenthesis from file name

Mp3tag Filename with Year between parenthesis

After clicking the Actions button, select Replace with regular expression, select the _FILENAME field and enter the regular expression \( 2o12 \). Press OK and you’re done:

Mp3tag File name with Year between parenthesis regex

Guessing values for Artist and Title from File name

Mp3tag Guess Values for Artist and Title from File name

As you see the MP3 files don’t have Artist and Title information. This is bad. If you use services like Last.fm to keep track of the music you’ve been listening to, you won’t be able to scrobble given the missing metadata. Of course you can fill the info by hand (Oh Lord! How boring and time consuming this task is). There’s Mp3tag to the rescue.

Taking the previous use case as a necessary step to format the file name accordingly…

After clicking the Actions button, select Guess values, in Source format enter %_filename%, in Guessing pattern enter \%artist% - %title%. Press OK and you’re done:

Mp3tag Guess Values for Artist and Title from File name regex

References

MP3 Tag - The Universal Tag Editor Help pages

Software to automate website screenshot capture

I needed a software that allowed me to capture screenshots of a web application I developed. The software should do it automatically (batch capture). This way it’d save me a lot of time.

How do I used to do that?
I visited each web page I wanted to take a screenshot. It took me about 1 hour to finish the work.

I posted a question at Super User as always: Software to automate website screenshot capture and got an answer suggesting that I use a combination of a URL fetcher + Selenium capability to take screenshots.

Well, I tried Selenium (.NET bindings selenium-dotnet-2.0rc3.zip ) to test its screenshot capture feature but it doesn’t seem to fit the job because it doesn’t allow you to configure screenshot properties as size (height x width). Moreover it doesn’t work well with Ajax (requires you to write a lot of code to check for the existence of Ajax calls, etc). This kills a screenshot that needs everything in place (I mean every DOM object should be part of the screenshot). I tried the 3 drivers available: Internet Explorer, Firefox and Chrome. Screenshots taken with Internet Explorer driver were close to what I expected.

This is a sample code I used based on the code taken from here:

using System;
using System.Drawing.Imaging;
using System.Text;
using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.IE;
using OpenQA.Selenium.Support.UI;

namespace SeleniumTest
{
    [TestFixture]
    public class SeleniumExample
    {
        private FirefoxDriver firefoxDriver;
    
        #region Setup

        [SetUp]
        public void Setup()
        {
            firefoxDriver = new FirefoxDriver();
        }

        #endregion

        #region Tests

        [Test]
        public void DisplayReport()
        {
            // Navigate
            firefoxDriver.Navigate().GoToUrl("http://localhost/FitnessCenter/Report/TotalPaymentsByPeriod");

            IWebElement startDate = firefoxDriver.FindElement(By.Name("StartDate"));
            
            startDate.Clear();
            startDate.SendKeys("January 2011");

            IWebElement generate = firefoxDriver.FindElement(By.Id("Generate"));
            generate.Click();

            var wait = new WebDriverWait(firefoxDriver, TimeSpan.FromSeconds(5));
            wait.Until(driver => driver.FindElement(By.Id("Map")));

            SaveScreenShot(firefoxDriver.Title);
        }

        /// <summary>
        /// Saves a screenshot of the current error page
        /// </summary>
        public void SaveScreenShot(string fileName)
        {
            // Get the screenshot
            Screenshot screenshot = firefoxDriver.GetScreenshot();

            // Build up our filename
            StringBuilder filename = new StringBuilder(fileName);
            filename.Append("-");
            filename.Append(DateTime.Now.ToString("yyyy-MM-dd HH_mm_ss"));
            filename.Append(".png");

            // Save the image
            screenshot.SaveAsFile(filename.ToString(), ImageFormat.Png);
        }

        #endregion

        #region TearDown

        [TearDown]
        public void FixtureTearDown()
        {
            if (firefoxDriver != null) firefoxDriver.Close();
        }

        #endregion
    }
}

Indeed, Selenium is powerful for what it does, that is, helping you automate browser interactions while you test your code. It even allows you to take a screenshot let’s say when something goes wrong (a test fail for example). That’s great and that’s what it does best. It’s a choice for every operating system since it’s an API that can be programmed against.

Paparazzi! beautiful application iconWhat I needed was something more specialized to take screenshots. A software that allows me to configure screenshot properties. The good news is that I managed to find such piece of software and it’s called Paparazzi! - a very suggestive name by the way. One drawback is that it’s only available for Mac OS. As one would expect, it uses Safari browser engine behind the curtains to capture the screenshots. Paparazzi! has minor bugs but it gets the job done. It doesn’t have documentation. I had a hard time trying to make it work. It has batch capture capability but no docs explaining how to do it. So I hope this post will shed some light…

The following lines describe what I did to achieve my objective with Paparazzi!:

1 - Created a list of URLs I’d like to take screenshots of. Like this (one URL per line):

http://192.168.1.106/FitnessCenter/Account/ChangeCulture?lang=en&returnUrl=%2FFitnessCenter%2F
http://192.168.1.106/FitnessCenter/Student
http://192.168.1.106/FitnessCenter/Student/Create
http://192.168.1.106/FitnessCenter/Student/Edit/79
http://192.168.1.106/FitnessCenter/Student/Details/79
http://192.168.1.106/FitnessCenter/Student/Delete/79
http://192.168.1.106/FitnessCenter/Anamnesis
http://192.168.1.106/FitnessCenter/Anamnesis/Create
http://192.168.1.106/FitnessCenter/Anamnesis/Edit/79
http://192.168.1.106/FitnessCenter/Anamnesis/Details/79

.
.
.

2 - Open Paparazzi! and click the Window menu => Batch capture (really difficult to find this option Disappointed smile ):

Paparazzi! difficult to find Batch Capture menu optionPicture 1 - Paparazzi! difficult to find Batch Capture menu option

3 - Drag and drop a text file .txt (the file that contains the URLs) to the Batch Capture window:

Paparazzi! Batch Capture window surfacePicture 2 - Paparazzi! Batch Capture window surface

Here is where I think I found a limitation and it’s by design. This should definitely not happen IMHO. If you try to add a file clicking on ( + button), Paparazzi won’t let you select a text file. The only way I got it working was selecting the .txt file and then drag and dropping the file to the Batch Capture window.

4 - Configure screenshot properties by clicking the list button (see mouse cursor above it):

Paparazzi! screenshot process basic configurationsPicture 3 - Paparazzi! screenshot process basic configurations

You can define the screenshot size. There are pre-defined values for standard screen resolutions. It allows you to define new presets.

You can also delay the capture to wait the page finish loading, etc.

There are a set of configurations available related to the batch capture functionality. To access these configurations, go to Paparazzi! menu and select Preferences:

Paparazzi! Preferences… menu optionPicture 4 - Paparazzi! Preferences… menu option

The first configuration worth mentioning the Default Filename Format available in the General section:

Paparazzi! General preferences sectionPicture 5 - Paparazzi! General preferences section

Above I’m defining this format:

%t = page title
%Y = year
%m = month
%d = day
%H = hour
%M = minute
%S = second

The example in the picture is pretty clear… Smile

Another set of configurations is available in the Batch capture section:

Paparazzi! Batch Capture preferences sectionPicture 6 - Paparazzi! Batch Capture preferences section

Here you can choose where to save the screenshots as well as the type of the images.

After configuring the batch capture session, it’s the gran finale time...

5 - Click the Play button, go take a coffee and relax while the computer does the job for you Fingers crossed.

Paparazzi! Batch Capture in actionPicture 7 - Paparazzi! Batch Capture in action

Hope you have found this post interesting and that it’s useful to help in documenting a little bit of this small but really powerful application.

Pointing up Now I get all the screenshots in less than 1 minute!

References
Paparazzi!
http://derailer.org/paparazzi/

More MP3 guessing pattern with Mp3tag in Mac OS

I mentioned in my last MP3 series post that I had the material to write a new post regarding this topic and so today I’m fulfilling the promise I made. I’m going to show how you can use the powerful Swiss Army knife called Mp3tag (Windows “only” app) right within your Mac. Yes, you read it right. You can run Mp3tag using your Mac. Nowadays almost everything is possible… Open-mouthed smile

The great thing here is that there’s a way to use our beloved Mp3tag in Mac OS. I even asked a question at SuperUser where I was trying to find some similar software that I could use in Mac. Here’s the question: Alternative to mp3tag for Mac OS X. Well, after searching a little bit more I found a great site called PlayOnMac. What is PlayOnMac?

PlayOnMac is like wineskin, winebottler or crossover a piece of software which allows you to easily install and use in your Mac numerous games and software designed to run only with Microsoft®'s Windows®.

I then found Mp3tag bundle here. You get a .dmg file which contains Mp3 Tag.app (172.5 MB) on disk. Just mount the .dmg file with a double click and extract the .app file to your Applications folder in Mac OS dock. Doing this you have the power of Mp3tag right inside your Mac. No Windows virtual machine needed/no need to load your bootcamp Windows. It’s good because you’ll have more memory left for your Mac (in the case of a virtual machine) or you won’t spend your time changing the operating system (in the bootcamp case).

Ok, the bundle is a little bit lazy to load and the visual (retro) is Windows like but who mind?

There’s nothing better than a use case to showcase something. Today I need to organize some MP3 tags because their Track - Artist - Title fields are all a complete mess. Some data are already there and some are missing completely. I of course will use Mp3tag guessing pattern feature to solve this.

To get to the Guess values dialog window, click the Actions (Quick) icon in the toolbar and select Guess values in the dropdown menu. Screenshots can be seen here.

Here are the MP3 files before the process:

Mp3tag Guess Values for Track Artist and Title in FileName [ before ]Figure 1 - Mp3tag Guess Values Window for Track Artist and Title in File Name [ before ]

As you see most of the tracks have 1 in the Track field and Title and Artist fields are missing in most of cases. All the information that is missing is present in the Filename field. Really interesting fact.

Let’s take advantage of Filename info and fill the missing tags with that data. How? Using Mp3tag Guess values window.

Source format: %_filename%

Guessing pattern: %track% - %artist% - %title%

Really easy, isn’t it?

What the hell these % symbols are doing here? They are simple placeholders that tell Mp3tag about a specific pattern found in fields of MP3 files. In this specific case, Mp3tag will extract data from the Filename field ( source ). Looking at Figure 1 we see that all file names follow a pattern: Track # - Artist - Title. Such pattern is then passed to Mp3tag in the Guessing pattern field. With this input Mp3tag is able to infer/parse the file names and split them accordingly. Each part will then be used to fill the correct MP3 tags.

Here’s the post-processed MP3 files:

Mp3tag Guess Values Window for Track Artist and Title in File Name [ after ] Figure 2 - Mp3tag Guess Values Window for Track Artist and Title in File Name [ after ]

That’s a much better view and experience within your preferred Media Library software!

Things like this makes me really happy with computers…

Hope you find it as useful as it’s being to me in this hard task of keeping a MP3 collection organized. I at least try my best.

To see more ways of using the Guessing Pattern, check the MP3 series of posts.

Batch renaming and copying MP3 values from tag to tag

This is just one more post in the MP3 series where I write about how you can organize your MP3 library/collection performing batch renaming to correct MP3 metadata and save time.

Just after I posted about Using Regular Expressions to correct mistagged MP3 I had other task to accomplish with Mp3tag but I didn’t know how to do that. What I want now is somewhat like what I showed in that previous post. The difference is that now I want to use the content of a given tag to fill another tag, thus copying/cutting that content from tag to tag.

As always I have a feeling that there must be a way of doing what I want and as always I go after it.

Here’s the problem this time:

Title tag has both the Title and Artist names and Artist tag has a wrong valuePicture 1 - Title tag has both the Title and Artist names and Artist tag has a wrong value

As you see in Picture 1, I have some MP3 files that have the Artist name included in the Title tag. The Artist name is between brackets while the Artist tag has the text Various. Obviously this is wrong because the Artist name should be in its proper Artist tag.

How can we correct this without manual intervention that would be a time consuming task?
The simple answer is using Mp3tag and its powerful set of features like the one called Guess values.

Guess values is so amazing that its window dialog just takes 2 parameters to get the job done. They are: Source format and Guessing pattern.

The Source format field in this case has the value %title% and the Guessing pattern field has the value %title% (%artist%). You can use any mp3 tag field between percent signs (%). What do these values mean?

Source format retrieves the value present in the Title tag of each MP3 and by guessing the values through the Guessing pattern it’s possible to split the Title tag according to the pattern. This opens up a world of possibilities where you can use any kind of combinations (masks/patterns) to split the value of a given tag and have those split values fill any MP3 tag of your choice.

So, in this case we have something as this happening behind the curtains:

Title: Begins With Me (Point of Grace)

Source format = %title%
Guessing pattern = %title% (%artist%)

Making the substitution, we have:

Guessing pattern = %Begins With Me% (%Point of Grace%)

With this, Mp3tag now knows what values it must use to fill the MP3 tags we want correctly.

Here’s the final result after you press the OK button present in Picture 1:

Correctly tagged MP3 files
Picture 2 - Correctly tagged MP3 files

Hope you got the idea and make good use of this.

I already have the material to write the next post in this series. Keep an eye in this blog. :)

Using Regular Expressions to correct mistagged MP3

Two months have passed since I last posted something here. These were 2 busy months in my life. Hooray, I bought a brand new car and got my driver license, not necessarily in this order.

This post is about something I had planned to write sometime ago… the two screenshots shown here I got maybe 3 months ago. :D So let’s get to it.

As a big and eclectic fan of music that I’m, every now and then I see mistagged MP3 files like the ones with title tags that contain both the artist name and the song name. The following picture shows what I mean:

Mistagged MP3 files (Title field has both the Artist and Song names) Picture 1 - Mistagged MP3 files (Title field has both the Artist and Song names)

Here’s where Mp3tag comes to the rescue. As you see in Picture 1, I’m using the dialog “Replace with regular expression”. Read my previous post about this great piece of software called Mp3tag to see how to get to this dialog. It has 3 fields that you must fill to make some magic happen allowing you to correct those wrongly tagged/mistagged MP3 titles all at once. Ha! You won’t lose your precious time correcting MP3 by MP3. I know that this is boring and that’s why I desperately searched for a solution. I know that if you’re reading this, you’re probably in the same situation and you just found a solution. :)

I’ve chosen the Field TITLE since it’s the problematic field in this particular case. Now the most important part, the so called Regex or Regular expression: (.*) - (.*). This thing means that we’re gonna separate the MP3 Title field in two parts. One part will have everything (.*) before the hyphen - and the other part will contain everything after the hyphen (.*).

Example:

Dru Hill - Away (Prod. by B.Cox) (Full + NoShout) (2010)

The regex (.*) - (.*) will separate the MP3 title above in two parts…

$1 = Dru Hill
$2 = Away (Prod. by B.Cox) (Full + NoShout) (2010)

The Replace matches with field has the value $2 because in this case I want to replace/substitute the MP3 Title with only the Song/Track name (the 2nd part/match of the regex above). If instead I wanted to keep the Artist name in the Title tag (D'oh!, not something I’d want to do), I’d write $1 in this field.

Now, take a look at Picture 2. When you click OK, this is the end result/magic you get. Nice and correctly titled/tagged MP3 files. The way I wanted them to be.

Correctly tagged MP3 filesPicture 2 - Correctly tagged MP3 files

To make things last forever, do not forget to click the Save button present in Mp3tag’s toolbar or in the Save tag option present in the File menu. I like to press Ctrl+S as a shortcut.

If you want to learn the basics about regular expressions to use with Mp3tag, check this out: http://help.mp3tag.de/options_format.html#regexp

As you see, using regexes (one of the most powerful features of computers) you can make any kind of change to your MP3 tags like for example removing that (2010) present in each MP3 Title field above. That 2010 should be in its proper MP3 tag, namely the Year tag. Don’t ya think?

Hope this simple process helps someone out there keep an organized MP3 library as I do like to keep mine.

Note
Mp3tag is a Windows only application as is Windows Live Writer that I use to write these blog posts. I use/run it through Parallels Desktop on my Mac mini. Read this post to get more info about how to run Windows side by side with your Mac OS.

Software to add Lyrics to MP3 files ID3 metadata

Take a look at the MP3 series. Probably you’ll find something interesting.

If you're like me, you also like to take a look at the lyrics of music that is currently playing in your computer or mobile device as the iPhone. I do it to learn a bit more of English since its not my main language and of course because I also want to sing along correctly. :)

The iPhone for example allows you to read the lyrics of the current song if the lyrics are present in the MP3 ID3 metadata container. This is pretty cool. If you already have lyrics embedded in your MP3 files you can see them while in a bus trip, waiting for a service, etc.

Every MP3 has a specific field (also know as frame) in its metadata to store lyrics information. It’s just a matter of filling this field with the correct lyrics. This is a hard work to do manually because you have to search for the lyrics and then copy/paste it in the right field. This sounds like a great thing to be done by software instead. Again, that’s what computers are for… save us time.

In iTunes (the media player/library software I use) for example, one would right-click a music file and then select the Get Info context menu option. Then you’d select the Lyrics tab and paste the lyrics in the white huge field making sure to click OK as seen in Figure 1 below:

Adding lyrics to an iTunes music file through the Lyrics tab
Figure 1 - Adding lyrics to an iTunes music file through the Lyrics tab

Some time ago I asked a question at SuperUser site: Software to add Lyrics to MP3 files ID3 metadata. It seems that there are a lot of people (3,356 to be precise as the time of this post) out there looking to accomplish what this post tries to clarify.

When I asked the question I was using Windows and I got good answers.

I also discovered other software by myself as MiniLyrics for Windows at that time. If you’re interested in MiniLyrics, here goes a small tutorial to save the lyrics to MP3 metadata!

MiniLyrics
Right click MiniLyrics icon in the system tray, choose Preferences and then select the Lyrics icon. Under the Save downloaded lyrics in: - select Save lyrics in mp3 file.

Other great feature MiniLyrics has is that while the music is playing the lyrics can be shown on your screen according to what is being sung, that is, the lyrics flows in your screen according to the music timing. Fantastic job from crintsoft people... :)

Besides saving the lyrics to MP3 metadata, there are lots of features and possibilities when it comes to lyrics in MiniLyrics software.

From the official site:

    MiniLyrics Display lyrics for your favorite music!

        * Lyrics plugin software for iTunes, Windows Media Player, MediaMonkey, Winamp, etc. You do not need to change the way you enjoy music.
        * Display scrolling lyrics, you can follow along with the artist and catch every word.
        * Automatically search and download lyrics.
        * Huge lyrics database, and it is expanding everyday.
        * Free Trial version that never expires.

Lyricator
Lyricator as suggested by merv is a fantastic/great/cool piece of software to go with MediaMonkey but it is having some problems currently as you can find in this thread.

I had to resort to other service while Lyricator is being repaired. I found other free software that does the job, but only on a Mac computer (that’s OK because I’ve switched to the Mac world). It's name is Get Lyrical.

Get Lyrical

Get Lyrical doing its job in the background
Figure 2 - Get Lyrical doing its job in the background

    Get Lyrical auto-magically add lyrics to songs in iTunes!

You can choose either a selection of tracks, or the current track. Or turn on "Active Tagging" to get lyrics for songs as you play them.

    You can also browse and edit the lyrics of your iTunes tracks right from Get Lyrical.

I highlighted in yellow above a powerful feature of Get Lyrical. You can even add lyrics to a selection of tracks at once. This is a batch processing feature really welcome when you want to add lyrics to an artist’s complete discography for example.

I’ve been using Get Lyrical for some time now and it is really competent in the job. I highly recommend it.

Add Songs to iTunes Playlist with Automator

Last time I showed you how to Automate tasks in Mac OS with Automator. I used Automator to create a simple workflow that helps moving MP3 files to iTunes folder. Check that here.

Now I have another task to Automator.

This is the description of what I want to accomplish or the problem description if you prefer:

I often download some free legal MP3 files from the internet for evaluation, more specifically from Indie Rock Cafe (great great site by the way :D - check it out if you like Indie Rock music). I use IndieRockCafe mainly to discover bands that I’ve never heard about. It’s being a great experience so far. I’ve come to know some really good bands that, else I would never hear a song of theirs.

To download those MP3s I use DownThemAll that is a really nice piece of software that works beautifully with Firefox. I wrote about DownThemAll in Automate the download of a list of URLs/links. Although I didn’t write how to download only MP3 files with DownThemAll, this post gives you an idea about the purpose of DownThemAll. I’ll write about how to download only specific kind of files (MP3 in this case) using DownThemAll, but that’s another post. Probably I’ll detail this download process I’m mentioning here.

As I was telling you, I often do the same task, that is, I go to IndieRockCafe, click on DownThemAll icon in my Firefox toolbar and tada, the download of IndieRockCafe’s recently added MP3s just start. DownThemAll will download only page links that point to MP3 files saving these MP3 in a single folder called IndieRockCafe.

After the download I used to select all the files within that folder and drag and drop them inside an iTunes playlist called IndieRockCafe. iTunes is wise enough to tell me that some files are already part of the playlist and gives me the option to skip them adding only new files into that playlist. Doing so I always have a fresh playlist with the latest files of IndieRockCafe. It works, but it has a lot of manual steps.

Yesterday I thought: the above steps are a perfect fit to be automated with Automator.

Let’s create a workflow:

1 - Go to the Applications folder and select Automator.

2 - You’ll be presented with the following screen to choose a template for your workflow. Select Folder Action as the template.

Types of templates available to create an Automator workflow (Folder Action)Figure 1 - Types of templates available to create an Automator workflow (Folder Action)

3 - In Folder Action receives folders and files added to, select the folder you want. In my case it is the IndieRockCafe folder.

4 - Now select Music in Library list and then select Import Files into iTunes under the Actions list. Drag this action to the workflow area in the right.

5 - Select Existing playlist and the playlist you want the files to go to. As I wrote above I already have a Playlist called IndieRockCafe inside iTunes. So I selected it.

6 - Go to the File menu and select Save. Give the workflow an appropriate name, e.g. IndieRockCafe.

The following screenshot shows the Folder Action workflow configured:

IndieRockCafe.workflow configured according to the six steps described above
Figure 2 - IndieRockCafe.workflow configured according to the six steps described above

7 - Now that the workflow is created, there’s a last step required to orchestrate things: go to the IndieRockCafe folder and right-click it. Select Services > Folder Actions Setup… Make sure you attach the IndieRockCafe workflow to this folder as shown in Figure 3:

Attaching IndieRockCafe.workflow in Folder Actions Setup
Figure 3 - Attaching IndieRockCafe.workflow in Folder Actions Setup

Make sure you click the Enable Folder Actions checkbox too:

Enabling Folder Actions and turning IndieRockCafe.workflow ON for the IndieRockCafe folder
Figure 4 - Enabling Folder Actions and turning IndieRockCafe.workflow ON for the IndieRockCafe folder

… and we’re done! As you see this is totally life saver.

Every new MP3 that gets added in my IndieRockCafe folder through DownThemAll or that I manually place in this folder will be automatically added in IndieRockCafe playlist.

Task successfully automated!

I’m a music lover and I hope you can take advantage of it too.

Important
DownThemAll creates file segments ( *.dtapart files ) while downloading. DownThemAll splits the file into several parts and then downloads each segment of the file individually, which gives you better speed from servers, especially those that choose to limit your download speed. This behavior will cause the workflow created above to fail because iTunes won’t recognize those parted files when trying to import them. To solve this problem, do the following:

In Firefox Tools menu choose More dTa Tools and then select Preferences.

In tab Advanced and under Temporary files choose a directory to store those dtapart files. See screenshot below to have an idea:

Using a temporary folder to store DownThemAll file parts or segmentsFigure 5 - Using a temporary folder to store DownThemAll file parts or segments

Doing the above, DownThemAll will store those partial files in a separate folder. When it finishes downloading a file it will join its parts and then will move that file to the IndieRockCafe folder I specified in the workflow. Now iTunes will import the MP3.

Note
Folder action workflows are saved in
/Users/YourUserName/Library/Workflows/Applications/Folder Actions

Download
You can download this workflow at:
https://sites.google.com/site/leniel/blog/IndieRockCafe.workflow.zip

Automate tasks in Mac OS with Automator

This one is about an incredible application that comes with Mac OS X. Its name is Automator.

Jesus Christ, this is a life saver app!

This is the description of Automator:Automator Apple Mac OS application icon

With Automator, you can accomplish time-consuming, repetitive manual tasks quickly, efficiently, and effortlessly. Automator lets you skip the complex programming and scripting that is normally required to create automations. Instead, you assemble individual steps into a complete task by dragging these actions into an Automator workflow. Automator comes with a library of hundreds of actions. And with the Watch Me Do action, you can record an action — such as pressing a button or controlling an application without built-in Automator support — and replay it as an action in a workflow.

I have lots of MP3 files that I need to go through analyzing if I really want to keep them in my media library. During the last year I stored all those MP3 in a folder and such a folder is now 55.56 GB and contains 11840 files to be precise. That’s a lot of MP3! I keep postponing this open/listen to task but today I thought I’d start. That’s where Automator fits the job.

In this post I’ll show you how to create a simple workflow that helps moving the MP3 files to iTunes folder /Users/leniel/Music/iTunes/iTunes Media/Automatically Add to iTunes. The folder Automatically Add to iTunes is a special folder that iTunes keeps watching for new files added to it. When a file is added in this folder, iTunes automatically adds it to the media library using MP3 metadata to organize the library. When added files will reside in /Users/leniel/Music/iTunes/iTunes Media/Music.

Let’s create the workflow:

1 - Go to the Applications folder and select Automator.

2 - You’ll be presented with the following screen to choose a template for your workflow. Select Service as the template.

Types of templates available to create an Automator workflow
Figure 1 - Types of templates available to create an Automator workflow

3 - In Service receives selected, select audio files. “In” select Finder.

4 - Now select Files & Folders in Library list and then select Move Finder Items under the Actions list. Drag this action to the workflow area in the right.

5 - In Move Finder Items select the folder where you want the files to be moved to. You also have the option of showing the action when the workflow runs.

6 - Go to the File menu and select Save. Give it an appropriate name as Add to iTunes and you’re done.

The following screenshot shows the Service workflow configured:

Add to iTunes.workflow configured according to the six steps described above 
Figure 2 - Add to iTunes.workflow configured according to the six steps described above

Now, let’s use this service workflow. To do this, go to Finder and open any folder that contains audio files such as MP3. Right click the MP3 file and voila. Now there’s an extra context menu option called Add to iTunes. What a marvelous thing.

Add to iTunes context menu option in Finder when right clicking MP3 file(s)
Figure 3 - Add to iTunes context menu option in Finder when right clicking MP3 file(s)

What happens when Add to iTunes is clicked? The workflow we created will be executed and the selected file(s) will be moved to the folder specified in the workflow, in this case /Users/leniel/Music/iTunes/iTunes Media/Automatically Add to iTunes.

As you see this is totally life saver.

I can play the MP3 in iTunes and if I decide that I want to keep it in my media library I just have to select Add to iTunes.

The possibilities with Automator are endless given the amount of options in its Library and Actions lists and workflow template types.

I hope you could get an idea of what Automator can do.

Updated on 12/16/2010

If you make a slight change in step 3 above you can have this workflow add not only audio files but even entire folders to iTunes and better yet, iTunes will ask if you want to replace existing files so that you don’t end up with duplicate files in your iTunes library. This is great.

So what do you have to do? Instead of audio files, select files or folders. Just this. Save the workflow. Now right click over any folder in Finder and you’ll see that you get a new menu option under Services called Add to iTunes.

Add to iTunes context menu option in Finder when right clicking a folderFigure 4 - Add to iTunes context menu option in Finder when right clicking a folder

Notes
Service workflows are saved in /Users/YourUserName/Library/Services.

In prior versions of Mac OS, there was an option to save the workflow as a plug-in. This was necessary so that you could have a context menu option (right-click) in Finder to run the workflow. I tried to go this way but this option isn’t available in Mac OS X 10.6.4. I realized that I had to create a Service workflow when I read this question at Apple’s Support site: No Automator plug-in in 10.6?

Download
You can download this workflow at:
https://sites.google.com/site/leniel/blog/AddtoiTunes.workflow.zip

References
Automator - Your Personal Automation Assistant

Automator - Learn by example

Automator at Apple’s Mac OS – All Applications and Utilities

Automator article at Wikipedia