Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions debian/control
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Build-Depends:
libglib2.0-dev,
libudisks2-dev,
libisoburn-dev,
libssl-dev,
libmediainfo-dev,
libsecret-1-dev,
liblucene++-dev,
Expand Down
1 change: 1 addition & 0 deletions debian/control.in
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Build-Depends:
libglib2.0-dev,
libudisks2-dev,
libisoburn-dev,
libssl-dev,
libmediainfo-dev,
libsecret-1-dev,
liblucene++-dev,
Expand Down
1 change: 1 addition & 0 deletions debian/libdfm-burn.install
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
/usr/lib/*/libdfm-burn*.so*
usr/bin/dfm-burner
1 change: 1 addition & 0 deletions debian/libdfm6-burn.install
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
/usr/lib/*/libdfm6-burn*.so*
usr/bin/dfm-burner
1 change: 1 addition & 0 deletions include/dfm-burn/dfm-burn/dburn_global.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ enum class BurnOption : unsigned int {
kJolietSupport = 1 << 4, // add joliet extension
kRockRidgeSupport = 1 << 5, // add rockridge extension
kUDF102Supported = 1 << 6,
kChecksum = 1 << 7, // SM3 checksum verification
kJolietAndRockRidge = kJolietSupport | kRockRidgeSupport // add both of them, not used yet
};
Q_DECLARE_FLAGS(BurnOptions, BurnOption)
Expand Down
2 changes: 2 additions & 0 deletions include/dfm-burn/dfm-burn/dopticaldiscmanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ class DOpticalDiscManager : public QObject
bool checkmedia(double *qgood, double *qslow, double *qbad);
bool writeISO(const QString &isoPath, int speed = 0);
bool dumpISO(const QString &isoPath);
bool generateChecksumManifest(const QString &savePath);
bool verifyChecksum(const QString &manifestPath);
QString lastError() const;

Q_SIGNALS:
Expand Down
12 changes: 7 additions & 5 deletions src/dfm-burn/dfm-burn-client/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
cmake_minimum_required(VERSION 3.10)

project(dfm${DFM_VERSION_MAJOR}-burn-client)
project(dfm-burner)

set(SRCS
main.cpp
cli_options.cpp
cli_options.h
burn_utils.cpp
burn_utils.h
)

find_package(Qt${QT_VERSION_MAJOR}Core REQUIRED)

add_executable(${PROJECT_NAME} ${SRCS})

include_directories(
${PROJECT_SOURCE_DIR}/../dfm-burn-lib/inlcude
)

target_link_libraries(
${PROJECT_NAME}
Qt${QT_VERSION_MAJOR}::Core
dfm${DFM_VERSION_MAJOR}-burn
)

install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR})
169 changes: 169 additions & 0 deletions src/dfm-burn/dfm-burn-client/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
# Optical Disc Burner Utilities

A command-line tool for optical disc operations in Deepin File Manager, powered by libisoburn.

## Features

- **Disc information**: Query device, media type, capacity, write speeds
- **Burn files**: Burn files and directories to disc with various filesystem options
- **ISO operations**: Write ISO images to disc, or dump disc content to ISO
- **Disc erase**: Erase rewritable discs (CD-RW, DVD-RW, DVD+RW, BD-RE)
- **Quality check**: Verify disc media quality with detailed statistics
- **Packet writing**: UDF packet writing for incremental file operations

## Supported Media Types

CD-ROM, CD-R, CD-RW, DVD-ROM, DVD-R, DVD-RW, DVD+R, DVD+R DL, DVD-R DL, DVD-RAM, DVD+RW, BD-ROM, BD-R, BD-RE

## Usage

```
dfm-burner <command> [options] [arguments]
```

### Commands

| Command | Description |
|---------|-------------|
| `info` | Show optical disc information |
| `burn` | Burn files to disc |
| `write-iso` | Write an ISO image to disc |
| `dump-iso` | Dump disc content to an ISO image |
| `erase` | Erase a rewritable disc |
| `check` | Check media quality |
| `pw` | Packet writing (UDF) operations |

### info — Show disc information

```
dfm-burner info [--json] <device>
```

```bash
# Show disc info
dfm-burner info /dev/sr0

# JSON output for scripting
dfm-burner info --json /dev/sr0
```

### burn — Burn files to disc

```
dfm-burner burn [options] <device> <file_or_dir> [<file_or_dir>...]
```

Options:
- `--volume-id=<name>` — Set disc label shown in file manager (default: ISOIMAGE)
- `--speed=<number>` — Write speed in CD/DVD multiplier, 0 = auto (default)

Filesystem (pick one, default is iso9660):
- `--iso9660` — Basic format, works on virtually all systems
- `--joliet` — Long filenames and CJK characters, recommended for Windows
- `--rockridge` — Preserves Linux permissions and symlinks, Linux-only
- `--udf` — Modern format, files > 2GB, Unicode names. Best for mixed-OS

Behavior:
- `--appendable` — Leave disc open to add more data later (multi-session)
- `--verify` — Read back data after burning to detect errors

```bash
# Burn a directory
dfm-burner burn /dev/sr0 /home/user/data

# Burn with custom volume label
dfm-burner burn --volume-id=BACKUP /dev/sr0 /home/user/files

# Burn with UDF and appendable (multi-session)
dfm-burner burn --udf --appendable /dev/sr0 /home/user/archive

# Burn with Joliet + Rock Ridge + verification
dfm-burner burn --joliet --rockridge --verify /dev/sr0 file1.txt file2.txt
```

### write-iso — Write ISO to disc

```
dfm-burner write-iso [--speed=<number>] <device> <iso_path>
```

```bash
dfm-burner write-iso /dev/sr0 /home/user/image.iso
dfm-burner write-iso --speed=8 /dev/sr0 /home/user/image.iso
```

### dump-iso — Dump disc to ISO

```
dfm-burner dump-iso <device> <output_path>
```

```bash
dfm-burner dump-iso /dev/sr0 /home/user/backup.iso
```

### erase — Erase disc

```
dfm-burner erase <device>
```

```bash
dfm-burner erase /dev/sr0
```

### check — Check media quality

```
dfm-burner check [--json] <device>
```

```bash
dfm-burner check /dev/sr0
dfm-burner check --json /dev/sr0
```

### pw — Packet writing (UDF)

```
dfm-burner pw <action> <device> <working_path> [additional args]
```

Actions:
- `open <device> <working_path>` — Open a packet writing session
- `close <device> <working_path>` — Close the session
- `put <device> <working_path> <file>` — Add a file to the disc
- `mv <device> <working_path> <src> <dest>` — Rename a file on the disc
- `rm <device> <working_path> <file>` — Remove a file from the disc

```bash
# Open packet writing session
dfm-burner pw open /dev/sr0 /home/user/pw-work

# Add files incrementally
dfm-burner pw put /dev/sr0 /home/user/pw-work /home/user/data.txt
dfm-burner pw put /dev/sr0 /home/user/pw-work /home/user/photo.jpg

# Rename a file on disc
dfm-burner pw mv /dev/sr0 /home/user/pw-work old_name.txt new_name.txt

# Remove a file from disc
dfm-burner pw rm /dev/sr0 /home/user/pw-work unwanted.txt

# Close session
dfm-burner pw close /dev/sr0 /home/user/pw-work
```

## Implementation

The tool wraps all public APIs of the dfm-burn library:

- `DOpticalDiscInfo` — Disc properties and capabilities
- `DOpticalDiscManager` — Burn, erase, check, and ISO operations
- `DPacketWritingController` — UDF packet writing operations

Async operations (burn, write-iso, dump-iso, erase, check) display real-time progress via Qt's event loop. Sync operations (info, pw-*) return immediately.

## License

GPL-3.0-or-later
125 changes: 125 additions & 0 deletions src/dfm-burn/dfm-burn-client/burn_utils.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
// SPDX-FileCopyrightText: 2026 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later

#include "burn_utils.h"

DFM_BURN_BEGIN_NS

QString formatSize(quint64 bytes)
{
if (bytes == 0)
return "0 B";

const QStringList units = { "B", "KB", "MB", "GB", "TB" };
int idx = 0;
double size = bytes;

while (size >= 1024.0 && idx < units.size() - 1) {
size /= 1024.0;
++idx;
}

if (idx == 0)
return QString("%1 B").arg(bytes);

return QString("%1 %2").arg(size, 0, 'f', 1).arg(units.at(idx));
}

QString mediaTypeName(MediaType type)
{
switch (type) {
case MediaType::kNoMedia:
return "No Media";
case MediaType::kCD_ROM:
return "CD-ROM";
case MediaType::kCD_R:
return "CD-R";
case MediaType::kCD_RW:
return "CD-RW";
case MediaType::kDVD_ROM:
return "DVD-ROM";
case MediaType::kDVD_R:
return "DVD-R";
case MediaType::kDVD_RW:
return "DVD-RW";
case MediaType::kDVD_PLUS_R:
return "DVD+R";
case MediaType::kDVD_PLUS_R_DL:
return "DVD+R DL";
case MediaType::kDVD_R_DL:
return "DVD-R DL";
case MediaType::kDVD_RAM:
return "DVD-RAM";
case MediaType::kDVD_PLUS_RW:
return "DVD+RW";
case MediaType::kBD_ROM:
return "BD-ROM";
case MediaType::kBD_R:
return "BD-R";
case MediaType::kBD_RE:
return "BD-RE";
}
return "Unknown";
}

QString jobStatusName(JobStatus status)

Check warning on line 66 in src/dfm-burn/dfm-burn-client/burn_utils.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

The function 'jobStatusName' is never used.

Check warning on line 66 in src/dfm-burn/dfm-burn-client/burn_utils.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

The function 'jobStatusName' is never used.
{
switch (status) {
case JobStatus::kIdle:
return "Idle";
case JobStatus::kRunning:
return "Running";
case JobStatus::kStalled:
return "Stalled";
case JobStatus::kFinished:
return "Finished";
case JobStatus::kFailed:
return "Failed";
}
return "Unknown";
}

QString burnOptionsSummary(BurnOptions options)
{
QStringList parts;

// Filesystem
if (options.testFlag(BurnOption::kUDF102Supported))
parts << "UDF filesystem";
else if (options.testFlag(BurnOption::kJolietSupport) && options.testFlag(BurnOption::kRockRidgeSupport))
parts << "ISO9660 + Joliet + RockRidge";
else if (options.testFlag(BurnOption::kJolietSupport))
parts << "ISO9660 + Joliet";
else if (options.testFlag(BurnOption::kRockRidgeSupport))
parts << "ISO9660 + RockRidge";
else
parts << "ISO9660 filesystem";

// Behavior
if (options.testFlag(BurnOption::kKeepAppendable))
parts << "multi-session (disc stays open)";
if (options.testFlag(BurnOption::kVerifyDatas))
parts << "verify after burn";

return parts.join(", ");
}

/**
* @brief Check if a media type is rewritable
*/
bool isRewritable(MediaType type)
{
switch (type) {
case MediaType::kCD_RW:
case MediaType::kDVD_RW:
case MediaType::kDVD_PLUS_RW:
case MediaType::kDVD_RAM:
case MediaType::kBD_RE:
return true;
default:
return false;
}
}

DFM_BURN_END_NS
Loading
Loading