def getMaterialExport(request, *args, **kwargs): """ Check and return the PDF file of given material if exist """ format_name = request.path.strip("/").split("/")[-1].lower() mid = kwargs.get("mid", None) version = kwargs.get("version", None) if version: version = int(version) else: # only catch the case of missing version ~ getting latest # error will be raised in other cases version = getMaterialLatestVersion(mid) material = Material.objects.get(material_id=mid, version=version) export_format, created = models.ExportFormat.objects.get_or_create( name=format_name, description="", base_path=format_name ) get_it = False try: export_obj = MaterialExport.objects.get(material_id=mid, export_format=export_format, version=version) if str(request.GET.get("refresh", None)) == "1": export_obj.delete() get_it = requestMaterialExport(material, format_name) raise IOError # check if exported file existing if isExportProcessing(export_obj): get_it = requestMaterialExport(material, format_name) elif not os.path.exists(export_obj.path): export_obj.delete() raise IOError else: get_it = True except (MaterialExport.DoesNotExist, IOError): get_it = requestMaterialExport(material, format_name) except: raise Http404 # ready for download or not? if get_it: export_obj = MaterialExport.objects.get(pk=export_obj.id) # return the PDF content, this should be served be the web server with open(export_obj.path, "rb") as pdf: pdf_name = "%s-%d.%s" % (mid, version, format_name) data = pdf.read() response = HttpResponse(data, mimetype=settings.EXPORT_MIMETYPES[format_name]) try: friendly_name = "%s.%s" % (material.title.encode("utf-8"), format_name) except UnicodeEncodeError: friendly_name = "%s.%s" % slugify(material.title) except: friendly_name = pdf_name response["content-disposition"] = 'attachment; filename="%s"' % friendly_name return response else: return HttpResponse(status=HTTP_CODE_PROCESSING)
def getMaterialPDF(request, *args, **kwargs): """ Check and return the PDF file of given material if exist """ mid = kwargs.get('mid', None) version = kwargs.get('version', None) if version: version = int(version) else: # only catch the case of missing version ~ getting latest # error will be raised in other cases version = getMaterialLatestVersion(mid) material = Material.objects.get(material_id=mid, version=version) get_it = False try: export_obj = MaterialExport.objects.get(material_id=mid, version=version) if str(request.GET.get('refresh', None)) == '1': export_obj.delete() get_it = requestMaterialPDF(material) raise IOError # check if exported file existing if isExportProcessing(export_obj): get_it = requestMaterialPDF(material) elif not os.path.exists(export_obj.path): export_obj.delete() raise IOError else: get_it = True except (MaterialExport.DoesNotExist, IOError): get_it = requestMaterialPDF(material) except: raise Http404 # ready for download or not? if get_it: export_obj = MaterialExport.objects.get(pk=export_obj.id) # return the PDF content, this should be served be the web server with open(export_obj.path, 'rb') as pdf: pdf_name = '%s-%d.pdf' % (mid, version) data = pdf.read() response = HttpResponse(data, mimetype='application/pdf') try: friendly_name = '%s.pdf' % material.title.encode('utf-8') except UnicodeEncodeError: friendly_name = '%s.pdf' % slugify(material.title) except: friendly_name = pdf_name response['content-disposition'] = 'attachment; filename="%s"' % friendly_name return response else: return HttpResponse(status=HTTP_CODE_PROCESSING)
def zipMaterialInternal(material): """ Collects all material info and put it into a ZIP file. Full path of the zip file will be returned to the caller. """ mid = material.material_id version = material.version mtype = material.material_type # init the zip package zip_path = os.path.join(settings.TEMP_DIR, ZIP_FILE_NAME % (str(mid), str(version))) zf = ZipFile(zip_path, "w", ZIP_DEFLATED) # check if module or collection if mtype == MTYPE_MODULE: # read all material files, and put into the zip package mfids = listMaterialFiles(mid, version) for mfid in mfids: try: mf = MaterialFile.objects.get(id=mfid) zf.writestr(mf.name, mf.mfile.read()) mf.mfile.close() except: print "Error when getting material file %s" % mf.name # add material text content raw_content = material.text try: raw_content = raw_content.encode("utf-8") except: raw_content = raw_content.decode("utf-8").encode("utf-8") zf.writestr(ZIP_HTML_FILE, raw_content) # generate material json persons = models.getMaterialPersons(material.id) try: author_ids = persons["author"].split(",") except: author_ids = [] author_names = models.getPersonName(author_ids) index_content = { "title": material.title, "url": MOD_SOURCE_URL % material.material_id, "authors": author_names, "version": material.version, "language": material.language, } index_content = json.dumps(index_content) zf.writestr(ZIP_INDEX_MODULE, index_content) elif mtype == MTYPE_COLLECTION: # get list of all contained materials all_materials = getNestedMaterials(material) # load materials into ZIP for cid in range(len(all_materials)): m_id = all_materials[cid][0] m_version = all_materials[cid][1] m_title = all_materials[cid][2] if m_version is None: m_version = getMaterialLatestVersion(m_id) mfids = listMaterialFiles(m_id, m_version) m_object = Material.objects.get(material_id=m_id) for mfid in mfids: try: mf = MaterialFile.objects.get(id=mfid) zf.writestr(m_id + "/" + mf.name, mf.mfile.read()) mf.mfile.close() except: print "Error when reading material file: " + mf.name zf.writestr(m_id + "/" + ZIP_HTML_FILE, m_object.text) # prepare some fields editor_ids = models.getMaterialPersons(material.id)["editor"] editor_ids = editor_ids.split(",") editors = models.getPersonName(editor_ids) if isinstance(editors, str): editors = [editors] material_url = COL_SOURCE_URL % material.material_id # generate collection.json try: index_content = json.loads(material.text) index_content["id"] = material.material_id index_content["title"] = material.title index_content["version"] = str(material.version) index_content["license"] = MATERIAL_LICENSE index_content["url"] = material_url index_content["editors"] = editors index_content["language"] = material.language index_content = json.dumps(index_content) except: # another way index_content = '{"id":"%s",' % material.material_id index_content += '"title":"%s",' % material.title index_content += '"version":"%s",' % str(material.version) index_content += '"license":"%s",' % MATERIAL_LICENSE index_content += '"url":"%s",' % material_url index_content += '"editors":"%s",' % editors index_content += '"language": "%s",' % material.language index_content += material.text[material.text.index("{") + 1 :] zf.writestr(ZIP_INDEX_COLLECTION, index_content) zf.close() return realpath(zf.filename)
def zipMaterialExternal(material): """ Collects all material info and put into a folder, then call external zip command to do its job. Full path of the zip file will be returned to the caller. """ mid = material.material_id version = material.version mtype = material.material_type # create material directory dir_path = os.path.join(settings.TEMP_DIR, "%s-%d" % (mid, version)) # check if module or collection if mtype == MTYPE_MODULE: createMaterialDirectory(dir_path, material) elif mtype == MTYPE_COLLECTION: createDirectory(dir_path) # get list of all contained materials all_materials = getNestedMaterials(material) # load materials into ZIP for cid in range(len(all_materials)): m_id = all_materials[cid][0] m_version = all_materials[cid][1] or models.getMaterialLatestVersion(m_id) m_object = models.getMaterial(m_id, m_version) m_path = os.path.join(dir_path, m_id) createMaterialDirectory(m_path, m_object) # prepare some fields try: editor_ids = models.getMaterialPersons(material.id)["editor"] editor_ids = editor_ids.split(",") editors = models.getPersonName(editor_ids) except KeyError: editors = [""] if isinstance(editors, str): editors = [editors] material_url = COL_SOURCE_URL % material.material_id # generate collection.json try: index_content = json.loads(material.text) index_content["id"] = material.material_id index_content["title"] = material.title index_content["version"] = material.version index_content["license"] = MATERIAL_LICENSE index_content["url"] = material_url index_content["editors"] = editors index_content["language"] = material.language index_content = json.dumps(index_content) except: # another way index_content = '{"id":"%s",' % material.material_id index_content += '"title":"%s",' % material.title index_content += '"version":"%s",' % str(material.version) index_content += '"license":"%s",' % MATERIAL_LICENSE index_content += '"url":"%s",' % material_url index_content += '"editors":"%s",' % editors index_content += '"language":"%s",' % material.language index_content += material.text[material.text.index("{") + 1 :] with open(os.path.join(dir_path, ZIP_INDEX_COLLECTION), "w") as mnf: mnf.write(index_content) # zip the material files cmd = "zip -r5 %s ./*" % buildZipPath(dir_path) process = Popen(cmd, shell=True, cwd=dir_path) try: process.wait() except TimeoutExpired: print "Timed-out when creating material ZIP file" finally: rmtree(dir_path) if process.poll() == 0: return buildZipPath(dir_path)