Compare commits

...

3 Commits

5 changed files with 1599 additions and 656 deletions

190
.gitignore vendored
View File

@@ -1,24 +1,26 @@
# Byte-compiled / optimized / DLL files # Input and output directories
input/
output/
# BeReal export files (should be in input folder anyway)
memories.json
posts.json
realmojis.json
# macOS
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db
# Python
__pycache__/ __pycache__/
*.py[cod] *.py[cod]
*$py.class *$py.class
# C extensions
*.so *.so
#My stuff
betterSoFar.py
greatSoFar.py
# json files
*.json
# Input/Output Files
Photos/
out/
correctout/
# Distribution / packaging
.Python .Python
build/ build/
develop-eggs/ develop-eggs/
@@ -32,158 +34,26 @@ parts/
sdist/ sdist/
var/ var/
wheels/ wheels/
share/python-wheels/
*.egg-info/ *.egg-info/
.installed.cfg .installed.cfg
*.egg *.egg
MANIFEST MANIFEST
# PyInstaller # Virtual environments
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/latest/usage/project/#working-with-version-control
.pdm.toml
.pdm-python
.pdm-build/
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/ venv/
env/
ENV/ ENV/
env.bak/ env.bak/
venv.bak/ venv.bak/
# Spyder project settings # IDE
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
# VS-Code
.vscode/ .vscode/
*.code-workspace .idea/
*.swp
*.swo
*~
# Local History for Visual Studio Code # Temporary files
.history/ *.tmp
*.temp
# Built Visual Studio Code Extensions *.log
*.vsix
_tests/
tempCodeRunnerFile.py

View File

@@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) 2024 Lukullul Copyright (c) 2024 SoPat712
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

114
README.md
View File

@@ -1,21 +1,22 @@
# BeReal Exporter # BeReal Exporter
This python script doesn't export photos and realmojis from the social media platform BeReal directly for that, you have to make a request to the BeReal see [this Reddit post](https://www.reddit.com/r/bereal_app/comments/19dl0yk/experiencetutorial_for_exporting_all_bereal/?utm_source=share&utm_medium=web3x&utm_name=web3xcss&utm_term=1&utm_content=share_button) for more information. This python script doesn't export photos and realmojis from the social media platform BeReal directly - for that, you have to make a request to BeReal. See [this Reddit post](https://www.reddit.com/r/bereal_app/comments/19dl0yk/experiencetutorial_for_exporting_all_bereal/?utm_source=share&utm_medium=web3x&utm_name=web3xcss&utm_term=1&utm_content=share_button) for more information.
It simple processes the data from the BeReal export and exports the images(as well BTS-videos) with added metadata, such as the original date and location. It processes the data from the BeReal export and exports the images with added metadata, such as the original date and location. Now supports posts, memories, realmojis, and conversation images with parallel processing for speed. Also has interactive modes for when you want to manually choose which camera is which for conversation images.
I'm gonna be upfront and say it's BeReal's fault the dates are wonky on the output files, idk why they chose to save the time like this: I'm gonna be upfront and say it's BeReal's fault the dates are wonky on the output files, idk why they chose to save the time like this:
"takenTime": "2024-12-24T01:27:16.726Z", "takenTime": "2024-12-24T01:27:16.726Z",
"berealMoment": "2024-12-23T22:39:05.327Z", "berealMoment": "2024-12-23T22:39:05.327Z",
instead of the way everyone else always does it with UNIX Epoch time, but it makes it pretty hard to find out what time the picture was taken, and to properly tag the photos with the correct time. Scroll down to arguments and see default-timezone for a little more info.
instead of the way everyone else always does it with UNIX Epoch time, but it makes it pretty hard to find out what time the picture was taken, and to properly tag the photos with the correct time. The script now handles timezone conversion automatically using GPS coordinates when available, falling back to America/New_York timezone.
## Installation ## Installation
1. Clone the repository: 1. Clone the repository:
```sh ```sh
git clone https://github.com/Lukullul/bereal-exporter.git git@github.com:SoPat712/BeReal-Export-Manager.git
cd bereal-exporter cd BeReal-Export-Manager
``` ```
2. Install the required Python packages: 2. Install the required Python packages:
@@ -25,61 +26,132 @@ instead of the way everyone else always does it with UNIX Epoch time, but it mak
3. Ensure you have `exiftool` installed on your system and set it up as a `PATH` variable. You can download it [here](https://exiftool.org/). 3. Ensure you have `exiftool` installed on your system and set it up as a `PATH` variable. You can download it [here](https://exiftool.org/).
4. Put your BeReal export folder in the `input` directory. The script will automatically find it.
## Usage ## Usage
To export your images run the script within the BeReal export folder: Put your BeReal export in the `input` folder and run:
```sh ```sh
python bereal_exporter.py [OPTIONS] python bereal_exporter.py [OPTIONS]
``` ```
The script automatically finds your export folder and processes everything in parallel for speed.
## Options ## Options
- `-v, --verbose`: Explain what is being done. - `-v, --verbose`: Explain what is being done.
- `-t, --timespan`: Exports the given timespan. - `-t, --timespan`: Exports the given timespan.
- Valid format: `DD.MM.YYYY-DD.MM.YYYY`. - Valid format: `DD.MM.YYYY-DD.MM.YYYY`.
- Wildcards can be used: `DD.MM.YYYY-*`. - Wildcards can be used: `DD.MM.YYYY-*`.
- `--exiftool-path`: Set the path to the ExifTool executable (needed if it isn't on the $PATH)
- `-y, --year`: Exports the given year. - `-y, --year`: Exports the given year.
- `-p, --out-path`: Set a custom output path (default is `./out`). - `-p, --out-path`: Set a custom output path (default is `./output`).
- `--bereal-path`: Set a custom BeReal path (default `./`) - `--input-path`: Set the input folder path containing BeReal export (default `./input`).
- `--exiftool-path`: Set the path to the ExifTool executable (needed if it isn't on the $PATH).
- `--max-workers`: Maximum number of parallel workers (default 4).
- `--no-memories`: Don't export the memories. - `--no-memories`: Don't export the memories.
- `--no-realmojis`: Don't export the realmojis. - `--no-realmojis`: Don't export the realmojis.
- `--no-composites`: Don't create composites with the front image overlayed on the back. - `--no-posts`: Don't export the posts.
- `--default-timezone "America/New_York"`: Set fallback timezone, since memories.json has UTC times. - `--no-conversations`: Don't export the conversations.
This doesn't work the greatest but I do recommend running it with whatever timezone you're in. It goes Lat/Long time finding -> Default Timezone -> UTC or whatever BeReal is providing. - `--conversations-only`: Export only conversations (for debugging).
- `--interactive-conversations`: Manually choose front/back camera for conversation images.
- `--web-ui`: Use web UI for interactive conversation selection (requires `--interactive-conversations`).
The script automatically handles timezone conversion using GPS coordinates when available, falling back to America/New_York. It creates composite images with the back camera as the main image and front camera overlaid in the corner with rounded edges and a black border, just like BeReal shows them.
## Examples ## Examples
1. Export data for the year 2022: 1. Export everything (default behavior):
```sh
python bereal_exporter.py
```
2. Export data for the year 2022:
```sh ```sh
python bereal_exporter.py --year 2022 python bereal_exporter.py --year 2022
``` ```
2. Export data for a specific timespan: 3. Export data for a specific timespan:
```sh ```sh
python bereal_exporter.py --timespan '04.01.2022-31.12.2022' python bereal_exporter.py --timespan '04.01.2022-31.12.2022'
``` ```
3. Export data to a custom output path: 4. Export to a custom output path:
```sh ```sh
python bereal_exporter.py --path /path/to/output python bereal_exporter.py --out-path /path/to/output
``` ```
4. Specify the BeReal export folder: 5. Use a different input folder:
```sh ```sh
python bereal_exporter.py --bereal-path /path/to/export python bereal_exporter.py --input-path /path/to/bereal/export
``` ```
4. Use portable installed exiftool application: 6. Use portable exiftool:
```sh ```sh
python bereal_exporter.py --exiftool-path /path/to/exiftool.exe python bereal_exporter.py --exiftool-path /path/to/exiftool.exe
``` ```
5. Export memories only: 7. Export only memories and posts (skip realmojis and conversations):
```sh ```sh
python bereal_exporter.py --no-realmojis python bereal_exporter.py --no-realmojis --no-conversations
``` ```
8. Debug conversations only:
```sh
python bereal_exporter.py --conversations-only
```
9. Use more workers for faster processing:
```sh
python bereal_exporter.py --max-workers 8
```
10. Interactive conversation selection (command line):
```sh
python bereal_exporter.py --conversations-only --interactive-conversations
```
11. Interactive conversation selection (web UI):
```sh
python bereal_exporter.py --conversations-only --interactive-conversations --web-ui
```
## Interactive Conversation Processing
For conversation images, the script tries to automatically detect which image should be the main view vs selfie view, but sometimes it gets it wrong. That's where the interactive modes come in handy.
**Automatic Detection**: The script looks at filenames, image dimensions, and patterns to guess which camera is which. Works most of the time but not always.
**Interactive Mode**: You can manually choose which image should be the selfie view (front camera overlay):
- **Command Line** (`--interactive-conversations`): Opens images in your system viewer, you choose via keyboard
- **Web UI** (`--interactive-conversations --web-ui`): Opens a web page where you just click on the selfie image
The web UI is pretty nice - shows both images side by side, you click the one that should be the selfie view, and it automatically continues processing. Much easier than the command line version.
**File Naming**: All images get descriptive names so you know what's what:
- `2022-09-10_16-35-30_main-view.webp` (back camera)
- `2022-09-10_16-35-30_selfie-view.webp` (front camera)
- `2022-09-10_16-35-30_composited.webp` (combined image with selfie overlaid)
## What Gets Exported
The script exports different types of content to organized folders:
- **Posts**: Your daily BeReal posts (main-view/selfie-view images + composited versions)
- **Memories**: Same as posts but with richer metadata (location, multiple timestamps)
- **Realmojis**: Your reaction images
- **Conversations**: Images from private conversations
All images get proper EXIF metadata with:
- Original timestamps (converted to local timezone using GPS when available)
- GPS coordinates (when available)
- Composited images with front camera overlaid on back camera (BeReal style with rounded corners and black border)
The script automatically detects duplicate content between posts and memories to avoid saving the same image twice.
## Performance
Uses parallel processing with configurable worker threads (default 4) for faster exports. Progress bars show real-time status. On a decent machine, expect to process hundreds of images per minute. If you have a fast SSD and good CPU, try bumping up `--max-workers` to 8 or more.
## License ## License
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for more details. This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for more details.

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
Pillow pyexiftool==0.5.6
argparse Pillow>=9.0.0
pytz pytz>=2023.3
timezonefinder timezonefinder>=6.2.0
pyexiftool tqdm>=4.64.0