Skip to content

Commit

Permalink
Merge pull request #6 from SwagLyrics/dev
Browse files Browse the repository at this point in the history
V0.3
  • Loading branch information
flabbet authored Jul 18, 2020
2 parents 3cd8122 + df71935 commit 7400b46
Show file tree
Hide file tree
Showing 12 changed files with 211 additions and 28 deletions.
4 changes: 4 additions & 0 deletions SwagLyricsGUI/Bridge/swaglyrics_api_bridge.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import time
import sys
import base64
import os
import tempfile

from swaglyrics import cli
from SwSpotify import spotify, SpotifyNotRunning
Expand Down Expand Up @@ -38,4 +40,6 @@ def print_lyrics(song, artist):
paused = False
elif paused:
print_encoded("Resumed")
if not os.path.exists(os.path.join(tempfile.gettempdir(), "SwagLyricsGUI", "swaglyricsGUIOn.txt")): # kills the process if GUI is off and not closed it properly
sys.exit()
time.sleep(2)
38 changes: 38 additions & 0 deletions SwagLyricsGUI/Models/Command.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Input;

namespace SwagLyricsGUI.Models
{
public class Command : ICommand
{
private Action<object>? _execute;
private Predicate<object>? _canExecute;

public event EventHandler CanExecuteChanged;

#pragma warning disable CS8618
public Command(Action<object>? execute = null, Predicate<object>? canExecute = null)
#pragma warning restore CS8618
{
_execute = execute;
_canExecute = canExecute;
}

public virtual void NotifyCanExecuteChanged()
{
CanExecuteChanged?.Invoke(this, EventArgs.Empty);
}

public bool CanExecute(object parameter)
{
return _canExecute?.Invoke(parameter) ?? true;
}

public void Execute(object parameter)
{
_execute?.Invoke(parameter);
}
}
}
28 changes: 28 additions & 0 deletions SwagLyricsGUI/Models/Fact.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.Json.Serialization;

namespace SwagLyricsGUI.Models
{
public class Fact
{
[JsonPropertyName("text")]
public string Text { get; set; }
[JsonPropertyName("source_url")]
public string SourceUrl { get; set; }

public Fact(string text, string source)
{
Text = text;
SourceUrl = source;
}

public Fact()
{

}

public override string ToString() => $"{Text}\n\n\nSource: {SourceUrl}";
}
}
3 changes: 2 additions & 1 deletion SwagLyricsGUI/Models/PrerequisitesChecker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ public void InstallSwagLyricsIfMissing()
};
Process process = new Process() { StartInfo = start };
process.Start();
process.WaitForExit();
process.WaitForExit();
process.Kill();
}

private bool CheckPythonInstalled(string postfix)
Expand Down
33 changes: 33 additions & 0 deletions SwagLyricsGUI/Models/RandomFactsFetcher.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;

namespace SwagLyricsGUI.Models
{
public static class RandomFactsFetcher
{
public const string FactsUrl = @"https://uselessfacts.jsph.pl/random.json?language=en";
public static Fact GetRandomFact()
{
WebRequest request = WebRequest.Create(FactsUrl);
var response = request.GetResponse();
Fact result;

using (Stream dataStream = response.GetResponseStream())
{
// Open the stream using a StreamReader for easy access.
StreamReader reader = new StreamReader(dataStream);
// Read the content.
result = JsonSerializer.Deserialize<Fact>(reader.ReadToEnd());
}

// Close the response.
response.Close();
return result;
}
}
}
36 changes: 26 additions & 10 deletions SwagLyricsGUI/Models/SwagLyricsBridge.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,18 @@ public class SwagLyricsBridge
public event EventHandler<LyricsLoadedEventArgs> OnLyricsLoaded;
public event EventHandler<LyricsLoadedEventArgs> OnError;
public event EventHandler OnResumed;
public event EventHandler OnAdvertisement;

public void GetLyrics()
public string BridgeFileOnPath = Path.Join(BridgeManager.BridgeFilesPath, "swaglyricsGUIOn.txt");

public bool IsAdvertisement { get; private set; } = false;
public Process LyricsProcess { get; set; }

public void StartLyricsBridge()
{
File.Create(BridgeFileOnPath);
string path = Path.Join(BridgeManager.BridgeFilesPath, "swaglyrics_api_bridge.py");
var process = new Process
LyricsProcess = new Process
{
StartInfo = new ProcessStartInfo
{
Expand All @@ -24,16 +31,16 @@ public void GetLyrics()
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true,
CreateNoWindow = true,
},
EnableRaisingEvents = true
};
process.OutputDataReceived += Process_OutputDataReceived;
process.ErrorDataReceived += Process_ErrorDataReceived;
LyricsProcess.OutputDataReceived += Process_OutputDataReceived;
LyricsProcess.ErrorDataReceived += Process_ErrorDataReceived;

process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
LyricsProcess.Start();
LyricsProcess.BeginOutputReadLine();
LyricsProcess.BeginErrorReadLine();
Console.Read();
}

Expand All @@ -51,13 +58,22 @@ private void Process_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
string song = data.Split(":")[0];

OnNewSong?.Invoke(this, new NewSongEventArgs(song));
if(song.Split("by")[0].Trim() == "Advertisement")
{
IsAdvertisement = true;
OnAdvertisement?.Invoke(this, EventArgs.Empty);
}
else
{
IsAdvertisement = false;
OnNewSong?.Invoke(this, new NewSongEventArgs(song));
}
}
else if(data == "Resumed")
{
OnResumed?.Invoke(this, EventArgs.Empty);
}
else
else if(!IsAdvertisement)
{
OnLyricsLoaded?.Invoke(this, new LyricsLoadedEventArgs($"\n{data}\n")); // \n are "Margins"
}
Expand Down
5 changes: 3 additions & 2 deletions SwagLyricsGUI/SwagLyricsGUI.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
<TargetFramework>netcoreapp3.1</TargetFramework>
<RuntimeIdentifiers>win-x64;win-x86;osx-x64;linux-x64</RuntimeIdentifiers>
<ApplicationIcon>swaglyrics_pfp.ico</ApplicationIcon>
<Version>0.0.2</Version>
<Version>0.3</Version>
<Authors>Krzysztof Krysiński</Authors>
<Company>SwagLyrics</Company>
<PackageLicenseFile>LICENSE.md</PackageLicenseFile>
<RepositoryUrl>https://github.com/SwagLyrics/SwagLyricsGUI</RepositoryUrl>
<Description>A cross-platform, real-time lyrics fetching application.</Description>
<Copyright>Krzysztof Krysiński © 2020</Copyright>
<Copyright>© The SwagLyrics Project 2020</Copyright>
</PropertyGroup>
<ItemGroup>
<Compile Update="**\*.xaml.cs">
Expand Down Expand Up @@ -42,6 +42,7 @@
<PackageReference Include="Avalonia" Version="0.9.11" />
<PackageReference Include="Avalonia.Desktop" Version="0.9.11" />
<PackageReference Include="Avalonia.ReactiveUI" Version="0.9.11" />
<PackageReference Include="Avalonia.Xaml.Behaviors" Version="0.9.9" />
<PackageReference Include="System.Configuration.ConfigurationManager" Version="4.7.0" />
</ItemGroup>
<ItemGroup>
Expand Down
63 changes: 59 additions & 4 deletions SwagLyricsGUI/ViewModels/MainWindowViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,37 @@
using ReactiveUI;
using SwagLyricsGUI.Models;
using SwagLyricsGUI.Views;
using System;
using System.Configuration;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Windows.Input;

namespace SwagLyricsGUI.ViewModels
{
public class MainWindowViewModel : ViewModelBase
{
{
public ICommand CloseAppCommand { get; set; }
public static MainWindowViewModel Current { get; set; }
public ThemeManager ThemeManager { get; set; }
System.Timers.Timer _timer = new System.Timers.Timer(20)
{
AutoReset = true,
};
System.Timers.Timer _loadingTimer = new System.Timers.Timer(200)
{
AutoReset = true,
};
public char[] LoadingASCII;
private int _lastLoadingIndex = 0;
public double ScrollSpeed = 1.1;
private double t = 0;


private int _themeIndex = 1;
private int _themeIndex = 2;
public int ThemeIndex
{
get => _themeIndex;
Expand All @@ -45,6 +57,13 @@ public bool AutoScroll
}
}

private Avalonia.Layout.HorizontalAlignment _lyricsAlignment = Avalonia.Layout.HorizontalAlignment.Left;
public Avalonia.Layout.HorizontalAlignment LyricsAlignment
{
get => _lyricsAlignment;
set => this.RaiseAndSetIfChanged(ref _lyricsAlignment, value);
}

private Vector _scrollBarOffset;

public Vector ScrollBarOffset
Expand Down Expand Up @@ -77,6 +96,7 @@ public string Song

public MainWindowViewModel()
{
CloseAppCommand = new Command(OnClose);
bool pythonInstalled = checker.SupportedPythonVersionInstalled();
if (pythonInstalled)
{
Expand All @@ -86,12 +106,15 @@ public MainWindowViewModel()
Current = this;
ThemeManager = new ThemeManager();
ThemeManager.LoadThemes();
Bridge.GetLyrics();
Bridge.StartLyricsBridge();
Bridge.OnNewSong += Bridge_OnNewSong;
Bridge.OnLyricsLoaded += Bridge_OnLyricsLoaded;
Bridge.OnError += Bridge_OnError;
Bridge.OnResumed += Bridge_OnResumed;
Bridge.OnAdvertisement += Bridge_OnAdvertisement;
_timer.Elapsed += _timer_Elapsed;
_loadingTimer.Elapsed += _loadingTimer_Elapsed;
LoadingASCII = "|/-\\".ToCharArray();

Config = ConfigurationManager.OpenExeConfiguration(Assembly.GetExecutingAssembly().Location);
if (Config.AppSettings.Settings["Theme"]?.Value is string theme)
Expand All @@ -106,6 +129,35 @@ public MainWindowViewModel()
}
}

private void Bridge_OnAdvertisement(object sender, EventArgs e)
{
System.Timers.Timer factTimer = new System.Timers.Timer(15000)
{
AutoReset = true
};
Song = "Advertisement time. Catch some fun facts";
Lyrics = RandomFactsFetcher.GetRandomFact().ToString();
factTimer.Elapsed += (s, e) =>
{
if (!Bridge.IsAdvertisement) { factTimer.Stop(); }
else { Lyrics = RandomFactsFetcher.GetRandomFact().ToString(); }
};
factTimer.Start();
}

private void _loadingTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
Lyrics = LoadingASCII[_lastLoadingIndex].ToString();
if (_lastLoadingIndex == LoadingASCII.Length - 1) _lastLoadingIndex = -1;
_lastLoadingIndex++;
}

private void OnClose(object obj)
{
Bridge?.LyricsProcess.Kill(true);
File.Delete(Bridge.BridgeFileOnPath);
}

private void Bridge_OnResumed(object sender, System.EventArgs e)
{
_timer.Start();
Expand All @@ -125,14 +177,17 @@ private void Bridge_OnError(object sender, LyricsLoadedEventArgs e)

private void Bridge_OnLyricsLoaded(object sender, LyricsLoadedEventArgs e)
{
LyricsAlignment = Avalonia.Layout.HorizontalAlignment.Left;
_loadingTimer.Stop();
Lyrics = e.Lyrics;
Task.Delay(20000).ContinueWith((task) => { _timer.Start(); });
}

private void Bridge_OnNewSong(object sender, NewSongEventArgs e)
{
LyricsAlignment = Avalonia.Layout.HorizontalAlignment.Center;
Song = e.Song;
Lyrics = "Loading lyrics...";
_loadingTimer.Start();
ScrollBarOffset = new Vector(0, 0);
t = 0;
_timer.Stop();
Expand Down
18 changes: 13 additions & 5 deletions SwagLyricsGUI/Views/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,21 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:SwagLyricsGUI.ViewModels;assembly=SwagLyricsGUI"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:i="clr-namespace:Avalonia.Xaml.Interactivity;assembly=Avalonia.Xaml.Interactivity"
xmlns:ia="clr-namespace:Avalonia.Xaml.Interactions.Core;assembly=Avalonia.Xaml.Interactions"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
mc:Ignorable="d" Name="mainWindow"
x:Class="SwagLyricsGUI.Views.MainWindow" Design.Width="400" Design.Height="800"
Icon="/Assets/swaglyrics_pfp.ico" MinWidth="420" Width="420" MinHeight="400"
Title="SwagLyricsGUI" FontFamily="/Assets/Fonts/Roboto-Regular.ttf" Topmost="True"
Icon="/Assets/swaglyrics_pfp.ico" MinWidth="420" Width="420" MinHeight="250"
Title="SwagLyricsGUI" FontFamily="/Assets/Fonts/Roboto-Regular.ttf" Topmost="True"
WindowStartupLocation="Manual" >

<i:Interaction.Behaviors>
<ia:EventTriggerBehavior EventName="Closing" SourceObject="{Binding #mainWindow}">
<ia:InvokeCommandAction Command="{Binding CloseAppCommand}"/>
</ia:EventTriggerBehavior>
</i:Interaction.Behaviors>

<Design.DataContext>
<vm:MainWindowViewModel/>
</Design.DataContext>
Expand All @@ -30,8 +38,8 @@
<Separator BorderThickness="0.2" BorderBrush="Gray" Margin="0,5,0,5"/>
<ScrollViewer Name="scrollViewer" Offset="{Binding ScrollBarOffset}" Grid.Row="1" VerticalScrollBarVisibility="Auto">
<StackPanel Orientation="Vertical" Width="400">
<TextBlock Foreground="{DynamicResource ThemeAccentBrush}" TextWrapping="Wrap" Text="{Binding Song}" Width="400" HorizontalAlignment="Left" Margin="15" FontSize="20"/>
<TextBox Margin="20,0,0,0" AcceptsReturn="True" Name="lyricsText" BorderThickness="0" CaretBrush="Transparent" IsReadOnly="True" FontWeight="SemiBold" FontSize="14" TextWrapping="Wrap" Text="{Binding Lyrics}" HorizontalAlignment="Left" VerticalAlignment="Top"/>
<TextBlock Foreground="{DynamicResource ThemeAccentBrush}" TextWrapping="Wrap" Text="{Binding Song}" Width="385" HorizontalAlignment="Left" Margin="20" FontSize="20"/>
<TextBox Margin="15,0,0,0" AcceptsReturn="True" Name="lyricsText" BorderThickness="0" CaretBrush="Transparent" IsReadOnly="True" FontWeight="SemiBold" FontSize="14" TextWrapping="Wrap" Text="{Binding Lyrics}" HorizontalAlignment="{Binding LyricsAlignment}" VerticalAlignment="Top"/>
</StackPanel>
</ScrollViewer>
</Grid>
Expand Down
Loading

0 comments on commit 7400b46

Please sign in to comment.