private int WaitForRevision(int currentRevision) { ContentNode revNode = ContentParser.Parse(bag, fetcher.Fetch("/update", "revision-number=" + currentRevision)); return((int)revNode.GetChild("dmap.serverrevision").Value); }
public void Login(string username, string password) { fetcher.Username = username; fetcher.Password = password; try { bag = ContentCodeBag.ParseCodes(fetcher.Fetch("/content-codes")); ContentNode node = ContentParser.Parse(bag, fetcher.Fetch("/login")); ParseSessionId(node); FetchDatabases(); Refresh(); if (serverInfo.SupportsUpdate) { updateRunning = true; Thread thread = new Thread(UpdateLoop); thread.Name = "DAAP"; thread.IsBackground = true; thread.Start(); } } catch (WebException e) { if (e.Response != null && (e.Response as HttpWebResponse).StatusCode == HttpStatusCode.Unauthorized) { throw new AuthenticationException("Username or password incorrect"); } else { throw new LoginException("Failed to login", e); } } catch (Exception e) { throw new LoginException("Failed to login", e); } }
public Client(IPAddress address, UInt16 port) { this.address = address; this.port = port; fetcher = new ContentFetcher(address, port); ContentNode node = ContentParser.Parse(ContentCodeBag.Default, fetcher.Fetch("/server-info")); serverInfo = ServerInfo.FromNode(node); }
public static ContentCodeBag ParseCodes(byte[] buffer) { ContentCodeBag bag = new ContentCodeBag(); // add some codes to bootstrap us bag.AddCode("mccr", "dmap.contentcodesresponse", ContentType.Container); bag.AddCode("mdcl", "dmap.dictionary", ContentType.Container); bag.AddCode("mcnm", "dmap.contentcodesnumber", ContentType.Long); bag.AddCode("mcna", "dmap.contentcodesname", ContentType.String); bag.AddCode("mcty", "dmap.contentcodestype", ContentType.Short); bag.AddCode("mstt", "dmap.status", ContentType.Long); // some photo-specific codes bag.AddCode("ppro", "dpap.protocolversion", ContentType.Long); bag.AddCode("pret", "dpap.blah", ContentType.Container); ContentNode node = ContentParser.Parse(bag, buffer); foreach (ContentNode dictNode in (node.Value as ContentNode[])) { if (dictNode.Name != "dmap.dictionary") { continue; } ContentCode code = new ContentCode(); foreach (ContentNode item in (dictNode.Value as ContentNode[])) { switch (item.Name) { case "dmap.contentcodesnumber": code.Number = (int)item.Value; break; case "dmap.contentcodesname": code.Name = (string)item.Value; break; case "dmap.contentcodestype": code.Type = (ContentType)Enum.ToObject(typeof(ContentType), (short)item.Value); break; } } bag.codes[code.Number] = code; } return(bag); }
private void RefreshTracks(string revquery) { byte[] tracksData = client.Fetcher.Fetch(String.Format("/databases/{0}/items", id), TrackQuery + "&" + revquery); ContentNode tracksNode = ContentParser.Parse(client.Bag, tracksData); if (IsUpdateResponse(tracksNode)) { return; } // handle track additions/changes foreach (ContentNode trackNode in (ContentNode[])tracksNode.GetChild("dmap.listing").Value) { Track track = Track.FromNode(trackNode); Track existing = LookupTrackById(track.Id); if (existing == null) { AddTrack(track); } else { existing.Update(track); } } if ((byte)tracksNode.GetChild("dmap.updatetype").Value == 1) { // handle track deletions ContentNode deleteList = tracksNode.GetChild("dmap.deletedidlisting"); if (deleteList != null) { foreach (ContentNode deleted in (ContentNode[])deleteList.Value) { Track track = LookupTrackById((int)deleted.Value); if (track != null) { RemoveTrack(track); } } } } }
private void FetchDatabases() { ContentNode dbnode = ContentParser.Parse(bag, fetcher.Fetch("/databases")); foreach (ContentNode child in (ContentNode[])dbnode.Value) { if (child.Name != "dmap.listing") { continue; } foreach (ContentNode item in (ContentNode[])child.Value) { Database db = new Database(this, item); databases.Add(db); } } }
private void RefreshPlaylists(string revquery) { byte[] playlistsData; try { playlistsData = client.Fetcher.Fetch(String.Format("/databases/{0}/containers", id), revquery); } catch (WebException) { return; } ContentNode playlistsNode = ContentParser.Parse(client.Bag, playlistsData); if (IsUpdateResponse(playlistsNode)) { return; } // handle playlist additions/changes List <int> plids = new List <int> (); foreach (ContentNode playlistNode in (ContentNode[])playlistsNode.GetChild("dmap.listing").Value) { Playlist pl = Playlist.FromNode(playlistNode); if (pl != null) { plids.Add(pl.Id); Playlist existing = LookupPlaylistById(pl.Id); if (existing == null) { AddPlaylist(pl); } else { existing.Update(pl); } } } // delete playlists that no longer exist foreach (Playlist pl in new List <Playlist> (playlists)) { if (!plids.Contains(pl.Id)) { RemovePlaylist(pl); } } plids = null; // add/remove tracks in the playlists foreach (Playlist pl in playlists) { byte [] playlistTracksData = client.Fetcher.Fetch(String.Format( "/databases/{0}/containers/{1}/items", id, pl.Id), String.Format("meta=dmap.itemid,dmap.containeritemid&{0}", revquery) ); ContentNode playlistTracksNode = ContentParser.Parse(client.Bag, playlistTracksData); if (IsUpdateResponse(playlistTracksNode)) { return; } if ((byte)playlistTracksNode.GetChild("dmap.updatetype").Value == 1) { // handle playlist track deletions ContentNode deleteList = playlistTracksNode.GetChild("dmap.deletedidlisting"); if (deleteList != null) { foreach (ContentNode deleted in (ContentNode[])deleteList.Value) { int index = pl.LookupIndexByContainerId((int)deleted.Value); if (index < 0) { continue; } pl.RemoveAt(index); } } } // add new tracks, or reorder existing ones int plindex = 0; foreach (ContentNode plTrackNode in (ContentNode[])playlistTracksNode.GetChild("dmap.listing").Value) { Track pltrack = null; int containerId = 0; Track.FromPlaylistNode(this, plTrackNode, out pltrack, out containerId); if (pl[plindex] != null && pl.GetContainerId(plindex) != containerId) { pl.RemoveAt(plindex); pl.InsertTrack(plindex, pltrack, containerId); } else if (pl[plindex] == null) { pl.InsertTrack(plindex, pltrack, containerId); } plindex++; } } }
private int GetCurrentRevision() { ContentNode revNode = ContentParser.Parse(bag, fetcher.Fetch("/update"), "dmap.serverrevision"); return((int)revNode.Value); }