Compare commits
5 commits
6bece62893
...
8168566498
Author | SHA1 | Date | |
---|---|---|---|
8168566498 | |||
b30b9d7b9f | |||
7d153499ed | |||
4282889ebe | |||
9958c57c73 |
9 changed files with 292 additions and 70 deletions
19
.gitea/workflows/ci.yaml
Normal file
19
.gitea/workflows/ci.yaml
Normal file
|
@ -0,0 +1,19 @@
|
|||
name: CI
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
Test:
|
||||
runs-on: cimaster-latest
|
||||
steps:
|
||||
- name: 📦 Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
- name: 🦀 Setup Rust cache
|
||||
uses: https://github.com/Swatinem/rust-cache@v2
|
||||
with:
|
||||
cache-on-failure: "true"
|
||||
|
||||
- name: 📎 Clippy
|
||||
run: cargo clippy --all -- -D warnings
|
||||
|
||||
- name: 🧪 Test
|
||||
run: cargo test --workspace
|
38
.gitea/workflows/release.yaml
Normal file
38
.gitea/workflows/release.yaml
Normal file
|
@ -0,0 +1,38 @@
|
|||
name: Release
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "*/v*.*.*"
|
||||
|
||||
jobs:
|
||||
Release:
|
||||
runs-on: cimaster-latest
|
||||
steps:
|
||||
- name: 📦 Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Get variables
|
||||
run: |
|
||||
git fetch --tags --force #the checkout action does not load the tag message
|
||||
|
||||
echo "CRATE=$(echo '${{ github.ref_name }}' | awk 'BEGIN{RS="/"} NR==1{print}')" >> "$GITHUB_ENV"
|
||||
echo "CRATE_VERSION=$(echo '${{ github.ref_name }}' | awk 'BEGIN{RS="/"} NR==2{print}')" >> "$GITHUB_ENV"
|
||||
{
|
||||
echo 'CHANGELOG<<END_OF_FILE'
|
||||
git show -s --format=%N "${{ github.ref_name }}" | tail -n +4 | awk 'BEGIN{RS="-----BEGIN PGP SIGNATURE-----"} NR==1{printf $0}'
|
||||
echo END_OF_FILE
|
||||
} >> "$GITHUB_ENV"
|
||||
|
||||
- name: 📤 Publish crate on code.thetadev.de
|
||||
run: |
|
||||
mkdir -p ~/.cargo
|
||||
printf '[registries.thetadev]\nindex = "https://code.thetadev.de/ThetaDev/_cargo-index.git"\ntoken = "Bearer ${{ secrets.TOKEN_GITEA }}"\n' >> ~/.cargo/config.toml
|
||||
sed -i "s/^musixmatch-.*=\s*{/\0 registry = \"thetadev\",/g" Cargo.toml
|
||||
cargo publish --registry thetadev --package "${{ env.CRATE }}" --allow-dirty
|
||||
git restore Cargo.toml
|
||||
|
||||
- name: 🎉 Publish release
|
||||
uses: https://gitea.com/actions/release-action@main
|
||||
with:
|
||||
title: "${{ env.CRATE }} ${{ env.CRATE_VERSION }}"
|
||||
body: "${{ env.CHANGELOG }}"
|
|
@ -1,11 +0,0 @@
|
|||
steps:
|
||||
test:
|
||||
image: rust:latest
|
||||
secrets:
|
||||
- musixmatch_email
|
||||
- musixmatch_password
|
||||
commands:
|
||||
- rustup component add rustfmt clippy
|
||||
- cargo fmt --all --check
|
||||
- cargo clippy --all -- -D warnings
|
||||
- cargo test --workspace
|
|
@ -12,6 +12,9 @@ include = ["/src", "README.md", "LICENSE"]
|
|||
[workspace]
|
||||
members = [".", "cli"]
|
||||
|
||||
[workspace.dependencies]
|
||||
musixmatch-inofficial = { version = "0.1.0", path = ".", default-features = false }
|
||||
|
||||
[features]
|
||||
default = ["default-tls"]
|
||||
|
||||
|
@ -24,7 +27,7 @@ rustls-tls-webpki-roots = ["reqwest/rustls-tls-webpki-roots"]
|
|||
rustls-tls-native-roots = ["reqwest/rustls-tls-native-roots"]
|
||||
|
||||
[dependencies]
|
||||
reqwest = { version = "0.11.11", default-features = false, features = [
|
||||
reqwest = { version = "0.12.0", default-features = false, features = [
|
||||
"json",
|
||||
"gzip",
|
||||
] }
|
||||
|
@ -42,7 +45,7 @@ time = { version = "0.3.15", features = [
|
|||
hmac = "0.12.1"
|
||||
sha1 = "0.10.5"
|
||||
rand = "0.8.5"
|
||||
base64 = "0.21.0"
|
||||
base64 = "0.22.0"
|
||||
|
||||
[dev-dependencies]
|
||||
ctor = "0.2.0"
|
||||
|
|
44
Justfile
Normal file
44
Justfile
Normal file
|
@ -0,0 +1,44 @@
|
|||
test:
|
||||
cargo test
|
||||
|
||||
release crate="musixmatch-inofficial":
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
CRATE="{{crate}}"
|
||||
INCLUDES='--include-path README.md --include-path LICENSE --include-path Cargo.toml'
|
||||
CHANGELOG="CHANGELOG.md"
|
||||
|
||||
if [ "$CRATE" = "musixmatch-inofficial" ]; then
|
||||
INCLUDES="$INCLUDES --include-path src/** --include-path tests/** --include-path testfiles/**"
|
||||
else
|
||||
if [ ! -d "$CRATE" ]; then
|
||||
echo "$CRATE does not exist."; exit 1
|
||||
fi
|
||||
INCLUDES="$INCLUDES --include-path $CRATE/**"
|
||||
CHANGELOG="$CRATE/$CHANGELOG"
|
||||
CRATE="musixmatch-$CRATE" # Add crate name prefix
|
||||
fi
|
||||
|
||||
VERSION=$(cargo pkgid --package "$CRATE" | tr '#@' '\n' | tail -n 1)
|
||||
TAG="${CRATE}/v${VERSION}"
|
||||
echo "Releasing $TAG:"
|
||||
|
||||
if git rev-parse "$TAG" >/dev/null 2>&1; then echo "version tag $TAG already exists"; exit 1; fi
|
||||
|
||||
CLIFF_ARGS="--tag v${VERSION} --tag-pattern ${CRATE}/* --unreleased $INCLUDES"
|
||||
echo "git-cliff $CLIFF_ARGS"
|
||||
if [ -f "$CHANGELOG" ]; then
|
||||
git-cliff $CLIFF_ARGS --prepend "$CHANGELOG"
|
||||
else
|
||||
git-cliff $CLIFF_ARGS --output "$CHANGELOG"
|
||||
fi
|
||||
|
||||
editor "$CHANGELOG"
|
||||
|
||||
git add "$CHANGELOG"
|
||||
git commit -m "chore(release): release $CRATE v$VERSION"
|
||||
|
||||
awk 'BEGIN{RS="(^|\n)## [^\n]+\n*"} NR==2 { print }' "$CHANGELOG" | git tag -as -F - --cleanup whitespace "$TAG"
|
||||
|
||||
echo "🚀 Run 'git push origin $TAG' to publish"
|
|
@ -18,7 +18,7 @@ rustls-tls-webpki-roots = ["musixmatch-inofficial/rustls-tls-webpki-roots"]
|
|||
rustls-tls-native-roots = ["musixmatch-inofficial/rustls-tls-native-roots"]
|
||||
|
||||
[dependencies]
|
||||
musixmatch-inofficial = { path = "../" }
|
||||
musixmatch-inofficial.workspace = true
|
||||
tokio = { version = "1.20.0", features = ["macros", "rt-multi-thread"] }
|
||||
id3 = "1.3.0"
|
||||
mp3-duration = "0.1.10"
|
||||
|
|
|
@ -28,6 +28,20 @@ enum Commands {
|
|||
#[command(subcommand)]
|
||||
command: FileCommands,
|
||||
},
|
||||
#[group(required = true)]
|
||||
Search {
|
||||
/// Track name
|
||||
#[clap(short, long)]
|
||||
name: Option<String>,
|
||||
/// Artist
|
||||
#[clap(short, long)]
|
||||
artist: Option<String>,
|
||||
/// Lyrics
|
||||
#[clap(short, long)]
|
||||
lyrics: Option<String>,
|
||||
/// Search query
|
||||
query: Option<Vec<String>>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Subcommand)]
|
||||
|
@ -319,6 +333,42 @@ async fn run(cli: Cli) -> Result<()> {
|
|||
println!("{}", subtitles.subtitle_body);
|
||||
}
|
||||
},
|
||||
Commands::Search {
|
||||
query,
|
||||
name,
|
||||
artist,
|
||||
lyrics,
|
||||
} => {
|
||||
let mut sb = mxm
|
||||
.track_search()
|
||||
.s_track_rating(musixmatch_inofficial::models::SortOrder::Desc);
|
||||
let querystr;
|
||||
if let Some(q) = &query {
|
||||
querystr = q.join(" ");
|
||||
sb = sb.q(&querystr);
|
||||
}
|
||||
if let Some(n) = &name {
|
||||
sb = sb.q_track(n);
|
||||
}
|
||||
if let Some(a) = &artist {
|
||||
sb = sb.q_artist(a);
|
||||
}
|
||||
if let Some(l) = &lyrics {
|
||||
sb = sb.q_lyrics(l);
|
||||
}
|
||||
|
||||
let tracks = sb.send(20, 0).await?;
|
||||
for t in tracks {
|
||||
println!(
|
||||
"{} - {} ({}) ISRC'{}' <https://musixmatch.com/lyrics/{}>",
|
||||
t.track_name,
|
||||
t.artist_name,
|
||||
t.first_release_date.map(|d| d.year()).unwrap_or_default(),
|
||||
t.track_isrc.unwrap_or_default(),
|
||||
t.commontrack_vanity_id
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
|
|
99
cliff.toml
Normal file
99
cliff.toml
Normal file
|
@ -0,0 +1,99 @@
|
|||
# git-cliff ~ default configuration file
|
||||
# https://git-cliff.org/docs/configuration
|
||||
#
|
||||
# Lines starting with "#" are comments.
|
||||
# Configuration options are organized into tables and keys.
|
||||
# See documentation for more information on available options.
|
||||
|
||||
[changelog]
|
||||
# changelog header
|
||||
header = """
|
||||
# Changelog\n
|
||||
All notable changes to this project will be documented in this file.\n
|
||||
"""
|
||||
# template for the changelog body
|
||||
# https://keats.github.io/tera/docs/#introduction
|
||||
body = """
|
||||
{% set repo_url = "https://code.thetadev.de/ThetaDev/rustypipe" %}\
|
||||
{% if version %}\
|
||||
{%if previous.version %}\
|
||||
## [{{ version }}]({{ repo_url }}/compare/{{ previous.version }}..{{ version }})\
|
||||
{% else %}\
|
||||
## {{ version }}\
|
||||
{% endif %} - {{ timestamp | date(format="%Y-%m-%d") }}
|
||||
{% else %}\
|
||||
## [unreleased]
|
||||
{% endif %}\
|
||||
{% if previous.version %}\
|
||||
{% for group, commits in commits | group_by(attribute="group") %}
|
||||
### {{ group | striptags | trim | upper_first }}
|
||||
{% for commit in commits %}
|
||||
- {% if commit.scope %}*({{ commit.scope }})* {% endif %}\
|
||||
{% if commit.breaking %}[**breaking**] {% endif %}\
|
||||
{{ commit.message | upper_first }} - \
|
||||
([{{ commit.id | truncate(length=7, end="") }}]({{ repo_url }}/commit/{{ commit.id }}))\
|
||||
{% endfor %}
|
||||
{% endfor %}\
|
||||
{% else %}
|
||||
Initial release
|
||||
{% endif %}\n
|
||||
"""
|
||||
# template for the changelog footer
|
||||
footer = """
|
||||
<!-- generated by git-cliff -->
|
||||
"""
|
||||
# remove the leading and trailing s
|
||||
trim = true
|
||||
# postprocessors
|
||||
postprocessors = [
|
||||
# { pattern = '<REPO>', replace = "https://github.com/orhun/git-cliff" }, # replace repository URL
|
||||
]
|
||||
|
||||
[git]
|
||||
# parse the commits based on https://www.conventionalcommits.org
|
||||
conventional_commits = true
|
||||
# filter out the commits that are not conventional
|
||||
filter_unconventional = true
|
||||
# process each line of a commit as an individual commit
|
||||
split_commits = false
|
||||
# regex for preprocessing the commit messages
|
||||
commit_preprocessors = [
|
||||
# Replace issue numbers
|
||||
#{ pattern = '\((\w+\s)?#([0-9]+)\)', replace = "([#${2}](<REPO>/issues/${2}))"},
|
||||
# Check spelling of the commit with https://github.com/crate-ci/typos
|
||||
# If the spelling is incorrect, it will be automatically fixed.
|
||||
#{ pattern = '.*', replace_command = 'typos --write-changes -' },
|
||||
]
|
||||
# regex for parsing and grouping commits
|
||||
commit_parsers = [
|
||||
{ message = "^feat", group = "<!-- 0 -->🚀 Features" },
|
||||
{ message = "^fix", group = "<!-- 1 -->🐛 Bug Fixes" },
|
||||
{ message = "^doc", group = "<!-- 3 -->📚 Documentation" },
|
||||
{ message = "^perf", group = "<!-- 4 -->⚡ Performance" },
|
||||
{ message = "^refactor", group = "<!-- 2 -->🚜 Refactor" },
|
||||
{ message = "^style", group = "<!-- 5 -->🎨 Styling" },
|
||||
{ message = "^test", group = "<!-- 6 -->🧪 Testing" },
|
||||
{ message = "^chore\\(release\\): prepare for", skip = true },
|
||||
{ message = "^chore\\(pr\\)", skip = true },
|
||||
{ message = "^chore\\(pull\\)", skip = true },
|
||||
{ message = "^chore", group = "<!-- 7 -->⚙️ Miscellaneous Tasks" },
|
||||
{ message = "^ci", skip = true },
|
||||
{ body = ".*security", group = "<!-- 8 -->🛡️ Security" },
|
||||
{ message = "^revert", group = "<!-- 9 -->◀️ Revert" },
|
||||
]
|
||||
# protect breaking changes from being skipped due to matching a skipping commit_parser
|
||||
protect_breaking_commits = false
|
||||
# filter out the commits that are not matched by commit parsers
|
||||
filter_commits = false
|
||||
# regex for matching git tags
|
||||
# tag_pattern = "v[0-9].*"
|
||||
# regex for skipping tags
|
||||
# skip_tags = ""
|
||||
# regex for ignoring tags
|
||||
# ignore_tags = ""
|
||||
# sort the tags topologically
|
||||
topo_order = false
|
||||
# sort the commits inside sections by oldest/newest order
|
||||
sort_commits = "oldest"
|
||||
# limit the number of commits included in the changelog.
|
||||
# limit_commits = 42
|
|
@ -89,18 +89,9 @@ mod album {
|
|||
);
|
||||
assert_eq!(album.album_vanity_id, "410698/Gangnam-Style-Single");
|
||||
assert!(album.updated_time > datetime!(2022-6-3 0:00 UTC));
|
||||
assert_eq!(
|
||||
album.album_coverart_100x100.unwrap(),
|
||||
"https://s.mxmcdn.net/images-storage/albums/5/4/0/4/4/5/26544045.jpg"
|
||||
);
|
||||
assert_eq!(
|
||||
album.album_coverart_350x350.unwrap(),
|
||||
"https://s.mxmcdn.net/images-storage/albums/5/4/0/4/4/5/26544045_350_350.jpg"
|
||||
);
|
||||
assert_eq!(
|
||||
album.album_coverart_500x500.unwrap(),
|
||||
"https://s.mxmcdn.net/images-storage/albums/5/4/0/4/4/5/26544045_500_500.jpg"
|
||||
);
|
||||
assert_imgurl(&album.album_coverart_100x100, "/26544045.jpg");
|
||||
assert_imgurl(&album.album_coverart_350x350, "/26544045_350_350.jpg");
|
||||
assert_imgurl(&album.album_coverart_500x500, "/26544045_500_500.jpg");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
@ -333,18 +324,9 @@ mod track {
|
|||
"650e7db6-b795-4eb5-a702-5ea2fc46c848"
|
||||
);
|
||||
assert_eq!(track.artist_name, "Lady Gaga");
|
||||
assert_eq!(
|
||||
track.album_coverart_100x100.unwrap(),
|
||||
"https://s.mxmcdn.net/images-storage/albums/6/3/6/9/1/3/26319636.jpg"
|
||||
);
|
||||
assert_eq!(
|
||||
track.album_coverart_350x350.unwrap(),
|
||||
"https://s.mxmcdn.net/images-storage/albums/6/3/6/9/1/3/26319636_350_350.jpg"
|
||||
);
|
||||
assert_eq!(
|
||||
track.album_coverart_500x500.unwrap(),
|
||||
"https://s.mxmcdn.net/images-storage/albums/6/3/6/9/1/3/26319636_500_500.jpg"
|
||||
);
|
||||
assert_imgurl(&track.album_coverart_100x100, "/26319636.jpg");
|
||||
assert_imgurl(&track.album_coverart_350x350, "/26319636_350_350.jpg");
|
||||
assert_imgurl(&track.album_coverart_500x500, "/26319636_500_500.jpg");
|
||||
assert_eq!(track.commontrack_vanity_id, "Lady-Gaga/poker-face-1");
|
||||
let first_release = track.first_release_date.unwrap();
|
||||
assert_eq!(first_release.date(), date!(2008 - 1 - 1));
|
||||
|
@ -414,18 +396,9 @@ mod track {
|
|||
assert_eq!(track.album_name, "Black Mamba");
|
||||
assert_eq!(track.artist_id, 46970441);
|
||||
assert_eq!(track.artist_name, "aespa");
|
||||
assert_eq!(
|
||||
track.album_coverart_100x100.unwrap(),
|
||||
"https://s.mxmcdn.net/images-storage/albums5/2/7/7/6/5/1/52156772.jpg"
|
||||
);
|
||||
assert_eq!(
|
||||
track.album_coverart_350x350.unwrap(),
|
||||
"https://s.mxmcdn.net/images-storage/albums5/2/7/7/6/5/1/52156772_350_350.jpg"
|
||||
);
|
||||
assert_eq!(
|
||||
track.album_coverart_500x500.unwrap(),
|
||||
"https://s.mxmcdn.net/images-storage/albums5/2/7/7/6/5/1/52156772_500_500.jpg"
|
||||
);
|
||||
assert_imgurl(&track.album_coverart_100x100, "/52156772.jpg");
|
||||
assert_imgurl(&track.album_coverart_350x350, "/52156772_350_350.jpg");
|
||||
assert_imgurl(&track.album_coverart_500x500, "/52156772_500_500.jpg");
|
||||
assert_eq!(track.commontrack_vanity_id, "aespa/Black-Mamba");
|
||||
|
||||
let release_date = track.first_release_date.unwrap();
|
||||
|
@ -491,18 +464,9 @@ mod track {
|
|||
"650e7db6-b795-4eb5-a702-5ea2fc46c848"
|
||||
);
|
||||
assert_eq!(track.artist_name, "Lady Gaga");
|
||||
assert_eq!(
|
||||
track.album_coverart_100x100.unwrap(),
|
||||
"https://s.mxmcdn.net/images-storage/albums/6/3/6/9/1/3/26319636.jpg"
|
||||
);
|
||||
assert_eq!(
|
||||
track.album_coverart_350x350.unwrap(),
|
||||
"https://s.mxmcdn.net/images-storage/albums/6/3/6/9/1/3/26319636_350_350.jpg"
|
||||
);
|
||||
assert_eq!(
|
||||
track.album_coverart_500x500.unwrap(),
|
||||
"https://s.mxmcdn.net/images-storage/albums/6/3/6/9/1/3/26319636_500_500.jpg"
|
||||
);
|
||||
assert_imgurl(&track.album_coverart_100x100, "/26319636.jpg");
|
||||
assert_imgurl(&track.album_coverart_350x350, "/26319636_350_350.jpg");
|
||||
assert_imgurl(&track.album_coverart_500x500, "/26319636_500_500.jpg");
|
||||
assert_eq!(track.commontrack_vanity_id, "Lady-Gaga/poker-face-1");
|
||||
let first_release = track.first_release_date.unwrap();
|
||||
assert_eq!(first_release.date(), date!(2008 - 1 - 1));
|
||||
|
@ -702,16 +666,20 @@ mod lyrics {
|
|||
|
||||
// dbg!(&lyrics);
|
||||
|
||||
assert_eq!(lyrics.lyrics_id, 25947036);
|
||||
assert_eq!(lyrics.lyrics_id, 34583240);
|
||||
assert!(!lyrics.instrumental);
|
||||
assert!(!lyrics.explicit);
|
||||
assert!(lyrics
|
||||
.lyrics_body
|
||||
.starts_with("Eyes, in the sky, gazing far into the night\n"));
|
||||
assert!(
|
||||
lyrics
|
||||
.lyrics_body
|
||||
.starts_with("Eyes in the sky gazing far into the night\n"),
|
||||
"got: {}",
|
||||
lyrics.lyrics_body
|
||||
);
|
||||
assert_eq!(lyrics.lyrics_language.unwrap(), "en");
|
||||
assert_eq!(lyrics.lyrics_language_description.unwrap(), "English");
|
||||
let copyright = lyrics.lyrics_copyright.unwrap();
|
||||
assert!(copyright.contains("Kim Jeffeson"), "copyright: {copyright}",);
|
||||
assert!(copyright.contains("Jesse Warren"), "copyright: {copyright}",);
|
||||
assert!(lyrics.updated_time > datetime!(2021-6-3 0:00 UTC));
|
||||
}
|
||||
|
||||
|
@ -851,12 +819,12 @@ mod subtitles {
|
|||
|
||||
// dbg!(&subtitle);
|
||||
|
||||
assert_eq!(subtitle.subtitle_id, 36913312);
|
||||
assert_eq!(subtitle.subtitle_id, 35340319);
|
||||
assert_eq!(subtitle.subtitle_language.unwrap(), "en");
|
||||
assert_eq!(subtitle.subtitle_language_description.unwrap(), "English");
|
||||
let copyright = subtitle.lyrics_copyright.unwrap();
|
||||
assert!(copyright.contains("Kim Jeffeson"), "copyright: {copyright}",);
|
||||
assert_eq!(subtitle.subtitle_length, 315);
|
||||
assert!(copyright.contains("Jesse Warren"), "copyright: {copyright}",);
|
||||
assert_eq!(subtitle.subtitle_length, 316);
|
||||
assert!(subtitle.updated_time > datetime!(2021-6-30 0:00 UTC));
|
||||
}
|
||||
|
||||
|
@ -993,3 +961,15 @@ mod translation {
|
|||
assert_eq!(subtitles_trans.to_ttml().trim(), expected_ttml.trim());
|
||||
}
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
fn assert_imgurl(url: &Option<String>, ends_with: &str) {
|
||||
assert!(
|
||||
url.as_deref().is_some_and(
|
||||
|url| url.starts_with("https://s.mxmcdn.net/images-storage/")
|
||||
&& url.ends_with(ends_with)
|
||||
),
|
||||
"expected url ending with {ends_with}\ngot {:?}",
|
||||
url
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue