public ComposeBubble(long time, BubbleDirection direction, Service service, 
     VisualBubble bubbleToSend, Contact.ID[] ids) 
     : base(time, direction, service)
 {
     Ids = ids;
     BubbleToSend = bubbleToSend;
 }
 public static void UpdateLastBubbleOrAndLastModifiedIndex(string bubbleGroupId, VisualBubble lastBubble = null, long lastModifiedIndex = -1)
 {
     lock (_dbLock)
     {
         if (lastBubble == null && lastModifiedIndex == -1)
             return;
     
         using (var db = new SqlDatabase<Entry>(Location, false))
         {
             if (!db.Failed)
             {
                 foreach (var item in db.Store.Where(x => !x.Unified && x.Guid == bubbleGroupId))
                 {
                     if (lastBubble != null)
                     {
                         item.LastBubble = SerializeBubble(lastBubble);
                         item.LastBubbleGuid = lastBubble.ID;
                     }
                     if (lastModifiedIndex != -1)
                     {
                         item.LastModifiedIndex = lastModifiedIndex;
                     }
                     db.Update(item);
                 }
             }
         }
     }
 }
Example #3
0
 public ComposeBubble(long time, BubbleDirection direction, Service service,
                      VisualBubble bubbleToSend, Contact.ID[] ids)
     : base(time, direction, service)
 {
     Ids          = ids;
     BubbleToSend = bubbleToSend;
 }
        public static string GetMediaFilePathIfPossible(VisualBubble bubble)
        {
            var imageBubble = bubble as ImageBubble;
            if (imageBubble != null)
            {
                return imageBubble.ImagePath;
            }

            var videoBubble = bubble as VideoBubble;
            if (videoBubble != null)
            {
                return videoBubble.VideoPath;
            }

            var audioBubble = bubble as AudioBubble;
            if (audioBubble != null)
            {
                return audioBubble.AudioPath;
            }

            var fileBubble = bubble as FileBubble;
            if (fileBubble != null)
            {
                return fileBubble.Path;
            }

            return null;
        }
 public static Task JustQueue(VisualBubble visualBubble)
 {
     return Task.Factory.StartNew(() =>
     {
         var entry = Add(visualBubble);
     });
 }
Example #6
0
 public bool LoadBubblesComparer(VisualBubble localBubble, VisualBubble agentBubble)
 {
     if (localBubble.IdService == agentBubble.IdService)
     {
         return true;
     }
     return false;
 }
        public static BubbleGroup AddNewIfNotExist(VisualBubble bubble, bool updateUi = false)
        {
            var group =
                BubbleGroupManager.FindWithAddress(bubble.Service, bubble.Address);
            if (@group != null)
                return null;

            return AddNewInternal(bubble, updateUi);
        }
 public UnifiedBubbleGroup(List<BubbleGroup> groups, BubbleGroup primaryGroup,
     VisualBubble initialBubble, string id = null)
     : base(initialBubble, id, false)
 {
     _unifiedService = initialBubble.Service;
     Groups = groups;
     PrimaryGroup = primaryGroup;
     SendingGroup = primaryGroup;
 }
Example #9
0
 public bool LoadBubblesComparer(VisualBubble localBubble, VisualBubble agentBubble)
 {
     DebugPrint("###### Local bubble id service " + localBubble.IdService);
     DebugPrint("###### agent bubble id service " + agentBubble.IdService);
     if (localBubble.IdService == agentBubble.IdService)
     {
         return true;
     }
     return false;
 }
        protected internal void OnBubbleUpdated(VisualBubble bubble, BubbleGroup group)
        {
            if (Bubbles.Count > BubblesCapSize)
            {
                Bubbles.RemoveAt(0);
            }

            var addedToEnd = false;

            for (int i = Bubbles.Count - 1; i >= 0; i--)
            {
                var nBubble = Bubbles[i];
                if (nBubble.Time <= bubble.Time)
                {
                    // adding it to the end, we can do a simple contract
                    if (i == Bubbles.Count - 1)
                    {
                        addedToEnd = true;
                        Bubbles.Add(bubble);
                        if (bubble.Direction == Bubble.BubbleDirection.Incoming)
                        {
                            BubbleGroupSettingsManager.SetUnread(this, true);
                        }
                    }
                    // inserting, do a full contract
                    else
                    {
                        Bubbles.Insert(i + 1, bubble);
                    }
                    break;
                }

                // could not find a valid place to insert, then skip insertion.
                if (i == 0)
                {
                    return;
                }
            }

            if (SendingGroup != group && addedToEnd)
            {
                SendingGroup = group;
                BubbleGroupEvents.RaiseSendingServiceChange(this);
            }

            RaiseBubbleInserted(bubble);
        }
        public static void AddBubble(BubbleGroup group, VisualBubble b)
        {
            lock (OperationLock)
            {
                using (var ms = new MemoryStream())
                {
                    Serializer.Serialize(ms, b);

                    var bubbleData = ms.ToArray();
                    var bubbleHeader = b.GetType().Name + ":" + b.ID + ":" + b.Time;

                    var file = GetLocation(@group);

                    using (var stream = File.Open(file, FileMode.Append, FileAccess.Write))
                    {
                        BubbleGroupDatabasePrimitives.WriteBubbleData(stream, bubbleData);
                        BubbleGroupDatabasePrimitives.WriteBubbleHeader(stream, bubbleHeader);
                    }
                }
            }
        }
Example #12
0
        public static void ForwardCopyToMediaDirectoryIfNeeded(VisualBubble vb)
        {
            if (vb is TextBubble)
                return;
            if (vb is LocationBubble)
                return;

            var videoBubble = vb as VideoBubble;
            if (videoBubble != null)
            {
                if (IsInMediaLocation(videoBubble.VideoPath))
                    return;
                var path = CopyVideoToDisaVideoLocation(videoBubble.VideoPath);
                if (path == null)
                    return;
                videoBubble.VideoPath = path;
            }

            var audioBubble = vb as AudioBubble;
            if (audioBubble != null)
            {
                if (IsInMediaLocation(audioBubble.AudioPath))
                    return;
                var path = CopyAudioToDisaAudioLocation(audioBubble.AudioPath);
                audioBubble.AudioPath = path;
            }

            var imageBubble = vb as ImageBubble;
            if (imageBubble != null)
            {
                if (IsInMediaLocation(imageBubble.ImagePath))
                    return;
                var path = CopyPhotoToDisaPictureLocation(imageBubble.ImagePath);
                if (path == null)
                    return;
                imageBubble.ImagePath = path;
            }
        }
 public static bool UpdateBubble(BubbleGroup group, VisualBubble bubble, int searchDepth = 100)
 {
     return UpdateBubble(@group, new[] { bubble }, searchDepth);
 }
 public static bool InsertBubbleByTime(BubbleGroup group, VisualBubble bubble, int maxDepth = 1000)
 {
     return InsertBubblesByTime(@group, new [] { bubble }, maxDepth);
 }
 public static void UpdateStatus(VisualBubble b, Bubble.BubbleStatus status, BubbleGroup group, 
     bool updateBubbleGroupBubbles = true)
 {
     b.Status = status;
     BubbleGroupDatabase.UpdateBubble(@group, b);
     if (updateBubbleGroupBubbles)
         BubbleGroupEvents.RaiseBubblesUpdated(@group);
     BubbleGroupEvents.RaiseRefreshed(@group);
 }
 public static bool Update(BubbleGroup group, VisualBubble[] bubbles, int bubbleDepth = 100)
 {
     return BubbleGroupDatabase.UpdateBubble(@group, bubbles, bubbleDepth);
 }
Example #17
0
 public void AddVisualBubbleIdServices(VisualBubble bubble)
 {
     bubble.IdService2 = NextMessageId;
 }
Example #18
0
 public static void UpdateStatus(VisualBubble[] bubbles, Bubble.BubbleStatus status, BubbleGroup group, 
     bool updateBubbleGroupBubbles = true)
 {
     foreach (var bubble in bubbles)
     {
         bubble.Status = status;
     }
     BubbleGroupDatabase.UpdateBubble(@group, bubbles);
     if (updateBubbleGroupBubbles)
         BubbleGroupEvents.RaiseBubblesUpdated(@group);
     BubbleGroupEvents.RaiseRefreshed(@group);
 }
 private static void FailBubbleIfPathDoesntExist(VisualBubble bubble)
 {
     var path = GetMediaFilePathIfPossible(bubble);
     if (String.IsNullOrWhiteSpace(path))
         return;
     if (!File.Exists(path))
     {
         throw new ServiceBubbleSendFailedException("Visual bubble media file path doesn't exist.");
     }
 }
Example #20
0
        private void AddQuotedMessageToBubble(Message replyMessage, VisualBubble bubble)
        {
            if (replyMessage == null)
            {
                return;
            }

            if(!string.IsNullOrEmpty(replyMessage.MessageProperty))
            {
                bubble.QuotedType = VisualBubble.MediaType.Text;
                bubble.QuotedContext = replyMessage.MessageProperty;

            }
            else
            {
                var messageMedia = replyMessage.Media;
                var messageMediaPhoto = messageMedia as MessageMediaPhoto;
                var messageMediaDocument = messageMedia as MessageMediaDocument;
                var messageMediaGeo = messageMedia as MessageMediaGeo;
                var messageMediaVenue = messageMedia  as MessageMediaVenue;
                var messageMediaContact = messageMedia as MessageMediaContact;

                if (messageMediaPhoto != null)
                {
                    bubble.QuotedType = VisualBubble.MediaType.Image;
                    bubble.HasQuotedThumbnail = true;
                    bubble.QuotedThumbnail = GetCachedPhotoBytes(messageMediaPhoto.Photo);
                }
                if(messageMediaDocument != null)
                {
                    var document = messageMediaDocument.Document as Document;
                    if(document!=null)
                    {
                        if (document.MimeType.Contains("audio"))
                        {
                            bubble.QuotedType = VisualBubble.MediaType.Audio;
                            bubble.QuotedSeconds = GetAudioTime(document);
                        }
                        else if (document.MimeType.Contains("video"))
                        {
                            bubble.QuotedType = VisualBubble.MediaType.File;
                            bubble.QuotedContext = "Video";
                        }
                        else
                        {
                            bubble.QuotedType = VisualBubble.MediaType.File;
                            bubble.QuotedContext = GetDocumentFileName(document);
                        }

                    }
                }
                if(messageMediaGeo != null)
                {
                    var geoPoint = messageMediaGeo.Geo as GeoPoint;

                    if (geoPoint != null)
                    {
                        bubble.QuotedType = VisualBubble.MediaType.Location;
                        bubble.QuotedContext = (int)geoPoint.Lat + "," + (int)geoPoint.Long;
                        bubble.QuotedLocationLatitude = geoPoint.Lat;
                        bubble.QuotedLocationLongitude = geoPoint.Long;
                        bubble.HasQuotedThumbnail = true;
                    }
                        
                }
                if(messageMediaVenue != null)
                {
                    var geoPoint = messageMediaVenue.Geo as GeoPoint;

                    if (geoPoint != null)
                    {
                        bubble.QuotedType = VisualBubble.MediaType.Location;
                        bubble.QuotedContext = messageMediaVenue.Title;
                        bubble.QuotedLocationLatitude = geoPoint.Lat;
                        bubble.QuotedLocationLongitude = geoPoint.Long;
                        bubble.HasQuotedThumbnail = true;
                    }

                }
                if(messageMediaContact != null)
                {
                    bubble.QuotedType = VisualBubble.MediaType.Contact;
                    bubble.QuotedContext = messageMediaContact.FirstName + " " + messageMediaContact.LastName; 
                }
                    
            }
            bubble.QuotedAddress = replyMessage.FromId.ToString(CultureInfo.InvariantCulture);
            bubble.QuotedIdService = replyMessage.Id.ToString(CultureInfo.InvariantCulture);

        }
        public static bool Update(BubbleGroup group, VisualBubble visualBubble, int bubbleDepth = 100)
        {
            if (visualBubble.BubbleGroupReference != null)
            {
                BubbleGroupDatabase.UpdateBubble(visualBubble.BubbleGroupReference, visualBubble, bubbleDepth);
                return true;
            }

            var unifiedGroup = @group as UnifiedBubbleGroup;
            if (unifiedGroup == null)
            {
                BubbleGroupDatabase.UpdateBubble(@group, visualBubble, bubbleDepth);
                return true;
            }

            foreach (var innerGroup in unifiedGroup.Groups)
            {
                foreach (var bubble in innerGroup.Bubbles)
                {
                    if (bubble.ID != visualBubble.ID) continue;

                    BubbleGroupDatabase.UpdateBubble(innerGroup, visualBubble, bubbleDepth);
                    return true;
                }
            }

            return false;
        }
 private static bool IsBubbleSending(VisualBubble bubble)
 {
     if (bubble is NewBubble)
     {
         return false;
     }
     if (bubble.Status == Bubble.BubbleStatus.Waiting 
         && bubble.Direction == Bubble.BubbleDirection.Outgoing)
     {
         return true;
     }
     return false;
 }
        private static bool IsBubbleDownloading(VisualBubble bubble)
        {
            var imageBubble = bubble as ImageBubble;
            if (imageBubble != null)
            {
                return imageBubble.Transfer != null;
            }
            var videoBubble = bubble as VideoBubble;
            if (videoBubble != null)
            {
                return videoBubble.Transfer != null;
            }
            var audioBubble = bubble as AudioBubble;
            if (audioBubble != null)
            {
                return audioBubble.Transfer != null;
            }
            var fileBubble = bubble as FileBubble;
            if (fileBubble != null)
            {
                return fileBubble.Transfer != null;
            }

            return false;
        }
Example #24
0
 public DeliveredBubbleReceipt(long time, BubbleDirection direction, Service service, VisualBubble bubbleUpdated)
     : base(time, direction, service)
 {
     BubbleUpdated = bubbleUpdated;
 }
        internal static BubbleGroup Group(VisualBubble vb, bool resend = false, bool insertAtBottom = false)
        {
            lock (BubbleGroupDatabase.OperationLock)
            {
                Utils.DebugPrint("Grouping an " + vb.Direction + " bubble on service " + vb.Service.Information.ServiceName);

                var theGroup =
                    BubbleGroupManager.FindWithAddress(vb.Service, vb.Address);

                BubbleGroupFactory.LoadFullyIfNeeded(theGroup);

                var duplicate = false;
                var newGroup = false;
                if (theGroup == null)
                {
                    Utils.DebugPrint(vb.Service.Information.ServiceName + " unable to find suitable group. Creating a new one.");

                    theGroup = new BubbleGroup(vb, null, false);

                    newGroup = true;

                    Utils.DebugPrint("GUID of new group: " + theGroup.ID);

                    vb.Service.NewBubbleGroupCreated(theGroup).ContinueWith(x =>
                    {
                        // force the UI to refetch the photo
                        theGroup.IsPhotoSetFromService = false;
                        SendSubscribe(theGroup, true);
                        BubbleGroupUpdater.Update(theGroup);
                    });

                    BubbleGroupManager.BubbleGroupsAdd(theGroup);
                }
                else
                {
                    if (resend)
                    {
                        if (vb.Status == Bubble.BubbleStatus.Failed)
                        {
                            UpdateStatus(vb, Bubble.BubbleStatus.Waiting, theGroup);
                        }
                        return theGroup;
                    }

                    var visualBubbleServiceId = vb.Service as IVisualBubbleServiceId;
                    if (visualBubbleServiceId != null && 
                        visualBubbleServiceId.DisctinctIncomingVisualBubbleIdServices())
                    {
                        if (vb.IdService != null)
                        {
                            duplicate = theGroup.Bubbles.FirstOrDefault(x => x.GetType() == vb.GetType() && x.IdService == vb.IdService) != null;
                        }
                        if (!duplicate && vb.IdService2 != null)
                        {
                            duplicate = theGroup.Bubbles.FirstOrDefault(x => x.GetType() == vb.GetType() && x.IdService2 == vb.IdService2) != null;
                        }
                    }

                    if (!duplicate)
                    {
                        Utils.DebugPrint(vb.Service.Information.ServiceName + " found a group. Adding.");

                        if (insertAtBottom)
                        {
                            var lastBubble = theGroup.LastBubbleSafe();
                            if (lastBubble.Time > vb.Time)
                            {
                                vb.Time = lastBubble.Time;
                            }
                        }

                        theGroup.InsertByTime(vb);
                    }
                    else
                    {
                        Utils.DebugPrint("Yuck. It's a duplicate bubble. No need to readd: " + vb.IdService + ", " + vb.IdService2);
                    }
                }

                try
                {
                    if (theGroup.IsParty && !string.IsNullOrWhiteSpace(vb.ParticipantAddressNickname))
                    {
                        var participantAddressNicknamesArray = theGroup.ParticipantNicknames;
                        if (participantAddressNicknamesArray == null)
                        {
                            participantAddressNicknamesArray = new DisaParticipantNickname[0];
                        }
                        var participantAddressNicknames = participantAddressNicknamesArray.ToList();
                        var changed = false;
                        var adding = true;
                        foreach (var participantAddressNickname in participantAddressNicknames)
                        {
                            if (theGroup.Service.BubbleGroupComparer(participantAddressNickname.Address, vb.ParticipantAddress))
                            {
                                if (participantAddressNickname.Nickname != vb.ParticipantAddressNickname)
                                {
                                    participantAddressNickname.Nickname = vb.ParticipantAddressNickname;
                                    changed = true;
                                }
                                adding = false;
                                break;
                            }
                        }
                        if (adding)
                        {
                            participantAddressNicknames.Add(new DisaParticipantNickname
                            {
                                Address = vb.ParticipantAddress,
                                Nickname = vb.ParticipantAddressNickname,
                            });
                        }
                        if (changed || adding)
                        {
                            theGroup.ParticipantNicknames = participantAddressNicknames.ToArray();
                        }
                    }
                }
                catch (Exception ex)
                {
                    Utils.DebugPrint("Failed to insert/update participant nickname into cache: " + ex);   
                }

                if (!duplicate)
                {
                    Utils.DebugPrint("Inserting bubble into database group!");

                    try
                    {
                        if (newGroup)
                        {
                            BubbleGroupDatabase.AddBubble(theGroup, vb);
                        }
                        else
                        {
                            BubbleGroupDatabase.InsertBubbleByTime(theGroup, vb);
                        }
                    }
                    catch (Exception ex)
                    {
                        Utils.DebugPrint("Bubble failed to be inserting/added into the group " + theGroup.ID + ": " + ex);
                    }

                    try
                    {
                        BubbleGroupEvents.RaiseBubbleInserted(vb, theGroup);
                    }
                    catch (Exception ex)
                    {
                        Utils.DebugPrint(
                            "Error in notifying the interface that the bubble group has been updated (" +
                            vb.Service.Information.ServiceName + "): " + ex.Message);
                    }
                }

                return theGroup;
            }
        }
 public DeliveredBubbleReceipt(long time, BubbleDirection direction, Service service, VisualBubble bubbleUpdated)
     : base(time, direction, service)
 {
     BubbleUpdated = bubbleUpdated;
 }
        public static void AddBubbles(BubbleGroup group, VisualBubble[] bubbles)
        {
            lock (OperationLock)
            {
                var file = GetLocation(@group);

                using (var stream = File.Open(file, FileMode.Append, FileAccess.Write))
                {
                    BubbleGroupIndex.UpdateLastBubbleOrAndLastModifiedIndex(group.ID, bubbles.Last(), stream.Position);

                    foreach (var b in bubbles)
                    {
                        using (var ms = new MemoryStream())
                        {
                            Serializer.Serialize(ms, b);

                            var bubbleData = ms.ToArray();
                            var bubbleHeader = b.GetType().Name + ":" + b.ID + ":" + b.Time;

                            BubbleGroupDatabasePrimitives.WriteBubbleData(stream, bubbleData);
                            BubbleGroupDatabasePrimitives.WriteBubbleHeader(stream, bubbleHeader);
                        }
                    }
                }
            }
        }
 public void AddVisualBubbleIdServices(VisualBubble bubble)
 {
     bubble.IdService = _deviceId + ++_bubbleSendCount;
 }
        public static bool InsertBubblesByTime(BubbleGroup group, VisualBubble[] bubbles, int maxDepth = 1000, bool guidCheck = false, bool insertAtTop = false)
        {
            //we can't operate if a thread/worker is concurrently processing a new bubble
            lock (OperationLock)
            {
                var groupDatabaseLocation = GetLocation(@group);
                var bubbleTuples = bubbles.Select(x => new Tuple<long, VisualBubble>(x.Time, x)).ToList();

                VisualBubble lastBubble = null;
                long insertPosition = -1;

                using (var stream = File.Open(groupDatabaseLocation, FileMode.Open, FileAccess.ReadWrite))
                {
                    stream.Seek(stream.Length, SeekOrigin.Begin);

                    for (var i = 0; i < (maxDepth != -1 ? maxDepth : Int32.MaxValue); i++)
                    {
                        if (stream.Position == 0)
                        {
                            if (insertAtTop)
                            {
                                insertPosition = 0;

                                var cut = new byte[(int)stream.Length];
                                stream.Read(cut, 0, (int)stream.Length);
                                stream.Position = 0;

                                var bubblesToInsert = bubbleTuples.Select(x => x.Item2).ToList();
                                bubblesToInsert.TimSort((x, y) => x.Time.CompareTo(y.Time));
                                foreach (var bubbleToInsert in bubblesToInsert)
                                {
                                    using (var ms = new MemoryStream())
                                    {
                                        Serializer.Serialize(ms, bubbleToInsert);

                                        var bubbleToInsertData = ms.ToArray();
                                        var bubbleToInsertHeader = bubbleToInsert.GetType().Name + ":" + bubbleToInsert.ID
                                                                   + ":" + bubbleToInsert.Time;

                                        BubbleGroupDatabasePrimitives.WriteBubbleData(stream, bubbleToInsertData);
                                        BubbleGroupDatabasePrimitives.WriteBubbleHeader(stream, bubbleToInsertHeader);
                                    }
                                }

                                stream.Write(cut, 0, cut.Length);
                                stream.SetLength(stream.Position);

                                break;
                            }
                            else
                            {
                                break;
                            }
                        }

                        byte[] headerBytes;
                        int headerBytesLength;
                        int endPosition;

                        BubbleGroupDatabasePrimitives.ReadBubbleHeader(stream, out headerBytes, out headerBytesLength);
                        BubbleGroupDatabasePrimitives.FindBubbleHeaderDelimiter(headerBytes, headerBytesLength, 0, out endPosition);
                        var bubbleDataLength = BubbleGroupDatabasePrimitives.JumpBubbleData(stream); //we need to seek over the data.

                        var guid = BubbleGroupDatabasePrimitives.ReadBubbleHeaderStruct(headerBytes, headerBytesLength,
                            endPosition + 1, out endPosition);
                        var time = BubbleGroupDatabasePrimitives.AsciiBytesToString(headerBytes, endPosition + 1,
                            headerBytesLength);
                        long longTime;
                        Int64.TryParse(time, out longTime);

                        {
                            var bubblesToInsert = bubbleTuples.Where(x =>
                            {
                                if (guidCheck && guid == x.Item2.ID)
                                    return false;

                                if (longTime <= x.Item1)
                                    return true;

                                return false;

                            }).ToList();
                            if (!bubblesToInsert.Any())
                            {
                                continue;
                            }

                            var bubbleSize = headerBytesLength + bubbleDataLength + 8;
                            var insertLocation = stream.Position + bubbleSize;
                            stream.Seek(insertLocation, SeekOrigin.Begin);

                            var cutLength = stream.Length - insertLocation;
                            var cut = new byte[cutLength];
                            stream.Read(cut, 0, (int)cutLength); //should always work as long as the count ain't crazy high

                            stream.Seek(insertLocation, SeekOrigin.Begin);

                            insertPosition = stream.Position;

                            foreach (var bubbleToInsert in bubblesToInsert.Select(x => x.Item2))
                            {
                                using (var ms = new MemoryStream())
                                {
                                    Serializer.Serialize(ms, bubbleToInsert);

                                    var bubbleToInsertData = ms.ToArray();
                                    var bubbleToInsertHeader = bubbleToInsert.GetType().Name + ":" + bubbleToInsert.ID
                                                               + ":" + bubbleToInsert.Time;

                                    BubbleGroupDatabasePrimitives.WriteBubbleData(stream, bubbleToInsertData);
                                    BubbleGroupDatabasePrimitives.WriteBubbleHeader(stream, bubbleToInsertHeader);
                                }
                            }

                            stream.Write(cut, 0, cut.Length);
                            stream.SetLength(stream.Position);

                            // adding to end
                            if (cut.Length == 0)
                            {
                                lastBubble = bubblesToInsert.Last().Item2;
                            }

                            foreach (var bubbleToInsert in bubblesToInsert)
                            {
                                bubbleTuples.Remove(bubbleToInsert);
                            }

                            if (!bubbleTuples.Any())
                            {
                                break;
                            }
                        }
                    }

                    BubbleGroupIndex.UpdateLastBubbleOrAndLastModifiedIndex(group.ID, lastBubble, insertPosition);
                }

                if (!bubbleTuples.Any())
                {
                    return true;
                }

                return false;
            }
        }
        public static string PatchPath(VisualBubble bubble)
        {
            string path = null;
            string newBase = null;

            var imageBubble = bubble as ImageBubble;
            var videoBubble = bubble as VideoBubble;
            var audioBubble = bubble as AudioBubble;
            var fileBubble = bubble as FileBubble;
            if (imageBubble != null)
            {
                path = imageBubble.ImagePathNative;
                newBase = Platform.GetPicturesPath();
            }
            else if (videoBubble != null)
            {
                path = videoBubble.VideoPathNative;
                newBase = Platform.GetVideosPath();
            }
            else if (audioBubble != null)
            {
                path = audioBubble.AudioPathNative;
                newBase = Platform.GetAudioPath();
            }
            else if (fileBubble != null)
            {
                path = fileBubble.PathNative;
                newBase = Platform.GetFilesPath();
            }

            if (path == null || newBase == null)
                throw new Exception("Uknown bubble");

            var indexes = FindIndexesFromRear(path, Path.DirectorySeparatorChar);
            var seperators = indexes.Take(2).ToList();
            if (seperators.Count < 2)
                return path;

            var end = path.Substring(seperators[1] + 1);
            return Path.Combine(newBase, end);
        }
        public static bool UpdateBubble(BubbleGroup group, VisualBubble[] bubbles, int searchDepth = 100)
        {
            //we can't operate if a thread/worker is concurrently processing a new bubble
            lock (OperationLock)
            {
                var groupDatabaseLocation = GetLocation(@group);
                var bubbleTuples = bubbles.Select(x => new Tuple<string, VisualBubble>(x.ID, x)).ToList();

                VisualBubble lastBubble = null;
                long insertPosition = -1;

                using (var stream = File.Open(groupDatabaseLocation, FileMode.Open, FileAccess.ReadWrite))
                {
                    stream.Seek(stream.Length, SeekOrigin.Begin);

                    for (var i = 0; i < (searchDepth != -1 ? searchDepth : Int32.MaxValue); i++)
                    {
                        if (stream.Position == 0)
                        {
                            break;
                        }

                        byte[] headerBytes;
                        int headerBytesLength;
                        int endPosition;

                        BubbleGroupDatabasePrimitives.ReadBubbleHeader(stream, out headerBytes, out headerBytesLength);
                        BubbleGroupDatabasePrimitives.FindBubbleHeaderDelimiter(headerBytes, headerBytesLength, 0, out endPosition);
                        var bubbleDataLength = BubbleGroupDatabasePrimitives.JumpBubbleData(stream); //we need to seek over the data.

                        var guid = BubbleGroupDatabasePrimitives.ReadBubbleHeaderStruct(headerBytes, headerBytesLength,
                            endPosition + 1, out endPosition);

                        Tuple<string, VisualBubble> bubbleTuple;
                        if ((bubbleTuple = bubbleTuples.FirstOrDefault(x => x.Item1 == guid)) == null)
                        {
                            continue;
                        }

                        var b = bubbleTuple.Item2;

                        var bubbleSize = headerBytesLength + bubbleDataLength + 8;
                        var cutStart = stream.Position + bubbleSize;
                        var cutLength = stream.Length - cutStart;

                        insertPosition = stream.Position;

                        using (var ms = new MemoryStream())
                        {
                            Serializer.Serialize(ms, b);

                            var updatedBubbleData = ms.ToArray();
                            var updatedBubbleHeader = b.GetType().Name + ":" + b.ID + ":" + b.Time;
                            var updatedBubbleSize = updatedBubbleHeader.Length + updatedBubbleData.Length + 8;

                            var bubbleInjectDelta = bubbleSize - updatedBubbleSize;
                            //enough room
                            if (bubbleInjectDelta != 0)
                            {
                                var injectPosition = stream.Position;

                                stream.Position = cutStart; //higher 
                                var cut = new byte[cutLength];
                                stream.Read(cut, 0, (int)cutLength);//should always work as long as the count ain't crazy high

                                //var bw = new BinaryWriter(stream, Encoding.ASCII);
                                stream.Position = injectPosition;
                                BubbleGroupDatabasePrimitives.WriteBubbleData(stream, updatedBubbleData);
                                BubbleGroupDatabasePrimitives.WriteBubbleHeader(stream, updatedBubbleHeader);

                                stream.Write(cut, 0, cut.Length);
                                stream.SetLength(stream.Position);
                            }
                            //they're the same!
                            else if (bubbleInjectDelta == 0)
                            {
                                //var bw = new BinaryWriter(stream, Encoding.ASCII);
                                BubbleGroupDatabasePrimitives.WriteBubbleData(stream, updatedBubbleData);
                                BubbleGroupDatabasePrimitives.WriteBubbleHeader(stream, updatedBubbleHeader);
                            }
                        }
                            
                        if (cutLength == 0)
                        {
                            lastBubble = b;
                        }

                        bubbleTuples.Remove(bubbleTuple);
                        if (!bubbleTuples.Any())
                        {
                            break;
                        }
                    }

                    BubbleGroupIndex.UpdateLastBubbleOrAndLastModifiedIndex(group.ID, lastBubble, insertPosition);
                }

                if (!bubbleTuples.Any())
                {
                    return true;
                }

                return false;
            }
        }
Example #32
0
 public Task<bool> DeleteBubble(BubbleGroup @group, VisualBubble bubble)
 {
     //just basic true, since we plan on not implementing this stuff
     return Task<bool>.Factory.StartNew(() => true);
 }