Exemple #1
0
 internal Package GetProvider(Uri uri) {
     return new Package(this, uri.SingleItemAsEnumerable());
 }
Exemple #2
0
        internal static Task<RecognitionInfo> Recognize(string item, bool forceRescan = false)
        {
            var cachedResult = SessionCache<RecognitionInfo>.Value[item];
            if (cachedResult != null) {
                if (forceRescan) {
                    SessionCache<RecognitionInfo>.Value[item] = null;
                } else {
                    return cachedResult.AsResultTask();
                }
            }

            try {
                var location = new Uri(item);
                if (!location.IsFile) {
                    // some sort of remote item.
                    // since we can't do anything with a remote item directly,
                    // we have to issue a request to the client to get it for us

                    // before we go down this, check to see if we asked for it in this session
                    // in the last five minutes or so. We don't need to pound away at a URL for
                    // no reason.
                    var peek = SessionCache<RecognitionInfo>.Value[location.AbsoluteUri];
                    if( peek != null ) {
                        if( DateTime.Now.Subtract(peek.LastAccessed) < new TimeSpan(0,5,0) ) {
                            return peek.AsResultTask();
                        }
                    }

                    // since we're expecting that the canonicalname will be used as a filename
                    // in the .cache directory, we need to generate a safe filename based on the
                    // data in the URL
                    var safeCanonicalName = location.GetLeftPart(UriPartial.Path).MakeSafeFileName();

                    // BEFORE
                    // Check to see if there is a request for this file already in progress.
                    // attach a continuation to that if it is, instead of adding a new task
                    Task<RecognitionInfo> completion;
                    lock (SessionCache<Task<RecognitionInfo>>.Value) {
                        completion = SessionCache<Task<RecognitionInfo>>.Value[safeCanonicalName];
                        if (completion != null) {
                            return completion.ContinueAlways(antecedent => antecedent.Result);
                        }

                        // otherwise, let's create a delegate to run when the file gets resolved.
                        completion = new Task<RecognitionInfo>(rrfState => {
                            var state = rrfState as RequestRemoteFileState;
                            if (state == null || string.IsNullOrEmpty(state.LocalLocation)) {
                                // didn't fill in the local location? -- this happens when the client can't download.
                                // PackageManagerMessages.Invoke.FileNotRecognized() ?
                                var rslt = new RecognitionInfo {
                                    FullPath = location.AbsoluteUri,
                                    FullUrl = location,
                                    IsURL = true,
                                    IsInvalid = true,
                                };
                                // session cache it
                                SessionCache<RecognitionInfo>.Value[location.AbsoluteUri] = rslt;
                                return rslt;
                            }
                            var newLocation = new Uri(state.LocalLocation);
                            if (newLocation.IsFile) {
                                var continuedResult = Recognize(state.LocalLocation).Result;

                                // create the result object
                                var result = new RecognitionInfo {
                                    FullUrl = location,
                                };

                                // if( continuedResult.IsPackageFeed && forceRescan ) {
                                // this ensures that feed files aren't kept around needlessly.
                                //state.LocalLocation.MarkFileTemporary();
                                //}

                                result.CopyDetailsFrom(continuedResult);
                                result.IsURL = true;

                                return Cache(item, result);
                            }
                            // so, the callback comes, but it's not a file.
                            //
                            var r = new RecognitionInfo {
                                FullPath = location.AbsoluteUri,
                                IsInvalid = true,
                            };

                            // session cache it
                            SessionCache<RecognitionInfo>.Value[location.AbsoluteUri] = r;
                            return r;
                        }, new RequestRemoteFileState {
                            OriginalUrl = location.AbsoluteUri
                        }, TaskCreationOptions.AttachedToParent);

                        // store the task until the client tells us that it has the file.
                        SessionCache<Task<RecognitionInfo>>.Value[safeCanonicalName] = completion;
                    }

                    // GS01: Should we make a deeper path in the cache directory?
                    // perhaps that would let us use a cached version of the file we're looking for.
                    Event<GetResponseInterface>.RaiseFirst().RequireRemoteFile(safeCanonicalName, location.SingleItemAsEnumerable(),PackageManagerSettings.CoAppPackageCache, forceRescan);

                    // return the completion task, as whatever is waiting for this
                    // needs to continue on that.
                    return completion;
                }

                //----------------------------------------------------------------
                // we've managed to find a file system path.
                // let's figure out what it is.
                var localPath = location.LocalPath;

                if (localPath.Contains("?") || localPath.Contains("*")) {
                    // looks like a wildcard package feed.
                    // which is a directory feed with a filter.
                    var i = localPath.IndexOfAny(new[] {'*', '?'});

                    var lastSlash = localPath.LastIndexOf('\\', i);
                    var folder = localPath.Substring(0, lastSlash);
                    if (Directory.Exists(folder)) {
                        return CacheAndReturnTask(item, new RecognitionInfo {
                            FullPath = folder,
                            Filter = localPath.Substring(lastSlash + 1),
                            IsFolder = true,
                            IsPackageFeed = true
                        });
                    }
                }

                if (Directory.Exists(localPath)) {
                    // it's a directory.
                    // which means that it's a package feed.
                    return CacheAndReturnTask(item, new RecognitionInfo {
                        FullPath = localPath,
                        Filter = "*",
                        IsFolder = true,
                        IsPackageFeed = true,
                    });
                }

                if (File.Exists(localPath)) {
                    var ext = Path.GetExtension(localPath);
                    var result = new RecognitionInfo {
                        IsFile = true,
                        FullPath = localPath
                    };

                    switch (ext) {
                        case ".msi":
                            result.IsCoAppMSI = CoAppMSI.IsValidPackageFile(localPath);
                            result.IsLegacyMSI = !result.IsCoAppMSI;
                            result.IsPackageFile = true;
                            break;

                        case ".nupkg":
                            result.IsNugetPackage = true;
                            result.IsPackageFile = true;
                            break;

                        case ".exe":
                            result.IsLegacyEXE = true;
                            result.IsPackageFile = true;
                            break;

                        case ".zip":
                        case ".cab":
                        case ".rar":
                        case ".7z":
                            result.IsArchive = true;
                            result.IsPackageFeed = true;
                            break;

                        default:
                            // guess based on file contents
                            try {
                                if (CoAppMSI.IsValidPackageFile(localPath)) {
                                    result.IsCoAppMSI = true;
                                    result.IsPackageFile = true;
                                }
                            } catch {
                                // not a coapp file...
                            }

                            if (localPath.IsXmlFile()) {
                                try {
                                    // this could be an atom feed
                                    var feed = AtomFeed.LoadFile(localPath);
                                    if (feed != null) {
                                        result.IsPackageFeed = true;
                                        result.IsAtom = true;
                                    }
                                } catch {
                                    // can't seem to figure out what this is.
                                    result.IsInvalid = true;
                                }
                            }
                            break;
                    }
                    return CacheAndReturnTask(item, result);
                }
            } catch (UriFormatException) {
            }
            // item wasn't able to match any known URI, UNC or Local Path format.
            // or was file not found
            return new RecognitionInfo {
                FullPath = item,
                IsInvalid = true,
            }.AsResultTask();
        }
Exemple #3
0
        internal static Task<RecognitionInfo> Recognize(string item, bool forceRescan = false)
        {
            var cachedResult = SessionData.Current.RecognitionInfo[item];

            if (cachedResult != null) {
                if (forceRescan) {
                    SessionData.Current.RecognitionInfo[item] = null;
                } else {
                    return cachedResult.AsResultTask();
                }
            }

            try {
                var location = new Uri(item);
                if (!location.IsFile) {
                    // some sort of remote item.
                    // since we can't do anything with a remote item directly,
                    // we have to issue a request to the client to get it for us

                    // before we go down this, check to see if we asked for it in this session
                    // in the last five minutes or so. We don't need to pound away at a URL for
                    // no reason.
                    var peek = SessionData.Current.RecognitionInfo[location.AbsoluteUri];
                    if( peek != null ) {
                        if( DateTime.Now.Subtract(peek.LastAccessed) < new TimeSpan(0,5,0) ) {
                            return peek.AsResultTask();
                        }
                    }

                    // since we're expecting that the canonicalname will be used as a filename
                    // in the .cache directory, we need to generate a safe filename based on the
                    // data in the URL
                    var safeCanonicalName = location.GetLeftPart(UriPartial.Path).MakeSafeFileName();

                    return SessionData.Current.RequireRemoteFile(safeCanonicalName, location.SingleItemAsEnumerable(), PackageManagerSettings.CoAppPackageCache, forceRescan, state => {
                        if (state == null || string.IsNullOrEmpty(state.LocalLocation)) {
                            // didn't fill in the local location? -- this happens when the client can't download.
                            return Cache(location.AbsoluteUri, new RecognitionInfo {
                                FullPath = location.AbsoluteUri,
                                FullUrl = location,
                                IsURL = true,
                                IsInvalid = true,
                            });
                        }

                        var newLocation = new Uri(state.LocalLocation);
                        if (newLocation.IsFile) {
                            var continuedResult = Recognize(state.LocalLocation).Result;

                            // create the result object
                            var result = new RecognitionInfo {
                                FullUrl = location,
                            };

                            result.CopyDetailsFrom(continuedResult);
                            result.IsURL = true;

                            return Cache(item, result);
                        }

                        // so, the callback comes, but it's not a file.
                        // session cache it
                        return Cache(location.AbsoluteUri,new RecognitionInfo {
                            FullPath = location.AbsoluteUri,
                            IsInvalid = true,
                        });
                    }) as Task<RecognitionInfo>;
                }

                //----------------------------------------------------------------
                // we've managed to find a file system path.
                // let's figure out what it is.
                var localPath = location.LocalPath;

                if (localPath.Contains("?") || localPath.Contains("*")) {
                    // looks like a wildcard package feed.
                    // which is a directory feed with a filter.
                    var i = localPath.IndexOfAny(new[] {'*', '?'});

                    var lastSlash = localPath.LastIndexOf('\\', i);
                    var folder = localPath.Substring(0, lastSlash);
                    if (Directory.Exists(folder)) {
                        return CacheAndReturnTask(item, new RecognitionInfo {
                            FullPath = folder,
                            Filter = localPath.Substring(lastSlash + 1),
                            IsFolder = true,
                            IsPackageFeed = true
                        });
                    }
                }

                if (Directory.Exists(localPath)) {
                    // it's a directory.
                    // which means that it's a package feed.
                    return CacheAndReturnTask(item, new RecognitionInfo {
                        FullPath = localPath,
                        Filter = "*.msi", // TODO: evenutally, we have to expand this to detect other types.
                        IsFolder = true,
                        IsPackageFeed = true,
                    });
                }

                if (File.Exists(localPath)) {
                    var ext = Path.GetExtension(localPath);
                    var result = new RecognitionInfo {
                        IsFile = true,
                        FullPath = localPath
                    };

                    switch (ext) {
                        case ".msi":
                            result.IsCoAppMSI = CoAppMSI.IsValidPackageFile(localPath);
                            result.IsLegacyMSI = !result.IsCoAppMSI;
                            result.IsPackageFile = true;
                            break;

                        case ".nupkg":
                            result.IsNugetPackage = true;
                            result.IsPackageFile = true;
                            break;

                        case ".exe":
                            result.IsLegacyEXE = true;
                            result.IsPackageFile = true;
                            break;

                        case ".zip":
                        case ".cab":
                        case ".rar":
                        case ".7z":
                            result.IsArchive = true;
                            result.IsPackageFeed = true;
                            break;

                        default:
                            // guess based on file contents
                            try {
                                if (CoAppMSI.IsValidPackageFile(localPath)) {
                                    result.IsCoAppMSI = true;
                                    result.IsPackageFile = true;
                                }
                            } catch {
                                // not a coapp file...
                            }

                            if (localPath.IsXmlFile()) {
                                try {
                                    // this could be an atom feed
                                    var feed = AtomFeed.LoadFile(localPath);
                                    if (feed != null) {
                                        result.IsPackageFeed = true;
                                        result.IsAtom = true;
                                    }
                                } catch {
                                    // can't seem to figure out what this is.
                                    result.IsInvalid = true;
                                }
                            }
                            break;
                    }
                    return CacheAndReturnTask(item, result);
                }
            } catch (UriFormatException) {
            }
            // item wasn't able to match any known URI, UNC or Local Path format.
            // or was file not found
            return new RecognitionInfo {
                FullPath = item,
                IsInvalid = true,
            }.AsResultTask();
        }