Add warning for saving DCinema files in non-utf8-encoding

This commit is contained in:
Nikolaj Olsson 2020-07-20 19:09:30 +02:00
parent e969d8531e
commit b0b070ea51
7 changed files with 194 additions and 6 deletions

View File

@ -1321,6 +1321,7 @@ Go to "Options -> Settings -> Tools" to enter your Google translate API ke
File is read-only!</FileXIsReadOnly>
<UnableToSaveSubtitleX>Unable to save subtitle file {0}
Subtitle seems to be empty - try to re-save if you're working on a valid subtitle!</UnableToSaveSubtitleX>
<FormatXShouldUseUft8>UTF-8 encoding should be used when saving {0} files!</FormatXShouldUseUft8>
<BeforeNew>Before new</BeforeNew>
<New>New</New>
<BeforeConvertingToX>Before converting to {0}</BeforeConvertingToX>

View File

@ -1212,6 +1212,7 @@ namespace Nikse.SubtitleEdit.Core
OverwriteModifiedFile = "Overwrite the file {0} modified at {1} {2}{3} with current file loaded from disk at {4} {5}?",
FileXIsReadOnly = "Cannot save {0}" + Environment.NewLine + Environment.NewLine + "File is read-only!",
UnableToSaveSubtitleX = "Unable to save subtitle file {0}" + Environment.NewLine + "Subtitle seems to be empty - try to re-save if you're working on a valid subtitle!",
FormatXShouldUseUft8 = "UTF-8 encoding should be used when saving {0} files!",
BeforeNew = "Before new",
New = "New",
BeforeConvertingToX = "Before converting to {0}",

View File

@ -2656,6 +2656,9 @@ namespace Nikse.SubtitleEdit.Core
case "Main/UnableToSaveSubtitleX":
language.Main.UnableToSaveSubtitleX = reader.Value;
break;
case "Main/FormatXShouldUseUft8":
language.Main.FormatXShouldUseUft8 = reader.Value;
break;
case "Main/BeforeNew":
language.Main.BeforeNew = reader.Value;
break;

View File

@ -1082,6 +1082,7 @@
public string OverwriteModifiedFile { get; set; }
public string FileXIsReadOnly { get; set; }
public string UnableToSaveSubtitleX { get; set; }
public string FormatXShouldUseUft8 { get; set; }
public string BeforeNew { get; set; }
public string New { get; set; }
public string BeforeConvertingToX { get; set; }

View File

@ -1119,6 +1119,7 @@ $HorzAlign = Center
public string PreviewAssaText { get; set; }
public bool ShowProgress { get; set; }
public bool ShowNegativeDurationInfoOnSave { get; set; }
public bool ShowFormatRequiresUtf8Warning { get; set; }
public long CurrentVideoOffsetInMs { get; set; }
public string TitleBarAsterisk { get; set; } // Show asteriks "before" or "after" file name (any other value will hide asteriks)
public bool UseDarkTheme { get; set; }
@ -1243,6 +1244,7 @@ $HorzAlign = Center
LastCheckForUpdates = DateTime.Now;
ShowProgress = false;
ShowNegativeDurationInfoOnSave = true;
ShowFormatRequiresUtf8Warning = true;
UseDarkTheme = false;
TitleBarAsterisk = "before";
PreviewAssaText = "ABCDEFGHIJKL abcdefghijkl 123";
@ -3346,6 +3348,12 @@ $HorzAlign = Center
settings.General.ShowNegativeDurationInfoOnSave = Convert.ToBoolean(subNode.InnerText.Trim());
}
subNode = node.SelectSingleNode("ShowFormatRequiresUtf8Warning");
if (subNode != null)
{
settings.General.ShowFormatRequiresUtf8Warning = Convert.ToBoolean(subNode.InnerText.Trim());
}
subNode = node.SelectSingleNode("TitleBarAsterisk");
if (subNode != null)
{
@ -7406,6 +7414,7 @@ $HorzAlign = Center
textWriter.WriteElementString("PreviewAssaText", settings.General.PreviewAssaText);
textWriter.WriteElementString("ShowProgress", settings.General.ShowProgress.ToString(CultureInfo.InvariantCulture));
textWriter.WriteElementString("ShowNegativeDurationInfoOnSave", settings.General.ShowNegativeDurationInfoOnSave.ToString(CultureInfo.InvariantCulture));
textWriter.WriteElementString("ShowFormatRequiresUtf8Warning", settings.General.ShowFormatRequiresUtf8Warning.ToString(CultureInfo.InvariantCulture));
textWriter.WriteElementString("TitleBarAsterisk", settings.General.TitleBarAsterisk);
textWriter.WriteElementString("UseDarkTheme", settings.General.UseDarkTheme.ToString(CultureInfo.InvariantCulture));
textWriter.WriteElementString("ShowBetaStuff", settings.General.ShowBetaStuff.ToString(CultureInfo.InvariantCulture));

View File

@ -0,0 +1,143 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using Nikse.SubtitleEdit.Core.SubtitleFormats;
namespace Nikse.SubtitleEdit.Core.Translate
{
/// <summary>
/// Google translate via Google Cloud V3 API - see https://cloud.google.com/translate/
/// </summary>
public class GoogleTranslator3 : ITranslator
{
private readonly string _apiKey;
private readonly string _projectNumberOrId;
public GoogleTranslator3(string apiKey, string projectNumberOrId)
{
_apiKey = apiKey;
_projectNumberOrId = projectNumberOrId;
}
public List<TranslationPair> GetTranslationPairs()
{
return new GoogleTranslator2(null).GetTranslationPairs();
}
public string GetName()
{
return "Google translate V3";
}
public string GetUrl()
{
return "https://translate.google.com/";
}
public List<string> Translate(string sourceLanguage, string targetLanguage, List<Paragraph> paragraphs, StringBuilder log)
{
//TODO: Get access token...
var input = new StringBuilder();
var formatList = new List<Formatting>();
bool skipNext = false;
for (var index = 0; index < paragraphs.Count; index++)
{
if (skipNext)
{
skipNext = false;
continue;
}
var p = paragraphs[index];
var f = new Formatting();
formatList.Add(f);
if (input.Length > 0)
{
input.Append(",");
}
var nextText = string.Empty;
if (index < paragraphs.Count - 1 && paragraphs[index + 1].StartTime.TotalMilliseconds - p.EndTime.TotalMilliseconds < 200)
{
nextText = paragraphs[index + 1].Text;
}
var text = f.SetTagsAndReturnTrimmed(TranslationHelper.PreTranslate(p.Text, sourceLanguage), sourceLanguage, nextText);
skipNext = f.SkipNext;
if (!skipNext)
{
text = f.UnBreak(text, p.Text);
}
input.Append("\"" + Json.EncodeJsonText(text) + "\"");
}
var request = (HttpWebRequest)WebRequest.Create($"https://translation.googleapis.com/v3/{_projectNumberOrId}:translateText");
request.Proxy = Utilities.GetProxy();
request.ContentType = "application/json";
request.Method = "POST";
using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
var requestJson = "{ \"sourceLanguageCode\": \"" + sourceLanguage + "\", \"targetLanguageCode\": \"" + targetLanguage + "\", " +
"\"contents\": [" + input + "]}";
streamWriter.Write(requestJson);
}
var response = request.GetResponse();
var reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
string content = reader.ReadToEnd();
var skipCount = 0;
var resultList = new List<string>();
var parser = new JsonParser();
var x = (Dictionary<string, object>)parser.Parse(content);
foreach (var k in x.Keys)
{
if (x[k] is Dictionary<string, object> v)
{
foreach (var innerKey in v.Keys)
{
if (v[innerKey] is List<object> l)
{
foreach (var o2 in l)
{
if (o2 is Dictionary<string, object> v2)
{
foreach (var innerKey2 in v2.Keys)
{
if (v2[innerKey2] is string translatedText)
{
string nextText = null;
translatedText = Regex.Unescape(translatedText);
translatedText = string.Join(Environment.NewLine, translatedText.SplitToLines());
translatedText = TranslationHelper.PostTranslate(translatedText, targetLanguage);
if (resultList.Count - skipCount < formatList.Count)
{
translatedText = formatList[resultList.Count - skipCount].ReAddFormatting(translatedText, out nextText);
if (nextText == null)
{
translatedText = formatList[resultList.Count - skipCount].ReBreak(translatedText, targetLanguage);
}
}
resultList.Add(translatedText);
if (nextText != null)
{
resultList.Add(nextText);
skipCount++;
}
}
}
}
}
}
}
}
}
return resultList;
}
}
}

View File

@ -3197,6 +3197,15 @@ namespace Nikse.SubtitleEdit.Forms
MessageBox.Show(errors, Title, MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
else if (formatType == typeof(DCinemaSmpte2014))
{
format.ToText(_subtitle, string.Empty);
string errors = (format as DCinemaSmpte2014).Errors;
if (!string.IsNullOrEmpty(errors))
{
MessageBox.Show(errors, Title, MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
else if (formatType == typeof(CsvNuendo))
{
if (_subtitle.Paragraphs.Any(p => !string.IsNullOrEmpty(p.Actor)))
@ -3858,17 +3867,29 @@ namespace Nikse.SubtitleEdit.Forms
}
// force encoding
if (format.GetType() == typeof(WebVTT) || format.GetType() == typeof(WebVTTFileWithLineNumber))
var formatType = format.GetType();
if (formatType == typeof(WebVTT) || formatType == typeof(WebVTTFileWithLineNumber))
{
SetEncoding(Encoding.UTF8);
currentEncoding = Encoding.UTF8;
}
else if (format.GetType() == typeof(SwiftInterchange2))
else if (formatType == typeof(SwiftInterchange2))
{
SetEncoding(Encoding.Unicode);
currentEncoding = Encoding.Unicode;
}
if (Configuration.Settings.General.ShowFormatRequiresUtf8Warning && !currentEncoding.Equals(Encoding.UTF8) &&
(formatType == typeof(DCinemaInterop) || formatType == typeof(DCinemaSmpte2007) ||
formatType == typeof(DCinemaSmpte2010) || formatType == typeof(DCinemaSmpte2014)))
{
using (var form = new DialogDoNotShowAgain(Title, string.Format(_language.FormatXShouldUseUft8, GetCurrentSubtitleFormat().FriendlyName)))
{
form.ShowDialog(this);
Configuration.Settings.General.ShowFormatRequiresUtf8Warning = !form.DoNoDisplayAgain;
}
}
if (format.Extension == ".rtf")
{
currentEncoding = Encoding.ASCII;
@ -3879,7 +3900,7 @@ namespace Nikse.SubtitleEdit.Forms
allText = allText.Replace("\r\n", "\n");
}
if (format.GetType() == typeof(ItunesTimedText) || format.GetType() == typeof(ScenaristClosedCaptions) || format.GetType() == typeof(ScenaristClosedCaptionsDropFrame))
if (formatType == typeof(ItunesTimedText) || formatType == typeof(ScenaristClosedCaptions) || formatType == typeof(ScenaristClosedCaptionsDropFrame))
{
var outputEnc = new UTF8Encoding(false); // create encoding with no BOM
using (var file = new StreamWriter(_fileName, false, outputEnc)) // open file with encoding
@ -3887,7 +3908,7 @@ namespace Nikse.SubtitleEdit.Forms
file.Write(allText);
}
}
else if (Equals(currentEncoding, Encoding.UTF8) && (format.GetType() == typeof(TmpegEncAW5) || format.GetType() == typeof(TmpegEncXml)))
else if (Equals(currentEncoding, Encoding.UTF8) && (formatType == typeof(TmpegEncAW5) || formatType == typeof(TmpegEncXml)))
{
var outputEnc = new UTF8Encoding(false); // create encoding with no BOM
using (var file = new StreamWriter(_fileName, false, outputEnc)) // open file with encoding
@ -3927,7 +3948,7 @@ namespace Nikse.SubtitleEdit.Forms
new BookmarkPersistence(_subtitle, _fileName).Save();
_fileDateTime = File.GetLastWriteTime(_fileName);
ShowStatus(string.Format(_language.SavedSubtitleX, _fileName));
if (format.GetType() == typeof(NetflixTimedText))
if (formatType == typeof(NetflixTimedText))
{
NetflixGlyphCheck(true);
}
@ -6038,6 +6059,15 @@ namespace Nikse.SubtitleEdit.Forms
MessageBox.Show(errors, Title, MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
else if (formatType == typeof(DCinemaSmpte2014))
{
format.ToText(_subtitle, string.Empty);
string errors = (format as DCinemaSmpte2014).Errors;
if (!string.IsNullOrEmpty(errors))
{
MessageBox.Show(errors, Title, MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
}
else
{
@ -19637,7 +19667,7 @@ namespace Nikse.SubtitleEdit.Forms
toolStripMenuItemDvdStudioProProperties.Visible = false;
}
if (ft == typeof(DCinemaInterop) || ft == typeof(DCinemaSmpte2010) || ft == typeof(DCinemaSmpte2007))
if (ft == typeof(DCinemaInterop) || ft == typeof(DCinemaSmpte2014) || ft == typeof(DCinemaSmpte2010) || ft == typeof(DCinemaSmpte2007))
{
toolStripMenuItemDCinemaProperties.Visible = true;
}