Пример #1
0
        private static bool LoadInternal(SqlDatabase <Entry> db)
        {
            var entries = GetAllEntries(db);

            if (entries == null)
            {
                return(false);
            }

            var bubbleGroupsActualCount = Directory.GetFiles(BubbleGroupDatabase.GetBaseLocation(), "*.*", SearchOption.AllDirectories).Length;
            var entriesCount            = entries.Count(x => !x.Unified);

            if (!(bubbleGroupsActualCount > entriesCount - 5 &&
                  bubbleGroupsActualCount < entriesCount + 5))
            {
                Utils.DebugPrint("Actual count does not match index count (+-5 tolerance). We'll have to re-generate index.");
                return(false);
            }

            foreach (var entry in entries)
            {
                if (entry.Unified)
                {
                    continue;
                }

                var service = ServiceManager.GetByName(entry.Service);
                if (service != null)
                {
                    var mostRecentVisualBubble = DeserializeBubble(entry.LastBubble);
                    mostRecentVisualBubble.Service = service;
                    mostRecentVisualBubble.ID      = entry.LastBubbleGuid;

                    var bubbleGroup = new BubbleGroup(mostRecentVisualBubble, entry.Guid, true);

                    BubbleGroupManager.BubbleGroupsAdd(bubbleGroup, true);
                }
                else
                {
                    Utils.DebugPrint("Could not obtain a valid service object from " + entry.Id + " (" + entry.Service + ")");
                }
            }

            foreach (var entry in entries)
            {
                if (!entry.Unified)
                {
                    continue;
                }

                var innerGroups = new List <BubbleGroup>();

                var innerGroupsIds = entry.UnifiedBubbleGroupsGuids.Split(',');
                if (innerGroupsIds != null)
                {
                    foreach (var innerGroupId in innerGroupsIds)
                    {
                        var innerGroup = BubbleGroupManager.Find(innerGroupId);
                        if (innerGroup == null)
                        {
                            Utils.DebugPrint("Unified group, inner group " + innerGroupId + " could not be related.");
                        }
                        else
                        {
                            innerGroups.Add(innerGroup);
                        }
                    }
                }

                if (!innerGroups.Any())
                {
                    Utils.DebugPrint("This unified group has no inner groups. Skipping this unified group.");
                    continue;
                }

                var primaryGroup = innerGroups.FirstOrDefault(x => x.ID == entry.UnifiedPrimaryBubbleGroupGuid);
                if (primaryGroup == null)
                {
                    Utils.DebugPrint("Unified group, primary group " + entry.UnifiedPrimaryBubbleGroupGuid +
                                     " could not be related. Skipping this unified group.");
                    continue;
                }

                var id = entry.Guid;

                var unifiedGroup = BubbleGroupFactory.CreateUnifiedInternal(innerGroups, primaryGroup, id);

                var sendingGroup = innerGroups.FirstOrDefault(x => x.ID == entry.UnifiedSendingBubbleGroupGuid);
                if (sendingGroup != null)
                {
                    unifiedGroup._sendingGroup = sendingGroup;
                }

                BubbleGroupManager.BubbleGroupsAdd(unifiedGroup, true);
            }

            return(true);
        }
Пример #2
0
        private static void Generate()
        {
            lock (_migrationLock)
            {
                var groups       = new List <BubbleGroup>();
                var serviceNames = new Dictionary <string, string>();

                // Load all normal groups

                var bubbleGroupsLocations       = Directory.GetFiles(BubbleGroupDatabase.GetBaseLocation(), "*.*", SearchOption.AllDirectories);
                var bubbleGroupsLocationsSorted =
                    bubbleGroupsLocations.OrderByDescending(x => Time.GetUnixTimestamp(File.GetLastWriteTime(x))).ToList();

                foreach (var bubbleGroupLocation in bubbleGroupsLocationsSorted)
                {
                    String groupId = null;
                    try
                    {
                        var groupHeader = Path.GetFileNameWithoutExtension(bubbleGroupLocation);

                        var groupDelimeter = groupHeader.IndexOf("^", StringComparison.Ordinal);
                        var serviceName    = groupHeader.Substring(0, groupDelimeter);
                        groupId = groupHeader.Substring(groupDelimeter + 1);

                        serviceNames.Add(groupId, serviceName);
                        Service service = null;

                        var deserializedBubbleGroup = LoadPartiallyIfPossible(bubbleGroupLocation,
                                                                              service, groupId, 100);
                        if (deserializedBubbleGroup == null)
                        {
                            throw new Exception("DeserializedBubbleGroup is nothing.");
                        }

                        groups.Add(deserializedBubbleGroup);
                    }
                    catch (Exception ex)
                    {
                        Utils.DebugPrint("[Migration] Group " + bubbleGroupLocation + " is corrupt (deleting): " + ex);
                        if (File.Exists(bubbleGroupLocation))
                        {
                            File.Delete(bubbleGroupLocation);
                        }
                    }
                }

                // Load all unified groups

                var unifiedBubbleGroupsDatabase =
                    new SimpleDatabase <UnifiedBubbleGroup, DisaUnifiedBubbleGroupEntry>("UnifiedBubbleGroups");
                foreach (var group in unifiedBubbleGroupsDatabase)
                {
                    var innerGroups = new List <BubbleGroup>();
                    foreach (var innerGroupId in @group.Serializable.GroupIds)
                    {
                        var innerGroup = groups.FirstOrDefault(x => x.ID == innerGroupId);
                        if (innerGroup == null)
                        {
                            Utils.DebugPrint("[Migration] Unified group, inner group " + innerGroupId + " could not be related.");
                        }
                        else
                        {
                            innerGroups.Add(innerGroup);
                        }
                    }
                    if (!innerGroups.Any())
                    {
                        Utils.DebugPrint("[Migration] This unified group has no inner groups. Skipping this unified group.");
                        continue;
                    }

                    var primaryGroup = innerGroups.FirstOrDefault(x => x.ID == @group.Serializable.PrimaryGroupId);
                    if (primaryGroup == null)
                    {
                        Utils.DebugPrint("[Migration] Unified group, primary group " + @group.Serializable.PrimaryGroupId +
                                         " could not be related. Skipping this unified group.");
                        continue;
                    }

                    var id = @group.Serializable.Id;

                    var unifiedGroup = BubbleGroupFactory.CreateUnifiedInternal(innerGroups, primaryGroup, id);

                    var sendingGroup = innerGroups.FirstOrDefault(x => x.ID == @group.Serializable.SendingGroupId);
                    if (sendingGroup != null)
                    {
                        unifiedGroup.SendingGroup = sendingGroup;
                    }

                    groups.Add(unifiedGroup);
                }

                // save it to the new index

                var entries = new List <Entry>();
                foreach (var group in groups)
                {
                    var unified = group as UnifiedBubbleGroup;
                    if (unified == null)
                    {
                        var lastBubble  = group.LastBubbleSafe();
                        var serviceName = serviceNames[group.ID];
                        if (serviceName != null)
                        {
                            entries.Add(new Entry
                            {
                                Guid           = group.ID,
                                Service        = serviceName,
                                LastBubble     = SerializeBubble(lastBubble),
                                LastBubbleGuid = lastBubble.ID
                            });
                        }
                        else
                        {
                            Utils.DebugPrint("[Migration] Weird... there's no associated service name!");
                        }
                    }
                    else
                    {
                        entries.Add(new Entry
                        {
                            Guid    = group.ID,
                            Unified = true,
                            UnifiedBubbleGroupsGuids = unified.Groups.Select(x => x.ID).
                                                       Aggregate((current, next) => current + "," + next),
                            UnifiedPrimaryBubbleGroupGuid = unified.PrimaryGroup.ID,
                            UnifiedSendingBubbleGroupGuid = unified.SendingGroup.ID,
                        });
                    }
                }
                Save(entries.ToArray());
            }
        }
        internal static void LoadAllPartiallyIfPossible(int bubblesPerGroup = 100)
        {
            var corruptedGroups = new List <string>();

            var bubbleGroupsLocations       = Directory.GetFiles(BubbleGroupDatabase.GetBaseLocation(), "*.*", SearchOption.AllDirectories);
            var bubbleGroupsLocationsSorted =
                bubbleGroupsLocations.OrderByDescending(x => Time.GetUnixTimestamp(File.GetLastWriteTime(x))).ToList();

            foreach (var bubbleGroupLocation in bubbleGroupsLocationsSorted)
            {
                String groupId = null;
                try
                {
                    var groupHeader = Path.GetFileNameWithoutExtension(bubbleGroupLocation);

                    var groupDelimeter = groupHeader.IndexOf("^", StringComparison.Ordinal);
                    var serviceName    = groupHeader.Substring(0, groupDelimeter);
                    groupId = groupHeader.Substring(groupDelimeter + 1);

                    var service = ServiceManager.GetByName(serviceName);

                    if (service == null)
                    {
                        Utils.DebugPrint("Service " + serviceName +
                                         " not found in AllServices!");
                        continue;
                    }

                    var deserializedBubbleGroup = LoadPartiallyIfPossible(bubbleGroupLocation, service, groupId, bubblesPerGroup);
                    if (deserializedBubbleGroup == null)
                    {
                        throw new Exception("DeserializedBubbleGroup is nothing.");
                    }
                    BubbleGroupManager.BubbleGroupsAdd(deserializedBubbleGroup);
                }
                catch (Exception ex)
                {
                    Utils.DebugPrint("Group " + bubbleGroupLocation + " is corrupt. Deleting. " + ex);
                    File.Delete(bubbleGroupLocation);
                    if (groupId != null)
                    {
                        corruptedGroups.Add(groupId);
                    }
                }
            }

            var migrationResaveNeeded  = false;
            var corruptedUnifiedGroups =
                new List <SimpleDatabase <UnifiedBubbleGroup, DisaUnifiedBubbleGroupEntry> .Container>();
            var removeFromRuntime =
                new List <SimpleDatabase <UnifiedBubbleGroup, DisaUnifiedBubbleGroupEntry> .Container>();

            foreach (var group in UnifiedBubbleGroupsDatabase)
            {
                var innerGroupCorrupt = false;
                var innerGroups       = new List <BubbleGroup>();
                foreach (var innerGroupId in @group.Serializable.GroupIds)
                {
                    var innerGroup = BubbleGroupManager.Find(innerGroupId);
                    if (innerGroup == null)
                    {
                        Utils.DebugPrint("Unified group, inner group " + innerGroupId +
                                         " could not be related.");
                        if (corruptedGroups.Contains(innerGroupId))
                        {
                            Utils.DebugPrint(
                                "It was detected that this inner group was corrupted and deleted. Will delete unified group.");
                            innerGroupCorrupt = true;
                            corruptedUnifiedGroups.Add(@group);
                        }
                    }
                    else
                    {
                        innerGroups.Add(innerGroup);
                    }
                }
                if (!innerGroups.Any())
                {
                    Utils.DebugPrint("Yuck. This unified group has no inner groups. Removing from runtime.");
                    removeFromRuntime.Add(@group);
                    continue;
                }
                if (innerGroupCorrupt)
                {
                    continue;
                }

                var primaryGroup = innerGroups.FirstOrDefault(x => x.ID == @group.Serializable.PrimaryGroupId);
                if (primaryGroup == null)
                {
                    Utils.DebugPrint("Unified group, primary group " + @group.Serializable.PrimaryGroupId +
                                     " could not be related. Removing from runtime.");
                    removeFromRuntime.Add(@group);
                    continue;
                }

                var id = @group.Serializable.Id;

                var unifiedGroup = CreateUnifiedInternal(innerGroups, primaryGroup, id);
                if (id == null)
                {
                    migrationResaveNeeded  = true;
                    @group.Serializable.Id = unifiedGroup.ID;
                }

                var sendingGroup = innerGroups.FirstOrDefault(x => x.ID == @group.Serializable.SendingGroupId);
                if (sendingGroup != null)
                {
                    unifiedGroup.SendingGroup = sendingGroup;
                }

                @group.Object = unifiedGroup;
                BubbleGroupManager.BubbleGroupsAdd(unifiedGroup);
            }
            if (removeFromRuntime.Any())
            {
                foreach (var group in removeFromRuntime)
                {
                    UnifiedBubbleGroupsDatabase.Remove(@group);
                }
            }
            if (corruptedUnifiedGroups.Any())
            {
                foreach (var group in corruptedUnifiedGroups)
                {
                    UnifiedBubbleGroupsDatabase.Remove(@group);
                }
            }
            if (migrationResaveNeeded)
            {
                Utils.DebugPrint("It was detected that we need to save migration changes for UnifiedBubbleGroups.");
                UnifiedBubbleGroupsDatabase.SaveChanges();
            }

            try
            {
                foreach (var groupCache in BubbleGroupCacheManager.Load())
                {
                    var associatedGroup = BubbleGroupManager.Find(groupCache.Guid);
                    if (associatedGroup == null)
                    {
                        continue;
                    }

                    var unifiedGroup = associatedGroup as UnifiedBubbleGroup;
                    if (unifiedGroup != null)
                    {
                        associatedGroup = unifiedGroup.PrimaryGroup;
                    }

                    associatedGroup.Title = groupCache.Name;
                    associatedGroup.Photo = groupCache.Photo;
                    associatedGroup.IsPhotoSetInitiallyFromCache = true;
                    if (groupCache.Participants != null)
                    {
                        associatedGroup.Participants = groupCache.Participants.ToSynchronizedCollection();
                        foreach (var participant in associatedGroup.Participants)
                        {
                            participant.IsPhotoSetInitiallyFromCache = true;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Utils.DebugPrint("Failed to load bubble groups!: " + ex);
            }

            BubbleGroupSettingsManager.Load();
        }