diff --git a/QDXMVNC.sln b/QDXMVNC.sln
new file mode 100644
index 0000000..993dbb5
--- /dev/null
+++ b/QDXMVNC.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QDXMVNC", "QDXMVNC\QDXMVNC.csproj", "{3C478B87-7880-4B6D-8951-3F445B55948B}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x86 = Debug|x86
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {3C478B87-7880-4B6D-8951-3F445B55948B}.Debug|x86.ActiveCfg = Debug|x86
+ {3C478B87-7880-4B6D-8951-3F445B55948B}.Debug|x86.Build.0 = Debug|x86
+ {3C478B87-7880-4B6D-8951-3F445B55948B}.Release|x86.ActiveCfg = Release|x86
+ {3C478B87-7880-4B6D-8951-3F445B55948B}.Release|x86.Build.0 = Release|x86
+ EndGlobalSection
+ GlobalSection(MonoDevelopProperties) = preSolution
+ StartupItem = QDXMVNC\QDXMVNC.csproj
+ EndGlobalSection
+EndGlobal
diff --git a/QDXMVNC.userprefs b/QDXMVNC.userprefs
new file mode 100644
index 0000000..eb3d095
--- /dev/null
+++ b/QDXMVNC.userprefs
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/QDXMVNC/Program.cs b/QDXMVNC/Program.cs
new file mode 100644
index 0000000..771d357
--- /dev/null
+++ b/QDXMVNC/Program.cs
@@ -0,0 +1,135 @@
+using System;
+using System.IO;
+using System.Collections.Generic;
+using System.Text;
+
+namespace QDXMVNC
+{
+ class MainClass
+ {
+ public static void Main(string[] args)
+ {
+ Console.WriteLine("QDXMVNC - Quick & Dirty XBMC Music Video NFO Creator");
+ Console.WriteLine("© 2014 Natalia Portillo");
+ Console.WriteLine();
+
+ if (args.Length != 1)
+ {
+ Console.WriteLine("This little tool recursively scans a folder searching for music video files and creates a XBMC .nfo containing info extracted from path and filename");
+ Console.WriteLine("Expected structure is \"// .\"");
+ Console.WriteLine("Supported extensions are: mp4, m4v, avi, mkv, mpg, ts, ps, vob, ogm, divx, asf");
+
+ return;
+ }
+
+ if (!Directory.Exists(args[0]))
+ {
+ Console.WriteLine("Given argument is not a directory or does not exist");
+ return;
+ }
+
+ List artist_paths = new List(Directory.EnumerateDirectories(args[0]));
+
+ StringBuilder nfo_sb = new StringBuilder();
+ int skipped = 0;
+ int written = 0;
+ int videos = 0;
+ int albums = 0;
+
+ foreach (string artist_path in artist_paths)
+ {
+ string artist = Path.GetFileName(artist_path);
+
+ List album_paths = new List(Directory.EnumerateDirectories(artist_path));
+
+ foreach (string album_path in album_paths)
+ {
+ string album = Path.GetFileName(album_path);
+
+ List video_files = new List(Directory.EnumerateFiles(album_path));
+
+ foreach (string video_file in video_files)
+ {
+ string video_without_extension = Path.GetFileNameWithoutExtension(video_file);
+ string video_extension = Path.GetExtension(video_file);
+
+ string[] video_pieces = video_without_extension.Split(new char [] {' '}, 2);
+
+ if (video_extension.ToLower() == ".mp4" || video_extension.ToLower() == ".m4v" || video_extension.ToLower() == ".avi" ||
+ video_extension.ToLower() == ".mkv" || video_extension.ToLower() == ".mpg" || video_extension.ToLower() == ".ts" ||
+ video_extension.ToLower() == ".ps" || video_extension.ToLower() == ".vob" || video_extension.ToLower() == ".ogm" ||
+ video_extension.ToLower() == ".divx" || video_extension.ToLower() == ".asf")
+ {
+ string nfo_path_filename = album_path + Path.DirectorySeparatorChar + video_without_extension + ".nfo";
+
+ if(File.Exists(nfo_path_filename))
+ {
+ Console.WriteLine("{0} exists, skipping.", nfo_path_filename);
+ skipped++;
+ }
+ else
+ {
+ nfo_sb.AppendLine("");
+ nfo_sb.AppendFormat("\t{0}", System.Security.SecurityElement.Escape(album)).AppendLine();
+ nfo_sb.AppendFormat("\t{0}", System.Security.SecurityElement.Escape(artist)).AppendLine();
+ nfo_sb.AppendFormat("\t{0}", System.Security.SecurityElement.Escape(video_pieces[1])).AppendLine();
+ nfo_sb.AppendFormat("\t", System.Security.SecurityElement.Escape(video_pieces[0])).AppendLine();
+ nfo_sb.AppendLine("");
+
+ Console.WriteLine("Writing {0}", nfo_path_filename);
+ File.WriteAllText(nfo_path_filename, nfo_sb.ToString(), Encoding.UTF8);
+ written++;
+ }
+
+ videos++;
+ }
+ }
+ }
+
+ List non_album_files = new List(Directory.EnumerateFiles(artist_path));
+
+ foreach (string video_file in non_album_files)
+ {
+ string video_without_extension = Path.GetFileNameWithoutExtension(video_file);
+ string video_extension = Path.GetExtension(video_file);
+
+ string[] video_pieces = video_without_extension.Split(new char [] {' '}, 2);
+
+ if (video_extension.ToLower() == ".mp4" || video_extension.ToLower() == ".m4v" || video_extension.ToLower() == ".avi" ||
+ video_extension.ToLower() == ".mkv" || video_extension.ToLower() == ".mpg" || video_extension.ToLower() == ".ts" ||
+ video_extension.ToLower() == ".ps" || video_extension.ToLower() == ".vob" || video_extension.ToLower() == ".ogm" ||
+ video_extension.ToLower() == ".divx" || video_extension.ToLower() == ".asf")
+ {
+ string nfo_path_filename = artist_path + Path.DirectorySeparatorChar + video_without_extension + ".nfo";
+
+ if(File.Exists(nfo_path_filename))
+ {
+ Console.WriteLine("{0} exists, skipping.", nfo_path_filename);
+ skipped++;
+ }
+ else
+ {
+ nfo_sb.AppendLine("");
+ nfo_sb.AppendFormat("\t{0}", System.Security.SecurityElement.Escape("[non-album tracks]")).AppendLine();
+ nfo_sb.AppendFormat("\t{0}", System.Security.SecurityElement.Escape(artist)).AppendLine();
+ nfo_sb.AppendFormat("\t{0}", System.Security.SecurityElement.Escape(video_pieces[1])).AppendLine();
+ nfo_sb.AppendFormat("\t", System.Security.SecurityElement.Escape(video_pieces[0])).AppendLine();
+ nfo_sb.AppendLine("");
+
+ Console.WriteLine("Writing {0}", nfo_path_filename);
+ File.WriteAllText(nfo_path_filename, nfo_sb.ToString(), Encoding.UTF8);
+ written++;
+ }
+
+ videos++;
+ }
+ }
+ albums += album_paths.Count;
+ }
+
+ Console.WriteLine("{0} music videos from {1} artists in {2} albums", videos, artist_paths.Count, albums);
+ Console.WriteLine("{0} NFOs written", written);
+ Console.WriteLine("{0} NFOs skipped", skipped);
+ }
+ }
+}
diff --git a/QDXMVNC/Properties/AssemblyInfo.cs b/QDXMVNC/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..5d2df30
--- /dev/null
+++ b/QDXMVNC/Properties/AssemblyInfo.cs
@@ -0,0 +1,22 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+// Information about this assembly is defined by the following attributes.
+// Change them to the values specific to your project.
+[assembly: AssemblyTitle("QDXMVNC")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Claunia.com")]
+[assembly: AssemblyProduct("")]
+[assembly: AssemblyCopyright("© Claunia.com")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
+// The form "{Major}.{Minor}.*" will automatically update the build and revision,
+// and "{Major}.{Minor}.{Build}.*" will update just the revision.
+[assembly: AssemblyVersion("1.0.*")]
+// The following attributes are used to specify the signing key for the assembly,
+// if desired. See the Mono documentation for more information about signing.
+//[assembly: AssemblyDelaySign(false)]
+//[assembly: AssemblyKeyFile("")]
+
diff --git a/QDXMVNC/QDXMVNC.csproj b/QDXMVNC/QDXMVNC.csproj
new file mode 100644
index 0000000..211acc1
--- /dev/null
+++ b/QDXMVNC/QDXMVNC.csproj
@@ -0,0 +1,41 @@
+
+
+
+ Debug
+ x86
+ 12.0.0
+ 2.0
+ {3C478B87-7880-4B6D-8951-3F445B55948B}
+ Exe
+ QDXMVNC
+ QDXMVNC
+
+
+ true
+ full
+ false
+ bin\Debug
+ DEBUG;
+ prompt
+ 4
+ true
+ x86
+
+
+ full
+ true
+ bin\Release
+ prompt
+ 4
+ true
+ x86
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file