Skip to content

Commit

Permalink
2024.46.3
Browse files Browse the repository at this point in the history
- Output.Json targets SpotifyEntry metadata
- IInterfaceFront.GetObject() added to get the full object of concern
- SpotifyEntry defines JSON property names
  • Loading branch information
simon-techkid committed May 25, 2024
1 parent 490212f commit 487d50f
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 5 deletions.
19 changes: 17 additions & 2 deletions SpotifyGPX/IInterfaceFront.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ public interface IInterfaceFront<TInterface>
/// <summary>
/// Get a property value from this <typeparamref name="TInterface"/>, assuming it is of (and implemented by) the specified type <typeparamref name="TImplementer"/>.
/// </summary>
/// <typeparam name="T">The type of object the targeted property belongs to.
/// <typeparamref name="TImplementer"/> must implement <typeparamref name="TInterface"/></typeparam>
/// <typeparam name="TImplementer">The object of type <typeparamref name="TImplementer"/> (which must implement <typeparamref name="TInterface"/>) to get the property from.</typeparam>
/// <param name="propertySelector">The property of object type <typeparamref name="TImplementer"/> to return.</param>
/// <returns>If this <typeparamref name="TInterface"/> is <typeparamref name="TImplementer"/>, the selected object <see cref="object"/>. Otherwise, <see langword="null"/>.</returns>
public object? GetPropertyValue<TImplementer>(Func<TImplementer, object?> propertySelector)
Expand All @@ -27,4 +26,20 @@ public interface IInterfaceFront<TInterface>
return null;
}

/// <summary>
/// Get the object of type <typeparamref name="TImplementer"/> implementing <typeparamref name="TInterface"/>.
/// </summary>
/// <typeparam name="TImplementer">The object of type <typeparamref name="TImplementer"/> to return.</typeparam>
/// <returns>If <typeparamref name="TInterface"/> is <typeparamref name="TImplementer"/>, the object of type <typeparamref name="TImplementer"/> that implements <typeparamref name="TInterface"/>.</returns>
public TImplementer GetObject<TImplementer>()
{
if (this is TImplementer implementer)
{
return implementer;
}

throw new Exception($"Cannot cast {GetType().FullName} to {typeof(TImplementer).FullName}.");
//return default;
}

}
2 changes: 1 addition & 1 deletion SpotifyGPX/Output/Json.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ private List<JsonDocument> GetDocument(string? trackName)
IEnumerable<SongPoint> Pairs = DataProvider();

List<JsonDocument> objects = Pairs
.Select(pair => JsonDocument.Parse(JsonSerializer.Serialize(pair.Song)))
.Select(pair => JsonDocument.Parse(JsonSerializer.Serialize(pair.Song.GetObject<SpotifyEntry>())))
.ToList();

return objects;
Expand Down
2 changes: 1 addition & 1 deletion SpotifyGPX/Output/OutputHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ public void Save(bool transform)
{
AttemptSave(transform, FinalName);
}

private void AttemptSave(bool transform, string fileName, int attempt = 0)
{
try
Expand Down
2 changes: 1 addition & 1 deletion SpotifyGPX/Properties/launchSettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"profiles": {
"SpotifyGPX": {
"commandName": "Project",
"commandLineArgs": "--spotify \"F:\\vlog_sort\\Europe\\europe_spotifygpx\\2023.json\" --gps \"F:\\vlog_sort\\Europe\\europe_spotifygpx\\combined.gpx\" -v"
"commandLineArgs": "--spotify \"F:\\vlog_sort\\Europe\\europe_spotifygpx\\2023.json\" --gps \"F:\\vlog_sort\\Europe\\europe_spotifygpx\\combined.gpx\" -j"
}
}
}
32 changes: 32 additions & 0 deletions SpotifyGPX/SongEntries/SpotifyEntry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@
using SpotifyGPX.Input;
using System;
using System.Linq;
using System.Text.Json.Serialization;

namespace SpotifyGPX;

public partial struct SpotifyEntry : ISongEntry, IEstimatableSong, ISpotifyApiCompat, ISpotifyApiProportionable, IUrlLinkableSong, IAlbumableSong
{
public readonly override string ToString() => $"{Song_Artist} - {Song_Name}";

[JsonIgnore]
public string Description
{
get
Expand All @@ -28,119 +30,145 @@ public string Description
}
}

[JsonIgnore]
public int Index { get; set; }

[JsonPropertyName("ts")]
public DateTimeOffset FriendlyTime { get; set; }

[JsonIgnore]
public TimeInterpretation CurrentInterpretation { get; set; }

[JsonIgnore]
public readonly TimeUsage CurrentUsage => timeUsage;

/// <summary>
/// This field is your Spotify username.
/// </summary>
[JsonPropertyName("username")]
public string? Spotify_Username { get; set; }

/// <summary>
/// This field is the platform used when streaming the track (e.g. Android OS, Google Chromecast).
/// </summary>
[JsonPropertyName("platform")]
public string? Spotify_Platform { get; set; }

/// <summary>
/// This field is the number of milliseconds the stream was played.
/// </summary>
[JsonPropertyName("ms_played")]
public int Time_Played { get; set; }

[JsonIgnore]
public readonly TimeSpan TimePlayed => TimeSpan.FromMilliseconds(Time_Played);

/// <summary>
/// This field is the country code of the country where the stream was played (e.g. SE - Sweden).
/// </summary>
[JsonPropertyName("conn_country")]
public string? Spotify_Country { get; set; }

/// <summary>
/// This field contains the IP address logged when streaming the track.
/// </summary>
[JsonPropertyName("ip_addr_decrypted")]
public string? Spotify_IP { get; set; }

/// <summary>
/// This field contains the user agent used when streaming the track (e.g. a browser, like Mozilla Firefox, or Safari)
/// </summary>
[JsonPropertyName("user_agent_decrypted")]
public string? Spotify_UA { get; set; }

/// <summary>
/// This field is the name of the track.
/// </summary>
[JsonPropertyName("master_metadata_track_name")]
public string? Song_Name { get; set; }

/// <summary>
/// This field is the name of the artist, band or podcast.
/// </summary>
[JsonPropertyName("master_metadata_album_artist_name")]
public string? Song_Artist { get; set; }

/// <summary>
/// This field is the name of the album of the track.
/// </summary>
[JsonPropertyName("master_metadata_album_album_name")]
public string? Song_Album { get; set; }

/// <summary>
/// A Spotify URI, uniquely identifying the track in the form of “spotify:track:base-62 string”
/// </summary>
[JsonPropertyName("spotify_track_uri")]
public string? Song_URI { get; set; }

/// <summary>
/// The Spotify URI (song ID) of this song.
/// </summary>
[JsonIgnore]
public readonly string? Song_ID => Song_URI?.Split(':').Last();

/// <summary>
/// The URL of this song.
/// </summary>
[JsonIgnore]
public readonly string? Song_URL => Song_ID == null ? null : $"http://open.spotify.com/track/{Song_ID}";

/// <summary>
/// This field contains the name of the episode of the podcast.
/// </summary>
[JsonPropertyName("episode_name")]
public string? Episode_Name { get; set; }

/// <summary>
/// This field contains the name of the show of the podcast.
/// </summary>
[JsonPropertyName("episode_show_name")]
public string? Episode_Show { get; set; }

/// <summary>
/// A Spotify Episode URI, uniquely identifying the podcast episode in the form of “spotify:episode:base-62 string”
/// </summary>
[JsonPropertyName("spotify_episode_uri")]
public string? Episode_URI { get; set; }

/// <summary>
/// This field is a value telling why the track started (e.g. “trackdone”).
/// </summary>
[JsonPropertyName("reason_start")]
public string? Song_StartReason { get; set; }

/// <summary>
/// This field is a value telling why the track ended (e.g. “endplay”).
/// </summary>
[JsonPropertyName("reason_end")]
public string? Song_EndReason { get; set; }

/// <summary>
/// This field has the value True or False depending on if shuffle mode was used when playing the track.
/// </summary>
[JsonPropertyName("shuffle")]
public bool? Song_Shuffle { get; set; }

/// <summary>
/// This field indicates if the user skipped to the next song.
/// </summary>
[JsonPropertyName("skipped")]
public bool? Song_Skipped { get; set; }

/// <summary>
/// This field indicates whether the track was played in offline mode (“True”) or not (“False”).
/// </summary>
[JsonPropertyName("offline")]
public bool? Spotify_Offline { get; set; }

/// <summary>
/// This field is a timestamp of when offline mode was used, if used.
/// </summary>
[JsonPropertyName("offline_timestamp")]
public long? Spotify_OfflineTS
{
readonly get => OfflineTimestamp?.ToUnixTimeSeconds();
Expand All @@ -150,14 +178,18 @@ public long? Spotify_OfflineTS
/// <summary>
/// This field is a timestamp of when offline mode was used, if used.
/// </summary>
[JsonIgnore]
public DateTimeOffset? OfflineTimestamp { get; private set; }

/// <summary>
/// This field indicates whether the track was played in incognito mode (“True”) or not (“False”).
/// </summary>
[JsonPropertyName("incognito")]
public bool? Spotify_Incognito { get; set; }

[JsonIgnore]
public decimal? PercentListened => Metadata?.Duration != null ? Math.Round(((decimal)Time_Played / (decimal)Metadata?.Duration!) * 100, 0) : null;

[JsonIgnore]
public SpotifyApiEntry? Metadata { get; set; }
}

0 comments on commit 487d50f

Please sign in to comment.