Change encoding of a file with grails - grails

In my view i have a upload form:
<input type="file" name="file" value="search file" /><br />
In my controller I load it like that:
def file = request.getFile('file')
def f = file.getInputStream()
def input = f.getText()
So I have now a String called input with the content of the file.
I want it in UTF-8. How is this possible ?
Edit:
My problem is, that the file to be uploaded is in "Windows-1252" and German characters like äöü are different now in the string called "input".
If i convert the file with "Notepad++" in UTF-8 and then upload it, it works. But I cant do that every time.
Edit2:
def file = request.getFile('file') //get file from view
def File tmpfile = new File('C:/tmp/tmpfile.txt') //create temporary file
file.transferTo(tmpfile) //copy into tmpfile
CharsetToolkit toolkit = new CharsetToolkit(tmpfile) //toolkit with tmpfile
def charset = toolkit.getCharset() //save charset in a variable
def input = tmpfile.getText(charset) //get text with right charset
I tried this with a few different documents. But the variable charset is always UTF_8

You can use getText(String charset)
def input = f.getText('UTF-8')

I found a solution:
I used java-bib called jUniversalChardet and wrote the following method:
String getEncoding ( def inputstream ) {
def byte[] buf = new byte[4096]
def UniversalDetector detector = new UniversalDetector(null)
def nread
while ((nread = inputstream.read(buf)) > 0 && !detector.isDone()) {
detector.handleData(buf, 0, nread)
}
detector.dataEnd();
def encoding = detector.getDetectedCharset()
return encoding
}
In my code i have the following now:
def file = request.getFile('file')
def f = file.getInputStream()
def encoding = getEncoding(file.getInputStream())
def input = f.getText(encoding)
And it works :)

Related

I want to change the file name after downloading the zip file

What I want to solve
I want to change the name of the file after downloading the zip. I was trying to figure out how to remove the directory name in the middle of this.
In this case, the intermediate directory name is "output".
I would like to know if there is a better way.
2_J000001719_1202テスト/output/WNS_UP用データ.txt
2_J000001719_1202テスト/output/Images/1051687701.jpg
↓
2_J000001719_1202テスト/WNS_UP用データ.txt
2_J000001719_1202テスト/Images/1051687701.jpg
Original Source Code
add_dir_name = "#{order.priority}_#{order.orderno}_#{company_name[0, 15]}"
Zip::File.open_buffer(obj) do |zip|
zip.each do |entry|
ext = File.extname(entry.name)
file_name = File.basename(entry.name)
dir_name = File.dirname(entry.name)
next if ext.blank? || file_name.count(".") > 1
dir = File.join(add_dir_name, dir_name)
FileUtils.mkpath(dir.to_s)
zip.extract(entry, dir + ext) {true}
file_name.force_encoding("UTF-8")
new_file_name = "#{dir}/#{file_name}"
new_file_name.force_encoding("UTF-8")
File.rename(dir + ext, new_file_name)
#input_dir << new_file_name
end
end
What I tried
I added this method to the source code, but it did not work.
new_dir = Dir.glob(dir_name+"/*").last
demdem = new_dir.split('/').last
new_file_name = dir.sub("/" + demdem, "")
Here's a generic function to move all files (recursively) from one dir to another:
orig_dir = "2_J000001719_1202テスト/output"
new_dir = "2_J000001719_1202テスト"
def move_all_files(orig_dir, new_dir)
Dir.glob("#{orig_dir}/**/*").each do |path|
File.move(path, path.gsub(orig_dir, new_dir))
end
end

How to return file object from google drive download

I'm new to Rails.
I have a method that downloads a file from google drive and saves it in the local disc. When the file is downloaded, the console returns nil, but the file is in the folder.
I need to use this file in my controller, but if the download method is returning nil I can't pass it around as an object.
download method:
def download
found = google_files.select { |f| f.id == file_id }
file_title = found.first.title
file = session.file_by_title(file_title)
path = File.join(Backup.base_directory, file_title)
file.download_to_file("#{path}")
end
Controller:
def create
# file_id = params.fetch(:file_id)
file_id = "0Byyflt8z3jarbm5DZGNNVXZSWjg"
#backup = DiscourseDownloadFromDrive::DriveDownloader.new(file_id).download
end
console output after executing the download method:
[...]
Writing chunk (1397 bytes)
Writing chunk (1397 bytes)
Writing chunk (1397 bytes)
Writing chunk (619 bytes)
Success - nil
=> nil
[4] pry(main)>
Logger:
Rails.logger.debug(">>> #BACKUP >>>: #{#backup.inspect}")
D, [2017-09-07T20:21:24.835450 #7755] DEBUG -- : >>> #BACKUP >>>: nil
Any hint on how to proceed with this would be very much appreciated!
Your download method always returns nothing but nil. That's because the gem's download_to_file always returns nil.
You shoud change your download method for it to return something, that you can use to get the file. I think this method should return the path to the downloaded file.
def download
found = google_files.select { |f| f.id == file_id }
file_title = found.first.title
file = session.file_by_title(file_title)
path = File.join(Backup.base_directory, file_title)
file.download_to_file("#{path}")
path
end
Now you can use it in the controller:
def create
# file_id = params.fetch(:file_id)
file_id = "0Byyflt8z3jarbm5DZGNNVXZSWjg"
file_path = DiscourseDownloadFromDrive::DriveDownloader.new(file_id).download
#backup = File.open(file_path) # do whatever you want with the file, since now you know how to get it
end

Jenkins…Access XML Tag value in xml file using Groovy in Jenkins

I am using groovy script for automated deployment in jenkins.
In have a xml file, I want to read specific xml tag value from that xml file and assign it's value to a variable. Letter I am using that variable to write excel file. Below is the script. After executing the build it seems that I am not able to access the xml tag value. It seems the code inside of each function is not working. Can anyone please help me on this
def Build_Name= ""
def Build_Number= ""
def CR_Number=""
def Build_Status= ""
def Build_Failure_Reason=""
def Build_Date=""
Build_Number= "1201"
CR_Number="123"
Build_Status= "SUCCESS"
Build_Failure_Reason="NA"
Build_Date=""
boolean fileSuccessfullyDeleted = new File("/export/home/webm/.jenkins/Build_Report.csv").delete()
f = new File("/export/home/webm/.jenkins/Build_Report.csv")
def Job_Result_file = new File("/export/home/webm/.jenkins/global-build-stats/jobresults/Temp_Job_Result.xml")
//Parse it with XmlSlurper
def xml = new XmlSlurper().parse(Job_Result_file)
xml.list.jbr.each { sd ->
Build_Name= sd.n[0].value
f.append("\r\n"+Build_Name+","+Build_Number+","+CR_Number+","+Build_Status+","+Build_Failure_Reason+","+Build_Date+"")
}
EDIT: based on OP added as answer.
Below is the xml available in xml file and I want to read the value of tag and want to assign that value to a variable. In below xml tag n has value Send_Deployment_Request.
Xml:
<list>
<jbr plugin="global-build-stats#1.4">
<r>SUCCESS</r>
<n>Send_Deployment_Request</n>
<nb>187</nb>
<d>
<time>1502879887698</time>
<timezone></timezone>
</d>
<du>973</du>
<nn>master</nn>
<un></un>
</jbr>
<jbr plugin="global-build-stats#1.4">
<r>SUCCESS</r>
<n>Deploy</n>
<nb>187</nb>
<d>
<time>1502879887698</time>
<timezone></timezone>
</d>
<du>973</du>
<nn>master</nn>
<un></un>
</jbr>
</list>
Dear Rao,
Please see my code below.
//Delete if Build_Report fiile already exist
boolean fileSuccessfullyDeleted = new File("/export/home/webmadm/.jenkins/Build_Report.csv").delete()
//Craete new csv file
f = new File("/export/home/webmadm/.jenkins/Build_Report.csv")
def Job_Result_file = new File("/export/home/webmadm/.jenkins/global-build-stats/jobresults/Temp_Job_Result.xml")
def xml = new XmlSlurper().parse(Job_Result_file)
//Change the element name if needed
def Temp_Build_Name= "n"
def Temp_Build_Number= "nb"
def CR_Number=""
def Temp_Build_Status= "r"
def Build_Failure_Reason=""
def Temp_Build_Date="time"
def Temp_Build_Executor="un"
def Build_Name= ""
def Build_Number= ""
def Build_Status= ""
def Build_Date=""
def Build_Executor=""
//Get all the values of Tag - elementToFind
def Build_Name_List= xml.'**'.findAll{'it.name() == Temp_Build_Name'}
def Build_Number_List= xml.'**'.findAll{'it.name() == Temp_Build_Number'}
def Build_Status_List= xml.'**'.findAll{'it.name() == Temp_Build_Status'}
def Build_Date_List= xml.'**'.findAll{'it.name() == Temp_Build_Date'}
def Build_Executor_List= xml.'**'.findAll{'it.name() == Temp_Build_Executor'}
for(int i = 0; i<2; i++)
{
Build_Name= Build_Name_List[i].text()
Build_Number= Build_Number_List[i].text()
Build_Status= Build_Status_List[i].text()
Build_Date= Build_Date_List[i].text()
Build_Executor= Build_Executor_List[i].text()
f.append("\r\n"+Build_Name+","+Build_Number+","+CR_Number+","+Build_Status+","+Build_Failure_Reason+","+Build_Date+"")
}
I am trying to write .csv file. If you see f.append as per that in csc we have Build_Name value , Build_Number value and so on.
But actul result is different, Build_Name also contain the Build_Number, Build_Status Build_Date. Seems .findAll method reading entire tag from xml.
Can't we use .each method as we use it to update the xml node value in xml file
?
Here is what you would need and comments in-line:
def xml = new XmlSlurper().parse(Job_Result_file)
//Change the element name if needed
def elementToFind = 'n'
//Get all the values of Tag - elementToFind
def result = xml.'**'.findAll{it.name() == elementToFind}
println result
//Get the first item from the result
def requiredValue = result[0].text()
println "User required value : $requiredValue"
//Test if the value is as expected
assert 'Send_Deployment_Request' == requiredValue
You can quickly see it online demo

Jenkins Groovy with XMLSlurper Error "failed to serialize"

I am on Jenksin 2.46.2 and have a job that uses Active Choices Reactive Parameter. I select my servers in my first selection from a XML file using XMLSlurper and reference that for my second selection. When I hardcode the server name the code works fine. When I use the variable in my code I get an error.
This code works:
def serverList = new XmlSlurper().parse("/app/jenkins/jobs/servers.xml")
def SERVER = 'testserver1'
def output = []
serverList.Server.find { it.#name == SERVER}.CleanUp.GZIP.File.each{
it.output.add(p)
}
return output
When I reference the variable selection from my previous selection I get the error:
def serverList = new XmlSlurper().parse("/app/jenkins/jobs/servers.xml")
def SERVER = SERVER
def output = []
serverList.Server.find { it.#name == SERVER}.CleanUp.GZIP.File.each{
it.output.add(p)
}
return output
The error that I am getting is below. Any idea why I get an error?
WARNING: failed to serialize [[/app/test2/log], [/app/test2/log]] for ...*other text*... net.sf.json.JSONException: There is a cycle in the hierarchy!
Here is my XML file:
<ServerList>
<Server name="testserver1">
<CleanUP>
<GZIP>
<File KeepDays="30">/app/test1/log</File>
</GZIP>
</CleanUP>
</Server>
<Server name="testserver2">
<CleanUP>
<GZIP>
<File KeepDays="30">/app/test2/log</File>
</GZIP>
</CleanUP>
</Server>
</ServerList>
NE.jpg
Here is the script that you need, which reads the value of File element and returns a list:
def serverList = new XmlSlurper().parse("/app/jenkins/jobs/servers.xml")
return serverList.'**'.findAll{ it.name() == 'File'}*.text()
Output:
[/app/test1/log, /app/test2/log]
EDIT: based on OP comments
def server = 'testserver1'
def serverList = new XmlSlurper().parse("/app/jenkins/jobs/servers.xml")
def result = serverList.'**'.find{ it.#name == server}.CleanUP.GZIP.File
println result
return result
EDIT2:
If you want list or array, try below:
def server = 'testserver1'
def serverList = new XmlSlurper().parse("/app/jenkins/jobs/servers.xml")
def result = serverList.'**'.findAll{ it.#name == server}*.CleanUP.GZIP.File.text()
println result
return result

How to save Text of several QtextEdits within python PYQt4?

Could you please help me in solving this issue as i am a python PyQt beginner ...i have created a simple application with python PyQt4 for a simple math calculations and having the result in textEdit2 and textEdit3 every thing went fine when i click on calculate push button, values appear in the above textedits...what i want is to save the results on the same text edits so that next time when i open the application and open the data file i find every thing in place. I created the save and open actions...but it saves all the results in the same text edit..
i am attaching my code and also the main window with results that needed to be saved and another shot after saving and opening the application and having all the results in one textedit
enter code here
import sys
from PyQt4 import QtCore, QtGui, uic
import os #os used to interface with windows
import datetime as dt
import pickle
qtCreatorFile = "save.ui" # Enter ui file here
Ui_MainWindow, QtBaseClass = uic.loadUiType(qtCreatorFile)
class MyApp(QtGui.QMainWindow, Ui_MainWindow):
def __init__(self):
super (MyApp,self).__init__()
Ui_MainWindow.__init__(self)
self.setupUi(self)
self.initUI()
self.calc.clicked.connect(self.Bss)
def Bss (self):
x = float(self.textEdit.toPlainText())
y = float(self.textEdit1.toPlainText())
z= x+y
w= x**2
z_string = str(z) #convert z value to a string then add this string to textEdit and set as Text
self.textEdit2.setText(z_string)
w_string = str(w)
self.textEdit3.setText(w_string)
def initUI(self): #QAction class insert New,action save in the main menue bar
newAction = QtGui.QAction('New', self)
newAction.setShortcut('Ctrl+N')
newAction.setStatusTip('Create new file')
newAction.triggered.connect(self.newFile)
saveAction = QtGui.QAction('Save as', self)
saveAction.setShortcut('Ctrl+S')
saveAction.setStatusTip('Save current file')
saveAction.triggered.connect(self.saveFile)
openAction = QtGui.QAction('Open', self)
openAction.setShortcut('Ctrl+O')
openAction.setStatusTip('Open a file')
openAction.triggered.connect(self.openFile)
closeAction = QtGui.QAction('Close', self)
closeAction.setShortcut('Ctrl+Q')
closeAction.setStatusTip('Close Notepad')
closeAction.triggered.connect(self.close)
menubar = self.menuBar()
fileMenu = menubar.addMenu('&File')
fileMenu.addAction(newAction)
fileMenu.addAction(saveAction)
fileMenu.addAction(openAction)
fileMenu.addAction(closeAction)
self.show()
self.statusBar()
def newFile(self): #create a new function and remove all values in the QTEXTedit
self.textEdit.clear()
self.textEdit1.clear()
self.textEdit2.clear()
self.textEdit3.clear()
def openFile(self):
self.text = QtGui.QTextEdit(self)
filename = QtGui.QFileDialog.getOpenFileName(self, 'Open File', os.getenv('HOME'))
f = open(filename, 'r')
filedata = f.read()
self.textEdit1.setText(filedata)
self.textEdit2.setText(filedata)
self.textEdit3.setText(filedata)
f.close()
self.show()
def saveFile(self): # saving argument values in a filedata
self.text = QtGui.QTextEdit(self)
filename = QtGui.QFileDialog.getSaveFileName(self, 'Save File', os.getenv('HOME'))
f = open(filename, 'w')
filedata = self.textEdit1.toPlainText()
f.write(filedata)
filedata = self.textEdit2.toPlainText()
f.write(filedata)
filedata = self.textEdit3.toPlainText()
f.write(filedata)
f.close()
def closeEvent(self, event):
reply = QtGui.QMessageBox.question(self, 'Message',
"Are you sure to quit?", QtGui.QMessageBox.Yes |
QtGui.QMessageBox.No, QtGui.QMessageBox.No)
if reply == QtGui.QMessageBox.Yes:
event.accept()
else:
event.ignore()
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
window = MyApp()
window.show()
sys.exit(app.exec_())
if I understand your question properly, since you are writing textEdit values to a file in order, you'll need to read that values line by line when opening the file, instead of reading the whole file content using read() method. so the openFile() method should be something like this:
def openFile(self):
self.text = QtGui.QTextEdit(self)
filename = QtGui.QFileDialog.getOpenFileName(self, 'Open File', os.getenv('HOME'))
count = 0
with open(filename,'r') as f:
for line in f:
count = count + 1
if count == 1 : self.textEdit1.setText(line)
elif count == 2 : self.textEdit2.setText(line)
elif count == 3 : self.textEdit3.setText(line)
else: break
self.show()
hope it helps!
UPDATE:
also change saveFile() method like below:
def saveFile(self): # saving argument values in a filedata
self.text = QtGui.QTextEdit(self)
filename = QtGui.QFileDialog.getSaveFileName(self, 'Save File', os.getenv('HOME'))
f = open(filename, 'w')
filedata = self.textEdit1.toPlainText()
filedata = str(filedata)+"\n"
f.write(filedata)
filedata = self.textEdit2.toPlainText()
filedata = str(filedata)+"\n"
f.write(filedata)
filedata = self.textEdit3.toPlainText()
filedata = str(filedata)+"\n"
f.write(filedata)
f.close()

Resources