diff --git a/Downtify.sln b/Downtify.sln
index e26a7ed..cc85f07 100644
--- a/Downtify.sln
+++ b/Downtify.sln
@@ -1,10 +1,12 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
-VisualStudioVersion = 12.0.21005.1
+VisualStudioVersion = 12.0.31101.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Downtify", "Downtify\Downtify.csproj", "{311EACED-AFD3-42BE-B5BE-E5D046A69AAF}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DowntifyUpdater", "DowntifyUpdater\DowntifyUpdater.csproj", "{EC8D9553-021D-4787-9BD3-278F81C15397}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -15,6 +17,10 @@ Global
{311EACED-AFD3-42BE-B5BE-E5D046A69AAF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{311EACED-AFD3-42BE-B5BE-E5D046A69AAF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{311EACED-AFD3-42BE-B5BE-E5D046A69AAF}.Release|Any CPU.Build.0 = Release|Any CPU
+ {EC8D9553-021D-4787-9BD3-278F81C15397}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {EC8D9553-021D-4787-9BD3-278F81C15397}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EC8D9553-021D-4787-9BD3-278F81C15397}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EC8D9553-021D-4787-9BD3-278F81C15397}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/Downtify/Downtify.csproj b/Downtify/Downtify.csproj
index cd9319c..fac3a99 100644
--- a/Downtify/Downtify.csproj
+++ b/Downtify/Downtify.csproj
@@ -77,11 +77,11 @@
False
- .\yeti.mmedia.dll
+ Libs\yeti.mmedia.dll
False
- .\yeti.mp3.dll
+ Libs\yeti.mp3.dll
@@ -91,6 +91,9 @@
frmMain.cs
+
+ Component
+
Component
@@ -168,12 +171,12 @@
-
+
PreserveNewest
-
+
PreserveNewest
diff --git a/Downtify/GUI/TextProgressBar.cs b/Downtify/GUI/TextProgressBar.cs
new file mode 100644
index 0000000..c29a2ef
--- /dev/null
+++ b/Downtify/GUI/TextProgressBar.cs
@@ -0,0 +1,43 @@
+using System;
+using System.Drawing;
+using System.Windows.Forms;
+
+namespace Downtify.GUI
+{
+ public class TextProgressBar : ProgressBar
+ {
+ public override string Text { get; set; }
+ public int TotalTracks { get; set; }
+ public int CurrentTrack { get; set; }
+ public bool ShowText { get; set; }
+
+ public TextProgressBar()
+ {
+ SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true);
+ Text = "";
+ ShowText = false;
+ TotalTracks = 0;
+ CurrentTrack = 0;
+ }
+
+ protected override void OnPaint(PaintEventArgs e)
+ {
+ Rectangle rect = ClientRectangle;
+
+ ProgressBarRenderer.DrawHorizontalBar(e.Graphics, rect);
+ rect.Inflate(-3, -3);
+ if (Value > 0)
+ {
+ Rectangle clip = new Rectangle(rect.X, rect.Y, (int)Math.Round(((float)Value / Maximum) * rect.Width), rect.Height);
+ ProgressBarRenderer.DrawHorizontalChunks(e.Graphics, clip);
+ }
+ if (ShowText)
+ {
+ string text = String.Format(Text, CurrentTrack, TotalTracks);
+ float center_x = this.Width / 2.0f - (e.Graphics.MeasureString(text, SystemFonts.DefaultFont).Width / 2.0f);
+ float center_y = this.Height / 2.0f - (e.Graphics.MeasureString(text, SystemFonts.DefaultFont).Height / 2.0f);
+ e.Graphics.DrawString(text, SystemFonts.DefaultFont, Brushes.Black, new PointF(center_x, center_y));
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Downtify/GUI/frmMain.Designer.cs b/Downtify/GUI/frmMain.Designer.cs
index c69bc2d..61fb553 100644
--- a/Downtify/GUI/frmMain.Designer.cs
+++ b/Downtify/GUI/frmMain.Designer.cs
@@ -31,7 +31,7 @@ private void InitializeComponent()
this.listBoxTracks = new System.Windows.Forms.ListBox();
this.buttonDownload = new System.Windows.Forms.Button();
this.textBoxLink = new Downtify.GUI.PlaceholderTextBox();
- this.progressBar1 = new System.Windows.Forms.ProgressBar();
+ this.progressBar1 = new Downtify.GUI.TextProgressBar();
this.SuspendLayout();
//
// listBoxTracks
@@ -69,10 +69,13 @@ private void InitializeComponent()
//
// progressBar1
//
+ this.progressBar1.CurrentTrack = 0;
this.progressBar1.Location = new System.Drawing.Point(12, 241);
this.progressBar1.Name = "progressBar1";
+ this.progressBar1.ShowText = false;
this.progressBar1.Size = new System.Drawing.Size(381, 23);
this.progressBar1.TabIndex = 3;
+ this.progressBar1.TotalTracks = 0;
//
// frmMain
//
@@ -88,6 +91,7 @@ private void InitializeComponent()
this.Name = "frmMain";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Downtify";
+ this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.frmMain_Closing);
this.Load += new System.EventHandler(this.frmMain_Load);
this.Shown += new System.EventHandler(this.frmMain_Shown);
this.ResumeLayout(false);
@@ -100,7 +104,7 @@ private void InitializeComponent()
private System.Windows.Forms.ListBox listBoxTracks;
private Downtify.GUI.PlaceholderTextBox textBoxLink;
private System.Windows.Forms.Button buttonDownload;
- private System.Windows.Forms.ProgressBar progressBar1;
+ private Downtify.GUI.TextProgressBar progressBar1;
}
}
diff --git a/Downtify/GUI/frmMain.cs b/Downtify/GUI/frmMain.cs
index b086c40..b839586 100644
--- a/Downtify/GUI/frmMain.cs
+++ b/Downtify/GUI/frmMain.cs
@@ -1,6 +1,11 @@
using System;
using System.IO;
+using System.Collections.Generic;
+using System.Threading.Tasks;
using System.Windows.Forms;
+using System.Drawing;
+using System.Text.RegularExpressions;
+using System.Xml;
namespace Downtify.GUI
{
@@ -14,8 +19,9 @@ public frmMain()
{
InitializeComponent();
- downloader = new SpotifyDownloader();
configuration = new XmlConfiguration("config.xml");
+ configuration.LoadConfigurationFile();
+ downloader = new SpotifyDownloader();
downloader.OnLoginResult += OnLoginResult;
downloader.OnDownloadComplete += downloader_OnDownloadComplete;
downloader.OnDownloadProgress += downloader_OnDownloadProgress;
@@ -40,7 +46,7 @@ private void downloader_OnDownloadComplete(bool successfully)
EnableControls(true);
return;
}
-
+ progressBar1.CurrentTrack++;
downloader.Download(((TrackItem)listBoxTracks.SelectedItems[0]).Track);
}
@@ -60,22 +66,54 @@ private void frmMain_Load(object sender, EventArgs e)
EnableControls(false);
}
- private void frmMain_Shown(object sender, EventArgs e)
+ private async void frmMain_Shown(object sender, EventArgs e)
{
System.Threading.Thread.Sleep(200);
this.Activate();
- // very ugly, use config parser (json for example) would be nicer
string username = "", password = "";
- configuration.LoadConfigurationFile();
TransferConfig();
username = configuration.GetConfiguration("username");
password = configuration.GetConfiguration("password");
- lang = new LanguageXML(configuration.GetConfiguration("language"));
+ lang = new LanguageXML(configuration.GetConfiguration("language", "en"));
textBoxLink.Placeholder = lang.GetString("download/paste_uri");
+ progressBar1.Text = lang.GetString("download/progression");
downloader.Login(username, password);
+
+ if (configuration.GetConfiguration("continue_dl", "false").ToLower() == "true" && File.Exists("download.xml"))
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.Load("download.xml");
+ foreach (XmlNode node in doc.SelectNodes("tracks/track"))
+ await AddDownload(node.InnerText);
+ }
+ }
+
+ private void frmMain_Closing(object sender, FormClosingEventArgs e)
+ {
+ if (buttonDownload.Enabled == false && configuration.GetConfiguration("continue_dl", "false").ToLower() == "true")
+ {
+ if (File.Exists("download.xml"))
+ File.Delete("download.xml");
+ List tracks = new List();
+ foreach (TrackItem track in listBoxTracks.SelectedItems)
+ tracks.Add(SpotifySharp.Link.CreateFromTrack(track.Track, 0).AsString());
+ if (tracks.Count > 0)
+ {
+ XmlDocument doc = new XmlDocument();
+ XmlNode root = doc.CreateElement("tracks");
+ doc.AppendChild(root);
+ foreach (string trackLink in tracks)
+ {
+ XmlNode track = doc.CreateElement("track");
+ track.InnerText = trackLink;
+ root.AppendChild(track);
+ }
+ doc.Save("download.xml");
+ }
+ }
}
private void TransferConfig()
@@ -121,37 +159,85 @@ private void EnableControls(bool enable)
((Control)control).Enabled = enable;
}
- private async void textBoxLink_TextChanged(object sender, EventArgs e)
+ private async void textBoxLink_TextChanged(object sender, EventArgs e)
+ {
+ await AddDownload(textBoxLink.Text);
+ }
+
+ private void listBoxTracks_KeyDown(object sender, KeyEventArgs e)
+ {
+ if (e.KeyCode == Keys.Delete)
+ {
+ if (listBoxTracks.SelectedItems.Count == 0)
+ return;
+
+ var list = new TrackItem[listBoxTracks.SelectedItems.Count];
+ listBoxTracks.SelectedItems.CopyTo(list, 0);
+
+ foreach (var track in list)
+ listBoxTracks.Items.Remove(track);
+ }
+ else if (e.KeyCode == Keys.A && e.Control)
+ {
+ var list = new TrackItem[listBoxTracks.Items.Count];
+ listBoxTracks.Items.CopyTo(list, 0);
+
+ listBoxTracks.SelectedItems.Clear();
+ foreach (var track in list)
+ listBoxTracks.SelectedItems.Add(track);
+ }
+ }
+
+ private void buttonDownload_Click(object sender, EventArgs e)
+ {
+ if (listBoxTracks.SelectedItems.Count == 0)
+ {
+ MessageBox.Show(lang.GetString("error/no_download_selection"), lang.GetString("title/error"));
+ return;
+ }
+
+ progressBar1.TotalTracks = listBoxTracks.SelectedItems.Count;
+ progressBar1.CurrentTrack = 1;
+ progressBar1.ShowText = true;
+
+ EnableControls(false);
+ downloader.Download(((TrackItem)listBoxTracks.SelectedItems[0]).Track);
+ }
+
+ private async Task AddDownload(string link)
{
- var link = textBoxLink.Text;
try
{
EnableControls(false);
-
+
//Validate pasted URI
- if(link.Length > 0 && !link.ToLower().StartsWith("spotify:"))
+ if (link.Length > 0 && !link.ToLower().StartsWith("spotify:") && !link.Contains("play.spotify.com"))
{
MessageBox.Show(lang.GetString("download/invalid_uri"));
textBoxLink.Clear();
return;
}
+ else if (link.Contains("play.spotify.com"))
+ {
+ link = BuildSpotifyURI(link);
+ }
if (link.ToLower().Contains("playlist"))
{
- var playlist = await downloader.FetchPlaylist(textBoxLink.Text);
+ var playlist = await downloader.FetchPlaylist(link);
for (int i = 0; i < playlist.NumTracks(); i++)
listBoxTracks.Items.Add(new TrackItem(playlist.Track(i)));
textBoxLink.Clear();
}
else if (link.ToLower().Contains("track"))
{
- var track = await downloader.FetchTrack(textBoxLink.Text);
+ var track = await downloader.FetchTrack(link);
listBoxTracks.Items.Add(new TrackItem(track));
textBoxLink.Clear();
}
- else if(link.ToLower().Contains("album"))
+ else if (link.ToLower().Contains("album"))
{
- var album = await downloader.FetchAlbum(textBoxLink.Text);
+ var album = await downloader.FetchAlbum(link);
for (int i = 0; i < album.NumTracks(); i++)
listBoxTracks.Items.Add(new TrackItem(album.Track(i)));
textBoxLink.Clear();
@@ -166,40 +252,22 @@ private async void textBoxLink_TextChanged(object sender, EventArgs e)
}
}
- private void listBoxTracks_KeyDown(object sender, KeyEventArgs e)
+ private string BuildSpotifyURI(string url)
{
- if (e.KeyCode == Keys.Delete)
- {
- if (listBoxTracks.SelectedItems.Count == 0)
- return;
+ string uri = url;
- var list = new TrackItem[listBoxTracks.SelectedItems.Count];
- listBoxTracks.SelectedItems.CopyTo(list, 0);
+ Regex regex = new Regex(@"https?:\/\/play\.spotify\.com\/(user\/(?(\d.+))\/)?(?playlist|album|track)\/(?.+)"); //ToDo: Optimize this RegEx
- foreach (var track in list)
- listBoxTracks.Items.Remove(track);
- }
- else if (e.KeyCode == Keys.A && e.Control)
- {
- var list = new TrackItem[listBoxTracks.Items.Count];
- listBoxTracks.Items.CopyTo(list, 0);
+ Match match = regex.Match(url);
- listBoxTracks.SelectedItems.Clear();
- foreach (var track in list)
- listBoxTracks.SelectedItems.Add(track);
- }
- }
-
- private void buttonDownload_Click(object sender, EventArgs e)
- {
- if (listBoxTracks.SelectedItems.Count == 0)
+ if (match.Success)
{
- MessageBox.Show(lang.GetString("error/no_download_selection"), lang.GetString("title/error"));
- return;
+ string uid = match.Groups["uid"].Value != "" ? "user:" + match.Groups["uid"].Value + ":" : "";
+ string type = match.Groups["type"].Value;
+ string tid = match.Groups["tid"].Value;
+ uri = "spotify:" + uid + type + ":" + tid;
}
-
- EnableControls(false);
- downloader.Download(((TrackItem)listBoxTracks.SelectedItems[0]).Track);
+ return uri;
}
}
}
diff --git a/Downtify/SpotifyDownloader.cs b/Downtify/SpotifyDownloader.cs
index d293c4f..b3bfe25 100644
--- a/Downtify/SpotifyDownloader.cs
+++ b/Downtify/SpotifyDownloader.cs
@@ -66,12 +66,14 @@ public static string GetTrackFullName(Track track)
Mp3Writer wr;
SynchronizationContext syncContext;
- static string appPath = AppDomain.CurrentDomain.BaseDirectory;
- static string tmpPath = appPath + "cache\\";
- static string downloadPath = appPath + "download\\";
+ string tmpPath;
+ string downloadPath;
public SpotifyDownloader()
{
+ tmpPath = Downtify.GUI.frmMain.configuration.GetConfiguration("cache", "cache/");
+ downloadPath = Downtify.GUI.frmMain.configuration.GetConfiguration("download", "download/");
+
if (!Directory.Exists(tmpPath))
Directory.CreateDirectory(tmpPath);
@@ -386,7 +388,7 @@ private void AlbumBrowseCallBack(AlbumBrowse browse, object userdata)
private DownloadType GetDownloadType()
{
- var typeStr = Downtify.GUI.frmMain.configuration.GetConfiguration("file_exists").ToUpper();
+ var typeStr = Downtify.GUI.frmMain.configuration.GetConfiguration("file_exists", "SKIP").ToUpper();
DownloadType type;
try
{
diff --git a/Downtify/XMLConfiguration.cs b/Downtify/XMLConfiguration.cs
index 6252244..dbee3f8 100644
--- a/Downtify/XMLConfiguration.cs
+++ b/Downtify/XMLConfiguration.cs
@@ -56,5 +56,14 @@ public string GetConfiguration(string entry)
return Configuration.ContainsKey(entry) ? Configuration[entry] : null;
}
+ public string GetConfiguration(string entry, string defaultValue)
+ {
+ if (GetConfiguration(entry) != null)
+ return GetConfiguration(entry);
+ SetConfigurationEntry(entry, defaultValue);
+ SaveConfigurationFile();
+ return defaultValue;
+ }
+
}
}
diff --git a/Downtify/config.xml b/Downtify/config.xml
index 74e4179..bf480bd 100644
--- a/Downtify/config.xml
+++ b/Downtify/config.xml
@@ -3,4 +3,8 @@
PASSWORD
en
SKIP
+ download/
+ cache/
+ false
+ https://github.com/Shawak/downtify.git
\ No newline at end of file
diff --git a/Downtify/language/de.xml b/Downtify/language/de.xml
index a2dbdd7..65a58d3 100644
--- a/Downtify/language/de.xml
+++ b/Downtify/language/de.xml
@@ -5,6 +5,7 @@
Füge hier deinen Track, Playlist oder Album link ein
Download abgeschlossen
+ Download Track: {0} von {1}
Fehler beim einloggen. Besitzt du Spotify Premium?
diff --git a/Downtify/language/en.xml b/Downtify/language/en.xml
index fe82f1d..c6240a4 100644
--- a/Downtify/language/en.xml
+++ b/Downtify/language/en.xml
@@ -5,6 +5,7 @@
Paste your track, playlist or album link here
Download finished
+ Download Track: {0} of {1}
Error logging in. Are you a Spotify Premium User?
diff --git a/DowntifyUpdater/App.config b/DowntifyUpdater/App.config
new file mode 100644
index 0000000..74ade9d
--- /dev/null
+++ b/DowntifyUpdater/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/DowntifyUpdater/DowntifyUpdater.csproj b/DowntifyUpdater/DowntifyUpdater.csproj
new file mode 100644
index 0000000..3dfb0ca
--- /dev/null
+++ b/DowntifyUpdater/DowntifyUpdater.csproj
@@ -0,0 +1,106 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {EC8D9553-021D-4787-9BD3-278F81C15397}
+ Exe
+ Properties
+ DowntifyUpdater
+ DowntifyUpdater
+ v4.0
+ 512
+ 1e944375
+ publish\
+ true
+ Disk
+ false
+ Foreground
+ 7
+ Days
+ false
+ false
+ true
+ 0
+ 1.0.0.%2a
+ false
+ false
+ true
+
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ .\ICSharpCode.SharpZipLib.dll
+
+
+ .\NGit.dll
+
+
+ .\Sharpen.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ False
+ Microsoft .NET Framework 4.5 %28x86 and x64%29
+ true
+
+
+ False
+ .NET Framework 3.5 SP1 Client Profile
+ false
+
+
+ False
+ .NET Framework 3.5 SP1
+ false
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/DowntifyUpdater/ICSharpCode.SharpZipLib.dll b/DowntifyUpdater/ICSharpCode.SharpZipLib.dll
new file mode 100644
index 0000000..11c6d30
Binary files /dev/null and b/DowntifyUpdater/ICSharpCode.SharpZipLib.dll differ
diff --git a/DowntifyUpdater/NGit.dll b/DowntifyUpdater/NGit.dll
new file mode 100644
index 0000000..08a7392
Binary files /dev/null and b/DowntifyUpdater/NGit.dll differ
diff --git a/DowntifyUpdater/Program.cs b/DowntifyUpdater/Program.cs
new file mode 100644
index 0000000..093f7d1
--- /dev/null
+++ b/DowntifyUpdater/Program.cs
@@ -0,0 +1,175 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.IO;
+using System.Diagnostics;
+using System.Threading;
+using NGit;
+using NGit.Api;
+using NGit.Transport;
+
+namespace DowntifyUpdater
+{
+ class Program
+ {
+
+ static string Version = System.Reflection.Assembly.GetEntryAssembly().GetName().Version.ToString();
+ static string Repo_directory = Environment.CurrentDirectory + "\\repo";
+ static string Git_Remote = null;
+ static string Downtify_Executable = "Downtify.exe";
+
+ static void Main(string[] args)
+ {
+ bool forceInstall = false;
+ XmlConfiguration config = new XmlConfiguration("config.xml");
+ config.LoadConfigurationFile();
+ Git_Remote = config.GetConfiguration("update_repo", "https://github.com/Shawak/downtify.git");
+ for(int iArg = 0; iArg < args.Length; iArg++)
+ {
+ if (args[iArg].ToLower().Equals("--git"))
+ if (iArg != args.Length - 1)
+ Git_Remote = args[iArg + 1];
+ else
+ Console.WriteLine("No update_repo specified.");
+ if (args[iArg].ToLower().Equals("--force"))
+ forceInstall = true;
+ }
+ if (!File.Exists(Downtify_Executable))
+ {
+ Log(Downtify_Executable + " was not found. Please execute this Updater in the Downtify-Folder.");
+ Console.ReadKey(true);
+ return;
+ }
+ Console.Title = "Downtify Updater v" + Version;
+ Log("Repository Directory: " + Repo_directory);
+
+ if (forceInstall)
+ {
+ if (Directory.Exists(Repo_directory))
+ DeleteDirectory(Repo_directory);
+ Thread.Sleep(500);
+ Install();
+ }
+ else
+ {
+ if (!Directory.Exists(Repo_directory))
+ Install();
+ else
+ Update();
+ }
+
+ Build();
+ CopyUpdate();
+ Process downtify = new Process();
+ downtify.StartInfo.FileName = Downtify_Executable;
+ downtify.Start();
+ }
+
+ static void Install()
+ {
+ Log("Cloning from " + Git_Remote + " to Repository Directory");
+ Directory.CreateDirectory(Repo_directory);
+ Git.CloneRepository().SetDirectory(Repo_directory).SetURI(Git_Remote).Call();
+ }
+
+ static void Update()
+ {
+ Log("Checking for updates...");
+ Git repository = Git.Open(Repo_directory);
+ ICollection refUpdate = repository.Fetch().Call().GetTrackingRefUpdates();
+ if (refUpdate.Count > 0)
+ {
+ Log(String.Format("Downloading {0} Updates...", refUpdate.Count));
+ repository.BranchCreate().SetForce(true).SetName("master").SetStartPoint("origin/master").Call();
+ repository.Checkout().SetName("master").Call();
+ }
+ else
+ {
+ Log("Repository already up2date");
+ }
+ repository.GetRepository().Close();
+ repository.GetRepository().ObjectDatabase.Close();
+ }
+
+ static void Build()
+ {
+ DeleteDirectory(Repo_directory + @"\Downtify\bin");
+ Log("Build Downtify...");
+ string net_folder = Environment.GetFolderPath(Environment.SpecialFolder.Windows) + @"\Microsoft.NET\Framework";
+ if (Directory.Exists(net_folder + "64"))
+ net_folder += "64";
+ string[] subdir = Directory.GetDirectories(net_folder, "v4.*");
+ string msbuild = subdir.Length != 0 ? subdir[subdir.Length-1] : null;
+ if(msbuild == null)
+ {
+ Log(".NET Framework 4 is not installed. Please install .NET Framework 4");
+ return;
+ }
+ msbuild += @"\msbuild.exe";
+
+ Process buildProc = new Process();
+ buildProc.StartInfo.FileName = msbuild;
+ buildProc.StartInfo.CreateNoWindow = true;
+ buildProc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
+ buildProc.StartInfo.Arguments = "Downtify.csproj /t:Build";
+ buildProc.StartInfo.WorkingDirectory = Repo_directory + @"\Downtify";
+ buildProc.Start();
+ buildProc.WaitForExit();
+ Log("Downtify built.");
+ }
+
+ static void CopyUpdate()
+ {
+ //Copy Binary
+ if (File.Exists(Downtify_Executable))
+ File.Delete(Downtify_Executable);
+ File.Copy(Repo_directory + @"\Downtify\bin\Debug\" + Downtify_Executable, Downtify_Executable);
+ //Copy Libraries
+ foreach(string dll_file in Directory.GetFiles(Repo_directory + @"\Downtify\bin\Debug", "*.dll", SearchOption.TopDirectoryOnly))
+ {
+ if (File.Exists(GetFileName(dll_file)))
+ File.Delete(GetFileName(dll_file));
+ File.Copy(dll_file, GetFileName(dll_file));
+ }
+ //Copy Language Files
+ foreach (string language_file in Directory.GetFiles(Repo_directory + @"\Downtify\bin\Debug\language", "*.xml", SearchOption.TopDirectoryOnly))
+ {
+ if(File.Exists("language/" + GetFileName(language_file)))
+ File.Delete("language/" + GetFileName(language_file));
+ File.Copy(language_file, "language/" + GetFileName(language_file));
+ }
+ }
+
+ static string GetFileName(string filepath)
+ {
+ string[] splitter = filepath.Split('\\');
+ return splitter[splitter.Length - 1];
+ }
+
+ static void DeleteDirectory(string directory)
+ {
+ if (!Directory.Exists(directory))
+ return;
+ foreach(string dirname in Directory.GetDirectories(directory))
+ {
+ DeleteDirectory(dirname);
+ }
+ foreach(string filename in Directory.GetFiles(directory))
+ {
+ File.Delete(filename);
+ }
+ Directory.Delete(directory);
+ }
+
+ static void Log(string message)
+ {
+ string time = DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss");
+ Console.WriteLine(String.Format("[{0}] {1}", time, message));
+ StreamWriter sw = new StreamWriter("updater.log", true);
+ sw.WriteLine(String.Format("[{0}] {1}", time, message));
+ sw.Close();
+ }
+ }
+}
diff --git a/DowntifyUpdater/Properties/AssemblyInfo.cs b/DowntifyUpdater/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..944eff8
--- /dev/null
+++ b/DowntifyUpdater/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// Allgemeine Informationen über eine Assembly werden über die folgenden
+// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
+// die mit einer Assembly verknüpft sind.
+[assembly: AssemblyTitle("DowntifyUpdater")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("DowntifyUpdater")]
+[assembly: AssemblyCopyright("Copyright © 2015")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar
+// für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von
+// COM zugreifen müssen, legen Sie das ComVisible-Attribut für diesen Typ auf "true" fest.
+[assembly: ComVisible(false)]
+
+// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
+[assembly: Guid("2d9b7db8-6f32-460b-97e7-2900e37b14a7")]
+
+// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
+//
+// Hauptversion
+// Nebenversion
+// Buildnummer
+// Revision
+//
+// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern
+// übernehmen, indem Sie "*" eingeben:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.1")]
+[assembly: AssemblyFileVersion("1.0.0.1")]
diff --git a/DowntifyUpdater/Sharpen.dll b/DowntifyUpdater/Sharpen.dll
new file mode 100644
index 0000000..fcc7e84
Binary files /dev/null and b/DowntifyUpdater/Sharpen.dll differ
diff --git a/DowntifyUpdater/XMLConfiguration.cs b/DowntifyUpdater/XMLConfiguration.cs
new file mode 100644
index 0000000..8a82cb3
--- /dev/null
+++ b/DowntifyUpdater/XMLConfiguration.cs
@@ -0,0 +1,69 @@
+using System;
+using System.IO;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Xml;
+
+namespace DowntifyUpdater
+{
+ public class XmlConfiguration
+ {
+
+ private string FileName;
+ private Dictionary Configuration = new Dictionary();
+
+ public XmlConfiguration(string file)
+ {
+ this.FileName = file;
+ }
+
+ public void SetConfigurationEntry(string entry, string value)
+ {
+ if(Configuration.ContainsKey(entry))
+ Configuration.Remove(entry);
+ Configuration.Add(entry, value);
+ }
+
+ public void LoadConfigurationFile()
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.Load(this.FileName);
+ XmlNodeList nodes = doc.SelectSingleNode("configuration").ChildNodes;
+ foreach(XmlNode node in nodes)
+ SetConfigurationEntry(node.Name, node.InnerText);
+ }
+
+ public void SaveConfigurationFile()
+ {
+ XmlDocument doc = new XmlDocument();
+ XmlNode root = doc.CreateElement("configuration");
+ doc.AppendChild(root);
+ foreach(string key in Configuration.Keys)
+ {
+ XmlNode xmlKey = doc.CreateElement(key);
+ xmlKey.InnerText = Configuration[key];
+ root.AppendChild(xmlKey);
+ }
+ if(File.Exists(this.FileName))
+ File.Delete(this.FileName);
+ doc.Save(this.FileName);
+ }
+
+ public string GetConfiguration(string entry)
+ {
+ return Configuration.ContainsKey(entry) ? Configuration[entry] : null;
+ }
+
+ public string GetConfiguration(string entry, string defaultValue)
+ {
+ if (GetConfiguration(entry) != null)
+ return GetConfiguration(entry);
+ SetConfigurationEntry(entry, defaultValue);
+ SaveConfigurationFile();
+ return defaultValue;
+ }
+
+ }
+}
diff --git a/README.md b/README.md
index e0a2f0d..daec206 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,7 @@ playlists directly from spotify.
### Usage
-To use downtify, you just simple need enter any spotify premium account into the `config.txt`.
+To use downtify, you just simple need enter any spotify premium account into the `config.xml`.
### Downloading