Example #1
0
        private void RefreshAlbums(string revquery)
        {
            byte [] albums_data;

            try {
                albums_data = client.Fetcher.Fetch(String.Format("/databases/{0}/containers", id), "meta=dpap.aspectratio,dmap.itemid,dmap.itemname,dpap.imagefilename,dpap.imagefilesize,dpap.creationdate,dpap.imagepixelwidth,dpap.imagepixelheight,dpap.imageformat,dpap.imagerating,dpap.imagecomments,dpap.imagelargefilesize&type=photo");
            } catch (WebException) {
                return;
            }

            ContentNode albums_node = ContentParser.Parse(client.Bag, albums_data);

            // DEBUG data
            albums_node.Dump();
            Console.WriteLine("after dump!");

            if (IsUpdateResponse(albums_node))
            {
                return;
            }

            // handle album additions/changes
            ArrayList plids = new ArrayList();

            if (albums_node.GetChild("dmap.listing") == null)
            {
                return;
            }

            foreach (ContentNode albumNode in (ContentNode [])albums_node.GetChild("dmap.listing").Value)
            {
                // DEBUG
                Console.WriteLine("foreach loop");
                Album pl = Album.FromNode(albumNode);
                if (pl != null)
                {
                    plids.Add(pl.Id);
                    Album existing = LookupAlbumById(pl.Id);

                    if (existing == null)
                    {
                        AddAlbum(pl);
                    }
                    else
                    {
                        existing.Update(pl);
                    }
                }
            }
            // DEBUG
            Console.WriteLine("delete albums that don't exist");
            // delete albums that no longer exist
            foreach (Album pl in new List <Album> (albums))
            {
                if (!plids.Contains(pl.Id))
                {
                    RemoveAlbum(pl);
                }
            }

            plids = null;
            // DEBUG
            Console.WriteLine("Add/remove photos in the albums");
            // add/remove photos in the albums
            foreach (Album pl in albums)
            {
                byte [] album_photos_data = client.Fetcher.Fetch(String.Format("/databases/{0}/containers/{1}/items",
                                                                               id, pl.Id), "meta=dpap.aspectratio,dmap.itemid,dmap.itemname,dpap.imagefilename,dpap.imagefilesize,dpap.creationdate,dpap.imagepixelwidth,dpap.imagepixelheight,dpap.imageformat,dpap.imagerating,dpap.imagecomments,dpap.imagelargefilesize&type=photo");
                ContentNode album_photos_node = ContentParser.Parse(client.Bag, album_photos_data);

                if (IsUpdateResponse(album_photos_node))
                {
                    return;
                }

                if ((byte)album_photos_node.GetChild("dmap.updatetype").Value == 1)
                {
                    // handle album photo deletions
                    ContentNode delete_list = album_photos_node.GetChild("dmap.deletedidlisting");

                    if (delete_list != null)
                    {
                        foreach (ContentNode deleted in (ContentNode [])delete_list.Value)
                        {
                            int index = pl.LookupIndexByContainerId((int)deleted.Value);

                            if (index < 0)
                            {
                                continue;
                            }

                            pl.RemoveAt(index);
                        }
                    }
                }

                // add new photos, or reorder existing ones

                int plindex = 0;
                foreach (ContentNode pl_photo_node in (ContentNode [])album_photos_node.GetChild("dmap.listing").Value)
                {
                    Photo plphoto      = null;
                    int   container_id = 0;
                    Photo.FromAlbumNode(this, pl_photo_node, out plphoto, out container_id);

                    if (pl [plindex] != null && pl.GetContainerId(plindex) != container_id)
                    {
                        pl.RemoveAt(plindex);
                        pl.InsertPhoto(plindex, plphoto, container_id);
                    }
                    else if (pl [plindex] == null)
                    {
                        pl.InsertPhoto(plindex, plphoto, container_id);
                    }

                    plindex++;
                }
            }
        }
Example #2
0
        internal bool OnHandleRequest(Socket client, string username, string path, NameValueCollection query, int range)
        {
            string photoQuery;

            if (query ["query"] != null)
            {
                photoQuery = query ["query"];
            }
            else
            {
                photoQuery = "";
            }

            int session = 0;

            if (query ["session-id"] != null)
            {
                session = Int32.Parse(query ["session-id"]);
            }

/*            if (!sessions.ContainsKey (session) && path != "/server-info" && path != "/content-codes" &&
 *              path != "/login") {
 *              ws.WriteResponse (client, HttpStatusCode.Forbidden, "invalid session id");
 *              return true;
 *          }
 */
            if (session != 0)
            {
                sessions [session].LastActionTime = DateTime.Now;
            }

            int clientRev = 0;

            if (query ["revision-number"] != null)
            {
                clientRev = Int32.Parse(query ["revision-number"]);
            }

            int delta = 0;

            if (query ["delta"] != null)
            {
                delta = Int32.Parse(query ["delta"]);
            }
            // DEBUG data
            Console.WriteLine("Before returning resources for path " + path + ", meta " + query ["meta"] + " query " + photoQuery);
            if (dbItemsRegex.IsMatch(path))              //&& photoQuery.Length==0
            {
                Console.WriteLine("\tThis is a database/items request!");
            }

            if (path == "/server-info")
            {
                ws.WriteResponse(client, GetServerInfoNode());
            }
            else if (path == "/content-codes")
            {
                ws.WriteResponse(client, ContentCodeBag.Default.ToNode());
            }
            else if (path == "/login")
            {
                ExpireSessions();

                if (maxUsers > 0 && sessions.Count + 1 > maxUsers)
                {
                    ws.WriteResponse(client, HttpStatusCode.ServiceUnavailable, "too many users");
                    return(true);
                }

                session = random.Next();
                User user = new User(DateTime.Now, (client.RemoteEndPoint as IPEndPoint).Address, username);

                lock (sessions) {
                    sessions [session] = user;
                }

                ws.WriteResponse(client, GetLoginNode(session));
                OnUserLogin(user);
            }
            else if (path == "/logout")
            {
                Console.WriteLine("logout!");
                User user = sessions [session];

                lock (sessions) {
                    sessions.Remove(session);
                }

                ws.WriteResponse(client, HttpStatusCode.OK, new byte [0]);
                OnUserLogout(user);

                return(false);
            }
            else if (path == "/databases")
            {
                Console.WriteLine("path==/databases");
                ws.WriteResponse(client, GetDatabasesNode());
            }
            else if (dbItemsRegex.IsMatch(path) && photoQuery.Length == 0)    //&& !dbPhotoRegex.IsMatch (query ["query"])) {
            {
                Console.WriteLine("dbItemsRegex, query=" + query ["query"] + " meta=" + query ["meta"]);
                int dbid = Int32.Parse(dbItemsRegex.Match(path).Groups [1].Value);

                Database curdb = revmgr.GetDatabase(clientRev, dbid);

                if (curdb == null)
                {
                    ws.WriteResponse(client, HttpStatusCode.BadRequest, "invalid database id");
                    return(true);
                }

                ArrayList deletedIds = new ArrayList();

                if (delta > 0)
                {
                    Database olddb = revmgr.GetDatabase(clientRev - delta, dbid);

                    if (olddb != null)
                    {
                        foreach (Photo photo in olddb.Photos)
                        {
                            if (curdb.LookupPhotoById(photo.Id) == null)
                            {
                                deletedIds.Add(photo.Id);
                            }
                        }
                    }
                }

                ContentNode node = curdb.ToPhotosNode(query ["meta"].Split(','),
                                                      (int [])deletedIds.ToArray(typeof(int)));
                ws.WriteResponse(client, node);
            }
            else if (dbPhotoRegex.IsMatch(photoQuery))
            {
                Console.WriteLine("dbPhotoRegex");
                Console.WriteLine("dbPhotosRegex, query=" + query ["query"] + " meta=" + query ["meta"]);
                string [] photoIds = query ["query"].Split(',');
                Match     match    = dbPhotoRegex0.Match(path);
                int       dbid     = Int32.Parse(match.Groups [1].Value);
                int       photoid  = 0;


                //match = dbPhotoRegex.Match (photoQuery);

                Database db = revmgr.GetDatabase(clientRev, dbid);
                if (db == null)
                {
                    ws.WriteResponse(client, HttpStatusCode.BadRequest, "invalid database id");
                    return(true);
                }
                ArrayList photoNodes = new ArrayList();
                Photo     photo      = db.LookupPhotoById(1);

                foreach (string photoId in photoIds)
                {
                    match   = dbPhotoRegex.Match(photoId);
                    photoid = Int32.Parse(match.Groups [1].Value);
                    photo   = db.LookupPhotoById(photoid);
                    photoNodes.Add(photo.ToFileData(query ["meta"].Contains("dpap.thumb")));
                    // DEBUG
                    //Console.WriteLine ("Requested photo id=" + photoid);
                }

                ArrayList children = new ArrayList();
                children.Add(new ContentNode("dmap.status", 200));
                children.Add(new ContentNode("dmap.updatetype", (byte)0));
                children.Add(new ContentNode("dmap.specifiedtotalcount", 2));
                children.Add(new ContentNode("dmap.returnedcount", 2));
                children.Add(new ContentNode("dmap.listing", photoNodes));
                ContentNode dbsongs = new ContentNode("dpap.databasesongs", children);

                if (photo == null)
                {
                    ws.WriteResponse(client, HttpStatusCode.BadRequest, "invalid photo id");
                    return(true);
                }

                try {
                    try {
                        if (PhotoRequested != null)
                        {
                            PhotoRequested(this, new PhotoRequestedArgs(username,
                                                                        (client.RemoteEndPoint as IPEndPoint).Address,
                                                                        db, photo));
                        }
                    } catch {}

                    if (photo.FileName != null)
                    {
                        // DEBUG
                        //Console.WriteLine ("photo.Filename != null" + query ["meta"].Split (',') [0]);
                        //ContentNode node = photo.ToFileData ();
                        //node.Dump ();

                        ws.WriteResponse(client, dbsongs);
                    }
                    else if (db.Client != null)
                    {
                        Console.WriteLine("db.Client != null");
                        long   photoLength = 0;
                        Stream photoStream = db.StreamPhoto(photo, out photoLength);

                        try {
                            ws.WriteResponseStream(client, photoStream, photoLength);
                        } catch (IOException) {
                            Console.WriteLine("IOException!");
                        }
                    }
                    else
                    {
                        Console.WriteLine("Else - internal error");
                        ws.WriteResponse(client, HttpStatusCode.InternalServerError, "no file");
                    }
                } finally {
                    // commented out because it breaks the connection after sending a hires photo
                    // client.Close()
                }
            }
            else if (dbContainersRegex.IsMatch(path))
            {
                int dbid = Int32.Parse(dbContainersRegex.Match(path).Groups [1].Value);

                Database db = revmgr.GetDatabase(clientRev, dbid);
                if (db == null)
                {
                    ws.WriteResponse(client, HttpStatusCode.BadRequest, "invalid database id");
                    return(true);
                }

                ws.WriteResponse(client, db.ToAlbumsNode());
            }
            else if (dbContainerItemsRegex.IsMatch(path))
            {
                // DEBUG
                Console.WriteLine("ContainerItems ! path=" + path);

                Match match = dbContainerItemsRegex.Match(path);
                int   dbid  = Int32.Parse(match.Groups [1].Value);
                int   plid  = Int32.Parse(match.Groups [2].Value);

                Database curdb = revmgr.GetDatabase(clientRev, dbid);
                if (curdb == null)
                {
                    ws.WriteResponse(client, HttpStatusCode.BadRequest, "invalid database id");
                    return(true);
                }

                Album curpl = curdb.LookupAlbumById(plid);
                if (curdb == null)
                {
                    ws.WriteResponse(client, HttpStatusCode.BadRequest, "invalid playlist id");
                    return(true);
                }
                // DEBUG
                Console.WriteLine("db and album ready!");
                ArrayList deletedIds = new ArrayList();
                if (delta > 0)
                {
                    Database olddb = revmgr.GetDatabase(clientRev - delta, dbid);

                    if (olddb != null)
                    {
                        Album oldpl = olddb.LookupAlbumById(plid);

                        if (oldpl != null)
                        {
                            IList <Photo> oldplPhotos = oldpl.Photos;
                            for (int i = 0; i < oldplPhotos.Count; i++)
                            {
                                int id = oldpl.GetContainerId(i);
                                if (curpl.LookupIndexByContainerId(id) < 0)
                                {
                                    deletedIds.Add(id);
                                }
                            }
                        }
                    }
                }
                Console.WriteLine("About to send response... meta=" + query["meta"]);
                curpl.ToPhotosNode(query ["meta"].Split(',')).Dump();

                ws.WriteResponse(client, curpl.ToPhotosNode(query ["meta"].Split(',')));
                //, (int []) deletedIds.ToArray (typeof (int))));
            }
            else if (path == "/update")
            {
                int retrev;

                lock (revmgr) {
                    // if they have the current revision, wait for a change
                    if (clientRev == revmgr.Current)
                    {
                        Monitor.Wait(revmgr);
                    }

                    retrev = revmgr.Current;
                }

                if (!running)
                {
                    ws.WriteResponse(client, HttpStatusCode.NotFound, "server has been stopped");
                }
                else
                {
                    ws.WriteResponse(client, GetUpdateNode(retrev));
                }
            }
            else
            {
                ws.WriteResponse(client, HttpStatusCode.Forbidden, "GO AWAY");
            }

            return(true);
        }