-
-
Notifications
You must be signed in to change notification settings - Fork 689
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
A utility module has been created to work with android external storage files #2910
Open
SnayperTihCreator
wants to merge
18
commits into
beeware:main
Choose a base branch
from
SnayperTihCreator:AndroidUpdate
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
18 commits
Select commit
Hold shift + click to select a range
024dbb6
A utility module has been created to work with android external stora…
SnayperTihCreator 23684ae
The file opening dialog is partially implemented
SnayperTihCreator 9b7af36
Create 2910.misc.rst
SnayperTihCreator c4e245f
Update utilfile.py
SnayperTihCreator e46c5df
Update utilfile.py
SnayperTihCreator 0d66bbf
Добавлены коментарии
SnayperTihCreator f908fef
Update utilfile.py
SnayperTihCreator f122867
Generalization implementation
SnayperTihCreator 132f093
Updating file system usage
SnayperTihCreator 840bbbb
Update utilfile.py
SnayperTihCreator 31bd71d
Update utilfile.py
SnayperTihCreator ba66a0c
Update 2910.misc.rst
SnayperTihCreator 4bc9ed0
Update utilfile.py
SnayperTihCreator a89e3a9
Merge branch 'beeware:main' into AndroidUpdate
SnayperTihCreator cb321c1
update toga_android
SnayperTihCreator 3618da8
Merge remote-tracking branch 'origin/AndroidUpdate' into AndroidUpdate
SnayperTihCreator 653fdfc
Update utilfile.py
SnayperTihCreator e6d39e0
Merge branch 'beeware:main' into AndroidUpdate
SnayperTihCreator File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,205 @@ | ||
import abc | ||
import asyncio as aio | ||
import io | ||
import os | ||
from dataclasses import dataclass | ||
|
||
from java.io import BufferedReader, InputStreamReader, OutputStreamWriter | ||
from java.util import Objects | ||
|
||
import toga | ||
|
||
|
||
class BaseFile(io.TextIOBase): | ||
def __init__(self, stream, binary, encoding, newLineInt): | ||
self.aloop: aio.AbstractEventLoop = toga.App.app._impl.loop | ||
self._stream = stream | ||
self._buffer = None | ||
self._is_binary = binary | ||
self._new_line_int = newLineInt | ||
self._encoding = encoding | ||
|
||
def check_open(self): | ||
"""The defense mechanism on the open is that path""" | ||
if self._buffer is None: | ||
raise TypeError("File not open!") | ||
|
||
def __enter__(self): | ||
return self | ||
|
||
def __exit__(self, exc_type, exc_val, exc_tb): | ||
self.close() | ||
|
||
def close(self): | ||
self._stream.close() | ||
if self._buffer is not None: | ||
self._buffer.close() | ||
|
||
|
||
@dataclass | ||
class BaseDataOpen: | ||
binary: bool | ||
encoding: str | ||
newLineInt: int | ||
|
||
|
||
class BasePath(os.PathLike): | ||
modes = [] | ||
|
||
def __init__(self, content, uri): | ||
self._uri = uri | ||
self._content = content | ||
self._stream = None | ||
|
||
@abc.abstractmethod | ||
def open(self, mode, encoding="utf-8", new_line="\n"): | ||
"""Method for opening a file by path""" | ||
_new_line_int = new_line.encode(encoding)[0] | ||
if mode not in self.modes: | ||
raise ValueError( | ||
f"""invalid mode {mode}. | ||
It is allowed to use the following modes: R or RB""" | ||
) | ||
_is_binary = "b" in mode | ||
return BaseDataOpen(_is_binary, encoding, _new_line_int) | ||
|
||
|
||
class BaseFileReader(BaseFile, abc.ABC): | ||
|
||
def __init__(self, stream, binary, encoding, newLineInt): | ||
super().__init__(stream, binary, encoding, newLineInt) | ||
input_stream_reader = InputStreamReader(Objects.requireNonNull(self._stream)) | ||
self._buffer = BufferedReader(input_stream_reader) | ||
|
||
@abc.abstractmethod | ||
def read(self, size=0): | ||
pass | ||
|
||
@abc.abstractmethod | ||
def readline(self, size=0): | ||
pass | ||
|
||
@abc.abstractmethod | ||
async def aread(self, size=0): | ||
pass | ||
|
||
@abc.abstractmethod | ||
async def areadline(self, size=0): | ||
pass | ||
|
||
|
||
class FileReader(BaseFileReader): | ||
"""A phalloid object for reading. | ||
Reads the contents of the Android external storage file""" | ||
|
||
def readline(self, size: int = 0) -> str | bytes: | ||
"""A function for reading lines from a file | ||
:param size: the number of rows to be counted. | ||
(Currently not implemented, added for future implementation) | ||
:return: Data type str[bytes] | ||
(Depends on whether the flag and was passed) or the list of str[bytes] | ||
""" | ||
self.check_open() | ||
res = bytearray() | ||
counter = size if size else "-1" | ||
while counter: | ||
resp: int = self._buffer.read() | ||
if resp == -1: | ||
break | ||
if resp == self._new_line_int: | ||
break | ||
res.append(resp) | ||
if isinstance(counter, int): | ||
counter -= 1 | ||
if self._is_binary: | ||
return bytes(res) | ||
return res.decode(self._encoding) | ||
|
||
def read(self, size: int = 0) -> bytes | str: | ||
"""A function for reading a string | ||
:param size: the number of characters to be counted. | ||
If it is equal to 0, the entire file will be read | ||
:return: Data type str[bytes] | ||
(depends on whether the 'b' flag was passed)""" | ||
self.check_open() | ||
res = bytearray() | ||
counter = size if size else "-1" | ||
while counter: | ||
resp: int = self._buffer.read() | ||
if resp == -1: | ||
break | ||
res.append(resp) | ||
if isinstance(counter, int): | ||
counter -= 1 | ||
if self._is_binary: | ||
return bytes(res) | ||
return res.decode(self._encoding) | ||
|
||
async def aread(self, size=0): | ||
"""Asynchronous function for reading a string | ||
:parameter size: the number of characters to count. | ||
If it is equal to 0, the entire file will be read | ||
:returns: data type str[bytes] | ||
(depends on whether the 'b' flag was passed)""" | ||
self.check_open() | ||
return await self.aloop.run_in_executor(None, self.read, size) | ||
|
||
async def areadline(self, size=0): | ||
"""Asynchronous function for reading lines from a file | ||
: parameter size: the number of rows to count. | ||
(Currently not implemented, added for future implementation) | ||
:returns: data type str[byte] | ||
(Depends on whether and flag was passed) or the str[byte] list""" | ||
return await self.aloop.run_in_executor(None, self.readline, size) | ||
|
||
|
||
class BaseFileWriter(BaseFile, abc.ABC): | ||
|
||
def __init__(self, stream, binary, encoding, newLineInt): | ||
super().__init__(stream, binary, encoding, newLineInt) | ||
self._buffer = OutputStreamWriter(self._stream) | ||
|
||
def _convertion_type_data(self, data): | ||
if isinstance(data, bytes) and not self._is_binary: | ||
return data.decode(self._encoding) | ||
if isinstance(data, str) and self._is_binary: | ||
return data.encode(self._encoding) | ||
return data | ||
|
||
@abc.abstractmethod | ||
def write(self, text: str | bytes): | ||
pass | ||
|
||
@abc.abstractmethod | ||
async def awrite(self, text): | ||
pass | ||
|
||
|
||
class FileWriter(BaseFileWriter): | ||
def write(self, text: str | bytes): | ||
data = self._convertion_type_data(text) | ||
self._buffer.write(data) | ||
|
||
def awrite(self, text): | ||
pass | ||
|
||
|
||
class Path(BasePath): | ||
modes = ["r", "rb", "w", "wb"] | ||
|
||
def open(self, mode="r", encoding="utf-8", new_line="\n"): | ||
"""A method for opening a file for reading along the path""" | ||
dataOpen = super().open(mode.lower(), encoding, new_line) | ||
if "r" in mode.lower(): | ||
self._stream = self._content.openInputStream(self._uri) | ||
return FileReader( | ||
self._stream, dataOpen.binary, dataOpen.encoding, dataOpen.newLineInt | ||
) | ||
if "w" in mode.lower(): | ||
self._stream = self._content.openOutputStream(self._uri) | ||
return FileWriter( | ||
self._stream, dataOpen.binary, dataOpen.encoding, dataOpen.newLineInt | ||
) | ||
|
||
def __fspath__(self): | ||
return str(self._uri) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
Android implementation of OpenFileDialog | ||
|
||
Adding a utility module for reading from external storage files | ||
|
||
Adding singleton for file management on Android/Windows for API communication | ||
|
||
Support with Python 3.10+ |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A what? Are you sure this is the word you mean?