|
2 | 2 |
|
3 | 3 | *Because `pybinlog` was taken™*
|
4 | 4 |
|
5 |
| -`pybinhistory` reads and writes `.log` access log files, which accompany `.avb` Avid bins. It includes data validation and convenience methods, such as the ability to "touch" a bin in one command. |
6 |
| - |
7 |
| -In a multi-user Avid Media Composer environment, Avid will append an entry to a bin's log file each time a user writes to a bin. With `pybinhistory`, this functionality can be mimicked programmatically. |
| 5 | +`binhistory` is a python library for programmatically reading and writing Avid bin history log (`.log`) files in |
| 6 | +multi-user Avid Media Composer projects. |
8 | 7 |
|
9 | 8 | >[!WARNING]
|
10 |
| ->While the `.log` log file format is a very simple one, it is officially undocumented. Use this library at your own risk -- I assume no responsibility for any damage to your |
11 |
| ->project, loss of data, or reshoots being blatantly obvious in the final cut. |
12 |
| -
|
13 |
| -## Quick Start |
14 |
| - |
15 |
| -### Touching A Bin |
16 |
| - |
17 |
| -You can easily add an entry to the bin log with the `BinLog.touch()` convenience method. |
18 |
| - |
19 |
| -```python |
20 |
| -from binlog import BinLog |
21 |
| - |
22 |
| -# Write default entries containing the current datetime and user info |
23 |
| -BinLog.touch("/path/to/bin.log") # Specify a .log path directly |
24 |
| -BinLog.touch_bin("/path/to/bin.avb") # Specify a .avb path. This resolves the path to the same `bin.log` file |
25 |
| -``` |
26 |
| - |
27 |
| -You can add custom entries by providing a [`BinLogEntry`](#binlogentry) object: |
| 9 | +> `binlog` is an unofficial library created for educational purposes. While the ``.log`` file format |
| 10 | +>is a very simple one, it is officially undocumented. Use this library at your own risk -- the developer assumes |
| 11 | +>no responsibility for any damage to your project, loss of data, or weird snippy drama about who threw the audio |
| 12 | +>out of sync in the latest version of the reel. |
28 | 13 |
|
29 |
| -```python |
30 |
| -from binlog import BinLog, BinLogEntry |
| 14 | +## Interesting Uses |
31 | 15 |
|
32 |
| -my_cool_entry = BinLogEntry(user="me", computer="zAutomation") |
33 |
| -BinLog.touch_bin("/path/to/bin.avb", my_cool_entry) |
34 |
| -``` |
| 16 | +- Be a good citizen! Add a bin log entry when modifying a bin programmatically via automation/pipeline-y operations. |
| 17 | +- Snoop around! Easily gather metrics about modifications made by particular machines or users. |
| 18 | +- Makes you look cool! Everyone will be very impressed with you. "Wow!" they'll say. |
35 | 19 |
|
36 |
| -### Getting The Most Recent Entry |
| 20 | +## Installation |
37 | 21 |
|
38 |
| -You can obtain the most recent bin log entry with the `BinLog.last_entry()` method. |
| 22 | +Install the `pybinhistory` package [from PyPI](https://pypi.org/project/pybinhistory/) using `pip`: |
39 | 23 |
|
40 |
| -```python |
41 |
| -from binlog import BinLog |
42 |
| -print(BinLog.from_bin("/path/to/bin.avb").last_entry()) |
| 24 | +```bash |
| 25 | +pip install pybinhistory |
43 | 26 | ```
|
44 | 27 |
|
45 |
| -This returns the most recent [`BinLogEntry`](#binlogentry) item in the log: |
46 |
| - |
47 |
| -`BinLogEntry(timestamp=datetime.datetime(2023, 9, 22, 14, 8, 4), computer='zMichael', user='mj4u')` |
48 |
| - |
49 |
| -## `BinLog` |
50 |
| - |
51 |
| -A `BinLog` represents a... uh... bin log. It handles reading and writing to log files, and essentially encapsulates a list of [`BinLogEntry`](#binlogentry)s. |
| 28 | +Or clone from this repo: |
52 | 29 |
|
53 |
| -### Reading Bin Logs |
54 |
| - |
55 |
| -A bin log can be read from a given file path with the class method `BinLog.from_path()` |
56 |
| - |
57 |
| -```python |
58 |
| -from binlog import BinLog |
59 |
| -log = BinLog.from_path("/path/to/bin.log") |
| 30 | +```bash |
| 31 | +git clone https://github.com/mjiggidy/pybinhistory.git |
| 32 | +cd pybinhistory |
| 33 | +pip install . |
60 | 34 | ```
|
61 | 35 |
|
62 |
| -Or, you can pass a text stream directly with the class method `BinLog.from_path()`. This can be helpful if you're dealing with a weird text encoding, or using something other than a typical file on disk. |
63 |
| - |
64 |
| -```python |
65 |
| -from binlog import BinLog |
66 |
| -with open("/path/to/bin.log", encoding="mac_roman", errors="replace") as log_handle: |
67 |
| - log = BinLog.from_stream(log_handle) |
68 |
| -``` |
69 |
| - |
70 |
| ->[!NOTE] |
71 |
| ->Unless specified by `BinLog.from_stream(encoding="somethin_else")`, `binhistory` classes assume all `.log` files are UTF-8. |
72 |
| -> |
73 |
| ->In testing, this has worked quite well except for a single instance of a `mac_roman` character from an ancient Avid project. |
74 |
| -
|
75 |
| -### Writing Bin Logs |
76 |
| - |
77 |
| -Similar to [reading](#reading-bin-logs), `BinLog` can be written to a bin log with `BinLog.to_path("/path/to/bin.log")` or `BinLog.to_stream(textio_stream)`. |
78 |
| - |
79 |
| -### Creating Bin Logs |
80 |
| - |
81 |
| -Aside from [reading a bin log from a file](#reading-bin-logs), a new `BinLog` can be created directly with `BinLog()`, optionally passing it a list of [`BinLogEntry`](#binlogentry)s. |
82 |
| - |
83 |
| -### Accessing `BinLogEntry`s |
84 |
| - |
85 |
| -To access the [`BinLogEntry`](#binlogentry)s in a `BinLog`, the `BinLog` object can be directly iterated over; or a list of [`BinLogEntry`](#binlogentry)s can be retrieved via the `BinLog.entries` property. |
86 |
| - |
87 |
| -## `BinLogEntry` |
88 |
| - |
89 |
| -A `BinLog` contains a list of `BinLogEntry` objects. `BinLogEntry` is really just a python [`dataclass`](https://docs.python.org/3/library/dataclasses.html) with the following fields: |
90 |
| - |
91 |
| -* `timestamp` [[`datetime`](https://docs.python.org/3/library/datetime.html#datetime-objects)]: Timestamp of access |
92 |
| -* `computer` [[str](https://docs.python.org/3/library/string.html)]: Typically the hostname of the Avid that accessed the bin |
93 |
| -* `user` [[str](https://docs.python.org/3/library/string.html)]: The Avid user who accessed the bin |
94 |
| - |
95 |
| -### Formatting |
96 |
| - |
97 |
| -Although `BinLog` typically handles reading and writing `BinLogEntry`s internally, `BinLogEntry` can be formatted as a typical log entry string with `.to_string()`, or read in from a log entry string with `.from_string(str)`. |
98 |
| - |
99 |
| -## About Those Timestamps |
100 |
| - |
101 |
| -It should be noted that a timestamp in a typical log entry file does not specify the year, but it does specify the name of the day of the week. |
102 |
| - |
103 |
| -To derive a valid `datetime.datetime` object from this, `binhistory` methods that read existing log entries will resolve a valid year based on the file modified date of the `.log` file, working backwards until a valid day-of-the-week-name and month-day combo is found. This typically works quite well, but if file modified dates are wildly inaccurate (for instance, working with a very old project restored from an archive that didn't retain original file timestamps), the year |
104 |
| -may be determined incorrectly. |
| 36 | +## Usage |
105 | 37 |
|
106 |
| -Methods such as `BinLog.from_path()`, `BinLog.from_bin()`, and `BinLogEntry.from_string()` have an optional `max_year:int` argument for which you can provide the most recent year that should be considered when determining |
107 |
| -the correct year of the timestamp. |
| 38 | +See [readthedocs.io](https://pybinhistory.readthedocs.io) for general usage and API documentation! |
108 | 39 |
|
109 | 40 | ## See Also
|
110 |
| -- [`pybinlock`](https://github.com/mjiggidy/pybinlock) |
| 41 | +- [`pybinlock`](https://github.com/mjiggidy/pybinlock) - Programmatcially read and write Avid bin lock (`.lck`) files |
0 commit comments