Language Migration (#21)

* Blank slate

* Added gitignore

* Updated gitignore

* Added rust code

* Added modules

* Fixed build issues

* rustfmt

* Updated models

* Added parsers module

* Updated utilities module

* Updated main.rs

* Updated api_parser and song model

* Updated icarus_action model

* Updated structs in managers module

* Updated main.rs

* More changes

* Saving changes

* Added new struct and methods

* More changes. Not functional yet

* Changed name of the project

* Removed cmake workflow

* Adding rust workflow

* Adding code to the syncers module

* Cargo formatting

* Continuing work

* Adding code to the syncers module

* Added dependencies

* Adding more code to the syncers module

* Added more code to the syncers module

It's not 100 percent done yet, I'll work on other modules

* Added more code to the managers module

* Added code to request a token

* Cargo formatting

* Adding more code to multi target upload

* Adding more multi-target upload code and formatted code

* Added more multi-upload code

* cargo fmt

* Got uploading functional and cargo fmt-ing

* Uploading multi target works, but is buggy

Not all of the songs are being uploaded

* Added single target upload

* Single target upload is functional but need to revisit multi-target upload

Multi-target upload is broken now. Needs to be revisited

* Fixed multi target upload

* Can now retrieve songs

* Downloading functionality is working

* Delete functionality is operational

* Updated README

* More cleanup

* Added test
This commit was merged in pull request #21.
This commit is contained in:
Kun Deng
2024-06-15 12:22:17 -04:00
committed by GitHub
parent 5e9e7bc46a
commit ee4469b385
79 changed files with 2148 additions and 3376 deletions
+20
View File
@@ -0,0 +1,20 @@
use std::default::Default;
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct API {
pub url: String,
pub endpoint: String,
pub version: String,
}
impl Default for API {
fn default() -> Self {
API {
url: String::new(),
endpoint: String::new(),
version: String::new(),
}
}
}
+18
View File
@@ -0,0 +1,18 @@
use std::default::Default;
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Flags {
pub flag: String,
pub value: String,
}
impl Default for Flags {
fn default() -> Self {
Flags {
flag: String::new(),
value: String::new(),
}
}
}
+44
View File
@@ -0,0 +1,44 @@
use std::default::Default;
use serde::{Deserialize, Serialize};
use crate::models;
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct IcarusAction {
pub action: String,
pub flags: Vec<models::flags::Flags>,
}
impl Default for IcarusAction {
fn default() -> Self {
IcarusAction {
action: String::new(),
flags: Vec::new(),
}
}
}
impl IcarusAction {
pub fn retrieve_flag_value(&self, flag: &String) -> String {
let mut val: String = String::new();
for f in self.flags.iter() {
if f.flag == *flag {
val = f.value.clone();
break;
}
}
return val;
}
pub fn print_action_and_flags(&self) {
println!("Action: {}", self.action);
println!("Flag count: {}", self.flags.len());
for flag in self.flags.iter() {
println!("flag {} value {}", flag.flag, flag.value);
}
}
}
+7
View File
@@ -0,0 +1,7 @@
pub mod api;
pub mod flags;
pub mod icarus_action;
pub mod song;
pub mod token;
pub mod upload_form;
pub mod user;
+171
View File
@@ -0,0 +1,171 @@
use std::default::Default;
use std::io::Read;
use serde::{Deserialize, Serialize};
use crate::constants;
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Song {
#[serde(alias = "song_id")]
pub id: Option<i32>,
pub title: Option<String>,
pub artist: Option<String>,
pub album: Option<String>,
pub genre: Option<String>,
pub year: Option<i32>,
pub duration: Option<f64>,
pub track: Option<i32>,
pub disc: Option<i32>,
pub data: Option<Vec<u8>>,
pub filepath: Option<String>,
pub directory: Option<String>,
}
#[derive(Debug, Deserialize, Serialize)]
pub struct Album {
#[serde(alias = "album")]
pub title: String,
pub album_artist: String,
pub genre: String,
pub year: i32,
pub track_count: i32,
pub disc_count: i32,
#[serde(alias = "tracks")]
pub songs: Vec<Song>,
}
impl Default for Album {
fn default() -> Self {
Album {
title: String::new(),
album_artist: String::new(),
genre: String::new(),
year: 0,
track_count: 0,
disc_count: 0,
songs: Vec::new(),
}
}
}
impl Default for Song {
fn default() -> Self {
Song {
id: None,
title: None,
artist: None,
album: None,
genre: None,
year: None,
duration: None,
track: None,
disc: None,
data: None,
filepath: None,
directory: None,
}
}
}
impl Song {
pub fn print_info(&self) {
println!("Title: {:?}", self.title);
println!("Artist: {:?}", self.artist);
}
pub fn song_path(&self) -> String {
let directory =
&<std::option::Option<std::string::String> as Clone>::clone(&self.directory).unwrap();
let mut buffer: String = directory.to_string();
let count = buffer.len();
if buffer.chars().nth(count - 1) != Some('/') {
buffer += "/";
}
let filename =
&<std::option::Option<std::string::String> as Clone>::clone(&self.filepath).unwrap();
buffer += filename;
return buffer;
}
pub fn to_data(&self) -> Result<Vec<u8>, std::io::Error> {
let path = self.song_path();
println!("Converting song to data");
println!("Path: {:?}", path);
let mut file = std::fs::File::open(path)?;
let mut buffer = Vec::new();
file.read_to_end(&mut buffer)?;
if buffer.len() == 0 {
println!("Why is it empty?");
}
Ok(buffer)
}
// if 1 - wav, if 0 - mp3, anything else defaults to wav
pub fn _generate_filename_from_track(&mut self, i_type: i32) -> i32 {
let mut filename: String = String::new();
if self.track.unwrap() < 10 {
filename += "0";
}
filename += &self.track.unwrap().to_string();
if i_type == 0 {
filename += constants::file_extensions::_MP3_FILE_EXTENSION;
} else {
filename += constants::file_extensions::WAV_FILE_EXTENSION;
}
self.filepath = Some(filename);
return 0;
}
pub fn _to_metadata_json(&self) -> Result<String, serde_json::Error> {
return serde_json::to_string_pretty(&self);
}
}
#[derive(Debug, Deserialize, Serialize)]
pub struct CoverArt {
pub id: Option<i32>,
pub title: Option<String>,
pub path: Option<String>,
pub data: Option<Vec<u8>>,
}
impl Default for CoverArt {
fn default() -> Self {
CoverArt {
id: None,
title: None,
path: None,
data: None,
}
}
}
impl CoverArt {
pub fn to_data(&self) -> Result<Vec<u8>, std::io::Error> {
let mut path: String = String::new();
match &self.path {
Some(val) => {
path = String::from(val);
}
None => {
();
}
}
let mut file = std::fs::File::open(path)?;
let mut buffer = Vec::new();
file.read_to_end(&mut buffer)?;
Ok(buffer)
}
}
+47
View File
@@ -0,0 +1,47 @@
use std::default::Default;
use serde::{Deserialize, Serialize};
#[derive(Debug, Deserialize, Serialize)]
pub struct Token {
#[serde(alias = "user_id")]
pub user_id: i32,
#[serde(alias = "username")]
pub username: Option<String>,
#[serde(alias = "token")]
pub access_token: Option<String>,
#[serde(alias = "token_type")]
pub token_type: Option<String>,
#[serde(alias = "expiration")]
pub expiration: Option<i32>,
#[serde(alias = "message")]
pub message: Option<String>,
}
impl Default for Token {
fn default() -> Self {
Token {
user_id: -1,
username: None,
access_token: None,
token_type: None,
expiration: None,
message: None,
}
}
}
impl Token {
pub fn bearer_token(&self) -> String {
let mut token: String = String::from("Bearer ");
match &self.access_token {
Some(tok) => {
token += tok;
}
None => {}
}
return token;
}
}
+18
View File
@@ -0,0 +1,18 @@
use std::default::Default;
use serde::{Deserialize, Serialize};
#[derive(Debug, Deserialize, Serialize)]
pub struct UploadForm {
pub url: Option<String>,
pub filepath: Option<String>,
}
impl Default for UploadForm {
fn default() -> Self {
UploadForm {
url: None,
filepath: None,
}
}
}
+24
View File
@@ -0,0 +1,24 @@
use std::default::Default;
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct User {
pub username: String,
pub password: String,
}
impl Default for User {
fn default() -> Self {
User {
username: String::new(),
password: String::new(),
}
}
}
impl User {
pub fn _to_json(&self) -> Result<String, serde_json::Error> {
return serde_json::to_string_pretty(&self);
}
}