using System;
using System.IO;
using NaGet.Packages;
using NaGet.Packages.Install;
using NaGet.Net;
using NaGet.SubCommands;
namespace NaGet.SubCommands
{
public class NaGetUpdate : NaGetTaskSet
{
private RepositoriesList repoList;
private PackageListsManager pkgListMan;
private bool downloadPackageLists = false;
private bool packageListsDownloaded = true;
///
/// ダウンロードに使うダウンローダオブジェクト
///
public Downloader Downloader {
get {
if (downloader == null) {
downloader = new Downloader();
downloader.DownloadEventRaised += delegate(object sender, DownloadEventArgs e) {
if (e.Type == DownloadEventType.DOWNLOADING && e.TaskProgressPercent > 0) {
RaiseTaskSetEvent(NaGetTaskSetEventType.PING, string.Empty, GetProgressPercent(NaGetTaskSetEventType.PING, e.TaskProgressPercent));
}
};
}
return downloader;
}
}
private Downloader downloader;
private int currentTaskSetIndex = -1;
private bool done = false;
public override int CurrentTaskSetIndex {
get { return currentTaskSetIndex; }
}
public override bool Cancelable {
get { return ! packageListsDownloaded; }
}
public NaGetUpdate(PackageListsManager pkgListMan)
: this(pkgListMan, true)
{
}
public NaGetUpdate(PackageListsManager pkgMan, bool downloadPackageListsFlag)
{
pkgListMan = pkgMan;
downloadPackageLists = downloadPackageListsFlag;
System.Collections.Generic.List taskSetNames = new System.Collections.Generic.List();
if (downloadPackageLists) {
// repos.list.xmlがあるとき、そこからよみとる。
repoList = NaGet.Utils.GetDeserializedObject(NaGet.Env.RepositoriesListFile);
foreach (RepositoryInfo repo in repoList.EnabledRepositories) {
taskSetNames.Add(string.Format("リスト取得: {0}", repo.Url.Href));
}
taskSetNames.Add(string.Format("リスト更新: {0}", NaGet.Env.PackageListFile));
}
taskSetNames.Add(string.Format("リスト更新: {0}", NaGet.Env.ArchiveInstalledPackageListFile));
taskSetNames.Add(string.Format("リスト更新: {0}", NaGet.Env.SystemInstalledPackageListFile));
TaskSetNames = taskSetNames.ToArray();
}
public override void Run()
{
currentTaskSetIndex ++;
RaiseTaskSetEvent(NaGetTaskSetEventType.STARTED, "リスト更新処理開始");
try {
// リストのダウンロード
if (downloadPackageLists) {
packageListsDownloaded = false;
try {
runDownloadPackageLists();
} catch (NaGetTaskCanceledException) {
RaiseTaskSetEvent(NaGetTaskSetEventType.WARNING, "リストのダウンロード処理がキャンセルされました");
pkgListMan.LoadPackageLists();
} catch (System.Net.WebException e) {
RaiseTaskSetEvent(NaGetTaskSetEventType.WARNING, e.Message);
if (System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable()) {
RaiseTaskSetEvent(NaGetTaskSetEventType.WARNING, "ネットワークに接続されていません。");
} else {
RaiseTaskSetEvent(NaGetTaskSetEventType.WARNING, "ネットワークに接続できませんでした。ネットワークが切断されているか、ファイアウォールによって遮断された可能性があります。");
}
pkgListMan.LoadPackageLists();
} finally {
int numOfEnabledRepos = NaGet.Utils.IEnumerable2Array(repoList.EnabledRepositories).Length;
currentTaskSetIndex = numOfEnabledRepos + 1;
}
packageListsDownloaded = true;
}
runLocalUpdate();
} finally {
done = true;
}
RaiseTaskSetEvent(NaGetTaskSetEventType.COMPLETED, "終了", 100);
}
private void runDownloadPackageLists()
{
PackageList avaiablePackageList = new PackageList();
foreach(RepositoryInfo repo in repoList.EnabledRepositories) {
RaiseTaskSetEvent(NaGetTaskSetEventType.STARTED_TASKSET, TaskSetNames[currentTaskSetIndex]);
if (Uri.IsWellFormedUriString(repo.Url.Href, UriKind.Absolute)) {
string tmpfileName = Path.GetTempFileName();
try {
Downloader.Download(repo.Url.Href, tmpfileName);
if (repo.Type == RepositoryType.APPLISTATION_NATIVE_XML_1_0) {
try {
PackageList pkgList = NaGet.Utils.GetDeserializedObject>(tmpfileName);
pkgList.FixPackageListName(); // PackageListNameとの紐付けを行う
// RepositoryReferenceの名前を読み込む // TODO RepositoryReferenceの名前を読み込む処理はここでいいのか?
repo.Name = (string.IsNullOrEmpty(pkgList.Name))? repo.Name : pkgList.Name;
avaiablePackageList.AddPackages(pkgList);
} catch (InvalidOperationException) {
RaiseTaskSetEvent(NaGetTaskSetEventType.ERROR, string.Format("レポジトリ'{0}'はAppliStation Native XML softlist形式ではありません。", repo.Name ?? repo.Url.Href));
}
} else {
RaiseTaskSetEvent(NaGetTaskSetEventType.WARNING, string.Format("レポジトリ'{0}'の設定が不正です。", repo.Name ?? repo.Url.Href));
}
} finally {
if (File.Exists(tmpfileName)) {
File.Delete(tmpfileName);
}
}
} else {
RaiseTaskSetEvent(NaGetTaskSetEventType.WARNING, string.Format("レポジトリ'{0}'のURLが不正なため、ソフトリストは取得できませんでした。", repo.Name ?? repo.Url.Href));
}
RaiseTaskSetEvent(NaGetTaskSetEventType.COMPLETED_TASKSET, TaskSetNames[currentTaskSetIndex]);
currentTaskSetIndex ++;
}
// TODO 暫定的にかならず常にrepositoryリストに書き込む。
if ( true ) {
NaGet.Utils.PutSerializeObject(NaGet.Env.RepositoriesListFile, repoList);
}
RaiseTaskSetEvent(NaGetTaskSetEventType.STARTED_TASKSET, TaskSetNames[currentTaskSetIndex]);
pkgListMan.availablePkgList = avaiablePackageList; // Mediatorのリストを更新
pkgListMan.SaveAvailablePackageList();
RaiseTaskSetEvent(NaGetTaskSetEventType.COMPLETED_TASKSET, TaskSetNames[currentTaskSetIndex]);
currentTaskSetIndex ++;
}
private void runLocalUpdate()
{
// インストールトリストの更新
RaiseTaskSetEvent(NaGetTaskSetEventType.STARTED_TASKSET, TaskSetNames[currentTaskSetIndex]);
pkgListMan.DetectInstalledPkgs();
pkgListMan.SaveInstalledPackageList();
RaiseTaskSetEvent(NaGetTaskSetEventType.COMPLETED_TASKSET, TaskSetNames[currentTaskSetIndex]);
currentTaskSetIndex++;
// システムにインストールされているリストの更新
RaiseTaskSetEvent(NaGetTaskSetEventType.STARTED_TASKSET, TaskSetNames[currentTaskSetIndex]);
pkgListMan.DetectSystemInstalledPkgs();
pkgListMan.SaveSystemInstalledPackageList();
RaiseTaskSetEvent(NaGetTaskSetEventType.COMPLETED_TASKSET, TaskSetNames[currentTaskSetIndex]);
currentTaskSetIndex++;
}
public override bool Cancel()
{
return Downloader.Cancel();
}
public override bool Done {
get { return done; }
}
}
}