/// <summary> /// Validates this message against the given server support /// </summary> public override void Validate(ServerSupport serverSupport) { base.Validate( serverSupport ); if ( serverSupport != null && serverSupport.MaxWatches <= 0 ) { throw new InvalidMessageException( NeboResources.ServerDoesNotSupportWatch ); } }
public async void NewProfile() { if (Model.SelectedAutoSelect != null) { var profile = Model.SelectedAutoSelect; var newp = new NewProfileViewModel() { Model = Model, Title = "自動選択プロファイル", Operation = "追加", IsDuplicate = Name => Model.AutoSelectList.Any( s => s.Model.Name.Equals(Name, StringComparison.OrdinalIgnoreCase)), Name = profile.Model.Name + "のコピー" }; await Messenger.RaiseAsync(new TransitionMessage( typeof(Views.NewProfileWindow), newp, TransitionMode.Modal, "FromProfile")); if (newp.Success) { var newprofile = ServerSupport.DeepCopy(profile.Model); newprofile.Name = newp.Name; await Model.AddAutoSelect(newprofile); } } }
public async void NewProfile() { if (Model.SelectedProfile != null) { var profile = Model.SelectedProfile; var newp = new NewProfileViewModel() { Model = Model, Title = "プロファイル", Operation = "追加", IsDuplicate = Name => Model.ProfileList.Any( s => s.Data.Name.Equals(Name, StringComparison.OrdinalIgnoreCase)), Name = profile.Data.Name + "のコピー" }; await Messenger.RaiseAsync(new TransitionMessage( typeof(Views.NewProfileWindow), newp, TransitionMode.Modal, "FromProfile")); if (newp.Success) { var newprofile = ServerSupport.DeepCopy(profile.Data); var invalidChars = System.IO.Path.GetInvalidFileNameChars(); newprofile.Name = new string(newp.Name.ToCharArray() .Where(c => Array.IndexOf(invalidChars, c) == -1).ToArray()); await Model.AddProfile(newprofile); } } }
public void Initialize() { if (Item.Outputs[0].DstPath == null) { ResetOutPath(); } if (Item.Outputs[0].Profile == null) { // 設定なしなら「デフォルト」を使う SelectedProfile = Model.ProfileList.FirstOrDefault(s => s.Data.Name == "デフォルト"); } else { bool isAuto = false; var profileName = ServerSupport.ParseProfileName(Item.Outputs[0].Profile, out isAuto); SelectedProfile = isAuto ? (object)Model.AutoSelectList.FirstOrDefault(s => s.Model.Name == profileName) : Model.ProfileList.FirstOrDefault(s => s.Data.Name == profileName); } OutPathHistory = Model.UIState.Model.OutputPathHistory.Select( path => new OutPathHistoryViewModel() { OutPathVM = this, Path = path }).ToList(); }
/// <summary> /// Validates this message against the given server support /// </summary> public override void Validate( ServerSupport serverSupport ) { base.Validate( serverSupport ); if ( serverSupport != null && !serverSupport.CallerId ) { throw new InvalidMessageException( NeboResources.ServerDoesNotSupportAccept ); } }
/// <summary> /// Validates this message against the given server support /// </summary> public override void Validate(ServerSupport serverSupport) { base.Validate(serverSupport); if (serverSupport != null && serverSupport.MaxMonitors == 0) { throw new InvalidMessageException(Resources.ServerDoesNotSupportMonitor); } }
/// <summary> /// Validates this message against the given server support /// </summary> public override void Validate(ServerSupport serverSupport) { base.Validate(serverSupport); for (int i = 0; i < this.Channels.Count; i++) { this.Channels[i] = MessageUtil.EnsureValidChannelName(this.Channels[i], serverSupport); } }
public void EnsureValidChannelName() { var defaultSupport = new ServerSupport(); Assert.AreEqual("#foo", MessageUtil.EnsureValidChannelName("#foo", defaultSupport)); Assert.AreEqual("#foo", MessageUtil.EnsureValidChannelName("foo", defaultSupport)); Assert.AreEqual("#", MessageUtil.EnsureValidChannelName("#", defaultSupport)); Assert.AreEqual("#irc", MessageUtil.EnsureValidChannelName("", defaultSupport)); }
/// <summary> /// Validates this message's properties according to the given <see cref="ServerSupport"/>. /// </summary> public override void Validate( ServerSupport serverSupport ) { base.Validate( serverSupport ); if ( serverSupport == null ) { return; } this.Channel = MessageUtil.EnsureValidChannelName( this.Channel, serverSupport ); if ( !serverSupport.Knock ) { System.Diagnostics.Trace.WriteLine( "Knock Is Not Supported On This Server" ); } }
public byte[] GetMacAddress() { // リモートのクライアントを見つけて、 // 接続に使っているNICのMACアドレスを取得する IPHostEntry iphostentry = Dns.GetHostEntry(Dns.GetHostName()); foreach (var client in ClientList) { if (IsRemoteHost(iphostentry, client.RemoteIP.Address)) { return(ServerSupport.GetMacAddress(client.LocalIP.Address)); } } return(null); }
private void DuplicateItem(QueueItem item, List <Task> waits) { var newItem = ServerSupport.DeepCopy(item); newItem.Id = nextItemId++; Queue.Add(newItem); // 状態はリセットしておく newItem.Reset(); UpdateQueueItem(newItem, null); waits.Add(ClientQueueUpdate(new QueueUpdate() { Type = UpdateType.Add, Item = newItem })); }
static void Main(string[] args) { try { // ログパスを設定 log4net.GlobalContext.Properties["Root"] = Directory.GetCurrentDirectory(); log4net.Config.XmlConfigurator.Configure(new FileInfo( Path.GetDirectoryName(typeof(ServerCLI).Assembly.Location) + "\\Log4net.Config.xml")); TaskSupport.SetSynchronizationContext(); GUIOPtion option = new GUIOPtion(args); using (var lockFile = ServerSupport.GetLock()) { log4net.ILog LOG = log4net.LogManager.GetLogger("Server"); Util.LogHandlers.Add(text => LOG.Info(text)); using (var server = new EncodeServer(option.ServerPort, null, () => { TaskSupport.Finish(); })) { var task = server.Init(); // この時点でtaskが完了していなくてもEnterMessageLoop()で続きが処理される TaskSupport.EnterMessageLoop(); // この時点では"継続"を処理する人がいないので、 // task.Wait()はデッドロックするので呼べないことに注意 // あとはプログラムが終了するだけなのでWait()しても意味がない } } } catch (MultipleInstanceException) { Console.WriteLine("多重起動を検知しました"); return; } catch (Exception e) { Console.WriteLine(e.Message); return; } }
public void Initialize() { if (Item.Outputs[0].DstPath == null) { ResetOutPath(); } if (Item.Outputs[0].Profile == null) { // 設定なしなら「デフォルト」を使う SelectedProfile = Model.ProfileList.FirstOrDefault(s => s.Data.Name == "デフォルト"); } else { bool isAuto = false; var profileName = ServerSupport.ParseProfileName(Item.Outputs[0].Profile, out isAuto); SelectedProfile = isAuto ? (object)Model.AutoSelectList.FirstOrDefault(s => s.Model.Name == profileName) : Model.ProfileList.FirstOrDefault(s => s.Data.Name == profileName); } }
public WebServerService(string physicalPath, int port) { if (port < 0) { port = GetPort(); } DirectoryInfo webDirectory = new DirectoryInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, physicalPath)); physicalPath = webDirectory.FullName; string serverType = typeof (Server).Assembly.Location; DeployAssembly(physicalPath, serverType); string serverSideType = typeof (ServerSupport).Assembly.Location; DeployAssembly(physicalPath, serverSideType); server = new Server(port, "/", physicalPath, false); string appId = (server.VirtualPath + server.PhysicalPath).ToLowerInvariant().GetHashCode().ToString("x", CultureInfo.InvariantCulture); ApplicationManager appManager = (ApplicationManager) server.GetType().GetField("_appManager", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(server); _serverSupport = (ServerSupport) appManager.CreateObject(appId, typeof (ServerSupport), server.VirtualPath, server.PhysicalPath, true, true); server.Start(); }
private async Task <bool> GetGlobalLock() { try { lockFile = ServerSupport.GetLock(); } catch (MultipleInstanceException) { var message = new InformationMessage( "多重起動を検知しました", "AmatsukazeServer", "Message"); await Messenger.RaiseAsync(message); await RealCloseWindow(); return(false); } return(true); }
public async void NewProfile() { if (Model.SelectedAutoSelect != null) { var profile = Model.SelectedAutoSelect; var newp = new NewAutoSelectViewModel() { Model = Model, Name = profile.Model.Name + "のコピー" }; await Messenger.RaiseAsync(new TransitionMessage( typeof(Views.NewAutoSelectWindow), newp, TransitionMode.Modal, "FromProfile")); if (newp.Success) { var newprofile = ServerSupport.DeepCopy(profile.Model); newprofile.Name = newp.Name; await Model.AddAutoSelect(newprofile); } } }
public async void StopServer() { if (ServerSupport.IsLocalIP(Model.ServerIP)) { var message = new ConfirmationMessage( "AmatsukazeServerを終了しますか?", "AmatsukazeServer", System.Windows.MessageBoxImage.Information, System.Windows.MessageBoxButton.OKCancel, "Confirm"); await Messenger.RaiseAsync(message); if (message.Response == true) { await Model.Server?.EndServer(); } } else { // } }
private bool CheckProfile(QueueItem item, List <Task> waits) { if (item.Profile != server.PendingProfile) { // すでにプロファイルが決定済み return(true); } if (item.State == QueueState.PreFailed) { // TSファイルの情報取得に失敗している return(false); } // ペンディングならプロファイルの決定を試みる int itemPriority = 0; var profile = server.SelectProfile(item, out itemPriority); if (profile == null) { return(false); } item.Profile = ServerSupport.DeepCopy(profile); if (itemPriority > 0) { item.Priority = itemPriority; } waits?.Add(ClientQueueUpdate(new QueueUpdate() { Type = UpdateType.Remove, Item = item })); return(true); }
public async void NewProfile() { if (Model.SelectedProfile != null) { var profile = Model.SelectedProfile; var newp = new NewProfileViewModel() { Model = Model, Name = profile.Data.Name + "のコピー" }; await Messenger.RaiseAsync(new TransitionMessage( typeof(Views.NewProfileWindow), newp, TransitionMode.Modal, "FromProfile")); if (newp.Success) { var newprofile = ServerSupport.DeepCopy(profile.Data); var invalidChars = System.IO.Path.GetInvalidFileNameChars(); newprofile.Name = new string(newp.Name.ToCharArray() .Where(c => Array.IndexOf(invalidChars, c) == -1).ToArray()); await Model.AddProfile(newprofile); } } }
public async void MakeBatchFile() { string cur = Directory.GetCurrentDirectory(); string exe = Path.GetDirectoryName(GetType().Assembly.Location); string dst = Model.MakeScriptData.OutDir?.TrimEnd(Path.DirectorySeparatorChar); string prof = DisplayProfile.GetProfileName(Model.MakeScriptData.SelectedProfile); string bat = Model.MakeScriptData.Model.AddQueueBat; string nas = null; string ip = "localhost"; int port = Model.ServerPort; string subnet = null; string mac = null; bool direct = Model.MakeScriptData.IsDirect; if (prof == null) { Description = "プロファイルを選択してください"; return; } if (string.IsNullOrEmpty(dst)) { Description = "出力先が設定されていません"; return; } if (Directory.Exists(dst) == false) { Description = "出力先ディレクトリにアクセスできません"; return; } if (Model.MakeScriptData.IsNasEnabled) { if (string.IsNullOrEmpty(Model.MakeScriptData.NasDir)) { Description = "NAS保存先を指定してください。"; return; } nas = Model.MakeScriptData.NasDir.TrimEnd(Path.DirectorySeparatorChar);; } if (IsRemoteClient) { ip = Model.ServerIP; if (Model.MakeScriptData.IsWakeOnLan) { var localIP = Model.LocalIP; if (localIP == null) { Description = "IPアドレス取得に失敗"; return; } if (localIP.AddressFamily != System.Net.Sockets.AddressFamily.InterNetwork) { Description = "IPv4以外の接続には対応していません"; return; } var subnetaddr = ServerSupport.GetSubnetMask(((IPEndPoint)localIP).Address); if (subnetaddr == null) { Description = "サブネットマスク取得に失敗"; return; } subnet = subnetaddr.ToString(); var macbytes = Model.MacAddress; if (macbytes == null) { Description = "MACアドレス取得に失敗"; return; } mac = string.Join(":", macbytes.Select(s => s.ToString("X"))); } } Description = ""; var sb = new StringBuilder(); if (direct) { sb.Append("rem _EDCBX_DIRECT_\r\n"); } sb.AppendFormat("\"{0}\\AmatsukazeAddTask.exe\"", exe) .AppendFormat(" -r \"{0}\"", cur) .AppendFormat(" -f \"{0}FilePath{0}\" -ip \"{1}\"", direct ? "%" : "$", ip) .AppendFormat(" -p {0}", port) .AppendFormat(" -o \"{0}\"", dst) .AppendFormat(" -s \"{0}\"", prof) .AppendFormat(" --priority {0}", Model.MakeScriptData.Priority); if (nas != null) { sb.AppendFormat(" -d \"{0}\"", nas); } if (mac != null) { sb.AppendFormat(" --subnet \"{0}\"", subnet) .AppendFormat(" --mac \"{0}\"", mac); } if (Model.MakeScriptData.MoveAfter == false) { sb.Append(" --no-move"); } if (Model.MakeScriptData.ClearSucceeded) { sb.Append(" --clear-succeeded"); } if (Model.MakeScriptData.WithRelated) { sb.Append(" --with-related"); } if (!string.IsNullOrEmpty(bat)) { sb.AppendFormat(" -b \"{0}\"", bat); } var saveFileDialog = new SaveFileDialog(); saveFileDialog.FilterIndex = 1; saveFileDialog.Filter = "バッチファイル(.bat)|*.bat|All Files (*.*)|*.*"; bool?result = saveFileDialog.ShowDialog(); if (result != true) { return; } try { File.WriteAllText(saveFileDialog.FileName, sb.ToString(), Encoding.Default); } catch (Exception e) { Description = "バッチファイル作成に失敗: " + e.Message; return; } var resvm = new MakeBatchResultViewModel() { Path = saveFileDialog.FileName }; await Messenger.RaiseAsync(new TransitionMessage( typeof(Views.MakeBatchResultWindow), resvm, TransitionMode.Modal, "Key")); await Model.SendMakeScriptData(); }
public async Task Exec() { string srcpath = option.FilePath; byte[] hash = null; if (string.IsNullOrEmpty(option.NasDir) == false) { if (File.Exists(option.FilePath) == false) { throw new Exception("入力ファイルが見つかりません"); } if (option.ClearSucceeded) { // succeededを空にする var succeeded = option.NasDir + Path.DirectorySeparatorChar + "succeeded"; if (Directory.Exists(succeeded)) { foreach (var file in Directory.GetFiles(succeeded)) { File.Delete(file); } } } // NASにコピー var remotepath = option.NasDir + Path.DirectorySeparatorChar + Path.GetFileName(srcpath); hash = await HashUtil.CopyWithHash(option.FilePath, remotepath); srcpath = remotepath; if (option.WithRelated) { var body = Path.GetFileNameWithoutExtension(option.FilePath); var tsext = Path.GetExtension(option.FilePath); var srcDir = Path.GetDirectoryName(option.FilePath); foreach (var ext in ServerSupport.GetFileExtentions(null, true)) { string srcPath = srcDir + Path.DirectorySeparatorChar + body + ext; string dstPath = option.NasDir + Path.DirectorySeparatorChar + body + ext; if (File.Exists(srcPath)) { File.Copy(srcPath, dstPath); } } } } if (string.IsNullOrEmpty(option.RemoteDir) == false) { // これはサーバからのアクセス用パスなので"\\"で区切る srcpath = option.RemoteDir + "\\" + Path.GetFileName(srcpath); } Console.WriteLine(srcpath + " を追加します"); // リクエストを生成 request = new AddQueueRequest() { DirPath = Path.GetDirectoryName(srcpath), Outputs = new List <OutputInfo>() { new OutputInfo() { DstPath = option.OutPath, Profile = option.Profile, Priority = option.Priority, } }, Targets = new List <AddQueueItem>() { new AddQueueItem() { Path = srcpath, Hash = hash } }, Mode = ProcMode.AutoBatch, RequestId = UniqueId(), AddQueueBat = option.AddQueueBat }; server = new CUIServerConnection(this); bool isLocal = !IsRunningOnMono() && ServerSupport.IsLocalIP(option.ServerIP); int maxRetry = isLocal ? 3 : 5; for (int i = 0; i < maxRetry; ++i) { if (i > 0) { Console.WriteLine("再試行します・・・"); } try { // サーバに接続 server.Connect(option.ServerIP, option.ServerPort); } catch (Exception e0) { Console.WriteLine(e0.StackTrace); // サーバに繋がらなかった // ローカルの場合は、起動を試みる if (isLocal) { await ServerSupport.TerminateStandalone(option.AmatsukazeRoot); ServerSupport.LaunchLocalServer(option.ServerPort, option.AmatsukazeRoot); // 10秒待つ await Task.Delay(10 * 1000); } else { // リモートの場合は、Wake On Lanする if (option.MacAddress == null) { throw new Exception("リモートサーバへの接続に失敗しました。"); } Console.WriteLine("Wake On Lanで起動を試みます。"); WakeOnLan.Wake( IPAddress.Parse(option.ServerIP), IPAddress.Parse(option.Subnet), option.MacAddress); // 40秒待つ await Task.Delay(40 * 1000); } continue; } try { // サーバにタスク登録 await server.AddQueue(request); // リクエストIDの完了通知ゲット or タイムアウトしたら終了 var timeout = Task.Delay(30 * 1000); while (okReceived == false) { var recv = server.ProcOneMessage(); if (await Task.WhenAny(recv, timeout) == timeout) { Console.WriteLine("サーバのリクエスト受理を確認できませんでした。"); throw new Exception(); } } } catch (Exception e1) { Console.WriteLine(e1.StackTrace); // なぜか失敗した continue; } if (string.IsNullOrEmpty(option.NasDir) == false && !option.NoMove) { // NASにコピーしたファイルはtransferredフォルダに移動 string trsDir = Path.GetDirectoryName(option.FilePath) + Path.DirectorySeparatorChar + "transferred"; Directory.CreateDirectory(trsDir); string trsFile = trsDir + Path.DirectorySeparatorChar + Path.GetFileName(option.FilePath); if (File.Exists(option.FilePath)) { if (File.Exists(trsFile)) { // 既に存在している同名ファイルは削除 File.Delete(trsFile); } File.Move(option.FilePath, trsFile); } if (option.WithRelated) { var body = Path.GetFileNameWithoutExtension(option.FilePath); var tsext = Path.GetExtension(option.FilePath); var srcDir = Path.GetDirectoryName(option.FilePath); foreach (var ext in ServerSupport.GetFileExtentions(null, true)) { string srcPath = srcDir + Path.DirectorySeparatorChar + body + ext; string dstPath = trsDir + Path.DirectorySeparatorChar + body + ext; if (File.Exists(srcPath)) { if (File.Exists(dstPath)) { // 既に存在している同名ファイルは削除 File.Delete(dstPath); } File.Move(srcPath, dstPath); } } } } break; } server.Finish(); }
/// <summary> /// Validates this message against the given server support /// </summary> public override void Validate(ServerSupport serverSupport) { base.Validate(serverSupport); MessageUtil.EnsureValidChannelName(this.Channel, serverSupport); if (string.IsNullOrEmpty(this.Target)) { throw new InvalidMessageException(Resources.TargetcannotBeEmpty); } if (string.IsNullOrEmpty(this.Channel)) { throw new InvalidMessageException(Resources.ChannelCannotBeEmpty); } }
/// <exclude /> public override void Validate( ServerSupport serverSupport ) { base.Validate( serverSupport ); if ( serverSupport != null ) { if ( MaxUsers >= 0 || MinUsers >= 0 ) { VerifySupport( serverSupport, ServerSupport.ExtendedListParameters.UserCount ); } if ( YoungerThan >= 0 || OlderThan >= 0 ) { VerifySupport( serverSupport, ServerSupport.ExtendedListParameters.CreationTime ); } if ( !String.IsNullOrEmpty( MatchMask ) ) { VerifySupport( serverSupport, ServerSupport.ExtendedListParameters.Mask ); } if ( !String.IsNullOrEmpty( NotMatchMask ) ) { VerifySupport( serverSupport, ServerSupport.ExtendedListParameters.NotMask ); } if ( TopicOlderThan >= 0 || TopicYoungerThan >= 0 ) { VerifySupport( serverSupport, ServerSupport.ExtendedListParameters.Topic ); } } }
/// <summary> /// Validates this message against the given server support /// </summary> public override void Validate( ServerSupport serverSupport ) { base.Validate( serverSupport ); Channel = MessageUtil.EnsureValidChannelName( Channel, serverSupport ); }
static void VerifySupport( ServerSupport serverSupport, ServerSupport.ExtendedListParameters parameter ) { if ( ( serverSupport.ExtendedList & parameter ) != parameter ) { throw new InvalidMessageException( String.Format( CultureInfo.InvariantCulture, NeboResources.ServerDoesNotSupportExtendedListParameter, parameter.ToString() ) ); } }
public Task ChangeItem(ChangeItemData data) { if (data.ChangeType == ChangeItemType.RemoveCompleted) { var waits = new List <Task>(); RemoveCompleted(waits); return(Task.WhenAll(waits)); } // アイテム操作 var target = Queue.FirstOrDefault(s => s.Id == data.ItemId); if (target == null) { return(server.NotifyError( "指定されたアイテムが見つかりません", false)); } if (data.ChangeType == ChangeItemType.ResetState || data.ChangeType == ChangeItemType.UpdateProfile || data.ChangeType == ChangeItemType.Duplicate) { if (target.State == QueueState.PreFailed) { return(server.NotifyError("このアイテムは追加処理に失敗しているため操作できません", false)); } if (data.ChangeType == ChangeItemType.ResetState) { // エンコード中は変更できない if (target.State == QueueState.Encoding) { return(server.NotifyError("エンコード中のアイテムはリトライできません", false)); } } else if (data.ChangeType == ChangeItemType.UpdateProfile) { // エンコード中は変更できない if (target.State == QueueState.Encoding) { return(server.NotifyError("エンコード中のアイテムはプロファイル更新できません", false)); } } else if (data.ChangeType == ChangeItemType.Duplicate) { // バッチモードでアクティブなやつは重複になるのでダメ if (target.IsBatch && target.IsActive) { return(server.NotifyError("通常モードで追加されたアイテムは複製できません", false)); } } var waits = new List <Task>(); if (target.IsBatch) { // バッチモードでfailed/succeededフォルダに移動されていたら戻す if (target.State == QueueState.Failed || target.State == QueueState.Complete) { if (Queue.Where(s => s.SrcPath == target.SrcPath).Any(s => s.IsActive) == false) { var dirPath = Path.GetDirectoryName(target.SrcPath); var movedDir = (target.State == QueueState.Failed) ? ServerSupport.FAIL_DIR : ServerSupport.SUCCESS_DIR; var movedPath = dirPath + "\\" + movedDir + "\\" + Path.GetFileName(target.SrcPath); if (File.Exists(movedPath)) { // EDCB関連ファイルも移動したかどうかは分からないが、あれば戻す try { ServerSupport.MoveTSFile(movedPath, dirPath, true); } catch (Exception e) { return(server.FatalError( "ファイルの移動に失敗しました", e)); } } } } } if (data.ChangeType == ChangeItemType.ResetState) { // リトライはプロファイル再適用も行う UpdateProfileItem(target, waits); ResetStateItem(target, waits); waits.Add(server.NotifyMessage("リトライします", false)); } else if (data.ChangeType == ChangeItemType.UpdateProfile) { if (UpdateProfileItem(target, waits)) { waits.Add(server.NotifyMessage("新しいプロファイルが適用されました", false)); } else { waits.Add(server.NotifyMessage("すでに最新のプロファイルが適用されています", false)); } } else { DuplicateItem(target, waits); waits.Add(server.NotifyMessage("複製しました", false)); } return(Task.WhenAll(waits)); } else if (data.ChangeType == ChangeItemType.Cancel) { if (server.CancelItem(target) || target.IsActive) { target.State = QueueState.Canceled; return(Task.WhenAll( ClientQueueUpdate(new QueueUpdate() { Type = UpdateType.Update, Item = target }), server.NotifyMessage("キャンセルしました", false))); } else { return(server.NotifyError( "このアイテムはアクティブ状態でないため、キャンセルできません", false)); } } else if (data.ChangeType == ChangeItemType.Priority) { target.Priority = data.Priority; server.ReScheduleQueue(); return(Task.WhenAll( ClientQueueUpdate(new QueueUpdate() { Type = UpdateType.Update, Item = target }), server.NotifyMessage("優先度を変更しました", false))); } else if (data.ChangeType == ChangeItemType.Profile) { if (target.State == QueueState.Encoding) { return(server.NotifyError("エンコード中はプロファイル変更できません", false)); } if (target.State == QueueState.PreFailed) { return(server.NotifyError("このアイテムはプロファイル変更できません", false)); } var waits = new List <Task>(); target.ProfileName = data.Profile; if (UpdateProfileItem(target, waits)) { waits.Add(server.NotifyMessage("プロファイルを「" + data.Profile + "」に変更しました", false)); } else { waits.Add(server.NotifyMessage("既に同じプロファイルが適用されています", false)); } return(Task.WhenAll(waits)); } else if (data.ChangeType == ChangeItemType.RemoveItem) { server.CancelItem(target); target.State = QueueState.Canceled; Queue.Remove(target); UpdateQueueOrder(); return(Task.WhenAll( ClientQueueUpdate(new QueueUpdate() { Type = UpdateType.Remove, Item = target }), server.NotifyMessage("アイテムを削除しました", false))); } else if (data.ChangeType == ChangeItemType.ForceStart) { if (target.State != QueueState.Queue) { return(server.NotifyError("待ち状態にないアイテムは開始できません", false)); } else { server.ForceStartItem(target); } } else if (data.ChangeType == ChangeItemType.RemoveSourceFile) { if (target.IsBatch == false) { return(server.NotifyError("通常or自動追加以外はTSファイル削除ができません", false)); } if (target.State != QueueState.Complete) { return(server.NotifyError("完了していないアイテムはTSファイル削除ができません", false)); } if (Queue.Where(s => s.SrcPath == target.SrcPath).Any(s => s.IsActive)) { return(server.NotifyError("まだ完了していない項目があるため、このTSは削除ができません", false)); } // !!!削除!!! var dirPath = Path.GetDirectoryName(target.SrcPath); var movedPath = dirPath + "\\" + ServerSupport.SUCCESS_DIR + "\\" + Path.GetFileName(target.SrcPath); if (File.Exists(movedPath)) { // EDCB関連ファイルも移動したかどうかは分からないが、あれば消す try { ServerSupport.DeleteTSFile(movedPath, true); } catch (Exception e) { return(server.FatalError( "ファイルの削除に失敗しました", e)); } } // アイテム削除 Queue.Remove(target); UpdateQueueOrder(); return(Task.WhenAll( ClientQueueUpdate(new QueueUpdate() { Type = UpdateType.Remove, Item = target }), server.NotifyMessage("TSファイルを削除しました", false))); } else if (data.ChangeType == ChangeItemType.Move) { if (data.Position >= Queue.Count) { return(server.NotifyError("位置が範囲外です", false)); } Queue.Remove(target); Queue.Insert(data.Position, target); UpdateQueueOrder(); return(Task.WhenAll( ClientQueueUpdate(new QueueUpdate() { Type = UpdateType.Move, Item = target, Position = data.Position }))); } return(Task.FromResult(0)); }
// アイテムのProfileNameからプロファイルを決定して、 // オプションでwaits!=nullのときはクライアントに通知 // 戻り値: プロファイルが変更された場合(結果、エラーになった場合も含む) private bool UpdateProfileItem(QueueItem item, List <Task> waits) { var getResult = server.GetProfile(item, item.ProfileName); var profile = (getResult != null) ? ServerSupport.DeepCopy(getResult.Profile) : server.PendingProfile; var priority = (getResult != null && getResult.Priority > 0) ? getResult.Priority : item.Priority; if (item.Profile == null || item.Profile.Name != profile.Name || item.Profile.LastUpdate != profile.LastUpdate || item.Priority != priority) { // 変更 item.Profile = profile; item.Priority = priority; // ハッシュリスト取得 if (profile != server.PendingProfile && // ペンディングの場合は決定したときに実行される item.IsSeparateHashRequired) { var hashpath = Path.GetDirectoryName(item.SrcPath) + ".hash"; if (hashCache.ContainsKey(hashpath) == false) { if (File.Exists(hashpath) == false) { item.State = QueueState.LogoPending; item.FailReason = "ハッシュファイルがありません: " + hashpath; return(true); } else { try { hashCache.Add(hashpath, new DirHash() { DirPath = hashpath, HashDict = HashUtil.ReadHashFile(hashpath) }); } catch (IOException e) { item.State = QueueState.LogoPending; item.FailReason = "ハッシュファイルの読み込みに失敗: " + e.Message; return(true); } } } var cacheItem = hashCache[hashpath]; var filename = item.FileName; if (cacheItem.HashDict.ContainsKey(filename) == false) { item.State = QueueState.LogoPending; item.FailReason = "ハッシュファイルにこのファイルのハッシュがありません"; return(true); } item.Hash = cacheItem.HashDict[filename]; } server.ReScheduleQueue(); UpdateQueueItem(item, waits); waits?.Add(ClientQueueUpdate(new QueueUpdate() { Type = UpdateType.Add, Item = item })); return(true); } return(false); }
public async Task AddQueue(AddQueueRequest req) { List <Task> waits = new List <Task>(); addQueueCanceled = false; // ユーザ操作でない場合はログを記録する bool enableLog = (req.Mode == ProcMode.AutoBatch); if (req.Outputs.Count == 0) { await server.NotifyError("出力が1つもありません", enableLog); return; } // 既に追加されているファイルは除外する // バッチのときは全ファイルが対象だが、バッチじゃなければバッチのみが対象 var ignores = req.IsBatch ? Queue : Queue.Where(t => t.IsBatch); var ignoreSet = new HashSet <string>( ignores.Where(item => item.IsActive) .Select(item => item.SrcPath)); var items = ((req.Targets != null) ? req.Targets : Directory.GetFiles(req.DirPath) .Where(s => { string lower = s.ToLower(); return(lower.EndsWith(".ts") || lower.EndsWith(".m2t")); }) .Select(f => new AddQueueItem() { Path = f })) .Where(f => !ignoreSet.Contains(f.Path)).ToList(); waits.Add(WriteLine("" + items.Count + "件を追加処理します")); var map = server.ServiceMap; var numItems = 0; var progress = 0; // TSファイル情報を読む foreach (var additem in items) { waits.Add(WriteLine("(" + (++progress) + "/" + items.Count + ") " + Path.GetFileName(additem.Path) + " を処理中")); using (var info = new TsInfo(amtcontext)) { var failReason = ""; var addItems = new List <QueueItem>(); if (await Task.Run(() => info.ReadFile(additem.Path)) == false) { failReason = "TS情報取得に失敗: " + amtcontext.GetError(); } else { failReason = "TSファイルに映像が見つかりませんでした"; var list = info.GetProgramList(); var videopids = new List <int>(); int numFiles = 0; for (int i = 0; i < list.Length; ++i) { var prog = list[i]; if (prog.HasVideo && videopids.Contains(prog.VideoPid) == false) { videopids.Add(prog.VideoPid); var serviceName = "不明"; var tsTime = DateTime.MinValue; if (info.HasServiceInfo) { var service = info.GetServiceList().Where(s => s.ServiceId == prog.ServiceId).FirstOrDefault(); if (service.ServiceId != 0) { serviceName = service.ServiceName; } tsTime = info.GetTime(); } var outname = Path.GetFileNameWithoutExtension(additem.Path); if (numFiles > 0) { outname += "-マルチ" + numFiles; } Debug.Print("解析完了: " + additem.Path); foreach (var outitem in req.Outputs) { var genre = prog.Content.Select(s => ServerSupport.GetGenre(s)).ToList(); var item = new QueueItem() { Id = nextItemId++, Mode = req.Mode, SrcPath = additem.Path, Hash = additem.Hash, DstPath = outitem.DstPath + "\\" + outname, ServiceId = prog.ServiceId, ImageWidth = prog.Width, ImageHeight = prog.Height, TsTime = tsTime, ServiceName = serviceName, EventName = prog.EventName, State = QueueState.LogoPending, Priority = outitem.Priority, AddTime = DateTime.Now, ProfileName = outitem.Profile, Genre = genre, Tags = new List <string>() }; if (item.IsOneSeg) { item.State = QueueState.PreFailed; item.FailReason = "映像が小さすぎます(" + prog.Width + "," + prog.Height + ")"; } else { // ロゴファイルを探す if (req.Mode != ProcMode.DrcsCheck && map.ContainsKey(item.ServiceId) == false) { // 新しいサービスを登録 waits.Add(server.AddService(new ServiceSettingElement() { ServiceId = item.ServiceId, ServiceName = item.ServiceName, LogoSettings = new List <LogoSetting>() })); } // 追加時バッチ if (string.IsNullOrEmpty(req.AddQueueBat) == false) { waits.Add(WriteLine("追加時バッチ起動")); using (var scriptExecuter = new UserScriptExecuter() { Server = server, Phase = ScriptPhase.OnAdd, ScriptPath = server.GetBatDirectoryPath() + "\\" + req.AddQueueBat, Item = item, Prog = prog, OnOutput = WriteTextBytes }) { process = scriptExecuter; await scriptExecuter.Execute(); process = null; } if (addQueueCanceled) { break; } } ++numFiles; } addItems.Add(item); } } } } if (addQueueCanceled) { break; } if (addItems.Count == 0) { // アイテムが1つもないときはエラー項目として追加 foreach (var outitem in req.Outputs) { bool isAuto = false; var profileName = ServerSupport.ParseProfileName(outitem.Profile, out isAuto); var profile = isAuto ? null : ServerSupport.DeepCopy(server.GetProfile(profileName)); var item = new QueueItem() { Id = nextItemId++, Mode = req.Mode, Profile = profile, SrcPath = additem.Path, Hash = additem.Hash, DstPath = "", ServiceId = -1, ImageWidth = -1, ImageHeight = -1, TsTime = DateTime.MinValue, ServiceName = "不明", State = QueueState.PreFailed, FailReason = failReason, AddTime = DateTime.Now, ProfileName = outitem.Profile, Tags = new List <string>() }; addItems.Add(item); } } // 1ソースファイルに対するaddはatomicに実行したいので、 // このループではawaitしないこと foreach (var item in addItems) { if (item.State != QueueState.PreFailed) { // プロファイルを設定 UpdateProfileItem(item, null); } // 追加 item.Order = Queue.Count; Queue.Add(item); // まずは内部だけで状態を更新 UpdateQueueItem(item, null); // 状態が決まったらクライアント側に追加通知 waits.Add(ClientQueueUpdate(new QueueUpdate() { Type = UpdateType.Add, Item = item })); } numItems += addItems.Count; UpdateProgress(); waits.Add(server.RequestState()); } if (addQueueCanceled) { break; } } if (addQueueCanceled) { waits.Add(WriteLine("キャンセルされました")); } waits.Add(WriteLine("" + numItems + "件追加しました")); if (addQueueCanceled == false && numItems == 0) { waits.Add(server.NotifyError( "エンコード対象ファイルがありませんでした。パス:" + req.DirPath, enableLog)); await Task.WhenAll(waits); return; } else { waits.Add(server.NotifyMessage("" + numItems + "件追加しました", false)); } if (req.Mode != ProcMode.AutoBatch) { // 最後に使った設定を記憶しておく server.LastUsedProfile = req.Outputs[0].Profile; server.AddOutPathHistory(req.Outputs[0].DstPath); server.LastAddQueueBat = req.AddQueueBat; waits.Add(server.RequestUIState()); } waits.Add(server.RequestFreeSpace()); await Task.WhenAll(waits); }
/// <summary> /// Validates this message against the given server support /// </summary> public override void Validate( ServerSupport serverSupport ) { base.Validate( serverSupport ); if ( serverSupport == null ) { return; } if ( Reason.Length > serverSupport.MaxKickCommentLength ) { Reason = Reason.Substring( 0, serverSupport.MaxKickCommentLength ); } for ( Int32 i = 0; i < Channels.Count; i++ ) { Channels[ i ] = MessageUtil.EnsureValidChannelName( Channels[ i ], serverSupport ); } }
/// <summary> /// Validates this message against the given server support. /// </summary> public virtual void Validate(ServerSupport serverSupport) { }
private static void VerifySupport(ServerSupport serverSupport, ServerSupport.ExtendedListParameters parameter) { if (!serverSupport.ExtendedList.HasFlag(parameter)) { throw new InvalidMessageException(string.Format(CultureInfo.InvariantCulture, Resources.ServerDoesNotSupportExtendedListParameter, parameter)); } }
/// <summary> /// Validates this message against the given server support /// </summary> public override void Validate(ServerSupport serverSupport) { base.Validate(serverSupport); Channels = (from channel in Channels select MessageUtil.EnsureValidChannelName(channel, serverSupport)).ToList(); }
public void SupportMessage() { var raws = new[] { ":irc.easynews.com 005 _aLfa_ CHANLIMIT=#&:25 WALLCHOPS KNOCK EXCEPTS INVEX MODES=4 MAXCHANNELS=35 MAXBANS=25 MAXTARGETS=4 NICKLEN=9 TOPICLEN=120 KICKLEN=120 :are supported by this server", ":irc.foxlink.net 005 SupayBot STD=i-d STATUSMSG=@+ KNOCK EXCEPTS=e INVEX=I MODES=4 MAXCHANNELS=50 MAXLIST=beI:100 MAXTARGETS=7 NICKLEN=9 TOPICLEN=120 KICKLEN=120 :are supported by this server", ":irc.foxlink.net 005 SupayBot CHANTYPES=#& PREFIX=(ov)@+ CHANMODES=eIb,k,l,imnpst NETWORK=EFNet CASEMAPPING=rfc1459 CHARSET=ascii CALLERID ETRACE WALLCHOPS :are supported by this server" }; for (var i = 0; i < raws.Length; i++) { var msg = MessageAssert.TypeAndRoundTrip<SupportMessage>(raws[i]); var support = new ServerSupport(); support.LoadInfo(msg); switch (i) { case 0: Assert.AreEqual(12, msg.SupportedItems.Count, "SupportItems Count"); Assert.IsNotNull(msg.SupportedItems["CHANLIMIT"], "CHANLIMIT"); Assert.IsNotNull(msg.SupportedItems["WALLCHOPS"], "WALLCHOPS"); Assert.IsNotNull(msg.SupportedItems["KNOCK"], "KNOCK"); Assert.IsNotNull(msg.SupportedItems["EXCEPTS"], "EXCEPTS"); Assert.IsNotNull(msg.SupportedItems["INVEX"], "INVEX"); Assert.IsNotNull(msg.SupportedItems["MODES"], "MODES"); Assert.IsNotNull(msg.SupportedItems["MAXCHANNELS"], "MAXCHANNELS"); Assert.IsNotNull(msg.SupportedItems["MAXBANS"], "MAXBANS"); Assert.IsNotNull(msg.SupportedItems["MAXTARGETS"], "MAXTARGETS"); Assert.IsNotNull(msg.SupportedItems["NICKLEN"], "NICKLEN"); Assert.IsNotNull(msg.SupportedItems["TOPICLEN"], "TOPICLEN"); Assert.IsNotNull(msg.SupportedItems["KICKLEN"], "KICKLEN"); Assert.AreEqual("#&:25", msg.SupportedItems["CHANLIMIT"], "CHANLIMIT"); Assert.AreEqual("4", msg.SupportedItems["MODES"], "MODES"); Assert.AreEqual("35", msg.SupportedItems["MAXCHANNELS"], "MAXCHANNELS"); Assert.AreEqual("25", msg.SupportedItems["MAXBANS"], "MAXBANS"); Assert.AreEqual("4", msg.SupportedItems["MAXTARGETS"], "MAXTARGETS"); Assert.AreEqual("9", msg.SupportedItems["NICKLEN"], "NICKLEN"); Assert.AreEqual("120", msg.SupportedItems["TOPICLEN"], "TOPICLEN"); Assert.AreEqual("120", msg.SupportedItems["KICKLEN"], "KICKLEN"); Assert.AreEqual(2, support.ChannelLimits.Count, "ChannelLimits"); Assert.AreEqual(25, support.ChannelLimits["#"], "ChannelLimits"); Assert.AreEqual(25, support.ChannelLimits["&"], "ChannelLimits"); Assert.IsTrue(support.MessagesToOperators, "MessagesToOperators"); Assert.IsTrue(support.Knock, "Knock"); Assert.IsTrue(support.BanExceptions, "BanExceptions"); Assert.IsTrue(support.InvitationExceptions, "InvitationExceptions"); Assert.AreEqual(4, support.MaxModes, "MaxModes"); Assert.AreEqual(35, support.MaxChannels, "MaxChannels"); Assert.AreEqual(25, support.MaxBans, "MaxBans"); Assert.AreEqual(4, support.MaxMessageTargets[""], "MaxMessageTargets"); Assert.AreEqual(9, support.MaxNickLength, "MaxNickLength"); Assert.AreEqual(120, support.MaxTopicLength, "MaxTopicLength"); Assert.AreEqual(120, support.MaxKickCommentLength, "MaxKickCommentLength"); break; case 1: Assert.AreEqual(12, msg.SupportedItems.Count, "SupportedItems Count"); Assert.IsNotNull(msg.SupportedItems["STD"], "STD"); Assert.IsNotNull(msg.SupportedItems["STATUSMSG"], "STATUSMSG"); Assert.IsNotNull(msg.SupportedItems["KNOCK"], "KNOCK"); Assert.IsNotNull(msg.SupportedItems["EXCEPTS"], "EXCEPTS"); Assert.IsNotNull(msg.SupportedItems["INVEX"], "INVEX"); Assert.IsNotNull(msg.SupportedItems["MODES"], "MODES"); Assert.IsNotNull(msg.SupportedItems["MAXCHANNELS"], "MAXCHANNELS"); Assert.IsNotNull(msg.SupportedItems["MAXLIST"], "MAXLIST"); Assert.IsNotNull(msg.SupportedItems["MAXTARGETS"], "MAXTARGETS"); Assert.IsNotNull(msg.SupportedItems["NICKLEN"], "NICKLEN"); Assert.IsNotNull(msg.SupportedItems["TOPICLEN"], "TOPICLEN"); Assert.IsNotNull(msg.SupportedItems["KICKLEN"], "KICKLEN"); Assert.AreEqual("i-d", msg.SupportedItems["STD"], "STD"); Assert.AreEqual("@+", msg.SupportedItems["STATUSMSG"], "STATUSMSG"); Assert.AreEqual("e", msg.SupportedItems["EXCEPTS"], "EXCEPTS"); Assert.AreEqual("I", msg.SupportedItems["INVEX"], "INVEX"); Assert.AreEqual("4", msg.SupportedItems["MODES"], "MODES"); Assert.AreEqual("50", msg.SupportedItems["MAXCHANNELS"], "MAXCHANNELS"); Assert.AreEqual("beI:100", msg.SupportedItems["MAXLIST"], "MAXLIST"); Assert.AreEqual("7", msg.SupportedItems["MAXTARGETS"], "MAXTARGETS"); Assert.AreEqual("9", msg.SupportedItems["NICKLEN"], "NICKLEN"); Assert.AreEqual("120", msg.SupportedItems["TOPICLEN"], "TOPICLEN"); Assert.AreEqual("120", msg.SupportedItems["KICKLEN"], "KICKLEN"); Assert.AreEqual("i-d", support.Standard, "Standard"); Assert.AreEqual("@+", support.StatusMessages, "StatusMessages"); Assert.IsTrue(support.Knock, "Knock"); Assert.IsTrue(support.BanExceptions, "BanExceptions"); Assert.IsTrue(support.InvitationExceptions, "InvitationExceptions"); Assert.AreEqual(4, support.MaxModes, "MaxModes"); Assert.AreEqual(50, support.MaxChannels, "MaxChannels"); Assert.AreEqual(100, support.MaxBans, "MaxBans"); Assert.AreEqual(100, support.MaxBanExceptions, "MaxBanExceptions"); Assert.AreEqual(100, support.MaxInvitationExceptions, "MaxInvitationExceptions"); Assert.AreEqual(7, support.MaxMessageTargets[""], "MaxMessageTargets"); Assert.AreEqual(9, support.MaxNickLength, "MaxNickLength"); Assert.AreEqual(120, support.MaxTopicLength, "MaxTopicLength"); Assert.AreEqual(120, support.MaxKickCommentLength, "MaxKickCommentLength"); break; case 2: Assert.AreEqual(9, msg.SupportedItems.Count, "SupportedItems Count"); Assert.IsNotNull(msg.SupportedItems["CHANTYPES"], "CHANTYPES"); Assert.IsNotNull(msg.SupportedItems["PREFIX"], "PREFIX"); Assert.IsNotNull(msg.SupportedItems["CHANMODES"], "CHANMODES"); Assert.IsNotNull(msg.SupportedItems["NETWORK"], "NETWORK"); Assert.IsNotNull(msg.SupportedItems["CASEMAPPING"], "CASEMAPPING"); Assert.IsNotNull(msg.SupportedItems["CHARSET"], "CHARSET"); Assert.IsNotNull(msg.SupportedItems["CALLERID"], "CALLERID"); Assert.IsNotNull(msg.SupportedItems["ETRACE"], "ETRACE"); Assert.IsNotNull(msg.SupportedItems["WALLCHOPS"], "WALLCHOPS"); Assert.AreEqual("#&", msg.SupportedItems["CHANTYPES"], "CHANTYPES"); Assert.AreEqual("(ov)@+", msg.SupportedItems["PREFIX"], "PREFIX"); Assert.AreEqual("eIb,k,l,imnpst", msg.SupportedItems["CHANMODES"], "CHANMODES"); Assert.AreEqual("EFNet", msg.SupportedItems["NETWORK"], "NETWORK"); Assert.AreEqual("rfc1459", msg.SupportedItems["CASEMAPPING"], "CASEMAPPING"); Assert.AreEqual("ascii", msg.SupportedItems["CHARSET"], "CHARSET"); Assert.IsTrue(support.CallerId, "CallerId"); Assert.IsTrue(support.ETrace, "ETrace"); Assert.IsTrue(support.MessagesToOperators, "MessagesToOperators"); Assert.AreEqual(2, support.ChannelTypes.Count, "ChannelTypes"); Assert.AreEqual("(ov)@+", support.ChannelStatuses, "ChannelStatuses"); Assert.AreEqual(4, support.ModesWithParameters.Count, "ModesWithParameters"); Assert.AreEqual(6, support.ModesWithoutParameters.Count, "ModesWithoutParameters"); Assert.AreEqual(1, support.ModesWithParametersWhenSet.Count, "ModesWithParametersWhenSet"); Assert.AreEqual("EFNet", support.NetworkName, "NetworkName"); Assert.AreEqual("rfc1459", support.CaseMapping, "CaseMapping"); Assert.AreEqual("ascii", support.CharacterSet, "CharacterSet"); break; } } }