33 Commits
Author SHA1 Message Date
Yorick Rommers 96683d3b57 merge gui to dev 2015-11-02 21:52:47 +01:00
Yorick Rommers 5a07e6251b added reset button 2015-11-02 21:40:28 +01:00
Yorick Rommers b9b300b14d Merge remote-tracking branch 'origin/search' into developer 2015-11-02 21:38:32 +01:00
Yorick Rommers 4e9d2222cf Merge branch 'developer' of https://github.com/yorickr/musicplayer into developer 2015-11-02 21:37:41 +01:00
Yorick Rommers 4a869f3399 added advanced search 2015-11-02 21:37:24 +01:00
kennyboy55 0d0a92f33a Fix albumart interface 2015-11-02 21:27:33 +01:00
kennyboy55 66c5285418 Merge remote-tracking branch 'origin/gui' into gui 2015-11-02 21:15:46 +01:00
kennyboy55 292405cf4d Remove playlist and songs from playlist 2015-11-02 21:15:24 +01:00
Janco Kock 8d7d8eaabc Some album art edits, bigger covers and current playing cover 2015-11-02 20:37:39 +01:00
kennyboy55 40cb55d7f6 Implemented Advanced Search interface 2015-11-02 18:17:22 +01:00
yorickr 56586355d3 Merge remote-tracking branch 'origin/gui' into developer 2015-11-02 17:38:12 +01:00
yorickr 56a2cb91a4 Removed useless arguments 2015-11-02 17:37:50 +01:00
kennyboy55 a4031daae8 Playlist based on server 2015-11-02 17:25:52 +01:00
kennyboy55 a1bfb15e6b Implemented song searching in application. API does not support it yet. 2015-11-02 17:03:31 +01:00
kennyboy55 c2229db72a Handle server error's 2015-11-02 12:18:09 +01:00
kennyboy55 f81c526255 Translate to english 2015-11-02 11:14:43 +01:00
kennyboy55 7b712460d2 Small GUI changes 2015-11-02 11:09:39 +01:00
kennyboy55 515f17eb62 Made genre/artist box larger 2015-11-01 20:16:55 +01:00
kennyboy55 98f6ab9bc0 Better handling of radiostation 2015-11-01 19:51:43 +01:00
kennyboy55 90f35de242 Better naming and buffering 2015-11-01 19:10:30 +01:00
kennyboy55 aa85ca5d26 Clear playlist when starting radio 2015-11-01 19:03:55 +01:00
kennyboy55 270db2d1a4 Added Slam-FM 2015-11-01 18:59:59 +01:00
Janco Kock fd629f54ff Fixed 3fm radio 2015-11-01 14:39:11 +01:00
kennyboy55 d774e250c5 Calculate length if unknown. 2015-11-01 14:24:16 +01:00
Janco Kock 93f9879c14 Fixed cross thread bug 2015-11-01 14:07:09 +01:00
kennyboy55 a6514189b0 Fix bufferbar not filling completely 2015-11-01 14:05:14 +01:00
Yorick Rommers 192e132f1d Changed artwork folder and server 2015-11-01 14:00:27 +01:00
Yorick Rommers d8a900ecb9 Changed artwork folder and server 2015-11-01 13:59:15 +01:00
kennyboy55 7e5dcb3cef Fix 3FM url and name 2015-11-01 13:55:34 +01:00
kennyboy55 17eaac40bf Added 3FM, added custom Radio URL 2015-11-01 13:39:37 +01:00
kennyboy55 dad829d1dd Added URL tools 2015-11-01 13:39:24 +01:00
kennyboy55 e218b58421 Faster buffering of radio station 2015-11-01 13:39:06 +01:00
Janco Kock 7f45afe80f Added support for radio stations 2015-11-01 13:07:11 +01:00
48 changed files with 2356 additions and 989 deletions
+74 -4
View File
@@ -20,6 +20,16 @@ namespace MusicPlayer
defaultCover = Image.FromStream(nw.downloadArtwork("default-cover.png"));
}
public JObject GetAllBySearch(string search, string album, string artist, string genre)
{
// Q artist genre album
JObject o = nw.SendString($"search?q={search}&album={album}&genre={genre}&artist={artist}");
Console.WriteLine(o.PropertyValues().ToString());
if (o["result"].ToString() == "OK") { return o; }
return null;
}
public string GetSongURLByID(string id)
{
JObject o = nw.SendString("getsongbyid?id=" + id);
@@ -49,6 +59,66 @@ namespace MusicPlayer
return GetSongsByArgs("album=" + year);
}
public List<Song> GetSongsBySearch(string search)
{
return GetSongsByArgs("search=" + search);
}
public List<Genre> Genrify(JObject o)
{
List<Genre> genreslist = new List<Genre>();
if (o["result"].ToString() == "OK")
{
for (int i = 0; i < o["genres"].Count(); i++)
{
genreslist.Add(new Genre(o["genres"][i][0].ToString()));
}
}
return genreslist;
}
public List<Artist> Artistify(JObject o)
{
List<Artist> artistlist = new List<Artist>();
if (o["result"].ToString() == "OK")
{
for (int i = 0; i < o["artists"].Count(); i++)
{
artistlist.Add(new Artist(o["artists"][i][0].ToString()));
}
}
return artistlist;
}
public List<Song> Songify(JObject o)
{
List<Song> allsongslist = new List<Song>();
if (o["result"].ToString() == "OK")
{
dynamic songs = o["songs"];
for (int i = 0; i < songs.Count; i++)
{
allsongslist.Add(new Song(songs[i][0].ToString(), songs[i][3].ToString(), songs[i][5].ToString(), songs[i][4].ToString(), songs[i][1].ToString(), (int)songs[i][9], this));
}
}
return allsongslist;
}
public List<Album> Albumify(JObject o)
{
List<Album> albumlist = new List<Album>();
if (o["result"].ToString() == "OK")
{
for (int i = 0; i < o["albums"].Count(); i++)
{
albumlist.Add(new Album(o["albums"][i][0].ToString()));
}
}
return albumlist;
}
public List<Song> GetAllSongs()
{
List<Song> allsongslist = new List<Song>();
@@ -85,7 +155,7 @@ namespace MusicPlayer
{
List<Artist> artistlist = new List<Artist>();
JObject o = nw.SendString("getartists?id=hallo");
JObject o = nw.SendString("getartists?");
if (o["result"].ToString() == "OK")
{
for (int i = 0; i < o["artists"].Count(); i++) {
@@ -109,7 +179,7 @@ namespace MusicPlayer
{
List<Album> albumlist = new List<Album>();
JObject o = nw.SendString("getalbums?id=hallo");
JObject o = nw.SendString("getalbums?");
if (o["result"].ToString() == "OK")
{
for (int i = 0; i < o["albums"].Count(); i++)
@@ -124,7 +194,7 @@ namespace MusicPlayer
public List<Year> GetYears()
{
List<Year> yearlist = new List<Year> ();
JObject o = nw.SendString("getyears?id=hallo");
JObject o = nw.SendString("getyears?");
if (o["result"].ToString() == "OK")
{
for (int i = 0; i < o["years"].Count(); i++)
@@ -138,7 +208,7 @@ namespace MusicPlayer
public List<Genre> GetGenres()
{
List<Genre> genreslist = new List<Genre>();
JObject o = nw.SendString("getgenres?id=hallo");
JObject o = nw.SendString("getgenres?");
if (o["result"].ToString() == "OK")
{
for (int i = 0; i < o["genres"].Count(); i++)
+177
View File
@@ -0,0 +1,177 @@
using System.Windows.Forms;
namespace MusicPlayer
{
partial class AdvancedSearch
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AdvancedSearch));
this.SearchTermTextBox = new System.Windows.Forms.TextBox();
this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.AlbumTextBox = new System.Windows.Forms.TextBox();
this.label3 = new System.Windows.Forms.Label();
this.ArtistTextBox = new System.Windows.Forms.TextBox();
this.GenreTextBox = new System.Windows.Forms.TextBox();
this.label4 = new System.Windows.Forms.Label();
this.SearchButton = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// SearchTermTextBox
//
this.SearchTermTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.SearchTermTextBox.Location = new System.Drawing.Point(12, 29);
this.SearchTermTextBox.Name = "SearchTermTextBox";
this.SearchTermTextBox.Size = new System.Drawing.Size(210, 20);
this.SearchTermTextBox.TabIndex = 0;
this.SearchTermTextBox.KeyDown += TextBox_KeyDown;
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(12, 13);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(68, 13);
this.label1.TabIndex = 1;
this.label1.Text = "Search Term";
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(12, 70);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(36, 13);
this.label2.TabIndex = 2;
this.label2.Text = "Album";
//
// AlbumTextBox
//
this.AlbumTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.AlbumTextBox.Location = new System.Drawing.Point(12, 86);
this.AlbumTextBox.Name = "AlbumTextBox";
this.AlbumTextBox.Size = new System.Drawing.Size(210, 20);
this.AlbumTextBox.TabIndex = 3;
this.AlbumTextBox.KeyDown += TextBox_KeyDown;
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(12, 119);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(30, 13);
this.label3.TabIndex = 4;
this.label3.Text = "Artist";
//
// ArtistTextBox
//
this.ArtistTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.ArtistTextBox.Location = new System.Drawing.Point(12, 135);
this.ArtistTextBox.Name = "ArtistTextBox";
this.ArtistTextBox.Size = new System.Drawing.Size(210, 20);
this.ArtistTextBox.TabIndex = 5;
this.ArtistTextBox.KeyDown += TextBox_KeyDown;
//
// GenreTextBox
//
this.GenreTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.GenreTextBox.Location = new System.Drawing.Point(12, 187);
this.GenreTextBox.Name = "GenreTextBox";
this.GenreTextBox.Size = new System.Drawing.Size(210, 20);
this.GenreTextBox.TabIndex = 6;
this.GenreTextBox.KeyDown += TextBox_KeyDown;
//
// label4
//
this.label4.AutoSize = true;
this.label4.Location = new System.Drawing.Point(13, 168);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(36, 13);
this.label4.TabIndex = 7;
this.label4.Text = "Genre";
//
// SearchButton
//
this.SearchButton.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.SearchButton.Location = new System.Drawing.Point(12, 226);
this.SearchButton.Name = "SearchButton";
this.SearchButton.Size = new System.Drawing.Size(210, 23);
this.SearchButton.TabIndex = 8;
this.SearchButton.Text = "Search";
this.SearchButton.UseVisualStyleBackColor = true;
this.SearchButton.Click += new System.EventHandler(this.SearchButton_Click);
//
// AdvancedSearch
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(234, 261);
this.Controls.Add(this.SearchButton);
this.Controls.Add(this.label4);
this.Controls.Add(this.GenreTextBox);
this.Controls.Add(this.ArtistTextBox);
this.Controls.Add(this.label3);
this.Controls.Add(this.AlbumTextBox);
this.Controls.Add(this.label2);
this.Controls.Add(this.label1);
this.Controls.Add(this.SearchTermTextBox);
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.MaximumSize = new System.Drawing.Size(450, 300);
this.MinimumSize = new System.Drawing.Size(250, 300);
this.Name = "AdvancedSearch";
this.Text = "Advanced Search";
this.ResumeLayout(false);
this.PerformLayout();
}
private void TextBox_KeyDown(object sender, KeyEventArgs e)
{
if(e.KeyCode == Keys.Enter)
{
SearchButton_Click(sender, new System.EventArgs());
}
}
#endregion
private TextBox SearchTermTextBox;
private Label label1;
private Label label2;
private TextBox AlbumTextBox;
private Label label3;
private TextBox ArtistTextBox;
private TextBox GenreTextBox;
private Label label4;
private Button SearchButton;
}
}
+38
View File
@@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace MusicPlayer
{
public partial class AdvancedSearch : Form
{
private Main main;
public AdvancedSearch(Main main)
{
this.main = main;
InitializeComponent();
}
private void SearchButton_Click(object sender, EventArgs e)
{
if(SearchTermTextBox.Text.Length > 1)
{
SearchTermTextBox.ForeColor = Color.Black;
main.AdvancedSearchFilter(SearchTermTextBox.Text, AlbumTextBox.Text, ArtistTextBox.Text, GenreTextBox.Text);
this.Close();
}
else
{
SearchTermTextBox.ForeColor = Color.Red;
}
}
}
}
File diff suppressed because it is too large Load Diff
+34 -12
View File
@@ -17,7 +17,13 @@ namespace MusicPlayer
public AudioState AState { get; set; }
public BufferState BState { get; set; }
public int Buffered { get { return Math.Min((int)((bufpos / (double)LengthBuffer) * 1000), 1000); } }
public int Buffered { get
{
if(CurrentSong is RadioStation)
return Math.Min((int)((bufpos - ms.Position) / 1000), 1000);
else
return Math.Min((int)((bufpos / (double)LengthBuffer) * 1000), 1000);
} }
private long LengthBuffer { get; set; }
private long bufpos = 0;
@@ -33,7 +39,7 @@ namespace MusicPlayer
private long seek = 0;
private Stream ms;
private MemoryStream ms;
private Thread network;
private Thread audio;
@@ -55,7 +61,7 @@ namespace MusicPlayer
CurrentSong = null;
Thread.Sleep(11);
Thread.Sleep(10);
ms = new MemoryStream();
@@ -135,7 +141,10 @@ namespace MusicPlayer
waveOut.Init(blockAlignedStream);
waveOut.Play();
Length = CurrentSong.Seconds * waveOut.OutputWaveFormat.AverageBytesPerSecond;
if (CurrentSong.Seconds == 0)
Length = ms.Length / waveOut.OutputWaveFormat.AverageBytesPerSecond;
else
Length = CurrentSong.Seconds * waveOut.OutputWaveFormat.AverageBytesPerSecond;
CurrentTime = (int)(ms.Position / waveOut.OutputWaveFormat.AverageBytesPerSecond);
while (waveOut.PlaybackState != PlaybackState.Stopped)
@@ -164,10 +173,17 @@ namespace MusicPlayer
}
if (BState == BufferState.DONE && firstrun )
{
position = mp3fr.Position;
mp3fr.Close();
StreamFromMP3(ms,position, false);
break;
if( ! (CurrentSong is RadioStation))
{
position = mp3fr.Position;
mp3fr.Close();
StreamFromMP3(ms, position, false);
break;
}
else
{
AState = AudioState.STOPPED;
}
}
playpos = blockAlignedStream.Position;
@@ -175,7 +191,7 @@ namespace MusicPlayer
}
if(AState == AudioState.PLAYING)
if(AState == AudioState.PLAYING && !firstrun)
main.form.SongFinished();
AState = AudioState.STOPPED;
playpos = 0;
@@ -187,7 +203,14 @@ namespace MusicPlayer
private void PlayAudio()
{
AState = AudioState.WAITING;
while (ms.Length < 65536 * 10 && BState != BufferState.DONE)
int buffertime = 0;
if (CurrentSong is RadioStation)
buffertime = 32768 * 10;
else
buffertime = 65536 * 10;
while (ms.Length < buffertime && BState != BufferState.DONE)
Thread.Sleep(1000);
AState = AudioState.PLAYING;
@@ -218,7 +241,7 @@ namespace MusicPlayer
using (var stream = response.GetResponseStream())
{
byte[] buffer = new byte[65536]; // 64KB chunks
//byte[] buffer = new byte[65536*4]; // 256KB chunks
int read;
BState = BufferState.BUFFERING;
AState = AudioState.WAITING;
@@ -230,7 +253,6 @@ namespace MusicPlayer
ms.Write(buffer, 0, read);
ms.Position = pos;
this.bufpos = ms.Length;
}
}
@@ -0,0 +1,48 @@
namespace MusicPlayer
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.SuspendLayout();
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(284, 261);
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);
this.ResumeLayout(false);
}
#endregion
}
}
@@ -0,0 +1,39 @@
namespace MusicPlayer
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Text = "Form1";
}
#endregion
}
}
@@ -0,0 +1,48 @@
namespace MusicPlayer
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.SuspendLayout();
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(284, 261);
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);
this.ResumeLayout(false);
}
#endregion
}
}
@@ -0,0 +1,48 @@
namespace MusicPlayer
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.SuspendLayout();
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(284, 261);
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);
this.ResumeLayout(false);
}
#endregion
}
}
+98 -4
View File
@@ -5,6 +5,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Newtonsoft.Json.Linq;
namespace MusicPlayer
{
@@ -29,6 +30,8 @@ namespace MusicPlayer
this.api = api;
this.form = form;
form.main = this;
pl.main = this;
pl.Populate();
this.pl = pl;
audio = new AudioHandler(this);
@@ -77,15 +80,29 @@ namespace MusicPlayer
{
BackgroundWorker b = o as BackgroundWorker;
ImageList imagelist = new ImageList();
foreach (ListViewItem item in form.AlbumListView.Items)
List<string> templist = new List<string>();
Action action = () =>
{
imagelist.Images.Add(item.ToString(), api.getAlbumCover(item.Text));
foreach (ListViewItem item in form.AlbumListView.Items)
{
templist.Add(item.Text);
}
};
form.Invoke(action);
foreach (string item in templist)
{
imagelist.Images.Add(item, api.getAlbumCover(item));
}
Action action = () => {
action = () => {
imagelist.ImageSize = new System.Drawing.Size(64,64);
imagelist.ColorDepth = ColorDepth.Depth32Bit;
form.AlbumListView.View = View.LargeIcon;
form.AlbumListView.LargeImageList = imagelist;
foreach (ListViewItem item in form.AlbumListView.Items)
{
item.ImageKey = item.ToString();
item.ImageKey = item.Text;
}
};
form.Invoke(action);
@@ -114,6 +131,71 @@ namespace MusicPlayer
});
}
public void SearchFilter(string search)
{
table.Clear();
api.GetSongsBySearch(search).ForEach(s =>
{
table.Add(s);
});
}
public void AdvancedSearchFilter(string search, string album, string artist, string genre)
{
JObject o = api.GetAllBySearch(search, album, artist, genre);
if (o != null)
{
//q
form.AlbumListView.Items.Clear();
form.ArtistListBox.Items.Clear();
form.GenreListBox.Items.Clear();
form.PlaylistBox.Items.Clear();
table.Clear();
api.Songify(o).ForEach(s => table.Add(s));
//albums
api.Albumify(o).ForEach(a => form.AlbumListView.Items.Add(a.albumnaam));
//artists
api.Artistify(o).ForEach(a => form.ArtistListBox.Items.Add(a.naam));
//genres
api.Genrify(o).ForEach(g => form.GenreListBox.Items.Add(g.name));
BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += new DoWorkEventHandler(
delegate (object x, DoWorkEventArgs args)
{
BackgroundWorker b = x as BackgroundWorker;
ImageList imagelist = new ImageList();
List<string> templist = new List<string>();
Action action = () =>
{
foreach (ListViewItem item in form.AlbumListView.Items)
{
templist.Add(item.Text);
}
};
form.Invoke(action);
foreach (string item in templist)
{
imagelist.Images.Add(item, api.getAlbumCover(item));
}
action = () => {
form.AlbumListView.LargeImageList = imagelist;
foreach (ListViewItem item in form.AlbumListView.Items)
{
item.ImageKey = item.Text;
}
};
form.Invoke(action);
});
bw.RunWorkerAsync();
}
}
public void FilterCurrentPlaying()
{
table.Clear();
@@ -214,6 +296,18 @@ namespace MusicPlayer
return str;
}
public static bool CheckURLValid(string source)
{
Uri uriResult;
return Uri.TryCreate(source, UriKind.Absolute, out uriResult) && uriResult.Scheme == Uri.UriSchemeHttp;
}
public static string GetDomain(string url)
{
Uri uri = new Uri(url);
return uri.Host;
}
}
}
+222 -46
View File
@@ -31,7 +31,7 @@ namespace MusicPlayer
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle();
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle4 = new System.Windows.Forms.DataGridViewCellStyle();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
this.SongsTableView = new System.Windows.Forms.DataGridView();
this.GenreListBox = new System.Windows.Forms.ListBox();
@@ -52,13 +52,15 @@ namespace MusicPlayer
this.overviewToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.playlistsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator();
this.ViewCurrentPlaylistButton = new System.Windows.Forms.ToolStripMenuItem();
this.ViewQueueButton = new System.Windows.Forms.ToolStripMenuItem();
this.playbackToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.PlayNextSongButton = new System.Windows.Forms.ToolStripMenuItem();
this.LoopSongButton = new System.Windows.Forms.ToolStripMenuItem();
this.ShuffleSongButton = new System.Windows.Forms.ToolStripMenuItem();
this.playlistToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.makeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator6 = new System.Windows.Forms.ToolStripSeparator();
this.viewPlaylistToolstripMenuButton = new System.Windows.Forms.ToolStripMenuItem();
this.searchToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.SearchGenresToolStripLabel = new System.Windows.Forms.ToolStripMenuItem();
this.SearchGenresTextBox = new System.Windows.Forms.ToolStripTextBox();
@@ -66,10 +68,25 @@ namespace MusicPlayer
this.SearchArtistToolStripLabel = new System.Windows.Forms.ToolStripMenuItem();
this.SearchArtistsTextBox = new System.Windows.Forms.ToolStripTextBox();
this.ClearArtistSearchButton = new System.Windows.Forms.ToolStripMenuItem();
this.songsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.SearchSongsTextBox = new System.Windows.Forms.ToolStripTextBox();
this.SearchSongsButton = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator7 = new System.Windows.Forms.ToolStripSeparator();
this.AdvancedSearchButton = new System.Windows.Forms.ToolStripMenuItem();
this.serverToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.SelectServerJancoButton = new System.Windows.Forms.ToolStripMenuItem();
this.SelectServerYorickButton = new System.Windows.Forms.ToolStripMenuItem();
this.radioToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripMenuItem();
this.fMToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.slamFMToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.qDanceToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator();
this.customToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.RadioStationTextBox = new System.Windows.Forms.ToolStripTextBox();
this.SetRadioStationButton = new System.Windows.Forms.ToolStripMenuItem();
this.ControlsPanel = new System.Windows.Forms.Panel();
this.pictureBox1 = new System.Windows.Forms.PictureBox();
this.NextButton = new System.Windows.Forms.Button();
this.PreviousButton = new System.Windows.Forms.Button();
this.CurrentSongLabel = new System.Windows.Forms.Label();
@@ -93,6 +110,7 @@ namespace MusicPlayer
this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator();
this.NotifyMenuStripNextButton = new System.Windows.Forms.ToolStripMenuItem();
this.NotifyMenuStripPreviousButton = new System.Windows.Forms.ToolStripMenuItem();
this.resetToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
((System.ComponentModel.ISupportInitialize)(this.SongsTableView)).BeginInit();
this.MainPanel.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.SplitContainer)).BeginInit();
@@ -101,6 +119,7 @@ namespace MusicPlayer
this.SplitContainer.SuspendLayout();
this.MenuStrip.SuspendLayout();
this.ControlsPanel.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.PositionTrackBar)).BeginInit();
this.NotifyMenuStrip.SuspendLayout();
this.SuspendLayout();
@@ -112,14 +131,14 @@ namespace MusicPlayer
this.SongsTableView.AllowUserToResizeRows = false;
this.SongsTableView.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.Fill;
this.SongsTableView.BackgroundColor = System.Drawing.SystemColors.Control;
dataGridViewCellStyle1.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
dataGridViewCellStyle1.BackColor = System.Drawing.SystemColors.ControlLight;
dataGridViewCellStyle1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
dataGridViewCellStyle1.ForeColor = System.Drawing.SystemColors.WindowText;
dataGridViewCellStyle1.SelectionBackColor = System.Drawing.SystemColors.Highlight;
dataGridViewCellStyle1.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
dataGridViewCellStyle1.WrapMode = System.Windows.Forms.DataGridViewTriState.True;
this.SongsTableView.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle1;
dataGridViewCellStyle4.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
dataGridViewCellStyle4.BackColor = System.Drawing.SystemColors.ControlLight;
dataGridViewCellStyle4.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
dataGridViewCellStyle4.ForeColor = System.Drawing.SystemColors.WindowText;
dataGridViewCellStyle4.SelectionBackColor = System.Drawing.SystemColors.Highlight;
dataGridViewCellStyle4.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
dataGridViewCellStyle4.WrapMode = System.Windows.Forms.DataGridViewTriState.True;
this.SongsTableView.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle4;
this.SongsTableView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.SongsTableView.Dock = System.Windows.Forms.DockStyle.Fill;
this.SongsTableView.Location = new System.Drawing.Point(0, 0);
@@ -144,7 +163,7 @@ namespace MusicPlayer
this.GenreListBox.FormattingEnabled = true;
this.GenreListBox.Location = new System.Drawing.Point(0, 0);
this.GenreListBox.Name = "GenreListBox";
this.GenreListBox.Size = new System.Drawing.Size(150, 121);
this.GenreListBox.Size = new System.Drawing.Size(175, 121);
this.GenreListBox.Sorted = true;
this.GenreListBox.TabIndex = 1;
this.GenreListBox.SelectedIndexChanged += new System.EventHandler(this.GenreListBox_SelectedIndexChanged);
@@ -155,13 +174,13 @@ namespace MusicPlayer
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.AlbumListView.BackColor = System.Drawing.SystemColors.Control;
this.AlbumListView.Location = new System.Drawing.Point(312, 0);
this.AlbumListView.Location = new System.Drawing.Point(362, 0);
this.AlbumListView.MultiSelect = false;
this.AlbumListView.Name = "AlbumListView";
this.AlbumListView.Size = new System.Drawing.Size(448, 121);
this.AlbumListView.Size = new System.Drawing.Size(398, 121);
this.AlbumListView.Sorting = System.Windows.Forms.SortOrder.Ascending;
this.AlbumListView.TabIndex = 2;
this.AlbumListView.TileSize = new System.Drawing.Size(140, 30);
this.AlbumListView.TileSize = new System.Drawing.Size(185, 30);
this.AlbumListView.UseCompatibleStateImageBehavior = false;
this.AlbumListView.View = System.Windows.Forms.View.Tile;
this.AlbumListView.SelectedIndexChanged += new System.EventHandler(this.AlbumListView_SelectedIndexChanged);
@@ -172,9 +191,9 @@ namespace MusicPlayer
| System.Windows.Forms.AnchorStyles.Left)));
this.ArtistListBox.BackColor = System.Drawing.SystemColors.Control;
this.ArtistListBox.FormattingEnabled = true;
this.ArtistListBox.Location = new System.Drawing.Point(156, 0);
this.ArtistListBox.Location = new System.Drawing.Point(181, 0);
this.ArtistListBox.Name = "ArtistListBox";
this.ArtistListBox.Size = new System.Drawing.Size(150, 121);
this.ArtistListBox.Size = new System.Drawing.Size(175, 121);
this.ArtistListBox.Sorted = true;
this.ArtistListBox.TabIndex = 3;
this.ArtistListBox.SelectedIndexChanged += new System.EventHandler(this.ArtistListBox_SelectedIndexChanged);
@@ -234,7 +253,7 @@ namespace MusicPlayer
// AlbumListLabel
//
this.AlbumListLabel.AutoSize = true;
this.AlbumListLabel.Location = new System.Drawing.Point(321, 8);
this.AlbumListLabel.Location = new System.Drawing.Point(371, 9);
this.AlbumListLabel.Name = "AlbumListLabel";
this.AlbumListLabel.Size = new System.Drawing.Size(36, 13);
this.AlbumListLabel.TabIndex = 6;
@@ -243,7 +262,7 @@ namespace MusicPlayer
// ArtistListLabel
//
this.ArtistListLabel.AutoSize = true;
this.ArtistListLabel.Location = new System.Drawing.Point(165, 8);
this.ArtistListLabel.Location = new System.Drawing.Point(190, 9);
this.ArtistListLabel.Name = "ArtistListLabel";
this.ArtistListLabel.Size = new System.Drawing.Size(30, 13);
this.ArtistListLabel.TabIndex = 5;
@@ -252,7 +271,7 @@ namespace MusicPlayer
// GenreListLabel
//
this.GenreListLabel.AutoSize = true;
this.GenreListLabel.Location = new System.Drawing.Point(9, 8);
this.GenreListLabel.Location = new System.Drawing.Point(9, 9);
this.GenreListLabel.Name = "GenreListLabel";
this.GenreListLabel.Size = new System.Drawing.Size(36, 13);
this.GenreListLabel.TabIndex = 4;
@@ -270,14 +289,15 @@ namespace MusicPlayer
//
// MenuStrip
//
this.MenuStrip.BackColor = System.Drawing.SystemColors.WindowFrame;
this.MenuStrip.BackColor = System.Drawing.SystemColors.GrayText;
this.MenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.fileToolStripMenuItem,
this.viewToolStripMenuItem,
this.playbackToolStripMenuItem,
this.playlistToolStripMenuItem,
this.searchToolStripMenuItem,
this.serverToolStripMenuItem});
this.serverToolStripMenuItem,
this.radioToolStripMenuItem});
this.MenuStrip.Location = new System.Drawing.Point(0, 0);
this.MenuStrip.Name = "MenuStrip";
this.MenuStrip.Size = new System.Drawing.Size(784, 24);
@@ -311,7 +331,7 @@ namespace MusicPlayer
this.overviewToolStripMenuItem,
this.playlistsToolStripMenuItem,
this.toolStripSeparator4,
this.ViewCurrentPlaylistButton});
this.ViewQueueButton});
this.viewToolStripMenuItem.Name = "viewToolStripMenuItem";
this.viewToolStripMenuItem.Size = new System.Drawing.Size(44, 20);
this.viewToolStripMenuItem.Text = "View";
@@ -319,28 +339,28 @@ namespace MusicPlayer
// overviewToolStripMenuItem
//
this.overviewToolStripMenuItem.Name = "overviewToolStripMenuItem";
this.overviewToolStripMenuItem.Size = new System.Drawing.Size(154, 22);
this.overviewToolStripMenuItem.Size = new System.Drawing.Size(123, 22);
this.overviewToolStripMenuItem.Text = "Overview";
this.overviewToolStripMenuItem.Click += new System.EventHandler(this.overviewToolStripMenuItem_Click);
//
// playlistsToolStripMenuItem
//
this.playlistsToolStripMenuItem.Name = "playlistsToolStripMenuItem";
this.playlistsToolStripMenuItem.Size = new System.Drawing.Size(154, 22);
this.playlistsToolStripMenuItem.Size = new System.Drawing.Size(123, 22);
this.playlistsToolStripMenuItem.Text = "Playlists";
this.playlistsToolStripMenuItem.Click += new System.EventHandler(this.playlistsToolStripMenuItem_Click);
//
// toolStripSeparator4
//
this.toolStripSeparator4.Name = "toolStripSeparator4";
this.toolStripSeparator4.Size = new System.Drawing.Size(151, 6);
this.toolStripSeparator4.Size = new System.Drawing.Size(120, 6);
//
// ViewCurrentPlaylistButton
// ViewQueueButton
//
this.ViewCurrentPlaylistButton.Name = "ViewCurrentPlaylistButton";
this.ViewCurrentPlaylistButton.Size = new System.Drawing.Size(154, 22);
this.ViewCurrentPlaylistButton.Text = "Current Playlist";
this.ViewCurrentPlaylistButton.Click += new System.EventHandler(this.ViewCurrentPlaylistButton_Click);
this.ViewQueueButton.Name = "ViewQueueButton";
this.ViewQueueButton.Size = new System.Drawing.Size(123, 22);
this.ViewQueueButton.Text = "Queue";
this.ViewQueueButton.Click += new System.EventHandler(this.ViewCurrentPlaylistButton_Click);
//
// playbackToolStripMenuItem
//
@@ -381,7 +401,9 @@ namespace MusicPlayer
// playlistToolStripMenuItem
//
this.playlistToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.makeToolStripMenuItem});
this.makeToolStripMenuItem,
this.toolStripSeparator6,
this.viewPlaylistToolstripMenuButton});
this.playlistToolStripMenuItem.Name = "playlistToolStripMenuItem";
this.playlistToolStripMenuItem.Size = new System.Drawing.Size(56, 20);
this.playlistToolStripMenuItem.Text = "Playlist";
@@ -393,11 +415,27 @@ namespace MusicPlayer
this.makeToolStripMenuItem.Text = "Create / Edit";
this.makeToolStripMenuItem.Click += new System.EventHandler(this.makeToolStripMenuItem_Click);
//
// toolStripSeparator6
//
this.toolStripSeparator6.Name = "toolStripSeparator6";
this.toolStripSeparator6.Size = new System.Drawing.Size(136, 6);
//
// viewPlaylistToolstripMenuButton
//
this.viewPlaylistToolstripMenuButton.Name = "viewPlaylistToolstripMenuButton";
this.viewPlaylistToolstripMenuButton.Size = new System.Drawing.Size(139, 22);
this.viewPlaylistToolstripMenuButton.Text = "View";
this.viewPlaylistToolstripMenuButton.Click += new System.EventHandler(this.playlistsToolStripMenuItem_Click);
//
// searchToolStripMenuItem
//
this.searchToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.SearchGenresToolStripLabel,
this.SearchArtistToolStripLabel});
this.SearchArtistToolStripLabel,
this.songsToolStripMenuItem,
this.toolStripSeparator7,
this.AdvancedSearchButton,
this.resetToolStripMenuItem});
this.searchToolStripMenuItem.Name = "searchToolStripMenuItem";
this.searchToolStripMenuItem.Size = new System.Drawing.Size(54, 20);
this.searchToolStripMenuItem.Text = "Search";
@@ -408,7 +446,7 @@ namespace MusicPlayer
this.SearchGenresTextBox,
this.ClearGenreSearchButton});
this.SearchGenresToolStripLabel.Name = "SearchGenresToolStripLabel";
this.SearchGenresToolStripLabel.Size = new System.Drawing.Size(110, 22);
this.SearchGenresToolStripLabel.Size = new System.Drawing.Size(127, 22);
this.SearchGenresToolStripLabel.Text = "Genres";
//
// SearchGenresTextBox
@@ -431,7 +469,7 @@ namespace MusicPlayer
this.SearchArtistsTextBox,
this.ClearArtistSearchButton});
this.SearchArtistToolStripLabel.Name = "SearchArtistToolStripLabel";
this.SearchArtistToolStripLabel.Size = new System.Drawing.Size(110, 22);
this.SearchArtistToolStripLabel.Size = new System.Drawing.Size(127, 22);
this.SearchArtistToolStripLabel.Text = "Artists";
//
// SearchArtistsTextBox
@@ -448,6 +486,40 @@ namespace MusicPlayer
this.ClearArtistSearchButton.Text = "Clear Search";
this.ClearArtistSearchButton.Click += new System.EventHandler(this.ClearArtistSearchButton_Click);
//
// songsToolStripMenuItem
//
this.songsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.SearchSongsTextBox,
this.SearchSongsButton});
this.songsToolStripMenuItem.Name = "songsToolStripMenuItem";
this.songsToolStripMenuItem.Size = new System.Drawing.Size(127, 22);
this.songsToolStripMenuItem.Text = "Songs";
//
// SearchSongsTextBox
//
this.SearchSongsTextBox.Name = "SearchSongsTextBox";
this.SearchSongsTextBox.Size = new System.Drawing.Size(100, 23);
//
// SearchSongsButton
//
this.SearchSongsButton.Enabled = false;
this.SearchSongsButton.Name = "SearchSongsButton";
this.SearchSongsButton.Size = new System.Drawing.Size(160, 22);
this.SearchSongsButton.Text = "Search";
this.SearchSongsButton.Click += new System.EventHandler(this.SearchSongsButton_Click);
//
// toolStripSeparator7
//
this.toolStripSeparator7.Name = "toolStripSeparator7";
this.toolStripSeparator7.Size = new System.Drawing.Size(124, 6);
//
// AdvancedSearchButton
//
this.AdvancedSearchButton.Name = "AdvancedSearchButton";
this.AdvancedSearchButton.Size = new System.Drawing.Size(127, 22);
this.AdvancedSearchButton.Text = "Advanced";
this.AdvancedSearchButton.Click += new System.EventHandler(this.AdvancedSearchButton_Click);
//
// serverToolStripMenuItem
//
this.serverToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
@@ -471,9 +543,77 @@ namespace MusicPlayer
this.SelectServerYorickButton.Text = "imegumii.nl";
this.SelectServerYorickButton.Click += new System.EventHandler(this.SelectServerYorickButton_Click);
//
// radioToolStripMenuItem
//
this.radioToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.toolStripMenuItem2,
this.fMToolStripMenuItem,
this.slamFMToolStripMenuItem,
this.qDanceToolStripMenuItem,
this.toolStripSeparator5,
this.customToolStripMenuItem});
this.radioToolStripMenuItem.Name = "radioToolStripMenuItem";
this.radioToolStripMenuItem.Size = new System.Drawing.Size(49, 20);
this.radioToolStripMenuItem.Text = "Radio";
//
// toolStripMenuItem2
//
this.toolStripMenuItem2.Name = "toolStripMenuItem2";
this.toolStripMenuItem2.Size = new System.Drawing.Size(122, 22);
this.toolStripMenuItem2.Text = "538";
this.toolStripMenuItem2.Click += new System.EventHandler(this.toolStripMenuItem2_Click);
//
// fMToolStripMenuItem
//
this.fMToolStripMenuItem.Name = "fMToolStripMenuItem";
this.fMToolStripMenuItem.Size = new System.Drawing.Size(122, 22);
this.fMToolStripMenuItem.Text = "3FM";
this.fMToolStripMenuItem.Click += new System.EventHandler(this.fMToolStripMenuItem_Click);
//
// slamFMToolStripMenuItem
//
this.slamFMToolStripMenuItem.Name = "slamFMToolStripMenuItem";
this.slamFMToolStripMenuItem.Size = new System.Drawing.Size(122, 22);
this.slamFMToolStripMenuItem.Text = "Slam-FM";
this.slamFMToolStripMenuItem.Click += new System.EventHandler(this.slamFMToolStripMenuItem_Click);
//
// qDanceToolStripMenuItem
//
this.qDanceToolStripMenuItem.Name = "qDanceToolStripMenuItem";
this.qDanceToolStripMenuItem.Size = new System.Drawing.Size(122, 22);
this.qDanceToolStripMenuItem.Text = "Q-Dance";
this.qDanceToolStripMenuItem.Click += new System.EventHandler(this.qDanceToolStripMenuItem_Click);
//
// toolStripSeparator5
//
this.toolStripSeparator5.Name = "toolStripSeparator5";
this.toolStripSeparator5.Size = new System.Drawing.Size(119, 6);
//
// customToolStripMenuItem
//
this.customToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.RadioStationTextBox,
this.SetRadioStationButton});
this.customToolStripMenuItem.Name = "customToolStripMenuItem";
this.customToolStripMenuItem.Size = new System.Drawing.Size(122, 22);
this.customToolStripMenuItem.Text = "Custom";
//
// RadioStationTextBox
//
this.RadioStationTextBox.Name = "RadioStationTextBox";
this.RadioStationTextBox.Size = new System.Drawing.Size(100, 23);
//
// SetRadioStationButton
//
this.SetRadioStationButton.Name = "SetRadioStationButton";
this.SetRadioStationButton.Size = new System.Drawing.Size(160, 22);
this.SetRadioStationButton.Text = "Set";
this.SetRadioStationButton.Click += new System.EventHandler(this.SetRadioStationButton_Click);
//
// ControlsPanel
//
this.ControlsPanel.BackColor = System.Drawing.SystemColors.WindowFrame;
this.ControlsPanel.BackColor = System.Drawing.SystemColors.GrayText;
this.ControlsPanel.Controls.Add(this.pictureBox1);
this.ControlsPanel.Controls.Add(this.NextButton);
this.ControlsPanel.Controls.Add(this.PreviousButton);
this.ControlsPanel.Controls.Add(this.CurrentSongLabel);
@@ -491,9 +631,19 @@ namespace MusicPlayer
this.ControlsPanel.Size = new System.Drawing.Size(784, 83);
this.ControlsPanel.TabIndex = 4;
//
// pictureBox1
//
this.pictureBox1.BackColor = System.Drawing.SystemColors.Control;
this.pictureBox1.Location = new System.Drawing.Point(5, 5);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(72, 72);
this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
this.pictureBox1.TabIndex = 14;
this.pictureBox1.TabStop = false;
//
// NextButton
//
this.NextButton.Location = new System.Drawing.Point(214, 51);
this.NextButton.Location = new System.Drawing.Point(295, 54);
this.NextButton.Name = "NextButton";
this.NextButton.Size = new System.Drawing.Size(31, 23);
this.NextButton.TabIndex = 13;
@@ -503,7 +653,7 @@ namespace MusicPlayer
//
// PreviousButton
//
this.PreviousButton.Location = new System.Drawing.Point(177, 51);
this.PreviousButton.Location = new System.Drawing.Point(258, 54);
this.PreviousButton.Name = "PreviousButton";
this.PreviousButton.Size = new System.Drawing.Size(31, 23);
this.PreviousButton.TabIndex = 12;
@@ -514,7 +664,7 @@ namespace MusicPlayer
// CurrentSongLabel
//
this.CurrentSongLabel.AutoSize = true;
this.CurrentSongLabel.Location = new System.Drawing.Point(256, 56);
this.CurrentSongLabel.Location = new System.Drawing.Point(338, 59);
this.CurrentSongLabel.Name = "CurrentSongLabel";
this.CurrentSongLabel.Size = new System.Drawing.Size(111, 13);
this.CurrentSongLabel.TabIndex = 11;
@@ -533,7 +683,7 @@ namespace MusicPlayer
// LabelCurrentTime
//
this.LabelCurrentTime.AutoSize = true;
this.LabelCurrentTime.Location = new System.Drawing.Point(12, 26);
this.LabelCurrentTime.Location = new System.Drawing.Point(93, 29);
this.LabelCurrentTime.Name = "LabelCurrentTime";
this.LabelCurrentTime.Size = new System.Drawing.Size(49, 13);
this.LabelCurrentTime.TabIndex = 8;
@@ -544,10 +694,10 @@ namespace MusicPlayer
this.PositionTrackBar.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.PositionTrackBar.Enabled = false;
this.PositionTrackBar.Location = new System.Drawing.Point(3, 3);
this.PositionTrackBar.Location = new System.Drawing.Point(83, 3);
this.PositionTrackBar.Maximum = 1000;
this.PositionTrackBar.Name = "PositionTrackBar";
this.PositionTrackBar.Size = new System.Drawing.Size(778, 45);
this.PositionTrackBar.Size = new System.Drawing.Size(698, 45);
this.PositionTrackBar.TabIndex = 7;
this.PositionTrackBar.TickStyle = System.Windows.Forms.TickStyle.None;
this.PositionTrackBar.MouseDown += new System.Windows.Forms.MouseEventHandler(this.PositionTrackBar_MouseDown);
@@ -573,7 +723,7 @@ namespace MusicPlayer
// StopButton
//
this.StopButton.Enabled = false;
this.StopButton.Location = new System.Drawing.Point(122, 51);
this.StopButton.Location = new System.Drawing.Point(203, 54);
this.StopButton.Name = "StopButton";
this.StopButton.Size = new System.Drawing.Size(49, 23);
this.StopButton.TabIndex = 2;
@@ -584,7 +734,7 @@ namespace MusicPlayer
// PauseButton
//
this.PauseButton.Enabled = false;
this.PauseButton.Location = new System.Drawing.Point(67, 51);
this.PauseButton.Location = new System.Drawing.Point(148, 54);
this.PauseButton.Name = "PauseButton";
this.PauseButton.Size = new System.Drawing.Size(49, 23);
this.PauseButton.TabIndex = 1;
@@ -594,7 +744,7 @@ namespace MusicPlayer
//
// PlayButton
//
this.PlayButton.Location = new System.Drawing.Point(12, 51);
this.PlayButton.Location = new System.Drawing.Point(93, 54);
this.PlayButton.Name = "PlayButton";
this.PlayButton.Size = new System.Drawing.Size(49, 23);
this.PlayButton.TabIndex = 0;
@@ -611,7 +761,7 @@ namespace MusicPlayer
//
this.NotifyIcon.ContextMenuStrip = this.NotifyMenuStrip;
this.NotifyIcon.Icon = ((System.Drawing.Icon)(resources.GetObject("NotifyIcon.Icon")));
this.NotifyIcon.Text = "NotifyIcon";
this.NotifyIcon.Text = "YJMPD Music Player";
this.NotifyIcon.Visible = true;
this.NotifyIcon.MouseUp += new System.Windows.Forms.MouseEventHandler(this.NotifyIcon_Click);
//
@@ -693,6 +843,13 @@ namespace MusicPlayer
this.NotifyMenuStripPreviousButton.Text = "Previous";
this.NotifyMenuStripPreviousButton.Click += new System.EventHandler(this.NotifyMenuStripPreviousButton_Click);
//
// resetToolStripMenuItem
//
this.resetToolStripMenuItem.Name = "resetToolStripMenuItem";
this.resetToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
this.resetToolStripMenuItem.Text = "Reset";
this.resetToolStripMenuItem.Click += new System.EventHandler(this.resetToolStripMenuItem_Click);
//
// MainForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@@ -719,6 +876,7 @@ namespace MusicPlayer
this.MenuStrip.PerformLayout();
this.ControlsPanel.ResumeLayout(false);
this.ControlsPanel.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.PositionTrackBar)).EndInit();
this.NotifyMenuStrip.ResumeLayout(false);
this.ResumeLayout(false);
@@ -784,10 +942,28 @@ namespace MusicPlayer
private System.Windows.Forms.ToolStripMenuItem NotifyMenuStripNextButton;
private System.Windows.Forms.ToolStripMenuItem NotifyMenuStripPreviousButton;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator4;
private System.Windows.Forms.ToolStripMenuItem ViewCurrentPlaylistButton;
private System.Windows.Forms.ToolStripMenuItem ViewQueueButton;
private System.Windows.Forms.ToolStripMenuItem serverToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem SelectServerJancoButton;
private System.Windows.Forms.ToolStripMenuItem SelectServerYorickButton;
private System.Windows.Forms.ToolStripMenuItem radioToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem2;
private System.Windows.Forms.ToolStripMenuItem qDanceToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem customToolStripMenuItem;
private System.Windows.Forms.ToolStripTextBox RadioStationTextBox;
private System.Windows.Forms.ToolStripMenuItem SetRadioStationButton;
private System.Windows.Forms.ToolStripMenuItem fMToolStripMenuItem;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator5;
private System.Windows.Forms.ToolStripMenuItem slamFMToolStripMenuItem;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator6;
private System.Windows.Forms.ToolStripMenuItem viewPlaylistToolstripMenuButton;
private System.Windows.Forms.ToolStripMenuItem songsToolStripMenuItem;
private System.Windows.Forms.ToolStripTextBox SearchSongsTextBox;
private System.Windows.Forms.ToolStripMenuItem SearchSongsButton;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator7;
private System.Windows.Forms.ToolStripMenuItem AdvancedSearchButton;
private System.Windows.Forms.ToolStripMenuItem resetToolStripMenuItem;
private System.Windows.Forms.PictureBox pictureBox1;
}
}
+99 -19
View File
@@ -92,7 +92,8 @@ namespace MusicPlayer
PositionTrackBar.Value = Math.Max(main.audio.Position, 0);
//Buffer display
BufferBar.Value = main.audio.Buffered / 10;
if(main.audio.Buffered / 10 >= BufferBar.Minimum && main.audio.Buffered / 10 <= BufferBar.Maximum)
BufferBar.Value = main.audio.Buffered / 10;
//Time labels
if (!clicked)
@@ -109,8 +110,15 @@ namespace MusicPlayer
CurrentSongLabel.Text = "Currently playing: " + main.audio.CurrentSong.Name;
}
//Buttons and context menu
if (main.audio.AState == AudioHandler.AudioState.PLAYING)
//image box
if (AlbumListView.LargeImageList != null && main.audio.CurrentSong != null)
{
//Console.WriteLine(AlbumListView.LargeImageList.Images["Get Wet"]);
pictureBox1.Image = AlbumListView.LargeImageList.Images[main.audio.CurrentSong.Album];
}
//Buttons and context menu
if (main.audio.AState == AudioHandler.AudioState.PLAYING)
{
PlayButton.Enabled = false;
NotifyMenuStripPlayButton.Enabled = false;
@@ -136,6 +144,11 @@ namespace MusicPlayer
else
SelectServerYorickButton.Enabled = true;
if (SearchSongsTextBox.Text.Length == 0)
SearchSongsButton.Enabled = false;
else
SearchSongsButton.Enabled = true;
if (main.audio.AState == AudioHandler.AudioState.PAUSED)
{
PauseButton.Enabled = false;
@@ -166,6 +179,11 @@ namespace MusicPlayer
NotifyMenuStripStopButton.Enabled = true;
}
if (RadioStationTextBox.Text.Length <= 10)
SetRadioStationButton.Enabled = false;
else
SetRadioStationButton.Enabled = true;
if(PlayNextSongButton.Checked)
{
ShuffleSongButton.Enabled = true;
@@ -185,32 +203,42 @@ namespace MusicPlayer
}
else
{
NextButton.Enabled = true;
NotifyMenuStripNextButton.Enabled = true;
if (ShuffleSongButton.Checked)
if (main.audio.CurrentSong is RadioStation)
{
PreviousButton.Enabled = false;
NotifyMenuStripPreviousButton.Enabled = false;
main.currentPlayingList.Clear();
}
else
{
PreviousButton.Enabled = true;
NotifyMenuStripPreviousButton.Enabled = true;
NextButton.Enabled = true;
NotifyMenuStripNextButton.Enabled = true;
if (ShuffleSongButton.Checked)
{
PreviousButton.Enabled = false;
NotifyMenuStripPreviousButton.Enabled = false;
}
else
{
PreviousButton.Enabled = true;
NotifyMenuStripPreviousButton.Enabled = true;
}
}
}
if (songFinished)
{
Thread.Sleep(20);
if (! (main.audio.CurrentSong is RadioStation) )
{
Thread.Sleep(20);
if (PlayNextSongButton.Checked)
{
NextButton_Click(this, new EventArgs());
}
else if (LoopSongButton.Checked)
{
main.audio.Play(main.audio.CurrentSong);
if (PlayNextSongButton.Checked)
{
NextButton_Click(this, new EventArgs());
}
else if (LoopSongButton.Checked)
{
main.audio.Play(main.audio.CurrentSong);
}
}
songFinished = false;
@@ -522,5 +550,57 @@ namespace MusicPlayer
{
main.SwitchServer("http://imegumii.nl");
}
private void toolStripMenuItem2_Click(object sender, EventArgs e)
{
main.audio.Play(new RadioStation("538", main.api, "http://vip-icecast.538.lw.triple-it.nl:80/RADIO538_MP3"));
}
private void qDanceToolStripMenuItem_Click(object sender, EventArgs e)
{
main.audio.Play(new RadioStation("Q-Dance", main.api, "http://stream01.platform02.true.nl:8000/qdance-hard"));
}
private void fMToolStripMenuItem_Click(object sender, EventArgs e)
{
main.audio.Play(new RadioStation("3FM", main.api, "http://icecast.omroep.nl:80/3fm-bb-mp3"));
}
private void slamFMToolStripMenuItem_Click(object sender, EventArgs e)
{
main.audio.Play(new RadioStation("Slam-FM", main.api, "http://vip-icecast.538.lw.triple-it.nl/SLAMFM_MP3"));
}
private void SetRadioStationButton_Click(object sender, EventArgs e)
{
string input = RadioStationTextBox.Text;
if(Main.CheckURLValid(input))
{
main.audio.Play(new RadioStation(Main.GetDomain(input), main.api, input));
}
RadioStationTextBox.Text = "";
}
private void SearchSongsButton_Click(object sender, EventArgs e)
{
if(SearchSongsTextBox.Text.Length > 0)
{
main.SearchFilter(SearchSongsTextBox.Text);
SearchSongsTextBox.Text = "";
}
}
private void AdvancedSearchButton_Click(object sender, EventArgs e)
{
AdvancedSearch av = new AdvancedSearch(main);
av.ShowDialog();
}
private void resetToolStripMenuItem_Click(object sender, EventArgs e)
{
main.Repopulate();
}
}
}
@@ -77,6 +77,12 @@
<Compile Include="NetworkHandler.cs" />
<Compile Include="Playlist.cs" />
<Compile Include="PlaylistHandler.cs" />
<Compile Include="AdvancedSearch.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="AdvancedSearch.Designer.cs">
<DependentUpon>AdvancedSearch.cs</DependentUpon>
</Compile>
<Compile Include="PlaylistMaker.cs">
<SubType>Form</SubType>
</Compile>
@@ -85,6 +91,7 @@
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="RadioStation.cs" />
<Compile Include="Song.cs" />
<Compile Include="SongsTable.cs">
<SubType>Component</SubType>
@@ -93,6 +100,9 @@
<EmbeddedResource Include="MainForm.resx">
<DependentUpon>MainForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="AdvancedSearch.resx">
<DependentUpon>AdvancedSearch.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="PlaylistMaker.resx">
<DependentUpon>PlaylistMaker.cs</DependentUpon>
</EmbeddedResource>
@@ -0,0 +1,99 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{E2B99339-3251-48BE-91C9-FAB21CD07A39}</ProjectGuid>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>MusicPlayer</RootNamespace>
<AssemblyName>MusicPlayer</AssemblyName>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="MainForm.cs" >
<SubType>Form</SubType>
</Compile>
<Compile Include="Album.cs" />
<Compile Include="APIHandler.cs" />
<Compile Include="Artist.cs" />
<Compile Include="MainForm.Designer.cs">
<DependentUpon>MainForm.cs</DependentUpon>
</Compile>
<Compile Include="NetworkHandler.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<<<<<<< HEAD
<EmbeddedResource Include="MainForm.resx">
<DependentUpon>MainForm.cs</DependentUpon>
=======
<EmbeddedResource Include="Form1.resx">
<DependentUpon>Form1.cs</DependentUpon>
>>>>>>> origin/api
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
+32 -18
View File
@@ -24,33 +24,47 @@ namespace MusicPlayer
public JObject SendString(string m)
{
string encodedstring = Microsoft.Security.Application.Encoder.HtmlEncode(m);
Console.WriteLine(encodedstring);
HttpWebRequest server = (HttpWebRequest)WebRequest.Create(ip+":"+port+"/"+encodedstring);
server.KeepAlive = false;
HttpWebResponse respond = (HttpWebResponse)server.GetResponse();
Stream streamResponse = respond.GetResponseStream();
StreamReader streamRead = new StreamReader(streamResponse);
Char[] readBuff = new Char[256];
int count = streamRead.Read(readBuff, 0, 256);
string data = "";
while (count > 0)
{
String outputData = new String(readBuff, 0, count);
data +=outputData;
count = streamRead.Read(readBuff, 0, 256);
try {
HttpWebResponse respond = (HttpWebResponse)server.GetResponse();
Stream streamResponse = respond.GetResponseStream();
StreamReader streamRead = new StreamReader(streamResponse);
Char[] readBuff = new Char[256];
int count = streamRead.Read(readBuff, 0, 256);
string data = "";
while (count > 0)
{
String outputData = new String(readBuff, 0, count);
data += outputData;
count = streamRead.Read(readBuff, 0, 256);
}
JObject o = JObject.Parse(data);
respond.Close();
streamResponse.Close();
streamRead.Close();
return o;
}
JObject o = JObject.Parse(data);
respond.Close();
streamResponse.Close();
streamRead.Close();
return o;
catch(WebException e)
{
Console.WriteLine("Server is offline");
}
catch(Exception e)
{
Console.WriteLine("Er is iets fout gegaan bij het communiceren met de server.");
}
return null;
}
public MemoryStream downloadArtwork(string album)
{
try
{
WebRequest req = WebRequest.Create((ip + "/music/artwork/"+album).Replace(" ", "%20"));
string encodedstring = Microsoft.Security.Application.Encoder.HtmlEncode(ip + "/music/.artwork/" + album);
WebRequest req = WebRequest.Create(encodedstring);
//WebRequest req = WebRequest.Create((ip + "/music/.artwork/" + album).Replace(" ","%20"));
WebResponse response = req.GetResponse();
Stream stream = response.GetResponseStream();
+24 -1
View File
@@ -9,14 +9,16 @@ namespace MusicPlayer
public string name { get; }
private string basedir;
public List<Song> songs;
public string server;
private APIHandler api;
public Playlist(string name, string basedir, APIHandler api)
public Playlist(string name, string basedir, string server, APIHandler api)
{
this.songs = new List<Song>();
this.name = name;
this.api = api;
this.basedir = basedir;
this.server = server;
this.ReadFromFile();
}
@@ -35,6 +37,8 @@ namespace MusicPlayer
try {
using (StreamReader str = new StreamReader(basedir + name + ".txt"))
{
server = str.ReadLine();
string readline;
while ((readline = str.ReadLine()) != null)
{
@@ -48,6 +52,7 @@ namespace MusicPlayer
{
FileStream fs = new FileStream(basedir + name + ".txt", FileMode.CreateNew);
fs.Close();
File.WriteAllText(basedir + name + ".txt", server);
ReadFromFile();
}
@@ -57,6 +62,8 @@ namespace MusicPlayer
{
using (StreamWriter stw = new StreamWriter(basedir + name + ".txt"))
{
stw.WriteLine(server.ToString());
this.songs.ForEach(s =>
{
stw.WriteLine(s.ToString());
@@ -64,5 +71,21 @@ namespace MusicPlayer
stw.Flush();
}
}
public void Delete()
{
try {
System.IO.File.Move(basedir + name + ".txt", basedir + name + ".txt.old");
}
catch(Exception)
{
//Already removed.
}
}
internal void RemoveSong(Song s)
{
this.songs.Remove(s);
}
}
}
+32 -8
View File
@@ -8,23 +8,26 @@ namespace MusicPlayer
public class PlaylistHandler
{
private List<Playlist> playlists;
private APIHandler api;
public Main main
{
get; set;
}
private readonly string basedir = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\\.mpplaylists\\";
public PlaylistHandler(APIHandler api)
public PlaylistHandler()
{
this.playlists = new List<Playlist>();
this.api = api;
Populate();
}
private void Populate()
public void Populate()
{
playlists.Clear();
try {
Directory.GetFiles(basedir).ToList().ForEach(f =>
{
if (f.EndsWith(".txt"))
{
playlists.Add(new Playlist(Path.GetFileName(f.Replace(".txt","")) ,basedir, api));
playlists.Add(new Playlist(Path.GetFileName(f.Replace(".txt","")) ,basedir, main.nw.ip, main.api));
}
});
}
@@ -39,7 +42,7 @@ namespace MusicPlayer
public void MakeNewPlaylistByName(string name)
{
playlists.Add(new Playlist(name, basedir, api));
playlists.Add(new Playlist(name, basedir, main.nw.ip, main.api));
}
public Playlist GetPlaylistByName(string name)
@@ -54,7 +57,28 @@ namespace MusicPlayer
public List<Playlist> GetPlaylists()
{
return playlists;
List<Playlist> currentPlaylists = new List<Playlist>();
foreach(Playlist pl in playlists)
{
if (pl.server == main.nw.ip)
currentPlaylists.Add(pl);
}
return currentPlaylists;
}
internal void RemovePlaylistByName(string name)
{
Playlist toRemove = null;
playlists.ForEach(p =>
{
if (p.name == name) { toRemove = p; }
});
if(toRemove != null)
{
toRemove.Delete();
playlists.Remove(toRemove);
}
}
}
}
+31 -2
View File
@@ -43,6 +43,8 @@ namespace MusicPlayer
this.label4 = new System.Windows.Forms.Label();
this.FilterTextBox = new System.Windows.Forms.TextBox();
this.label5 = new System.Windows.Forms.Label();
this.DeletePlaylistButton = new System.Windows.Forms.Button();
this.DeleteSongsButton = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// PlaylistSelectBox
@@ -87,6 +89,7 @@ namespace MusicPlayer
this.PlaylistSongContainer.FormattingEnabled = true;
this.PlaylistSongContainer.Location = new System.Drawing.Point(10, 319);
this.PlaylistSongContainer.Name = "PlaylistSongContainer";
this.PlaylistSongContainer.SelectionMode = System.Windows.Forms.SelectionMode.MultiExtended;
this.PlaylistSongContainer.Size = new System.Drawing.Size(306, 82);
this.PlaylistSongContainer.TabIndex = 3;
//
@@ -123,7 +126,7 @@ namespace MusicPlayer
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(10, 80);
this.label2.Location = new System.Drawing.Point(8, 75);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(97, 13);
this.label2.TabIndex = 7;
@@ -133,7 +136,7 @@ namespace MusicPlayer
//
this.label3.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(7, 303);
this.label3.Location = new System.Drawing.Point(11, 297);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(82, 13);
this.label3.TabIndex = 8;
@@ -165,11 +168,35 @@ namespace MusicPlayer
this.label5.TabIndex = 11;
this.label5.Text = "Filter";
//
// DeletePlaylistButton
//
this.DeletePlaylistButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.DeletePlaylistButton.Location = new System.Drawing.Point(225, 70);
this.DeletePlaylistButton.Name = "DeletePlaylistButton";
this.DeletePlaylistButton.Size = new System.Drawing.Size(92, 23);
this.DeletePlaylistButton.TabIndex = 12;
this.DeletePlaylistButton.Text = "Delete Playlist";
this.DeletePlaylistButton.UseVisualStyleBackColor = true;
this.DeletePlaylistButton.Click += new System.EventHandler(this.DeletePlaylistButton_Click);
//
// DeleteSongsButton
//
this.DeleteSongsButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.DeleteSongsButton.Location = new System.Drawing.Point(172, 292);
this.DeleteSongsButton.Name = "DeleteSongsButton";
this.DeleteSongsButton.Size = new System.Drawing.Size(143, 23);
this.DeleteSongsButton.TabIndex = 13;
this.DeleteSongsButton.Text = "Delete Selected Songs";
this.DeleteSongsButton.UseVisualStyleBackColor = true;
this.DeleteSongsButton.Click += new System.EventHandler(this.DeleteSongsButton_Click);
//
// PlaylistMaker
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(334, 411);
this.Controls.Add(this.DeleteSongsButton);
this.Controls.Add(this.DeletePlaylistButton);
this.Controls.Add(this.label5);
this.Controls.Add(this.FilterTextBox);
this.Controls.Add(this.label4);
@@ -206,5 +233,7 @@ namespace MusicPlayer
private Label label4;
private TextBox FilterTextBox;
private Label label5;
private Button DeletePlaylistButton;
private Button DeleteSongsButton;
}
}
+39 -1
View File
@@ -47,12 +47,17 @@ namespace MusicPlayer
PlaylistSelectBox.SelectedIndex = PlaylistSelectBox.Items.Count - 1;
else
PlaylistSelectBox.SelectedIndex = selection;
PlaylistSongContainer.Items.Clear();
if (PlaylistSelectBox.SelectedItem != null)
{
PlaylistSongContainer.Items.Clear();
allPlaylistSongs = pl.GetPlaylistByName(PlaylistSelectBox.SelectedItem.ToString()).GetSongs();
allPlaylistSongs.ForEach(s => PlaylistSongContainer.Items.Add(s.Name));
}
else
{
PlaylistSelectBox.SelectedIndex = -1;
PlaylistSelectBox.Text = "";
}
}
public void Repopulate()
@@ -145,5 +150,38 @@ namespace MusicPlayer
PlaylistNewButton_Click(sender, new EventArgs());
}
}
private void DeletePlaylistButton_Click(object sender, EventArgs e)
{
if (PlaylistSelectBox.SelectedItem != null)
if (MessageBox.Show("Are you sure to delete " + PlaylistSelectBox.SelectedItem.ToString() + "?", "Confirm Delete!", MessageBoxButtons.YesNo) == DialogResult.Yes)
{
pl.RemovePlaylistByName(PlaylistSelectBox.SelectedItem.ToString());
Repopulate(true);
}
}
private void DeleteSongsButton_Click(object sender, EventArgs e)
{
if (PlaylistSelectBox.SelectedItem != null)
{
Playlist currentPlaylist = pl.GetPlaylistByName(PlaylistSelectBox.SelectedItem.ToString());
foreach (string song in PlaylistSongSelector.SelectedItems)
{
for (int i = currentPlaylist.GetSongs().Count - 1; i > 0; i--)
{
Song s = currentPlaylist.GetSongs()[i];
if (s.Name == song)
{
currentPlaylist.RemoveSong(s);
break;
}
}
}
currentPlaylist.WriteToFile();
}
Thread.Sleep(10);
Repopulate();
}
}
}
+2 -3
View File
@@ -17,11 +17,10 @@ namespace MusicPlayer
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
NetworkHandler nw = new NetworkHandler("http://jancokock.me");
//NetworkHandler nw = new NetworkHandler("http://imegumii.nl");
NetworkHandler nw = new NetworkHandler("http://imegumii.nl");
APIHandler api = new APIHandler(nw);
MainForm form = new MainForm();
PlaylistHandler pl = new PlaylistHandler(api);
PlaylistHandler pl = new PlaylistHandler();
new Main(nw, api, form,pl);
Application.Run(form);
+23
View File
@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MusicPlayer
{
class RadioStation :Song
{
string radiourl;
public RadioStation(string name, APIHandler api, string url):base("-1", name,"","","",0,api)
{
radiourl = url;
}
protected override string GetURL()
{
return radiourl;
}
}
}
Executable → Regular
+25 -1
View File
@@ -34,7 +34,7 @@ namespace MusicPlayer
url = "";
}
private string GetURL()
protected virtual string GetURL()
{
if (url == "")
{
@@ -53,5 +53,29 @@ namespace MusicPlayer
{
return $"{this.SongID}|{this.Name}|{this.Album}|{this.Artist}|{this.Genre}|{this.Seconds}";
}
public override bool Equals(System.Object obj)
{
// If parameter is null return false.
if (obj == null)
{
return false;
}
// If parameter cannot be cast to Point return false.
Song s = obj as Song;
if ((System.Object)s == null)
{
return false;
}
// Return true if the fields match:
return (s.Name == Name) && (s.SongID == SongID);
}
public override int GetHashCode()
{
return int.Parse(this.SongID);
}
}
}
+2 -2
View File
@@ -12,9 +12,9 @@ namespace MusicPlayer
public SongsTable() : base()
{
this.Columns.Clear();
this.Columns.Add("Naam", typeof(string));
this.Columns.Add("Name", typeof(string));
this.Columns.Add("Album", typeof(string));
this.Columns.Add("Artiest", typeof(string));
this.Columns.Add("Artist", typeof(string));
this.Columns.Add("Genre", typeof(string));
this.Columns.Add("Duration", typeof(string));
this.Columns.Add("song", typeof(Song));
-16
View File
@@ -1,16 +0,0 @@
[HTTP]
port = 8585
[Daemon]
port = 17170
[Library]
musicdir = /media/USBHDD/shares/Music/English
jancodir = /mnt/Muziek/
[Database]
username = yjmpd
password = qLjStxr6xncrfcna
host = imegumii.nl
database = yjmpd
port = 3306
-3
View File
@@ -1,3 +0,0 @@
configparser
mutagen
PyMySQL
-72
View File
@@ -1,72 +0,0 @@
import sys
import os
import configparser
from yjdaemon.yjmpd import YJMPD
from yjdaemon.HTTPServer import HTTPServerThread
from yjdaemon.Database import Database
from yjdaemon.libraryscanner import LibraryScanner
debug = True
config = configparser.ConfigParser()
try:
config.read("config.cfg")
HTTP_PORT = int(config.get("HTTP", "port"))
DAEMON_PORT = int(config.get("Daemon","port"))
MUSIC_DIR = str(config.get("Library", "musicdir"))
DB_USERNAME = config.get("Database", "username")
DB_PASSWORD = config.get("Database", "password")
DB_HOST = config.get("Database", "host")
DB_DATABASE = config.get("Database", "database")
DB_PORT = config.getint("Database", "port")
except Exception as e:
print(e.with_traceback())
sys.exit(1)
class MainDaemon(YJMPD):
def run(self):
HTTP_thread = HTTPServerThread(HTTP_PORT)
HTTP_thread.start()
def Test():
print("Test")
# socket_thread = ServiceSocket(DAEMON_PORT)
# socket_thread.start()
#HTTP_thread = HTTPServerThread(HTTP_PORT)
#HTTP_thread.start()
db = Database(DB_USERNAME, DB_PASSWORD, DB_HOST, DB_PORT, DB_DATABASE)
LibraryScanner(db, MUSIC_DIR)
if debug:
Test()
else:
if __name__ == "__main__":
username = os.getenv('USER')
if None == username:
dir = "/tmp/.pydaemon.pid"
else:
dir = "/home/" + username + "/.pydaemon.pid"
daemon = MainDaemon(dir, MUSIC_DIR)
if len(sys.argv) == 2:
if 'start' == sys.argv[1]:
daemon.start()
elif 'stop' == sys.argv[1]:
daemon.stop()
elif 'restart' == sys.argv[1]:
daemon.restart()
elif 'status' == sys.argv[1]:
daemon.status()
else:
print("Unknown command")
sys.exit(2)
sys.exit(0)
else:
print("usage: %s start|stop|status|restart" % sys.argv[0])
sys.exit(2)
-72
View File
@@ -1,72 +0,0 @@
import sys
import os
import configparser
from yjdaemon.yjmpd import YJMPD
from yjdaemon.HTTPServer import HTTPServerThread
from yjdaemon.Database import Database
from yjdaemon.libraryscanner import LibraryScanner
debug = True
config = configparser.ConfigParser()
try:
config.read("config.cfg")
HTTP_PORT = int(config.get("HTTP", "port"))
DAEMON_PORT = int(config.get("Daemon","port"))
MUSIC_DIR = str(config.get("Library", "musicdir"))
DB_USERNAME = config.get("Database", "username")
DB_PASSWORD = config.get("Database", "password")
DB_HOST = config.get("Database", "host")
DB_DATABASE = config.get("Database", "database")
DB_PORT = config.getint("Database", "port")
except Exception as e:
print(e.with_traceback())
sys.exit(1)
class MainDaemon(YJMPD):
def run(self):
HTTP_thread = HTTPServerThread(HTTP_PORT)
HTTP_thread.start()
def Test():
print("Test")
# socket_thread = ServiceSocket(DAEMON_PORT)
# socket_thread.start()
HTTP_thread = HTTPServerThread(HTTP_PORT)
HTTP_thread.start()
#db = Database(DB_USERNAME, DB_PASSWORD, DB_HOST, DB_PORT, DB_DATABASE)
#LibraryScanner(db, MUSIC_DIR)
if debug:
Test()
else:
if __name__ == "__main__":
username = os.getenv('USER')
if None == username:
dir = "/tmp/.pydaemon.pid"
else:
dir = "/home/" + username + "/.pydaemon.pid"
daemon = MainDaemon(dir, MUSIC_DIR)
if len(sys.argv) == 2:
if 'start' == sys.argv[1]:
daemon.start()
elif 'stop' == sys.argv[1]:
daemon.stop()
elif 'restart' == sys.argv[1]:
daemon.restart()
elif 'status' == sys.argv[1]:
daemon.status()
else:
print("Unknown command")
sys.exit(2)
sys.exit(0)
else:
print("usage: %s start|stop|status|restart" % sys.argv[0])
sys.exit(2)
-169
View File
@@ -1,169 +0,0 @@
import json
from yjdaemon.Database import Database as db
import configparser
import string
"""
Add a key to the validAPIcalls dictionary, with a corresponding function
Function should return jsonified data, so that it can then be passed on to the client.
example:
Add this to the dictionary
"getsongs": calls.getsongs
then implement this function
@staticmethod
def getsongs():
return calls.jsonify({"song": song})
And the jsonified data will be returned to the client.
Every function MUST return jsonified data!
"""
class calls:
@staticmethod
def APIcall(sanitizedpath):
if sanitizedpath in validAPIcalls:
return validAPIcalls[sanitizedpath]
else:
return None
@staticmethod
def getfromrawjson(data, param):
return calls.dejsonify(data)[param]
@staticmethod
def jsonify(data):
return json.dumps(data, sort_keys=True, indent=4).encode("utf-8")
@staticmethod
def dejsonify(rawdata):
return json.loads(rawdata.decode("utf-8"))
@staticmethod
def getallsongs(args):
return calls.jsonify({"songs": db.executequerystatic("SELECT * FROM tracks;"), "args": args , "result": "OK"})
@staticmethod
def getartists(args):
return calls.jsonify({"artists": db.executequerystatic("SELECT artistName FROM tracks GROUP BY artistName;"), "args": args, "result" : "OK"})
@staticmethod
def getalbums(args):
return calls.jsonify({"albums": db.executequerystatic("SELECT albumName FROM tracks GROUP BY albumName;"), "args": args, "result":"OK"})
@staticmethod
def getgenres(args):
return calls.jsonify({"genres": db.executequerystatic("SELECT genre FROM tracks GROUP BY genre;"), "args": args, "result":"OK"})
@staticmethod
def getyears(args):
return calls.jsonify({"years": db.executequerystatic("SELECT year FROM tracks GROUP BY year;"), "args": args, "result":"OK"})
@staticmethod
def getalbumnames(args):
return calls.jsonify({"albumnames": db.executequerystatic("SELECT albumName FROM tracks GROUP BY albumName;"), "args": args})
@staticmethod
def search(args):
data = args.split("&")
genquery="""
SELECT $ident FROM tracks WHERE LCASE(trackName) LIKE LCASE(\"%$trackname%\") $orgenre LCASE(genre) LIKE LCASE(\"%$genre%\") $oralbum LCASE(albumName) LIKE LCASE(\"%$album%\") $orartist LCASE(artistName) LIKE LCASE(\"%$artistname%\") $end;
"""
query="""
SELECT $ident FROM tracks WHERE ($or1 OR $or2 OR $or3 ) $and1 $and2 $and3 $end;
"""
test = string.Template(query)
genqueryres = ""
arguments = []
general = ""
for entry in data:
values = entry.split("=")
values[1] = values[1].replace("%20"," ")
if values[0] == "q":
general = values[1]
continue
if values[1]:
arguments.append(values)
print(arguments)
finalstring = "" + genquery
for arg in arguments:
if arg[0] == "artist":
finalstring = string.Template(finalstring).safe_substitute(artistname=arg[1], orartist="AND")
test = string.Template(test.safe_substitute(and1="AND LCASE(artistName) LIKE LCASE(\"%"+ arg[1] +"%\")"))
elif arg[0] == "genre":
finalstring = string.Template(finalstring).safe_substitute(genre=arg[1],orgenre="AND")
test = string.Template(test.safe_substitute(and2="AND LCASE(genre) LIKE LCASE(\"%"+ arg[1] +"%\")"))
elif arg[0] == "album":
finalstring = string.Template(finalstring).safe_substitute(album=arg[1],oralbum="AND")
test = string.Template(test.safe_substitute(and3="AND LCASE(albumName) LIKE LCASE(\"%"+ arg[1] +"%\")"))
print(finalstring)
finalstring = string.Template(finalstring).safe_substitute(genre=general,artistname=general,album=general,trackname=general)
print(finalstring)
test = test.safe_substitute( and1="", and2="",and3="",or1="LCASE(artistName) LIKE LCASE(\"%"+general+"%\")",or2="LCASE(genre) LIKE LCASE(\"%"+general+"%\")",or3="LCASE(albumName) LIKE LCASE(\"%"+general+"%\")")
print(test)
print(string.Template(test).safe_substitute(ident="*",end=""))
return calls.jsonify({"result":"OK", "genres": db.executequerystatic(string.Template(test).safe_substitute(ident="genre",end="GROUP BY genre")),"artists": db.executequerystatic(string.Template(test).safe_substitute(ident="artistName",end="GROUP BY artistName")), "albums": db.executequerystatic(string.Template(test).safe_substitute(ident="albumName",end="GROUP BY albumName")), "songs" : db.executequerystatic(string.Template(test).safe_substitute(ident="*",end=""))})
@staticmethod
def getsongs(args):
"""Get song by album, genre, year, artist"""
data = args.partition("?")
splitstring = data[0].partition("=")
name= splitstring[0]
value = splitstring[2].replace("%20"," ")
if name == "album":
songs = db.executequerystatic("SELECT * FROM tracks WHERE albumName = \"" + value + "\"")
elif name == "genre":
songs = db.executequerystatic("SELECT * FROM tracks WHERE genre = \"" + value + "\"")
elif name == "year":
songs = db.executequerystatic("SELECT * FROM tracks WHERE year = \"" + value + "\"")
elif name == "artist":
songs = db.executequerystatic("SELECT * FROM tracks WHERE artistName = \"" + value + "\"")
elif name == "search":
songs = db.executequerystatic("SELECT * FROM tracks WHERE LCASE(trackName) LIKE LCASE(\"%"+ value + "%\") GROUP BY trackName")
else:
return calls.jsonify({"result":"NOK", "errormsg": "Not a valid argument"})
return calls.jsonify({"result":"OK","songs":songs})
@staticmethod
def getsongbyid(args):
config = configparser.ConfigParser()
try:
config.read("config.cfg")
musicdir = config.get("Library","musicdir")
port = config.get("HTTP","port")
except:
return calls.jsonify({"result" : "NOK" , "errormsg" : "I/O error while reading config."})
data = args.split("&")
splitsting = data[0].split("=")
id = splitsting[1]
file = db.executequerystatic(
"SELECT SUBSTRING_INDEX(trackUrl,'" + musicdir + "',-1) as filedir FROM `tracks` WHERE id = " + id)
try:
url = str(file[0][0])
except:
return calls.jsonify({"result": "NOK", "errormsg" : "Song ID does not exist in database."})
return calls.jsonify({"result": "OK", "songurl": "http://imegumii.nl:"+ "/music/English"+ url})
@staticmethod
def setsong(args, songname):
global song
song = songname
return calls.jsonify({"result": "OK", "args": args})
validAPIcalls = {"getallsongs": calls.getallsongs,
"setsong": calls.setsong,
"search": calls.search,
"getsongs": calls.getsongs,
"getsongbyid": calls.getsongbyid,
"getartists": calls.getartists,
"getalbums": calls.getalbums,
"getgenres": calls.getgenres,
"getyears": calls.getyears,
"getalbumnames": calls.getalbumnames
}
-81
View File
@@ -1,81 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import pymysql
import configparser
from threading import RLock as Lock
from warnings import filterwarnings
filterwarnings('ignore', category = pymysql.Warning)
class Database:
buffer = []
cout = 0
lock = Lock()
def __init__(self, DB_USERNAME, DB_PASSWORD, DB_HOST, DB_PORT, DB_DATABASE):
"""Init class """
self.cnx = pymysql.connect(user=DB_USERNAME, password=DB_PASSWORD, host=DB_HOST, database=DB_DATABASE, port=DB_PORT, charset='utf8')
self.cursor = self.cnx.cursor()
def executeQuery(self, query):
try:
self.cursor.execute(query)
self.cnx.commit()
return self.cursor.fetchall()
except pymysql.ProgrammingError as e:
print(e)
print(query)
@staticmethod
def executequerystatic(query):
config = configparser.ConfigParser()
try:
config.read("config.cfg")
DB_USERNAME = config.get("Database", "username")
DB_PASSWORD = config.get("Database", "password")
DB_HOST = config.get("Database", "host")
DB_DATABASE = config.get("Database", "database")
DB_PORT = config.getint("Database", "port")
except Exception as e:
print(e)
cnx = pymysql.connect(user=DB_USERNAME, password=DB_PASSWORD, host=DB_HOST, database=DB_DATABASE, port=DB_PORT)
cursor = cnx.cursor()
if query != "":
cursor.execute(query)
cnx.commit()
return cursor.fetchall()
else:
return []
def turnoffautocommit(self):
self.cursor.execute("SET autocommit=0;")
self.cnx.commit()
def removeSong(self, path):
self.db.executeQuery("DELETE FROM `tracks` WHERE trackUrl = " + path.replace("'", '\\\''))
def updateInsertSong(self, genre, trackname, artistname, albumname, albumartist, tracknumber, year, duration, path): #notworking
self.db.executeQuery("INSERT INTO `tracks` (`genre`, `trackUrl`, `trackName`, `artistName`, `albumName`, `albumArtist`, `trackNumber`, `year`, `duration`) VALUES ('" + genre + b"','" + path.replace("'", '\\\'') + "','" + trackname + "','" + artistname + "','" + albumname + "','" + albumartist + "','" + tracknumber + "','" + year + "','0') " +
b" ON DUPLICATE KEY UPDATE `genre`=VALUES(`genre`) , `trackName` = VALUES(`trackName`) , `artistName` = VALUES(`artistName`) ,`albumName` = VALUES(`albumName`) , `albumArtist` = VALUES(`albumArtist`) , `trackNumber` = VALUES(`trackNumber`) , `year` = VALUES(`year`) , `duration` = VALUES(`duration`)")
def insertMultipleSongs(self, genre, trackname, artistname, albumname, albumartist, tracknumber, year, duration, path):
self.buffer.append([genre, trackname, artistname, albumname, albumartist, tracknumber, year, duration, path])
# Database.lock.acquire()
if len(self.buffer) > 50:
self.pushbuffer()
# Database.lock.release()
def pushbuffer(self):
query = ('INSERT INTO `tracks` (`genre`, `trackUrl`, `trackName`, `artistName`, `albumName`, `albumArtist`, `trackNumber`, `year`, `duration`) VALUES ')
for song in self.buffer:
query += "("
for field in song:
query += "'" + field + "',"
query = query[:-1]
query += "),"
query = query[:-1]
query += " ON DUPLICATE KEY UPDATE `genre`=VALUES(`genre`) , `trackName` = VALUES(`trackName`) , `artistName` = VALUES(`artistName`) ,`albumName` = VALUES(`albumName`) , `albumArtist` = VALUES(`albumArtist`) , `trackNumber` = VALUES(`trackNumber`) , `year` = VALUES(`year`) , `duration` = VALUES(`duration`);"
self.executeQuery(query)
del self.buffer[:]
-82
View File
@@ -1,82 +0,0 @@
#!/usr/bin/env python3
import http.server
import socketserver
import threading
import html
import yjdaemon.API as API
"""
HTTP request handler.
"""
class HTTPServerThread(threading.Thread):
def __init__(self, PORT):
threading.Thread.__init__(self)
self.PORT = PORT
def run(self):
Handler = HTTPHandler
socketserver.TCPServer.allow_reuse_address = True
httpd = socketserver.TCPServer(("", self.PORT), Handler)
httpd.serve_forever()
"""
REST API
"""
class HTTPHandler(http.server.SimpleHTTPRequestHandler):
def send_message(self, status, content_type, data):
self.send_response(status)
self.send_header("Content-type:", content_type)
self.end_headers()
self.wfile.write(data)
self.wfile.write("\n".encode("utf-8"))
def do_GET(self):
""" Serve a GET request. """
path = html.unescape(self.path)
path = str(path).lstrip("/").split("?")[0]
retval = API.calls.APIcall(path)
if retval is not None: # if call is valid API function
try:
args = str(html.unescape(self.path)).lstrip("/").split("?")[1]
except IndexError as e:
print(e)
self.send_message(403, "application/json", API.calls.jsonify({"error": "Missing parameters."}))
return
self.send_message(200, "application/json", retval(args))
else: # else parse as normal HTTP request
f = self.send_head()
if f:
try:
self.copyfile(f, self.wfile)
finally:
f.close()
def do_POST(self):
""" Serve a POST request. """
path = html.unescape(self.path)
path = str(path).lstrip("/").split("?")[0]
retval = API.calls.APIcall(path)
if retval is not None: # if call is valid API function
try:
args = str(html.unescape(self.path)).lstrip("/").split("?")[1] #if no args
except IndexError as e:
print(e)
self.send_message(403, "application/json", API.calls.jsonify({"error": "Missing parameters."}))
return
if self.headers["Content-Type"] == 'application/json': # if data is json data
length = int(self.headers["Content-Length"])
rawdata = self.rfile.read(length)
result = retval(args, API.calls.getfromrawjson(rawdata, "data"))
self.send_message(200, "application/json", result)
else: # if not json data
self.send_message(422, "application/json", API.calls.jsonify({"error": "Not JSON data."}))
else: # if not API function
self.send_message(403, "application/json", API.calls.jsonify({"error": "Not an API function"}))
-36
View File
@@ -1,36 +0,0 @@
import socket
import threading
endline = "\r\n"
class ServiceSocket(threading.Thread):
def __init__(self, PORT):
threading.Thread.__init__(self)
self.PORT = PORT
def run(self):
self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.s.bind(("", self.PORT))
self.s.listen(1)
while 1:
conn, addr = self.s.accept()
ClientHandler(conn).start()
class ClientHandler(threading.Thread):
def __init__(self,conn):
threading.Thread.__init__(self)
self.conn = conn
def run(self):
while 1:
data = self.conn.recv(1024)
if not data:
break
else:
datastring = data.decode('utf-8', "ignore").rstrip(endline).lower()
print(datastring)
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
-78
View File
@@ -1,78 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from mutagen.easyid3 import EasyID3
from mutagen.mp3 import MP3
import mutagen._util
import os
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
class LibraryScanner:
def __init__(self, Database, librarypath):
"""Init class """
self.url = librarypath
self.db = Database
self.scanRecursif()
ob = Observer()
ob.schedule(Filehandler(self), self.url, recursive=True)
ob.start()
def scanRecursif(self):
print("Scanning library "+self.url+" recursively...")
# musicdirs = [os.path.join(self.url,o) for o in os.listdir(self.url) if os.path.isdir(os.path.join(self.url,o))]
self.db.turnoffautocommit()
for root, directories, filenames in os.walk(self.url):
self.scandir(filenames,root)
def scandir(self,filenames, root):
for filename in filenames:
if filename.lower().endswith(('.mp3')):
path = os.path.join(root,filename)
try:
print(path, end='\r')
id3 = EasyID3(path)
audio = MP3(path)
print(audio.info.length)
self.db.insertMultipleSongs(self.getValue(id3, "genre"),path.replace("'", '\\\''),self.getValue(id3, "title"),self.getValue(id3, "artist"),self.getValue(id3, "album"),self.getValue(id3, "performer"),self.getValue(id3, "tracknumber"),self.getValue(id3, "date"),str(audio.info.length))
except (mutagen.id3._util.ID3NoHeaderError):
print("Error reading ID3 tag", end='\r')
def insertSong(self, path):
try:
id3 = EasyID3(path)
self.db.executeQuery(b"INSERT INTO `tracks` (`genre`, `trackUrl`, `trackName`, `artistName`, `albumName`, `albumArtist`, `trackNumber`, `year`, `duration`) VALUES ('" + self.getValue(id3,"genre") + b"'," + b"'" + path.replace("'", '\\\'').encode('utf8') + b"'," + b"'" + self.getValue(id3, "title") + b"'," + b"'" + self.getValue(id3, "artist") + b"'," + b"'" + self.getValue(id3, "album") + b"'," + b"'" + self.getValue(id3, "performer") + b"'," + b"'" + self.getValue(id3, "tracknumber") + b"'," + b"'" + self.getValue(id3, "date") + b"'," + b"'0') " +
b" ON DUPLICATE KEY UPDATE `genre`=VALUES(`genre`) , `trackName` = VALUES(`trackName`) , `artistName` = VALUES(`artistName`) ,`albumName` = VALUES(`albumName`) , `albumArtist` = VALUES(`albumArtist`) , `trackNumber` = VALUES(`trackNumber`) , `year` = VALUES(`year`) , `duration` = VALUES(`duration`)")
except (mutagen.id3._util.ID3NoHeaderError):
pass
def removeSong(self,path):
self.db.removeSong(path)
def getValue(self, id3, value):
try:
return id3[value][0].replace("'", "\\'")
except (KeyError, IndexError, ValueError):
print("Error reading value of ID3 tag", end='\r')
return ""
class Filehandler(FileSystemEventHandler):
def __init__(self, LibraryScanner):
self.libscanner = LibraryScanner
def process(self, event):
if not(event.is_directory):
if os.path.isfile(event.src_path) and event.src_path.lower().endswith(('.mp3','.flac', 'm4a')):
self.libscanner.insertSong(event.src_path)
else:
self.libscanner.removeSong(event.src_path)
def on_modified(self, event):
self.process(event)
def on_created(self, event):
self.process(event)
-60
View File
@@ -1,60 +0,0 @@
import sys
import os
import configparser
from yjdaemon.Database import Database
from yjdaemon.libraryscanner import LibraryScanner
from yjdaemon.yjmpd import YJMPD
from yjdaemon.HTTPServer import HTTPServerThread
debug = False
config = configparser.ConfigParser()
try:
config.read("../config.cfg")
HTTP_PORT = int(config.get("HTTP", "port"))
DAEMON_PORT = int(config.get("Daemon", "port"))
MUSIC_DIR = str(config.get("Library", "jancodir"))
DB_USERNAME = config.get("Database", "username")
DB_PASSWORD = config.get("Database", "password")
DB_HOST = config.get("Database", "host")
DB_DATABASE = config.get("Database", "database")
DB_PORT = config.getint("Database", "port")
except Exception as e:
print(e.with_traceback())
sys.exit(1)
class MainDaemon(YJMPD):
def run(self):
HTTP_thread = HTTPServerThread(HTTP_PORT)
HTTP_thread.start()
db = Database(DB_USERNAME, DB_PASSWORD, DB_HOST, DB_PORT, DB_DATABASE)
LibraryScanner(db, MUSIC_DIR)
if __name__ == "__main__":
username = os.getenv('USER')
if None == username:
dir = "/tmp/.pydaemon.pid"
else:
dir = "/home/" + username + "/.pydaemon.pid"
daemon = MainDaemon(dir, MUSIC_DIR)
if len(sys.argv) == 2:
if 'start' == sys.argv[1]:
daemon.start()
elif 'stop' == sys.argv[1]:
daemon.stop()
elif 'restart' == sys.argv[1]:
daemon.restart()
elif 'status' == sys.argv[1]:
daemon.status()
else:
print("Unknown command")
sys.exit(2)
sys.exit(0)
else:
print("usage: %s start|stop|status|restart" % sys.argv[0])
sys.exit(2)
-135
View File
@@ -1,135 +0,0 @@
import sys
import os
import time
import atexit
import signal
class YJMPD:
"""A generic yjdaemon class.
Usage: subclass the yjdaemon class and override the run() method."""
def __init__(self, pidfile, root):
self.pidfile = pidfile
self.root = root
def daemonize(self):
"""Deamonize class. UNIX double fork mechanism."""
try:
pid = os.fork()
if pid > 0:
# exit first parent
sys.exit(0)
except OSError as err:
sys.stderr.write('fork #1 failed: {0}\n'.format(err))
sys.exit(1)
# decouple from parent environment
os.chdir(self.root)
os.setsid()
os.umask(0)
# do second fork
try:
pid = os.fork()
if pid > 0:
# exit from second parent
sys.exit(0)
except OSError as err:
sys.stderr.write('fork #2 failed: {0}\n'.format(err))
sys.exit(1)
# redirect standard file descriptors
sys.stdout.flush()
sys.stderr.flush()
si = open(os.devnull, 'r')
so = open(os.devnull, 'a+')
se = open(os.devnull, 'a+')
os.dup2(si.fileno(), sys.stdin.fileno())
os.dup2(so.fileno(), sys.stdout.fileno())
os.dup2(se.fileno(), sys.stderr.fileno())
# write pidfile
atexit.register(self.delpid)
pid = str(os.getpid())
with open(self.pidfile, 'w+') as f:
f.write(pid + '\n')
def delpid(self):
os.remove(self.pidfile)
def start(self):
"""Start the yjdaemon."""
# Check for a pidfile to see if the yjdaemon already runs
try:
with open(self.pidfile, 'r') as pf:
pid = int(pf.read().strip())
except IOError:
pid = None
if pid:
message = "pidfile {0} already exist. " + \
"Daemon already running?\n"
sys.stderr.write(message.format(self.pidfile))
sys.exit(1)
# Start the yjdaemon
self.daemonize()
self.run()
def stop(self):
"""Stop the yjdaemon."""
# Get the pid from the pidfile
try:
with open(self.pidfile, 'r') as pf:
pid = int(pf.read().strip())
except IOError:
pid = None
if not pid:
message = "pidfile {0} does not exist. " + \
"Daemon not running?\n"
sys.stderr.write(message.format(self.pidfile))
return # not an error in a restart
# Try killing the yjdaemon process
try:
while 1:
os.kill(pid, signal.SIGTERM)
time.sleep(0.1)
except OSError as err:
e = str(err.args)
if e.find("No such process") > 0:
if os.path.exists(self.pidfile):
os.remove(self.pidfile)
else:
print(str(err.args))
sys.exit(1)
def restart(self):
"""Restart the yjdaemon."""
self.stop()
self.start()
def status(self):
"""Print out status."""
if os.path.exists(self.pidfile):
message = "Daemon running.\n"
else:
message = "Daemon not running.\n"
sys.stdout.write(message)
def run(self):
"""You should override this method when you subclass Daemon.
It will be called after the process has been daemonized by
start() or restart()."""
-64
View File
@@ -1,64 +0,0 @@
-- phpMyAdmin SQL Dump
-- version 4.3.8deb0.1
-- http://www.phpmyadmin.net
--
-- Host: localhost
-- Gegenereerd op: 27 sep 2015 om 22:19
-- Serverversie: 5.6.19-0ubuntu0.14.04.1
-- PHP-versie: 5.5.9-1ubuntu4.11
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
--
-- Database: `yjmpd`
--
-- --------------------------------------------------------
--
-- Tabelstructuur voor tabel `tracks`
--
CREATE TABLE IF NOT EXISTS `tracks` (
`id` int(11) NOT NULL,
`genre` varchar(100) DEFAULT NULL,
`trackUrl` varchar(200) NOT NULL,
`trackName` varchar(100) DEFAULT NULL,
`artistName` varchar(100) DEFAULT NULL,
`albumName` varchar(100) DEFAULT NULL,
`albumArtist` varchar(100) DEFAULT NULL,
`trackNumber` int(11) DEFAULT NULL,
`year` int(11) DEFAULT NULL,
`duration` time DEFAULT NULL,
`playCount` int(11) NOT NULL DEFAULT '0'
) ENGINE=InnoDB AUTO_INCREMENT=8135 DEFAULT CHARSET=latin1;
--
-- Indexen voor geëxporteerde tabellen
--
--
-- Indexen voor tabel `tracks`
--
ALTER TABLE `tracks`
ADD PRIMARY KEY (`id`), ADD UNIQUE KEY `trackUrl` (`trackUrl`);
--
-- AUTO_INCREMENT voor geëxporteerde tabellen
--
--
-- AUTO_INCREMENT voor een tabel `tracks`
--
ALTER TABLE `tracks`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=8135;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;