link
This commit is contained in:
1 parent
c422878493
commit
3b9bcb1169
5 files changed
+264
-206
No files matched your search
@@ -25,3 +25,6 @@ dl trg:
|
|||||||
docker compose -f compose.yaml run \
|
docker compose -f compose.yaml run \
|
||||||
--remove-orphans \
|
--remove-orphans \
|
||||||
maple -- sldl {{trg}}
|
maple -- sldl {{trg}}
|
||||||
|
|
||||||
|
link plist dir:
|
||||||
|
python3 maple-py/link.py plist dir
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import os, sys, pathlib
|
||||||
|
|
||||||
|
m3u8 = pathlib.Path(sys.argv[1]).resolve()
|
||||||
|
outdir = pathlib.Path(sys.argv[2]).resolve()
|
||||||
|
outdir.mkdir(parents=True, exist_ok=True)
|
||||||
|
pl_dir = m3u8.parent
|
||||||
|
|
||||||
|
def next_free(p: pathlib.Path) -> pathlib.Path:
|
||||||
|
if not p.exists():
|
||||||
|
return p
|
||||||
|
stem, suf = p.stem, p.suffix
|
||||||
|
i = 1
|
||||||
|
while True:
|
||||||
|
cand = p.with_name(f"{stem}-{i}{suf}")
|
||||||
|
if not cand.exists():
|
||||||
|
return cand
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
with m3u8.open("r", encoding="utf-8") as f:
|
||||||
|
for line in f:
|
||||||
|
s = line.strip()
|
||||||
|
if not s or s.startswith("#"):
|
||||||
|
continue
|
||||||
|
src = pathlib.Path(s)
|
||||||
|
if not src.is_absolute():
|
||||||
|
src = (pl_dir / src).resolve()
|
||||||
|
else:
|
||||||
|
src = src.resolve()
|
||||||
|
|
||||||
|
if not src.exists():
|
||||||
|
print(f"skip (missing): {src}", file=sys.stderr)
|
||||||
|
continue
|
||||||
|
|
||||||
|
dest = next_free(outdir / src.name)
|
||||||
|
try:
|
||||||
|
dest.symlink_to(src)
|
||||||
|
except OSError:
|
||||||
|
# fallback to hardlink if symlink not permitted
|
||||||
|
os.link(src, dest)
|
||||||
+117
-109
@@ -1,3 +1,4 @@
|
|||||||
|
use rekordcrate::pdb::RowGroup;
|
||||||
use rekordcrate::pdb::Artwork;
|
use rekordcrate::pdb::Artwork;
|
||||||
use rekordcrate::pdb::ArtworkId;
|
use rekordcrate::pdb::ArtworkId;
|
||||||
use rekordcrate::pdb::Page;
|
use rekordcrate::pdb::Page;
|
||||||
@@ -55,123 +56,129 @@ pub struct Database {
|
|||||||
const PAGE_SIZE: u32 = 4096;
|
const PAGE_SIZE: u32 = 4096;
|
||||||
|
|
||||||
impl Database {
|
impl Database {
|
||||||
pub fn export(self, path: &Path) -> std::io::Result<()> {
|
pub fn export(self, path: &Path) -> Result<(), binrw::Error> {
|
||||||
// 1) Reserve header page
|
let pages = Page::from_rows(PageType::Tracks, 1, PAGE_SIZE, self.tracks.values().cloned().map(Row::Track))?;
|
||||||
let mut f = File::create(path)?;
|
println!("{:?}", pages);
|
||||||
f.write_all(&vec![0u8; PAGE_SIZE as usize])?;
|
|
||||||
|
|
||||||
// 2) Emit tables linearly, collect table metadata
|
|
||||||
let mut next_page_index: u32 = 1;
|
|
||||||
|
|
||||||
// ok now we're getting somewhere
|
|
||||||
// smash rows into row_groups of 16
|
|
||||||
// try to write those into a page until it is full
|
|
||||||
// yield pages until all the rows are in
|
|
||||||
// set the indices
|
|
||||||
// 420 blaze it
|
|
||||||
|
|
||||||
let (tracks_first, tracks_last) =
|
|
||||||
Self::write_table(&mut f, PageType::Tracks, next_page_index, self.tracks.values().cloned().map(Row::Track))?;
|
|
||||||
next_page_index = tracks_last + 1;
|
|
||||||
|
|
||||||
let (tree_first, tree_last) =
|
|
||||||
Self::write_table(&mut f, PageType::PlaylistTree, next_page_index, self.nodes.values().cloned().map(Row::PlaylistTreeNode))?;
|
|
||||||
next_page_index = tree_last + 1;
|
|
||||||
|
|
||||||
let plist_entries = self.entries.iter().flat_map(|(_pid, vec)| {
|
|
||||||
// ensure contiguous entry_index
|
|
||||||
let mut v = vec.clone();
|
|
||||||
v.sort_by_key(|e| e.entry_index);
|
|
||||||
v.into_iter().map(Row::PlaylistEntry)
|
|
||||||
});
|
|
||||||
let (entries_first, entries_last) =
|
|
||||||
Self::write_table(&mut f, PageType::PlaylistEntries, next_page_index, plist_entries)?;
|
|
||||||
next_page_index = entries_last + 1;
|
|
||||||
|
|
||||||
let (art_first, art_last) =
|
|
||||||
Self::write_table(&mut f, PageType::Artwork, next_page_index, self.artwork.values().cloned().map(Row::Artwork))?;
|
|
||||||
next_page_index = art_last + 1;
|
|
||||||
|
|
||||||
// 3) Build header and back-patch at page 0
|
|
||||||
let header = Header {
|
|
||||||
// fill other required fields in your crate
|
|
||||||
sequence: 1, // or previous+1
|
|
||||||
next_unused_page: PageIndex(next_page_index),
|
|
||||||
tables: vec![
|
|
||||||
Table { page_type: PageType::Tracks, first_page: PageIndex(tracks_first), last_page: PageIndex(tracks_last), empty_candidate: 0, /* … */ },
|
|
||||||
Table { page_type: PageType::PlaylistTree, first_page: PageIndex(tree_first), last_page: PageIndex(tree_last), empty_candidate: 0, /* … */ },
|
|
||||||
Table { page_type: PageType::PlaylistEntries, first_page: PageIndex(entries_first), last_page: PageIndex(entries_last), empty_candidate: 0, /* … */ },
|
|
||||||
Table { page_type: PageType::Artwork, first_page: PageIndex(art_first), last_page: PageIndex(art_last), empty_candidate: 0, /* … */ },
|
|
||||||
],
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
// Write header at offset 0 and pad to one page
|
|
||||||
f.seek(SeekFrom::Start(0))?;
|
|
||||||
header.write(&mut f);
|
|
||||||
// pad residual of page 0 if BinWrite didn’t fill it:
|
|
||||||
let pos = f.stream_position()?;
|
|
||||||
if pos < PAGE_SIZE as u64 {
|
|
||||||
f.write_all(&vec![0u8; (PAGE_SIZE as u64 - pos) as usize])?;
|
|
||||||
}
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
// pub fn export(self, path: &Path) -> std::io::Result<()> {
|
||||||
|
// // 1) Reserve header page
|
||||||
|
// let mut f = File::create(path)?;
|
||||||
|
// f.write_all(&vec![0u8; PAGE_SIZE as usize])?;
|
||||||
|
|
||||||
fn write_table<I>(
|
// // 2) Emit tables linearly, collect table metadata
|
||||||
f: &mut File,
|
// let mut next_page_index: u32 = 1;
|
||||||
page_type: PageType,
|
|
||||||
start_index: u32,
|
|
||||||
rows: I,
|
|
||||||
) -> std::io::Result<(u32, u32)>
|
|
||||||
where
|
|
||||||
I: IntoIterator<Item = Row>,
|
|
||||||
{
|
|
||||||
let mut page_index = start_index;
|
|
||||||
let mut first = 0;
|
|
||||||
let mut last = 0;
|
|
||||||
|
|
||||||
// Pack rows into pages. Use your crate’s Page builder to handle row groups.
|
// // ok now we're getting somewhere
|
||||||
let mut packer = PagePacker::new(page_type, PAGE_SIZE);
|
// // smash rows into row_groups of 16
|
||||||
|
// // try to write those into a page until it is full
|
||||||
|
// // yield pages until all the rows are in
|
||||||
|
// // set the indices
|
||||||
|
// // 420 blaze it
|
||||||
|
|
||||||
for row in rows {
|
// let (tracks_first, tracks_last) =
|
||||||
if !packer.try_push(&row) {
|
// Self::write_table(&mut f, PageType::Tracks, next_page_index, self.tracks.values().cloned().map(Row::Track))?;
|
||||||
// flush full page
|
// next_page_index = tracks_last + 1;
|
||||||
let mut page = packer.finish(page_index, /*next_page=*/0);
|
|
||||||
// Temporarily set next_page=0; we will fix it after writing the next page.
|
|
||||||
Self::write_page(f, &mut page)?;
|
|
||||||
if first == 0 { first = page_index; }
|
|
||||||
last = page_index;
|
|
||||||
page_index += 1;
|
|
||||||
// start new page with the row that didn’t fit
|
|
||||||
packer = PagePacker::new(page_type, PAGE_SIZE);
|
|
||||||
assert!(packer.try_push(&row));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// flush final page if it has content or if this is an empty table create one empty page
|
// let (tree_first, tree_last) =
|
||||||
if packer.is_empty() && first == 0 {
|
// Self::write_table(&mut f, PageType::PlaylistTree, next_page_index, self.nodes.values().cloned().map(Row::PlaylistTreeNode))?;
|
||||||
let mut page = Page::empty(page_type, page_index, /*next_page=*/0, PAGE_SIZE);
|
// next_page_index = tree_last + 1;
|
||||||
Self::write_page(f, &mut page)?;
|
|
||||||
first = page_index;
|
|
||||||
last = page_index;
|
|
||||||
} else {
|
|
||||||
let mut page = packer.finish(page_index, /*next_page=*/0);
|
|
||||||
Self::write_page(f, &mut page)?;
|
|
||||||
if first == 0 { first = page_index; }
|
|
||||||
last = page_index;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fix `next_page` pointers by rewriting page headers if your Page writer requires it.
|
// let plist_entries = self.entries.iter().flat_map(|(_pid, vec)| {
|
||||||
// Simpler: during emission, remember the previous page file offset and seek back
|
// // ensure contiguous entry_index
|
||||||
// to patch its `next_page` to `page_index`.
|
// let mut v = vec.clone();
|
||||||
|
// v.sort_by_key(|e| e.entry_index);
|
||||||
|
// v.into_iter().map(Row::PlaylistEntry)
|
||||||
|
// });
|
||||||
|
// let (entries_first, entries_last) =
|
||||||
|
// Self::write_table(&mut f, PageType::PlaylistEntries, next_page_index, plist_entries)?;
|
||||||
|
// next_page_index = entries_last + 1;
|
||||||
|
|
||||||
Ok((first, last))
|
// let (art_first, art_last) =
|
||||||
}
|
// Self::write_table(&mut f, PageType::Artwork, next_page_index, self.artwork.values().cloned().map(Row::Artwork))?;
|
||||||
|
// next_page_index = art_last + 1;
|
||||||
|
|
||||||
fn write_page(f: &mut File, page: &mut Page) -> std::io::Result<()> {
|
// // 3) Build header and back-patch at page 0
|
||||||
page.write(f);
|
// let header = Header {
|
||||||
Ok(())
|
// // fill other required fields in your crate
|
||||||
}
|
// sequence: 1, // or previous+1
|
||||||
|
// next_unused_page: PageIndex(next_page_index),
|
||||||
|
// tables: vec![
|
||||||
|
// Table { page_type: PageType::Tracks, first_page: PageIndex(tracks_first), last_page: PageIndex(tracks_last), empty_candidate: 0, /* … */ },
|
||||||
|
// Table { page_type: PageType::PlaylistTree, first_page: PageIndex(tree_first), last_page: PageIndex(tree_last), empty_candidate: 0, /* … */ },
|
||||||
|
// Table { page_type: PageType::PlaylistEntries, first_page: PageIndex(entries_first), last_page: PageIndex(entries_last), empty_candidate: 0, /* … */ },
|
||||||
|
// Table { page_type: PageType::Artwork, first_page: PageIndex(art_first), last_page: PageIndex(art_last), empty_candidate: 0, /* … */ },
|
||||||
|
// ],
|
||||||
|
// ..Default::default()
|
||||||
|
// };
|
||||||
|
|
||||||
|
// // Write header at offset 0 and pad to one page
|
||||||
|
// f.seek(SeekFrom::Start(0))?;
|
||||||
|
// header.write(&mut f);
|
||||||
|
// // pad residual of page 0 if BinWrite didn’t fill it:
|
||||||
|
// let pos = f.stream_position()?;
|
||||||
|
// if pos < PAGE_SIZE as u64 {
|
||||||
|
// f.write_all(&vec![0u8; (PAGE_SIZE as u64 - pos) as usize])?;
|
||||||
|
// }
|
||||||
|
// Ok(())
|
||||||
|
// }
|
||||||
|
|
||||||
|
// fn write_table<I>(
|
||||||
|
// f: &mut File,
|
||||||
|
// page_type: PageType,
|
||||||
|
// start_index: u32,
|
||||||
|
// rows: I,
|
||||||
|
// ) -> std::io::Result<(u32, u32)>
|
||||||
|
// where
|
||||||
|
// I: IntoIterator<Item = Row>,
|
||||||
|
// {
|
||||||
|
// let mut page_index = start_index;
|
||||||
|
// let mut first = 0;
|
||||||
|
// let mut last = 0;
|
||||||
|
|
||||||
|
// // Pack rows into pages. Use your crate’s Page builder to handle row groups.
|
||||||
|
// let mut packer = PagePacker::new(page_type, PAGE_SIZE);
|
||||||
|
|
||||||
|
// for row in rows {
|
||||||
|
// if !packer.try_push(&row) {
|
||||||
|
// // flush full page
|
||||||
|
// let mut page = packer.finish(page_index, /*next_page=*/0);
|
||||||
|
// // Temporarily set next_page=0; we will fix it after writing the next page.
|
||||||
|
// Self::write_page(f, &mut page)?;
|
||||||
|
// if first == 0 { first = page_index; }
|
||||||
|
// last = page_index;
|
||||||
|
// page_index += 1;
|
||||||
|
// // start new page with the row that didn’t fit
|
||||||
|
// packer = PagePacker::new(page_type, PAGE_SIZE);
|
||||||
|
// assert!(packer.try_push(&row));
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // flush final page if it has content or if this is an empty table create one empty page
|
||||||
|
// if packer.is_empty() && first == 0 {
|
||||||
|
// let mut page = Page::empty(page_type, page_index, /*next_page=*/0, PAGE_SIZE);
|
||||||
|
// Self::write_page(f, &mut page)?;
|
||||||
|
// first = page_index;
|
||||||
|
// last = page_index;
|
||||||
|
// } else {
|
||||||
|
// let mut page = packer.finish(page_index, /*next_page=*/0);
|
||||||
|
// Self::write_page(f, &mut page)?;
|
||||||
|
// if first == 0 { first = page_index; }
|
||||||
|
// last = page_index;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Fix `next_page` pointers by rewriting page headers if your Page writer requires it.
|
||||||
|
// // Simpler: during emission, remember the previous page file offset and seek back
|
||||||
|
// // to patch its `next_page` to `page_index`.
|
||||||
|
|
||||||
|
// Ok((first, last))
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
// fn write_page(f: &mut File, page: &mut Page) -> std::io::Result<()> {
|
||||||
|
// page.write(f);
|
||||||
|
// Ok(())
|
||||||
|
// }
|
||||||
|
|
||||||
pub fn load_from_pdb(path: impl AsRef<Path>) -> rekordcrate::Result<Self> {
|
pub fn load_from_pdb(path: impl AsRef<Path>) -> rekordcrate::Result<Self> {
|
||||||
let mut f = std::fs::File::open(path)?;
|
let mut f = std::fs::File::open(path)?;
|
||||||
@@ -180,6 +187,7 @@ impl Database {
|
|||||||
let mut tracks: BTreeMap<TrackId, Track> = BTreeMap::new();
|
let mut tracks: BTreeMap<TrackId, Track> = BTreeMap::new();
|
||||||
let mut albums: BTreeMap<AlbumId, Album> = BTreeMap::new();
|
let mut albums: BTreeMap<AlbumId, Album> = BTreeMap::new();
|
||||||
let mut artists: BTreeMap<ArtistId, Artist> = BTreeMap::new();
|
let mut artists: BTreeMap<ArtistId, Artist> = BTreeMap::new();
|
||||||
|
let mut artwork: BTreeMap<ArtworkId, Artwork> = BTreeMap::new();
|
||||||
let mut genres: BTreeMap<GenreId, Genre> = BTreeMap::new();
|
let mut genres: BTreeMap<GenreId, Genre> = BTreeMap::new();
|
||||||
let mut keys: BTreeMap<KeyId, Key> = BTreeMap::new();
|
let mut keys: BTreeMap<KeyId, Key> = BTreeMap::new();
|
||||||
let mut labels: BTreeMap<LabelId, Label> = BTreeMap::new();
|
let mut labels: BTreeMap<LabelId, Label> = BTreeMap::new();
|
||||||
@@ -230,6 +238,6 @@ impl Database {
|
|||||||
v.sort_by_key(|e| e.entry_index); // needs `pub entry_index`
|
v.sort_by_key(|e| e.entry_index); // needs `pub entry_index`
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Self { header, tracks, albums, artists, genres, keys, labels, nodes, entries })
|
Ok(Self { header, tracks, albums, artists, artwork, genres, keys, labels, nodes, entries })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+95
-91
@@ -22,115 +22,119 @@ use db::Database;
|
|||||||
fn main() -> rekordcrate::Result<()> {
|
fn main() -> rekordcrate::Result<()> {
|
||||||
let db = Database::load_from_pdb("ntr.pdb")?;
|
let db = Database::load_from_pdb("ntr.pdb")?;
|
||||||
println!("tracks: {}, playlists: {}", db.tracks.len(), db.nodes.len());
|
println!("tracks: {}, playlists: {}", db.tracks.len(), db.nodes.len());
|
||||||
|
println!("tables: {:?}", db.header);
|
||||||
|
println!("tables: {:?}", db.header.tables);
|
||||||
|
|
||||||
for n in db.nodes {
|
db.export(&Path::new("./data/output.pdb"))?;
|
||||||
println!("{:?}", n);
|
|
||||||
}
|
|
||||||
|
|
||||||
let (_first_id, first) = db.tracks.first_key_value().unwrap();
|
// for n in db.nodes {
|
||||||
let (_last_id, last) = db.tracks.last_key_value().unwrap();
|
// println!("{:?}", n);
|
||||||
|
|
||||||
println!("{:?}", first);
|
|
||||||
println!("{:?}", last);
|
|
||||||
|
|
||||||
// let pic = db.tracks.iter().find(|(_id, t)| t.artwork_id == ArtworkId(680));
|
|
||||||
// match pic {
|
|
||||||
// Some(it) => println!("{:?}", it),
|
|
||||||
// None => println!("wasnt there"),
|
|
||||||
// }
|
// }
|
||||||
|
|
||||||
create_dir_all("./data/PIONEER")?;
|
// let (_first_id, first) = db.tracks.first_key_value().unwrap();
|
||||||
|
// let (_last_id, last) = db.tracks.last_key_value().unwrap();
|
||||||
|
|
||||||
assert!(env::set_current_dir(&Path::new("./data")).is_ok());
|
// println!("{:?}", first);
|
||||||
|
// println!("{:?}", last);
|
||||||
|
|
||||||
// strip the leading slash of the path to make it relative
|
// // let pic = db.tracks.iter().find(|(_id, t)| t.artwork_id == ArtworkId(680));
|
||||||
let anlz = first.analyze_path.clone().into_string()?;
|
// // match pic {
|
||||||
let anlz = anlz.strip_prefix("/").unwrap();
|
// // Some(it) => println!("{:?}", it),
|
||||||
let mp3 = first.file_path.clone().into_string()?;
|
// // None => println!("wasnt there"),
|
||||||
let mp3 = mp3.strip_prefix("/").unwrap();
|
// // }
|
||||||
|
|
||||||
println!("mp3={:?} exists={:?}", mp3, exists(mp3));
|
// create_dir_all("./data/PIONEER")?;
|
||||||
println!("anlz={:?} exists={:?}", anlz, exists(anlz));
|
|
||||||
|
|
||||||
let filename = "a680_m.jpg";
|
// assert!(env::set_current_dir(&Path::new("./data")).is_ok());
|
||||||
|
|
||||||
for entry in WalkDir::new(".") // start from current directory
|
// // strip the leading slash of the path to make it relative
|
||||||
.into_iter()
|
// let anlz = first.analyze_path.clone().into_string()?;
|
||||||
.filter_map(Result::ok)
|
// let anlz = anlz.strip_prefix("/").unwrap();
|
||||||
.filter(|e| e.file_type().is_file())
|
// let mp3 = first.file_path.clone().into_string()?;
|
||||||
{
|
// let mp3 = mp3.strip_prefix("/").unwrap();
|
||||||
if entry.file_name() == filename {
|
|
||||||
println!("Found: {}", entry.path().display());
|
// println!("mp3={:?} exists={:?}", mp3, exists(mp3));
|
||||||
}
|
// println!("anlz={:?} exists={:?}", anlz, exists(anlz));
|
||||||
}
|
|
||||||
|
// let filename = "a680_m.jpg";
|
||||||
|
|
||||||
|
// for entry in WalkDir::new(".") // start from current directory
|
||||||
|
// .into_iter()
|
||||||
|
// .filter_map(Result::ok)
|
||||||
|
// .filter(|e| e.file_type().is_file())
|
||||||
|
// {
|
||||||
|
// if entry.file_name() == filename {
|
||||||
|
// println!("Found: {}", entry.path().display());
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
let first_table = db.header.tables.first();
|
// let first_table = db.header.tables.first();
|
||||||
println!("first_table={:?}", first_table);
|
// println!("first_table={:?}", first_table);
|
||||||
|
|
||||||
|
// let mut export = Header::default();
|
||||||
|
// // let tracks = Table { page_type: PageType::Tracks, first_page: 0}
|
||||||
|
// // println!("export={:?}", export);
|
||||||
|
|
||||||
|
// let track_table = Table {
|
||||||
|
// page_type: PageType::Tracks,
|
||||||
|
// first_page: PageIndex(1),
|
||||||
|
// last_page: PageIndex(1),
|
||||||
|
// empty_candidate: 2,
|
||||||
|
// };
|
||||||
|
|
||||||
|
// let tracks = vec![first, last];
|
||||||
|
|
||||||
|
// // let track_page = Page {
|
||||||
|
// // page_index: PageIndex(1),
|
||||||
|
// // page_type: PageType::Tracks,
|
||||||
|
// // next_page: PageIndex(2),
|
||||||
|
// // unknown1: 12,
|
||||||
|
// // unknown2: 0,
|
||||||
|
// // num_rows_small: 5,
|
||||||
|
// // unknown3: 160,
|
||||||
|
// // unknown4: 0,
|
||||||
|
// // page_flags: PageFlags(36),
|
||||||
|
// // free_size: 2302,
|
||||||
|
// // used_size: 1740,
|
||||||
|
// // unknown5: 1,
|
||||||
|
// // num_rows_large: 4,
|
||||||
|
// // unknown6: 0,
|
||||||
|
// // unknown7: 0,
|
||||||
|
// // row_groups: vec![row_groups],
|
||||||
|
// // };
|
||||||
|
// let mut row_group = RowGroup::default();
|
||||||
|
|
||||||
|
// println!("track_table={:?}", track_table);
|
||||||
|
// export.tables.push(track_table);
|
||||||
|
|
||||||
let mut export = Header::default();
|
|
||||||
// let tracks = Table { page_type: PageType::Tracks, first_page: 0}
|
|
||||||
// println!("export={:?}", export);
|
// println!("export={:?}", export);
|
||||||
|
|
||||||
let track_table = Table {
|
// db.header.tables.iter().for_each(|t| println!("{:?}", t.page_type));
|
||||||
page_type: PageType::Tracks,
|
|
||||||
first_page: PageIndex(1),
|
|
||||||
last_page: PageIndex(1),
|
|
||||||
empty_candidate: 2,
|
|
||||||
};
|
|
||||||
|
|
||||||
let tracks = vec![first, last];
|
// // write header
|
||||||
|
// // write page
|
||||||
|
// // write row_groups
|
||||||
|
|
||||||
// let track_page = Page {
|
// // // Add tables to header
|
||||||
// page_index: PageIndex(1),
|
// // export.tables.push(track_table);
|
||||||
// page_type: PageType::Tracks,
|
// // export.tables.push(playlist_tree_table);
|
||||||
// next_page: PageIndex(2),
|
// // export.tables.push(playlist_entries_table);
|
||||||
// unknown1: 12,
|
// // export.tables.push(artwork_table);
|
||||||
// unknown2: 0,
|
|
||||||
// num_rows_small: 5,
|
|
||||||
// unknown3: 160,
|
|
||||||
// unknown4: 0,
|
|
||||||
// page_flags: PageFlags(36),
|
|
||||||
// free_size: 2302,
|
|
||||||
// used_size: 1740,
|
|
||||||
// unknown5: 1,
|
|
||||||
// num_rows_large: 4,
|
|
||||||
// unknown6: 0,
|
|
||||||
// unknown7: 0,
|
|
||||||
// row_groups: vec![row_groups],
|
|
||||||
// };
|
|
||||||
let mut row_group = RowGroup::default();
|
|
||||||
|
|
||||||
println!("track_table={:?}", track_table);
|
// // println!("Created PDB header with {} tables:", export.tables.len());
|
||||||
export.tables.push(track_table);
|
// // println!(" - {} tracks", db.tracks.len());
|
||||||
|
// // println!(" - {} playlist nodes", db.nodes.len());
|
||||||
|
// // println!(" - {} playlist entries", db.entries.values().map(|v| v.len()).sum::<usize>());
|
||||||
|
|
||||||
println!("export={:?}", export);
|
// // for (i, table) in export.tables.iter().enumerate() {
|
||||||
|
// // println!(" Table {}: {:?} (pages {}-{})",
|
||||||
db.header.tables.iter().for_each(|t| println!("{:?}", t.page_type));
|
// // i + 1,
|
||||||
|
// // table.page_type,
|
||||||
// write header
|
// // table.first_page.0,
|
||||||
// write page
|
// // table.last_page.0
|
||||||
// write row_groups
|
// // );
|
||||||
|
// // }
|
||||||
// // Add tables to header
|
|
||||||
// export.tables.push(track_table);
|
|
||||||
// export.tables.push(playlist_tree_table);
|
|
||||||
// export.tables.push(playlist_entries_table);
|
|
||||||
// export.tables.push(artwork_table);
|
|
||||||
|
|
||||||
// println!("Created PDB header with {} tables:", export.tables.len());
|
|
||||||
// println!(" - {} tracks", db.tracks.len());
|
|
||||||
// println!(" - {} playlist nodes", db.nodes.len());
|
|
||||||
// println!(" - {} playlist entries", db.entries.values().map(|v| v.len()).sum::<usize>());
|
|
||||||
|
|
||||||
// for (i, table) in export.tables.iter().enumerate() {
|
|
||||||
// println!(" Table {}: {:?} (pages {}-{})",
|
|
||||||
// i + 1,
|
|
||||||
// table.page_type,
|
|
||||||
// table.first_page.0,
|
|
||||||
// table.last_page.0
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,9 @@
|
|||||||
{
|
{
|
||||||
"path": "C:\\Users\\ntr\\code\\rekordcrate",
|
"path": "C:\\Users\\ntr\\code\\rekordcrate",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "/home/ntr/code/rekordcrate"
|
||||||
|
},
|
||||||
],
|
],
|
||||||
"settings":
|
"settings":
|
||||||
{
|
{
|
||||||
@@ -23,11 +26,11 @@
|
|||||||
{
|
{
|
||||||
"run":
|
"run":
|
||||||
{
|
{
|
||||||
"target": "--bin maple"
|
"target": "--bin maple",
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user