summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCoprDistGit <infra@openeuler.org>2023-05-18 06:43:40 +0000
committerCoprDistGit <infra@openeuler.org>2023-05-18 06:43:40 +0000
commitffde5e8b2e9def8c3fa5e521fb793085c757e065 (patch)
tree2ddf7a6bddaf2d8b93a57fa9d0c38f8beb6ab989
parent214fa2ce52c9e0639fc05fad41635a26d6ff39ee (diff)
automatic import of python-faf-replay-parser
-rw-r--r--.gitignore1
-rw-r--r--python-faf-replay-parser.spec456
-rw-r--r--sources1
3 files changed, 458 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index e69de29..920a74d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -0,0 +1 @@
+/faf-replay-parser-0.5.3.tar.gz
diff --git a/python-faf-replay-parser.spec b/python-faf-replay-parser.spec
new file mode 100644
index 0000000..94fdc68
--- /dev/null
+++ b/python-faf-replay-parser.spec
@@ -0,0 +1,456 @@
+%global _empty_manifest_terminate_build 0
+Name: python-faf-replay-parser
+Version: 0.5.3
+Release: 1
+Summary: Python bindings for faf-replay-parser
+License: License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)
+URL: https://github.com/Askaholic/faf-replay-parser-python
+Source0: https://mirrors.nju.edu.cn/pypi/web/packages/3a/56/6712c09742fcc086c9ccbea56d726d0182c22b191340d58758b4e878f86a/faf-replay-parser-0.5.3.tar.gz
+
+Requires: python3-zstd
+
+%description
+# FAF Replay Parser
+![Build Status](https://github.com/Askaholic/faf-replay-parser-python/actions/workflows/test.yml/badge.svg?branch=main)
+[![pypi](https://badge.fury.io/py/faf-replay-parser.svg)](https://pypi.python.org/pypi/faf-replay-parser)
+![Supported Python Versions](https://img.shields.io/pypi/pyversions/faf-replay-parser.svg)
+
+A fast library for parsing Supreme Commander Forged Alliance replay files.
+
+## Installation
+Pre-built packages are available for Linux, MacOS, and Windows. You can install
+them with:
+
+```
+pip install faf-replay-parser
+```
+
+## Documentation
+Here are some examples of using the parser. Check `help(fafreplay)` for more
+details on available functions.
+
+### Gathering basic info
+For the most basic uses there are a few special functions that should be
+preferred over constructing a `Parser` object. These do only one job, but they
+do it very quickly.
+
+Current functions:
+ - `body_offset` - Used for splitting replay data into header and body.
+ - `body_ticks` - Used for extracting the game length.
+
+#### Example
+```python
+from datetime import timedelta
+from fafreplay import body_offset, body_ticks
+
+# Split replay data into header and body
+offset = body_offset(data)
+header_data, body_data = data[:offset], data[offset:]
+
+# Get replay length in ticks
+ticks = body_ticks(body_data)
+print("Game length:", timedelta(milliseconds=ticks*100))
+```
+
+### Using the Parser object
+The `Parser` object can be used to get fine grained control over how replay
+commands are parsed. Generally it's a good idea to parse only the minimum
+commands needed, as conversion back to python dictionaries is quite expensive.
+
+```python
+from datetime import timedelta
+from fafreplay import Parser, commands
+
+parser = Parser(
+ # Skip all commands except the ones defined here
+ commands=[
+ commands.Advance, # For the tick counter
+ commands.VerifyChecksum, # For desync detection
+ ],
+ # Throw away commands right after we parse them. Setting this to `True` will
+ # significantly increase the parse time.
+ save_commands=False,
+ limit=None,
+ stop_on_desync=False
+)
+# Or create a parser with default arguments (turn off save_commands though)
+# parser = Parser(save_commands=False)
+
+# Read replay to a `bytes` object
+with open("12345.scfareplay", "rb") as f:
+ data = f.read()
+
+# Parse to a python dictionary. Data must of type `bytes` or `bytearray`
+replay = parser.parse(data)
+print("Game time:", timedelta(milliseconds=replay["body"]["sim"]["tick"]*100))
+if replay["body"]["sim"]["desync_ticks"]:
+ print("Replay desynced!")
+```
+
+### Benchmark comparison
+To see how much faster the basic functions can be, consider this simple example
+done on replay `8653680` (an almost 50 minute long Seton's game).
+
+```python
+>>> len(body_data)
+5586339
+>>> body_ticks(body_data)
+28917
+>>> parser = Parser(
+... commands=[commands.Advance],
+... save_commands=False
+... )
+>>> timeit.timeit("parser.parse_body(body_data)['sim']['tick']", globals=globals(), number=100)
+1.4510237049980788
+>>> timeit.timeit("body_ticks(body_data)", globals=globals(), number=100)
+0.20173147800232982
+```
+
+In this case `body_ticks` turned out to be more than 7x faster than using a
+`Parser`.
+
+### Reading .fafreplay files
+Replays downloaded from [faforever.com](https://faforever.com) use a compressed
+data format to reduce the size of the files. These can be decompressed to the
+original `.scfareplay` data using the `extract_scfa` function.
+
+```python
+from fafreplay import extract_scfa
+
+
+with open("12345.scfareplay", "rb") as f:
+ scfa_data = f.read()
+
+with open("12345.fafreplay", "rb") as f:
+ faf_data = extract_scfa(f)
+
+# The extracted data is in the .scfareplay format
+assert faf_data == scfa_data
+```
+
+Note that there are several versions of the `.fafreplay` format. Version 1 uses
+base64 and zlib compression which are both part of the python standard library.
+However, version 2 uses `zstd` which must be installed through a third party
+package. To ensure that this dependency is installed you can use the `faf` extra
+when installing the parser:
+
+```
+pip install "faf-replay-parser[faf]"
+```
+
+
+%package -n python3-faf-replay-parser
+Summary: Python bindings for faf-replay-parser
+Provides: python-faf-replay-parser
+BuildRequires: python3-devel
+BuildRequires: python3-setuptools
+BuildRequires: python3-pip
+BuildRequires: python3-cffi
+BuildRequires: gcc
+BuildRequires: gdb
+%description -n python3-faf-replay-parser
+# FAF Replay Parser
+![Build Status](https://github.com/Askaholic/faf-replay-parser-python/actions/workflows/test.yml/badge.svg?branch=main)
+[![pypi](https://badge.fury.io/py/faf-replay-parser.svg)](https://pypi.python.org/pypi/faf-replay-parser)
+![Supported Python Versions](https://img.shields.io/pypi/pyversions/faf-replay-parser.svg)
+
+A fast library for parsing Supreme Commander Forged Alliance replay files.
+
+## Installation
+Pre-built packages are available for Linux, MacOS, and Windows. You can install
+them with:
+
+```
+pip install faf-replay-parser
+```
+
+## Documentation
+Here are some examples of using the parser. Check `help(fafreplay)` for more
+details on available functions.
+
+### Gathering basic info
+For the most basic uses there are a few special functions that should be
+preferred over constructing a `Parser` object. These do only one job, but they
+do it very quickly.
+
+Current functions:
+ - `body_offset` - Used for splitting replay data into header and body.
+ - `body_ticks` - Used for extracting the game length.
+
+#### Example
+```python
+from datetime import timedelta
+from fafreplay import body_offset, body_ticks
+
+# Split replay data into header and body
+offset = body_offset(data)
+header_data, body_data = data[:offset], data[offset:]
+
+# Get replay length in ticks
+ticks = body_ticks(body_data)
+print("Game length:", timedelta(milliseconds=ticks*100))
+```
+
+### Using the Parser object
+The `Parser` object can be used to get fine grained control over how replay
+commands are parsed. Generally it's a good idea to parse only the minimum
+commands needed, as conversion back to python dictionaries is quite expensive.
+
+```python
+from datetime import timedelta
+from fafreplay import Parser, commands
+
+parser = Parser(
+ # Skip all commands except the ones defined here
+ commands=[
+ commands.Advance, # For the tick counter
+ commands.VerifyChecksum, # For desync detection
+ ],
+ # Throw away commands right after we parse them. Setting this to `True` will
+ # significantly increase the parse time.
+ save_commands=False,
+ limit=None,
+ stop_on_desync=False
+)
+# Or create a parser with default arguments (turn off save_commands though)
+# parser = Parser(save_commands=False)
+
+# Read replay to a `bytes` object
+with open("12345.scfareplay", "rb") as f:
+ data = f.read()
+
+# Parse to a python dictionary. Data must of type `bytes` or `bytearray`
+replay = parser.parse(data)
+print("Game time:", timedelta(milliseconds=replay["body"]["sim"]["tick"]*100))
+if replay["body"]["sim"]["desync_ticks"]:
+ print("Replay desynced!")
+```
+
+### Benchmark comparison
+To see how much faster the basic functions can be, consider this simple example
+done on replay `8653680` (an almost 50 minute long Seton's game).
+
+```python
+>>> len(body_data)
+5586339
+>>> body_ticks(body_data)
+28917
+>>> parser = Parser(
+... commands=[commands.Advance],
+... save_commands=False
+... )
+>>> timeit.timeit("parser.parse_body(body_data)['sim']['tick']", globals=globals(), number=100)
+1.4510237049980788
+>>> timeit.timeit("body_ticks(body_data)", globals=globals(), number=100)
+0.20173147800232982
+```
+
+In this case `body_ticks` turned out to be more than 7x faster than using a
+`Parser`.
+
+### Reading .fafreplay files
+Replays downloaded from [faforever.com](https://faforever.com) use a compressed
+data format to reduce the size of the files. These can be decompressed to the
+original `.scfareplay` data using the `extract_scfa` function.
+
+```python
+from fafreplay import extract_scfa
+
+
+with open("12345.scfareplay", "rb") as f:
+ scfa_data = f.read()
+
+with open("12345.fafreplay", "rb") as f:
+ faf_data = extract_scfa(f)
+
+# The extracted data is in the .scfareplay format
+assert faf_data == scfa_data
+```
+
+Note that there are several versions of the `.fafreplay` format. Version 1 uses
+base64 and zlib compression which are both part of the python standard library.
+However, version 2 uses `zstd` which must be installed through a third party
+package. To ensure that this dependency is installed you can use the `faf` extra
+when installing the parser:
+
+```
+pip install "faf-replay-parser[faf]"
+```
+
+
+%package help
+Summary: Development documents and examples for faf-replay-parser
+Provides: python3-faf-replay-parser-doc
+%description help
+# FAF Replay Parser
+![Build Status](https://github.com/Askaholic/faf-replay-parser-python/actions/workflows/test.yml/badge.svg?branch=main)
+[![pypi](https://badge.fury.io/py/faf-replay-parser.svg)](https://pypi.python.org/pypi/faf-replay-parser)
+![Supported Python Versions](https://img.shields.io/pypi/pyversions/faf-replay-parser.svg)
+
+A fast library for parsing Supreme Commander Forged Alliance replay files.
+
+## Installation
+Pre-built packages are available for Linux, MacOS, and Windows. You can install
+them with:
+
+```
+pip install faf-replay-parser
+```
+
+## Documentation
+Here are some examples of using the parser. Check `help(fafreplay)` for more
+details on available functions.
+
+### Gathering basic info
+For the most basic uses there are a few special functions that should be
+preferred over constructing a `Parser` object. These do only one job, but they
+do it very quickly.
+
+Current functions:
+ - `body_offset` - Used for splitting replay data into header and body.
+ - `body_ticks` - Used for extracting the game length.
+
+#### Example
+```python
+from datetime import timedelta
+from fafreplay import body_offset, body_ticks
+
+# Split replay data into header and body
+offset = body_offset(data)
+header_data, body_data = data[:offset], data[offset:]
+
+# Get replay length in ticks
+ticks = body_ticks(body_data)
+print("Game length:", timedelta(milliseconds=ticks*100))
+```
+
+### Using the Parser object
+The `Parser` object can be used to get fine grained control over how replay
+commands are parsed. Generally it's a good idea to parse only the minimum
+commands needed, as conversion back to python dictionaries is quite expensive.
+
+```python
+from datetime import timedelta
+from fafreplay import Parser, commands
+
+parser = Parser(
+ # Skip all commands except the ones defined here
+ commands=[
+ commands.Advance, # For the tick counter
+ commands.VerifyChecksum, # For desync detection
+ ],
+ # Throw away commands right after we parse them. Setting this to `True` will
+ # significantly increase the parse time.
+ save_commands=False,
+ limit=None,
+ stop_on_desync=False
+)
+# Or create a parser with default arguments (turn off save_commands though)
+# parser = Parser(save_commands=False)
+
+# Read replay to a `bytes` object
+with open("12345.scfareplay", "rb") as f:
+ data = f.read()
+
+# Parse to a python dictionary. Data must of type `bytes` or `bytearray`
+replay = parser.parse(data)
+print("Game time:", timedelta(milliseconds=replay["body"]["sim"]["tick"]*100))
+if replay["body"]["sim"]["desync_ticks"]:
+ print("Replay desynced!")
+```
+
+### Benchmark comparison
+To see how much faster the basic functions can be, consider this simple example
+done on replay `8653680` (an almost 50 minute long Seton's game).
+
+```python
+>>> len(body_data)
+5586339
+>>> body_ticks(body_data)
+28917
+>>> parser = Parser(
+... commands=[commands.Advance],
+... save_commands=False
+... )
+>>> timeit.timeit("parser.parse_body(body_data)['sim']['tick']", globals=globals(), number=100)
+1.4510237049980788
+>>> timeit.timeit("body_ticks(body_data)", globals=globals(), number=100)
+0.20173147800232982
+```
+
+In this case `body_ticks` turned out to be more than 7x faster than using a
+`Parser`.
+
+### Reading .fafreplay files
+Replays downloaded from [faforever.com](https://faforever.com) use a compressed
+data format to reduce the size of the files. These can be decompressed to the
+original `.scfareplay` data using the `extract_scfa` function.
+
+```python
+from fafreplay import extract_scfa
+
+
+with open("12345.scfareplay", "rb") as f:
+ scfa_data = f.read()
+
+with open("12345.fafreplay", "rb") as f:
+ faf_data = extract_scfa(f)
+
+# The extracted data is in the .scfareplay format
+assert faf_data == scfa_data
+```
+
+Note that there are several versions of the `.fafreplay` format. Version 1 uses
+base64 and zlib compression which are both part of the python standard library.
+However, version 2 uses `zstd` which must be installed through a third party
+package. To ensure that this dependency is installed you can use the `faf` extra
+when installing the parser:
+
+```
+pip install "faf-replay-parser[faf]"
+```
+
+
+%prep
+%autosetup -n faf-replay-parser-0.5.3
+
+%build
+%py3_build
+
+%install
+%py3_install
+install -d -m755 %{buildroot}/%{_pkgdocdir}
+if [ -d doc ]; then cp -arf doc %{buildroot}/%{_pkgdocdir}; fi
+if [ -d docs ]; then cp -arf docs %{buildroot}/%{_pkgdocdir}; fi
+if [ -d example ]; then cp -arf example %{buildroot}/%{_pkgdocdir}; fi
+if [ -d examples ]; then cp -arf examples %{buildroot}/%{_pkgdocdir}; fi
+pushd %{buildroot}
+if [ -d usr/lib ]; then
+ find usr/lib -type f -printf "/%h/%f\n" >> filelist.lst
+fi
+if [ -d usr/lib64 ]; then
+ find usr/lib64 -type f -printf "/%h/%f\n" >> filelist.lst
+fi
+if [ -d usr/bin ]; then
+ find usr/bin -type f -printf "/%h/%f\n" >> filelist.lst
+fi
+if [ -d usr/sbin ]; then
+ find usr/sbin -type f -printf "/%h/%f\n" >> filelist.lst
+fi
+touch doclist.lst
+if [ -d usr/share/man ]; then
+ find usr/share/man -type f -printf "/%h/%f.gz\n" >> doclist.lst
+fi
+popd
+mv %{buildroot}/filelist.lst .
+mv %{buildroot}/doclist.lst .
+
+%files -n python3-faf-replay-parser -f filelist.lst
+%dir %{python3_sitearch}/*
+
+%files help -f doclist.lst
+%{_docdir}/*
+
+%changelog
+* Thu May 18 2023 Python_Bot <Python_Bot@openeuler.org> - 0.5.3-1
+- Package Spec generated
diff --git a/sources b/sources
new file mode 100644
index 0000000..5ff187b
--- /dev/null
+++ b/sources
@@ -0,0 +1 @@
+fdecd1efe1b5e28b54abe3758c10d044 faf-replay-parser-0.5.3.tar.gz