def upload_file(<EOL>self,<EOL>filename,<EOL>upload_as=None,<EOL>blocksize=None,<EOL>callback=None,<EOL>information_callback=None,<EOL>allow_timeout=False,<EOL>):
with delayed_close(<EOL>filename if hasattr(filename, "<STR_LIT>") else open(filename, "<STR_LIT:rb>")<EOL>) as file:<EOL><INDENT>filename = upload_as or os.path.split(filename)[<NUM_LIT:1>]<EOL>try:<EOL><INDENT>file.seek(<NUM_LIT:0>, <NUM_LIT:2>)<EOL>if file.tell() > self.config.max_file:<EOL><INDENT>raise ValueError(<EOL>f"<STR_LIT>"<EOL>)<EOL><DEDENT><DEDENT>finally:<EOL><INDENT>try:<EOL><INDENT>file.seek(<NUM_LIT:0>)<EOL><DEDENT>except Exception:<EOL><INDENT>pass<EOL><DEDENT><DEDENT>files = Data(<EOL>{"<STR_LIT:file>": {"<STR_LIT:name>": filename, "<STR_LIT:value>": file}},<EOL>blocksize=blocksize,<EOL>callback=callback,<EOL>)<EOL>headers = {"<STR_LIT>": BASE_URL}<EOL>headers.update(files.headers)<EOL>while True:<EOL><INDENT>key, server, file_id = self._generate_upload_key(<EOL>allow_timeout=allow_timeout<EOL>)<EOL>info = dict(<EOL>key=key,<EOL>server=server,<EOL>file_id=file_id,<EOL>room=self.room_id,<EOL>filename=filename,<EOL>len=files.len,<EOL>resumecount=<NUM_LIT:0>,<EOL>)<EOL>if information_callback:<EOL><INDENT>if information_callback(info) is False:<EOL><INDENT>continue<EOL><DEDENT><DEDENT>break<EOL><DEDENT>params = {"<STR_LIT>": self.room_id, "<STR_LIT:key>": key, "<STR_LIT:filename>": filename}<EOL>if self.key:<EOL><INDENT>params["<STR_LIT>"] = self.key<EOL><DEDENT>if self.password:<EOL><INDENT>params["<STR_LIT:password>"] = self.password<EOL><DEDENT>while True:<EOL><INDENT>try:<EOL><INDENT>post = self.conn.post(<EOL>f"<STR_LIT>",<EOL>params=params,<EOL>data=files,<EOL>headers=headers,<EOL>)<EOL>post.raise_for_status()<EOL>break<EOL><DEDENT>except requests.exceptions.ConnectionError as ex:<EOL><INDENT>if "<STR_LIT>" not in repr(ex):  <EOL><INDENT>raise<EOL><DEDENT>try:<EOL><INDENT>resume = self.conn.get(<EOL>f"<STR_LIT>",<EOL>params={"<STR_LIT:key>": key, "<STR_LIT:c>": <NUM_LIT:1>},<EOL>).text<EOL>resume = from_json(resume)<EOL>resume = resume["<STR_LIT>"]<EOL>if resume <= <NUM_LIT:0>:<EOL><INDENT>raise ConnectionError("<STR_LIT>")<EOL><DEDENT>file.seek(resume)<EOL>files = Data(<EOL>{"<STR_LIT:file>": {"<STR_LIT:name>": filename, "<STR_LIT:value>": file}},<EOL>blocksize=blocksize,<EOL>callback=callback,<EOL>logical_offset=resume,<EOL>)<EOL>headers.update(files.headers)<EOL>params["<STR_LIT>"] = resume<EOL>info["<STR_LIT>"] += <NUM_LIT:1><EOL>if information_callback:<EOL><INDENT>information_callback(info)<EOL><DEDENT><DEDENT>except requests.exceptions.ConnectionError as iex:<EOL><INDENT>if "<STR_LIT>" not in repr(iex):<EOL><INDENT>raise<EOL><DEDENT>continue  <EOL><DEDENT><DEDENT><DEDENT>return file_id<EOL><DEDENT>
Uploads a file with given filename to this room.
        You may specify upload_as to change the name it is uploaded as.
        You can also specify a blocksize and a callback if you wish.
        Returns the file's id on success and None on failure.