Here’s a script that lets you export translation units that are newer than a specified date. It might be useful if you get a project with a legacy TMX containing some perfect matches (that memory should be put into /tm/auto), and you want to be able to run QA tests only on new TU’s that have been translated since you’ve started to work on the project, or you want to keep your own translations for later and don’t really care for what has been translated before.
If the script is invoked without changing or specifying anything, it looks for TU’s that are one day old and works globally on the whole project. If you need to filter TU’s older or newer than that, you’ll have to specify the date on line 21.
The date should be in “yyyy-MM-dd HH:mm” (4_digit_year-2_digit_month-2_digit_day space 2_digit_hour_in_military_notation:2_digit_minute) format. If not specified properly, it will fall back to the default one-day-old value.
Beside that, the user can specify whether the script should work globally on the entire project, or only on selected files. To enable file selection, the line 27 should read:
select_files = 'yes'
Anything other than ‘yes’ means the script will work globally.
The script will write a file named translated_after_[_select].tmx and located in the project’s root. If file selection is enabled, the TMX file will have _select in its filename, plus the header part of the TMX will contain filenames of the files whose TU’s were exported.
-
write_new_trans2TMX.groovy
/* * Purpose: Export new translations completed after the specified * date (line 21) either for the entire project or for the * selected files ("select_files" must be set to 'yes' — line 27) * to TMX file * #Files: Writes 'translated_after_<date_time>.tmx' * in the current project's root * #File format: TMX v.1.4 * #Details: http:/ /wp.me / p3fHEs-6z * * @author Kos Ivantsov * @date 2013-08-12 * @version 0.3 */ /* * The date should be specified as "year-month-day HOURS:minutes" * If not specified or specified wrongly, the script will look for * translations that are newer than one day. */ def newdate = '' /* * Set "select_files" to 'yes' if you want to use file selector * to specify files for export. If anything else is specified, the script * will work with the complete project. */ select_files = '' import javax.swing.JFileChooser import org.omegat.util.StaticUtils import org.omegat.util.TMXReader import static javax.swing.JOptionPane.* import static org.omegat.util.Platform.* def prop = project.projectProperties if (!prop) { final def title = 'Export new translation' final def msg = 'Please try again after you open a project.' showMessageDialog null, msg, title, INFORMATION_MESSAGE return } try { newdate = new Date().parse("yyyy-MM-dd HH:mm", newdate) } catch (java.text.ParseException e) { newdate = new Date().minus(1) final def title = 'Wrong date format' final def msg = """\ The date has been specified in a wrong format. The script will work with entries exactly one day old, i.e. changed after $newdate\ """ console.println msg showMessageDialog null, msg, title, INFORMATION_MESSAGE } namedate = new Date().parse("E MMM dd H:m:s z yyyy", newdate.toString()).format("MMM-dd-yyyy_HH.mm") def fileloc = prop.projectRoot+'translated_after_'+namedate+"${ (select_files == 'yes') ? "_select" : ''}"+'.tmx' exportfile = new File(fileloc) if (prop.isSentenceSegmentingEnabled()) segmenting = TMXReader.SEG_SENTENCE else segmenting = TMXReader.SEG_PARAGRAPH def sourceLocale = prop.getSourceLanguage().toString() def targetLocale = prop.getTargetLanguage().toString() exportfile.write("", 'UTF-8') exportfile.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", 'UTF-8') exportfile.append("<!DOCTYPE tmx SYSTEM \"tmx11.dtd\">\n", 'UTF-8') exportfile.append("<tmx version=\"1.4\">\n", 'UTF-8') exportfile.append(" <header\n", 'UTF-8') exportfile.append(" creationtool=\"OmegaTScripting\"\n", 'UTF-8') exportfile.append(" segtype=\"" + segmenting + "\"\n", 'UTF-8') exportfile.append(" o-tmf=\"OmegaT TMX\"\n", 'UTF-8') exportfile.append(" adminlang=\"EN-US\"\n", 'UTF-8') exportfile.append(" srclang=\"" + sourceLocale + "\"\n", 'UTF-8') exportfile.append(" datatype=\"plaintext\"\n", 'UTF-8') exportfile.append(" >\n", 'UTF-8') def hitcount = 0 if ((select_files == 'yes')) { srcroot = new File(prop.getSourceRoot()) sourceroot = prop.getSourceRoot().toString() as String JFileChooser fc = new JFileChooser( currentDirectory: srcroot, dialogTitle: "Choose files to export", fileSelectionMode: JFileChooser.FILES_ONLY, //the file filter must show also directories, in order to be able to look into them multiSelectionEnabled: true) if(fc.showOpenDialog() != JFileChooser.APPROVE_OPTION) { console.println "Canceled" return } if (!(fc.selectedFiles =~ sourceroot.replaceAll(/\\+/, '\\\\\\\\'))) { console.println "Selection outside of ${prop.getSourceRoot()} folder" final def title = 'Wrong file(s) selected' final def msg = "Files must be in ${prop.getSourceRoot()} folder." showMessageDialog null, msg, title, INFORMATION_MESSAGE return } fc.selectedFiles.each { fl = "${it.toString()}" - "$sourceroot" exportfile.append(" <prop type=\"Filename\">" + fl + "</prop>\n", 'UTF-8') } exportfile.append(" </header>\n", 'UTF-8') exportfile.append(" <body>\n", 'UTF-8') fc.selectedFiles.each{ fl = "${it.toString()}" - "$sourceroot" files = project.projectFiles files.each{ if ( "${it.filePath}" != "$fl" ) { println "Skipping to the next file" }else{ it.entries.each { def info = project.getTranslationInfo(it) def changeId = info.changer def changeDate = info.changeDate def creationId = info.creator def creationDate = info.creationDate def alt = 'unknown' if (info.isTranslated()) { if (newdate.before(new Date(changeDate))){ hitcount++ source = StaticUtils.makeValidXML(it.srcText) target = StaticUtils.makeValidXML(info.translation) exportfile.append(" <tu>\n", 'UTF-8') exportfile.append(" <tuv xml:lang=\"" + sourceLocale + "\">\n", 'UTF-8') exportfile.append(" <seg>" + "$source" + "</seg>\n", 'UTF-8') exportfile.append(" </tuv>\n", 'UTF-8') exportfile.append(" <tuv xml:lang=\"" + targetLocale + "\"", 'UTF-8') exportfile.append(" changeid=\"${changeId ?: alt }\"", 'UTF-8') exportfile.append(" changedate=\"${ changeDate > 0 ? new Date(changeDate).format("yyyyMMdd'T'HHmmss'Z'") : alt }\"", 'UTF-8') exportfile.append(" creationid=\"${creationId ?: alt }\"", 'UTF-8') exportfile.append(" creationdate=\"${ creationDate > 0 ? new Date(creationDate).format("yyyyMMdd'T'HHmmss'Z'") : alt }\"", 'UTF-8') exportfile.append(">\n", 'UTF-8') exportfile.append(" <seg>" + "$target" + "</seg>\n", 'UTF-8') exportfile.append(" </tuv>\n", 'UTF-8') exportfile.append(" </tu>\n", 'UTF-8') } } } } } } } else { exportfile.append(" </header>\n", 'UTF-8') exportfile.append(" <body>\n", 'UTF-8') files = project.projectFiles files.each { it.entries.each { def info = project.getTranslationInfo(it) def changeId = info.changer def changeDate = info.changeDate def creationId = info.creator def creationDate = info.creationDate def alt = 'unknown' if (info.isTranslated()) { if (newdate.before(new Date(changeDate))){ hitcount++ source = StaticUtils.makeValidXML(it.srcText) target = StaticUtils.makeValidXML(info.translation) exportfile.append(" <tu>\n", 'UTF-8') exportfile.append(" <tuv xml:lang=\"" + sourceLocale + "\">\n", 'UTF-8') exportfile.append(" <seg>" + "$source" + "</seg>\n", 'UTF-8') exportfile.append(" </tuv>\n", 'UTF-8') exportfile.append(" <tuv xml:lang=\"" + targetLocale + "\"", 'UTF-8') exportfile.append(" changeid=\"${changeId ?: alt }\"", 'UTF-8') exportfile.append(" changedate=\"${ changeDate > 0 ? new Date(changeDate).format("yyyyMMdd'T'HHmmss'Z'") : alt }\"", 'UTF-8') exportfile.append(" creationid=\"${creationId ?: alt }\"", 'UTF-8') exportfile.append(" creationdate=\"${ creationDate > 0 ? new Date(creationDate).format("yyyyMMdd'T'HHmmss'Z'") : alt }\"", 'UTF-8') exportfile.append(">\n", 'UTF-8') exportfile.append(" <seg>" + "$target" + "</seg>\n", 'UTF-8') exportfile.append(" </tuv>\n", 'UTF-8') exportfile.append(" </tu>\n", 'UTF-8') } } } } } exportfile.append(" </body>\n", 'UTF-8') exportfile.append("</tmx>", 'UTF-8') final def title = 'TMX file written' final def msg = "$hitcount TU's written to " + exportfile.toString() console.println msg showMessageDialog null, msg, title, INFORMATION_MESSAGE return
The TMX file is rewritten each time the script in invoked with the same values for newdate and select_files.
It would be great to add a window that would prompt the user for date and have a checkbox to enable file selection, but Swing stuff seems to be a little too complicated for me. If anyone is willing to help, give a practical hint or show a working example with the source, I would be very thankful.
UPDATE: Here’s a way to include external GUI for date and time selection (Linux only so far).
Suggestions and comments are welcome, as ever.
But as of now,
Good luck!
Hi Kos,
here I am again….
I am testing all the scripts found here and on sf.net in order to see what they do and how they can help me with my work.
That said, this script gives me the following error when run.
Can you please help me out here… again. Thank you.
——-
Error
javax.script.ScriptException: org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
Script40.groovy: 31: unable to resolve class org.omegat.util.TMXReader
@ line 31, column 1.
import org.omegat.util.TMXReader
^
1 error
——-
I know the script is a relatively old one, but I know it is working for others.
However, I have a problem with the script (any script using the date).
Manually inserted date ‘2018-12-01 00:00’ gets error
javax.script.ScriptException: java.text.ParseException: Unparseable date: “Sat Dec 01 00:00:00 CET 2018”
I know it is a problem of the date format, but I have no idea what to change. I am on Windows 10, OmegaT is set to Czech language.
After literally years of searching, I have now workaround for this problem for me:
Just setting OmegaT/java language to en “java -jar -Duser.language=en” is enough to get it working.
It is just confirming for me the reason why I leave almost any program I can in English…