Exemple #1
0
    def do_GET(self):
        "Standard method to override in this Server object."
        dfh.DataFileHandler().get_data_dir_path_by_file_type(file_type="Loom")

        name = self.path.lstrip("/")
        if name == "":
            return None
        logger.debug(name)

        name = urllibparse.unquote(name)
        name = _decode_str_if_py2(name, "utf-8")

        # TODO: Refactor special-method handling to make more modular?
        # Include ability to self-define "special method" prefix path?
        # TODO Verify that this is path-injection proof
        localpath = _encode_str_if_py2(os.path.join(self.directory, name),
                                       "utf-8")
        with open(localpath, "rb") as f:
            self.send_resp_headers(
                200,
                {
                    "Content-length":
                    os.fstat(f.fileno())[6],
                    "Access-Control-Allow-Origin":
                    "*",
                    "Content-type":
                    "application/x-hdf5",
                    "Content-Disposition":
                    'attachment; filename="' + os.path.basename(name) + '""',
                },
                end=True,
            )
            shutil.copyfileobj(f, self.wfile)
Exemple #2
0
 def __init__(self, loom) -> None:
     self.loom = loom
     self.search_space_dict: SearchSpaceDict = {}
     self.search_space_version: int = CURRENT_SS_VERISON
     self.species: str
     self.gene_mappings: Dict[str, str]
     self.species, self.gene_mappings = loom.infer_species()
     self.dfh: Optional[dfh.DataFileHandler] = dfh.DataFileHandler()
Exemple #3
0
    def __init__(self, config: Dict[str, str]):

        self.config = config
        self.app_mode = False

        self.dfh = dfh.DataFileHandler()
        self.lfh = lfh.LoomFileHandler()

        self.dfh.set_global_data()
        self.lfh.set_global_data()
        self.dfh.read_UUID_db()
        self.dfh.read_ORCID_db()

        self.check_ORCID_connection()
Exemple #4
0
    def __init__(self, partial_md5_hash, file_path, abs_file_path,
                 loom_connection, loom_file_handler):
        self.lfh = loom_file_handler
        self.partial_md5_hash = partial_md5_hash
        self.file_path = file_path
        self.abs_file_path = abs_file_path
        self.loom_connection = loom_connection
        self.dfh = dfh.DataFileHandler()

        logger.info(f"New Loom object created for {file_path}")
        # Metrics
        self.nUMI = None
        self.species, self.gene_mappings = self.infer_species()
        self.ss_pickle_name = os.path.join(os.path.dirname(self.abs_file_path),
                                           partial_md5_hash + ".ss_pkl")

        try:
            with open(self.ss_pickle_name, "rb") as fh:
                logger.debug(
                    f"Loading prebuilt SS for {file_path} from {self.ss_pickle_name}"
                )
                self.ss = pickle.load(fh)

        except (EOFError, FileNotFoundError):
            logger.debug(f"Building Search Spaces for {file_path}")
            if self.species == "dmel":
                logger.debug(f"Building hsap Search Spaces for {file_path}")
                self.hsap_ss = ss.SearchSpace(loom=self,
                                              cross_species="hsap").build()
                logger.debug(f"Building mmus Search Spaces for {file_path}")

                self.mmus_ss = ss.SearchSpace(loom=self,
                                              cross_species="mmus").build()
            logger.debug(f"Building self Search Spaces for {file_path}")

            self.ss = ss.SearchSpace(loom=self).build()
            self.ss.loom = None  # Remove loom connection to enable pickling
            logger.debug(f"Built all Search Spaces for {file_path}")
            with open(self.ss_pickle_name, "wb") as fh:
                logger.debug(
                    f"Writing prebuilt SS for {file_path} to {self.ss_pickle_name}"
                )
                pickle.dump(self.ss, fh)
Exemple #5
0
    def __init__(
        self,
        file_path: Path,
        abs_file_path: Path,
        loom_connection: LoomConnection,
        loom_file_handler,
    ):
        self.lfh = loom_file_handler
        self.file_path = file_path
        self.abs_file_path = abs_file_path
        self.loom_connection = loom_connection
        self.dfh = dfh.DataFileHandler()

        logger.info(f"New Loom object created for {file_path}")
        # Metrics
        self.nUMI = None
        self.species, self.gene_mappings = self.infer_species()
        self.ss_pickle_name = self.abs_file_path.with_suffix(".ss_pkl")
        self.ss = ss.load_ss(self)
Exemple #6
0
def load_ss(loom) -> SearchSpace:
    ss_pickle_name: Path = loom.ss_pickle_name
    try:
        with open(ss_pickle_name, "rb") as fh:
            logger.debug(
                f"Loading prebuilt SS for {loom.file_path} from {ss_pickle_name}"
            )
            ss = pickle.load(fh)
            ss.loom = loom
            ss.dfh = dfh.DataFileHandler()
            if not hasattr(ss, "search_space_version"):
                logger.error(
                    f"Search space has no version key and is likely legacy. Rebuilding search space..."
                )
                ss = build(loom)
            elif ss.search_space_version != CURRENT_SS_VERISON:
                logger.error(
                    f"Cached search space version {ss.search_space_version} is not {CURRENT_SS_VERISON}. Rebuilding search space..."
                )
                ss = build(loom)
    except (EOFError, FileNotFoundError, TypeError):
        ss = build(loom)
    return ss
Exemple #7
0
    def do_POST(self):
        "Standard method to override in this Server object."
        # try:
        logger.info("Started file transfer")
        form = DroopyFieldStorage(fp=self.rfile,
                                  directory="",
                                  headers=self.headers,
                                  environ={"REQUEST_METHOD": self.command})

        data_file_handler = dfh.DataFileHandler()

        if "loomFilePath" in form.keys():
            self.directory = data_file_handler.get_data_dir_path_by_file_type(
                file_type=form.getvalue("file-type"))
            localpath = _encode_str_if_py2(
                os.path.join(self.directory, form.getvalue("loomFilePath")),
                "utf-8")
            with open(localpath, "rb") as f:
                self.send_resp_headers(
                    200,
                    {
                        "Content-length": os.fstat(f.fileno())[6],
                        "Access-Control-Allow-Origin": "*",
                        "Content-type": "application/x-hdf5",
                    },
                    end=True,
                )
                shutil.copyfileobj(f, self.wfile)
        else:
            if form.getvalue(
                    "file-type") in data_file_handler.get_data_dirs().keys():
                self.directory = data_file_handler.get_data_dir_path_by_file_type(
                    file_type=form.getvalue("file-type"),
                    UUID=form.getvalue("UUID"))
            else:
                self.send_error(415, "Unsupported file type")
                return None
            data_file_handler.update_UUID_db()
            try:
                if data_file_handler.current_UUIDs[form.getvalue(
                        "UUID")][1] == "ro":
                    self.send_error(403, "Session is read-only")
                    return None
            except KeyError:
                pass

            # Update the directory of DroopyFieldStorage
            form.directory = self.directory
            logger.info("Saving uploaded file in {0}".format(self.directory))
            file_items = form[self.form_field]

            # Handle multiple file upload
            if not isinstance(file_items, list):
                file_items = [file_items]
            for item in file_items:
                filename = _decode_str_if_py2(basename(item.filename), "utf-8")
                if filename == "":
                    continue
                localpath = _encode_str_if_py2(
                    os.path.join(self.directory, filename), "utf-8")
                root, ext = os.path.splitext(localpath)
                i = 1
                # TODO: race condition...
                while os.path.exists(localpath):
                    localpath = "%s-%d%s" % (root, i, ext)
                    i = i + 1
                if hasattr(item, "tmpfile"):
                    # DroopyFieldStorage.make_file() has been called
                    item.tmpfile.close()
                    shutil.move(item.tmpfilename, localpath)
                else:
                    # no temporary file, self.file is a StringIO()
                    # see cgi.FieldStorage.read_lines()
                    with open(localpath, "wb") as fout:
                        shutil.copyfileobj(item.file, fout)
                if self.file_mode is not None:
                    os.chmod(localpath, self.file_mode)
                logger.info("Received: {0}".format(
                    os.path.basename(localpath)))

            # -- Reply
            # The file list gives a feedback for the upload success
            try:
                # Always read in binary mode. Opening files in text mode may cause
                # newline translations, making the actual size of the content
                # transmitted *less* than the content-length!
                if form.getvalue("file-type") == "Loom":
                    try:
                        with lp.connect(localpath, mode="r",
                                        validate=False) as f:
                            logger.debug("Loom dimensions: {0}".format(
                                f.shape))
                            if not (f.shape[0] > 0 and f.shape[1] > 0):
                                raise KeyError
                            else:
                                f = open(localpath, "rb")
                    except (KeyError, OSError):
                        os.remove(localpath)
                        self.send_response(415, message="Upload Corrupt")
                        self.send_header("Access-Control-Allow-Origin", "*")
                        self.end_headers()
                        return None
                else:
                    logger.error("Not a loom: {0}".format(
                        form.getvalue("file-type")))
                    f = open(localpath, "rb")
            except IOError:
                self.send_error(404, "File not found")
                return None
            # Send correct HTTP headers and Allow CROS Origin
            fs = os.fstat(f.fileno())
            headers = {
                "Access-Control-Allow-Origin": "*",
                "Content-Type": "application/json",
                "Content-Length": 0,
                "Last-modified": self.date_time_string(fs.st_mtime),
            }
            self.send_resp_headers(200, headers, end=True)