Exemplo n.º 1
0
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)
Exemplo n.º 2
0
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)
Exemplo n.º 3
0
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)
Exemplo n.º 4
0
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)