Skip to content

Commit 9477a33

Browse files
committed
Update metadata
1 parent 9e2b49f commit 9477a33

File tree

3 files changed

+61
-32
lines changed

3 files changed

+61
-32
lines changed

README.md

Lines changed: 54 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -7,48 +7,59 @@
77
<a href="https://github.com/AT0myks/reolink-fw/blob/main/LICENSE"><img alt="License" src="https://img.shields.io/pypi/l/reolinkfw"></a>
88
</p>
99

10-
* [What is it](#what-is-it)
10+
* [Description](#description)
1111
* [Requirements](#requirements)
1212
* [Installation](#installation)
1313
* [Usage](#usage)
1414
* [Notes](#notes)
1515
* [Issues](#issues)
1616

17-
## What is it
17+
## Description
1818

19-
This is a small tool to get information on Reolink firmwares.
20-
It's able to read ZIP and PAK files, either local or at the end of a URL.
21-
The info is read from the files contained in the firmware (mainly `dvr.xml`) and
22-
if we trust them to be 100% correct, it allows to know precisely which
23-
model/hardware version a given firmware is targeting.
19+
This is a tool and library to read and extract Reolink firmwares.
20+
It supports ZIP and PAK files, local or remote.
21+
Information is retrieved directly from the files contained inside a firmware.
2422

25-
It was first developed as part of
26-
[another Reolink-related project](https://github.com/AT0myks/reolink-fw-archive)
27-
but became its own thing.
23+
It can extract:
24+
- File systems
25+
- Decompressed U-Boot
26+
- Decompressed kernel
27+
- Kernel config (some firmwares)
28+
- Devicetree source (some firmwares)
2829

29-
Currently it doesn't do anything more and is probably not that useful outside of
30-
this other project.
30+
This is what powers the
31+
[firmware archive](https://github.com/AT0myks/reolink-fw-archive)
32+
where you can also find
33+
[details](https://github.com/AT0myks/reolink-fw-archive/blob/main/pak_info.json)
34+
about all of the firmwares it lists without having to install the tool yourself.
3135

3236
## Requirements
3337

3438
- Python 3.9+
35-
- [python-lzo](https://github.com/jd-boyd/python-lzo) (manual steps not required on Windows, see below)
39+
- [python-lzo](https://github.com/jd-boyd/python-lzo)
3640

3741
## Installation
3842

39-
On Linux and macOS, install
40-
[python-lzo](https://github.com/jd-boyd/python-lzo#installation) first. Then
41-
4243
```
44+
pip install -i https://test.pypi.org/simple/ python-lzo
4345
pip install reolinkfw
4446
```
4547

46-
lxml doesn't have a wheel for Python 3.11 on macOS, you might want to look
47-
[here](https://lxml.de/installation.html).
48-
4948
python-lzo doesn't have wheels for Linux and for Python 3.9+ on macOS.
50-
A [PR](https://github.com/jd-boyd/python-lzo/pull/75) is open to have them be
51-
provided on PyPI.
49+
A [PR](https://github.com/jd-boyd/python-lzo/pull/75) has been merged to provide
50+
wheels for all version on all platforms but there needs to be a new release first.
51+
In the meantime you can install wheels from
52+
[TestPyPI](https://test.pypi.org/project/python-lzo/) as shown above.
53+
54+
> [!IMPORTANT]
55+
> No Python 3.12 wheels exist yet for python-lzo and lz4.
56+
> To build python-lzo from source see
57+
> [here](https://github.com/jd-boyd/python-lzo/blob/dc6a0f365267c4db99caf941e1beeb9fdfe0fe8c/README.md#installation)
58+
> (Linux and macOS) and
59+
> [here](https://github.com/jd-boyd/python-lzo?tab=readme-ov-file#building-from-source)
60+
> (Windows), and
61+
> [here](https://python-lz4.readthedocs.io/en/stable/install.html#installing-from-source)
62+
> for lz4.
5263
5364
## Usage
5465

@@ -62,7 +73,7 @@ usage: reolinkfw info [-h] [--no-cache] [-j [indent]] file_or_url
6273
positional arguments:
6374
file_or_url URL or on-disk file
6475
65-
optional arguments:
76+
options:
6677
-h, --help show this help message and exit
6778
--no-cache don't use cache for remote files (URLs)
6879
-j [indent], --json [indent] JSON output with optional indentation level for pretty print
@@ -138,12 +149,12 @@ the file name.
138149
```
139150
usage: reolinkfw extract [-h] [--no-cache] [-d DEST] [-f] file_or_url
140151
141-
Extract the file system from a Reolink firmware
152+
Extract the file system and a few other files from a Reolink firmware
142153
143154
positional arguments:
144155
file_or_url URL or on-disk file
145156
146-
optional arguments:
157+
options:
147158
-h, --help show this help message and exit
148159
--no-cache don't use cache for remote files (URLs)
149160
-d DEST, --dest DEST destination directory. Default: current directory
@@ -168,9 +179,9 @@ from reolinkfw import ReolinkFirmware, get_info
168179

169180
url = "https://reolink-storage.s3.amazonaws.com/website/firmware/20200523firmware/RLC-410-5MP_20_20052300.zip"
170181
print(get_info(url))
171-
file = "/home/ben/RLC-410-5MP_20_20052300.zip"
172-
print(get_info(file))
173-
with ReolinkFirmware.from_file(file) as fw:
182+
pak = "/home/ben/RLC-410-5MP_20_20052300.pak"
183+
with ReolinkFirmware.from_file(pak) as fw:
184+
print(fw.get_info())
174185
fw.extract()
175186
```
176187

@@ -181,7 +192,7 @@ But in some cases (for example beta firmwares) Reolink gives a Google Drive or
181192
a bit.ly link (that redirects to a Google Drive link).
182193

183194
These URLs are automatically handled so that you don't have to figure out the
184-
"real" download link, and in this case the `url` value(s) in the result JSON
195+
"real" download link, and in this case the `file` value(s) in the result JSON
185196
will not be the link that you gave but the direct download one.
186197

187198
However the Google Drive folder links (`drive.google.com/drive/folders`) are not
@@ -197,3 +208,18 @@ There are 3 types of file systems used for Reolink firmwares:
197208

198209
Some ZIP files provided by Reolink contain multiple PAKs. This is why `get_info`
199210
always returns a list.
211+
212+
Here's a map of vendors to hardware versions:
213+
214+
Cameras:
215+
- MStar/SigmaStar: IPC_30, IPC_32, IPC_MS
216+
- Grain Media: IPC_35, IPC_36, IPC_38
217+
- Novatek: DB_56, FE_52, IPC_51, IPC_52, IPC_56, IPC_NT
218+
219+
NVRs:
220+
- Novatek: hardware version is H3MB18 or starts with N
221+
- HiSilicon: hardware version starts with H (except H3MB18)
222+
223+
Grain Media was
224+
[transferred](https://web.archive.org/web/20170703025339/https://www.grain-media.com/)
225+
to Novatek around 2017.

pyproject.toml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,27 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "reolinkfw"
7-
description = "Extract information from Reolink firmware files."
7+
description = "Extract information and files from Reolink firmwares."
88
readme = "README.md"
99
requires-python = ">=3.9"
1010
keywords = ["reolink", "firmware"]
1111
authors = [
12-
{name = "AT0myks", email = "[email protected]"},
12+
{name = "AT0myks", email = "[email protected]"},
1313
]
1414
classifiers = [
1515
"Development Status :: 5 - Production/Stable",
1616
"Intended Audience :: Developers",
1717
"Intended Audience :: End Users/Desktop",
1818
"License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
19+
"Operating System :: OS Independent",
1920
"Programming Language :: Python :: 3",
2021
"Programming Language :: Python :: 3 :: Only",
2122
"Programming Language :: Python :: 3.9",
2223
"Programming Language :: Python :: 3.10",
2324
"Programming Language :: Python :: 3.11",
24-
"Operating System :: OS Independent",
25+
"Programming Language :: Python :: 3.12",
26+
"Topic :: Software Development :: Libraries",
27+
"Topic :: Software Development :: Libraries :: Python Modules",
2528
"Topic :: Utilities"
2629
]
2730
dependencies = [

reolinkfw/__main__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ def main() -> None:
7373
parser_i.add_argument("-j", "--json", nargs='?', type=int, const=-1, metavar="indent", help="JSON output with optional indentation level for pretty print")
7474
parser_i.set_defaults(func=info)
7575

76-
descex = "Extract the file system from a Reolink firmware"
76+
descex = "Extract the file system and a few other files from a Reolink firmware"
7777
parser_e = subparsers.add_parser("extract", parents=[pcache], aliases=['e'], help=descex.lower(), description=descex)
7878
parser_e.add_argument("file_or_url", help="URL or on-disk file")
7979
parser_e.add_argument("-d", "--dest", type=Path, help="destination directory. Default: current directory")

0 commit comments

Comments
 (0)