Using pdftk I generate some dynamic temporary pdf files, which then Django serves to the user.
On a desktop, it works fine - the pdf file opens which then user can save, however on my android phone in all browsers (maybe the same on iOS but don't have and iOS device so can't test), the pdf does not download successfully. It starts the download but then always fails and I can't figure out why.
The following is a snippet of the view and the function which generates the pdf binary data:
def get_pdf():
fdf = {...}
t1 = tempfile.NamedTemporaryFile(delete=False)
t2 = tempfile.NamedTemporaryFile(delete=False)
t1.file.write(fdf)
# close temp files for pdftk to work properly
t1.close()
t2.close()
p = Popen('pdftk %s fill_form %s output %s flatten' %
('original.pdf', t1.name, t2.name), shell=True)
p.wait()
with open(t2.name, 'rb') as fid:
data = fid.read()
# delete t1 and t2 since they are temp files
# at this point the data is the binary of the pdf
return data
def get_pdf(request):
pdf = get_pdf()
response = HttpResponse(pdf, mimetype='application/pdf')
response['Content-Disposition'] = 'filename=foofile.pdf'
return response
Any ideas as to why this might be happening?
As per #Pascal comment, I added Content-Length and the downloads now work on mobile devices.
However it was not being downloaded with the filename I assign it in the view. Adding attachment fixes this but I don't want the attachment to be present for desktop browsers. Hence the following is my final solution which works.
# I am using the decorator from http://code.google.com/p/minidetector/
#detect_mobile
def event_pdf(request, event_id, variant_id):
pdf = get_pdf()
response = HttpResponse(pdf, mimetype='application/pdf')
response['Content-Disposition'] = '%sfilename=foofile.pdf' %
request.mobile and 'attachment; ' or ''
response['Content-Length'] = len(pdf)
return response
Related
I am developing a NativeScript Android app and using QuickBlox.
I can open images and audio files inside the app, but there are some issues with .pdf, Word and Excel documents.
Code written by a co-worker:
var attID = message.attachments[0].id
var fileSrc = ChatManager.getQB().content.publicUrl(attID) + "/" + "/download.xml?token=" + ChatManager.getSessionToken()
I get the URL with blob + session token, then:
var intent = new android.content.Intent(android.content.Intent.ACTION_VIEW, android.net.Uri.parse(args.object.src));
intent.addCategory(android.content.Intent.CATEGORY_BROWSABLE);
application.android.startActivity.startActivity(intent);
In this way I successfully download .pdf files, but .doc, .docx, .xls and .xlsx return without extension.
I also tried getting the URL through privateUrl() (without interpolating the token), with the same result.
Another not working method:
httpModule.request({
url: uid,
method: 'GET',
headers: {
'QuickBlox-REST-API-Version': '0.1.0',
'QB-Token': ChatManager.getSessionToken()
}
}).then(res => {
var file = res.content.toFile();
var intent = new android.content.Intent(android.content.Intent.ACTION_VIEW);
var uri = android.net.Uri.fromFile(new java.io.File(file.path));
intent.setDataAndType(uri, 'application/pdf');
application.android.startActivity.startActivity(android.content.Intent.createChooser(intent, 'Apri file...'));
});
Any way I try, it feels like QuickBlox returns the extension on .pdf files only. Any suggestions?
UPDATE:
I tried opening the URL on different devices.
https://api.quickblox.com/blobs/[blobId]?token=[token]
On Chrome for Windows and iOS Safari, the file is downloaded or opened in browser correctly. On Android, it returns without extension on these browsers: Chrome e LineageOS stock browser. On Internet Samsung 7.4.00.70, it's opened in the browser correctly.
With httpModule.request(), I get this warning in the debug console on result:
Resource interpreted as Document but transferred with MIME type [my file mime type]
At the moment I am using this workaround in native code, but later I'll need to find something that works on iOS too.
I'm not marking this as an answer since it doesn't solve the problem
var r = new android.app.DownloadManager.Request(android.net.Uri.parse(args.object.src));
r.setDestinationInExternalPublicDir(android.os.Environment.DIRECTORY_DOWNLOADS, fileName.text);
r.allowScanningByMediaScanner();
r.setNotificationVisibility(android.app.DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
var dm = application.android.startActivity.getSystemService(android.content.Context.DOWNLOAD_SERVICE);
dm.enqueue(r);
I am working on a Python Script which reads the APK file which is stored in a folder on the same server on which the Script is running.
here is the code I am using:
apk_path = "/var/fibo-dev/public/uploads/apks/TvBox-release-signed-latest.apk"
apkf = APK(apk_path)
is_valid = apkf.is_valid_APK()
package = apkf.get_package()
version = apkf.androidversion
version = version['Name']
APK Parsing Package:
https://github.com/androguard/androguard
The Script reads the content of the APK like it's version, package name etc and then store the info in a csv.
As you can see the APK I am reading is stored on the same server on which the script is placed.
But now the thing is I want to read the APK which is placed on a different server. i.e. https://fibo.network/uploads/apks/18243602447plus_v4.3.4.apk
and when I try to do the same thing for the given url it doesn't work.
for example:
url = urllib2.urlopen("https://fibo.network/uploads/apks/18243602447plus_v4.3.4.apk")
apkf = APK(url.read())
It gives the error:
file() argument 1 must be encoded string without null bytes, not str
I tried to use a different methods like:
urlopen
,
requests.get
and more
But none of those worked for me.
So I am requesting you to help me to get this thing worked out.
Thanks.
I've made a class to pickle and unpickle data from a dictionary. Its fairly standard: it tried to open the file, if the file's not present it creates it and it offers methods to read from the dictionary and write to the dictionary.
However, when packaged as an APK using buildozer (I made sure to delete the data file before compiling), sometimes data is randomly lost on the device, and if you update the app through the android updater all data is lost. I don't know where the data file is, but I'm presuming it's kept in the APK. Can anyone offer a solution to this?
I'm using Python 2 and Kivy 1.10 and the built-in pickle module. Thanks in advance
The code for my pickler is as below:
import pickle
class Data(object):
def __init__(self,fname):
try:
f = open(fname,'r')
p = pickle.load(f)
f.close()
except IOError:
f = open(fname,'w')
pickle.dump({'highscore':0},f)
f.close() p = {'highscore':0}
self.fname = fname
self.data = p
def rewrite(self,key,value):
new = self.data
new[key] = value
f = open(self.fname,'w')
pickle.dump(new,f)
f.close()
self.data = new
def grab(self,key):
with open(self.fname,'r') as f:
self.data = pickle.load(f)
return self.data[key]
Using the Android sample in the WebViewer folder I have an application in Android Studio which when run on my device works and displays the xod file given as expected. However I've tried to change the lines:
String documentPath = getFilesDir().getPath() + "/GettingStarted.xod";
InputStream in = getAssets().open("xod/GettingStarted.xod");
to
String documentPath = getFilesDir().getPath() + "/sample.pdf";
InputStream in = getAssets().open("xod/sample.pdf");
And have also changed the endsWith(".xod") to endsWith(".pdf") but I only get a grey screen. For this to work does the file have to be a .xod? As it works for xod files but not pdf files.
Thanks for your time.
Yes, for mobile viewing you need to convert your files to the web-optimized XOD format.
The PDF backend for WebViewer is not available for mobile browsers. This is due to limitations of the hardware and the mobile browsers.
For desktop browsers, to switch from XOD backend to PDF backend, you need to follow the steps. See here for more details, especially if you run into any errors.
var myWebViewer = new PDFTron.WebViewer({
path: "lib",
type: "html5",
documentType: "pdf",
initialDoc: "GettingStarted.pdf"
}, viewerElement);
Notice the documentType parameter is set to pdf.
My server spits out the source of a PDF. With XHR2 I request that code using xhr.responseType = 'blob'; For iOS I then just use
blob = new Blob([this.response], {type: "application/pdf"});
and then save it using Phonegap's Filewriter. When I then open the saved file, I have a perfect PDF. I simply can't get anything similar to work on Android. My last attempt was:
if (!window.BlobBuilder && window.WebKitBlobBuilder){
window.BlobBuilder = window.WebKitBlobBuilder;
var bb = new window.BlobBuilder();
bb.append(this.response);
blob = bb.getBlob("application/pdf");}
since Android coughed over just plain 'BlobBuilder'. That duly creates a PDF which FileWriter then saves. The files structure is presumably OK as a PDF since PDF readers open it without complaint. Unfortunately, the PDF is completely blank.
I just don't seem to be able to get my elderly head around whatever is required by Android.