rmcrackan / Libation

Libation: Liberate your Library
GNU General Public License v3.0
2.75k stars 150 forks source link

Mac beta #327

Closed rmcrackan closed 1 year ago

rmcrackan commented 2 years ago

The original Libation is Windows only. We recently did a massive rewrite of the whole UI to make it cross platform. We have some VMs running linux that we can test on but we have no access to a mac. In theory, I should be able to use this same code with some different publish steps and then it will work on mac also.

I need mac people to tell me if it works for them. I know nothing about using a mac. I wouldn't even know if my output file was correct. Further complicating things, I don't know if the Intel/M1/M2 thing matters.

mkb79 commented 2 years ago

Maybe I can help out testing on a M1 mac.

Mbucari commented 2 years ago

@mkb79 Yes please!

Here you go!

rmcrackan commented 2 years ago

@Mbucari Damn you're fast. You beat me to it again. :) I just started looking at the profile.pubxml files. It looks like all I have to do is change these and build as per the linux-chardonnay dotnet publish steps. Is that what you did?

    <PublishDir>..\bin-Avalonia\publish\osx-x64\</PublishDir>
    <RuntimeIdentifier>osx-x64</RuntimeIdentifier>
Mbucari commented 2 years ago

@rmcrackan Yup, that's all. Then it comes down to actually executing it on mac and getting MP3 conversion to work. See the notes in my release.

Mbucari commented 2 years ago

I just realized, this package probably won't work for @mkb79 for 2 reasons.

He said an M1 mac, which is an arm architecture. My VS install only has a publish profile for mac x64. Also, it looks like only .netcore3.1 and .net6 runtimes are available on mac, but AAXClean targets .net 5.

rmcrackan commented 2 years ago

I hope that since M1 is still (relatively) new, that M1/M2 owners are familiar with how to run and/or virtualize Intel macos. Is it easy to upgrade AAXClean to 6?

mkb79 commented 2 years ago

I'll try this later this day. Maybe Rosetta 2 can help out.

Mbucari commented 2 years ago

Is it easy to upgrade AAXClean to 6?

Pretty easy, but:

rmcrackan commented 2 years ago

Especially after my manual mis-release last night, I'm working on my releaser app whenever I can find the time today. Does this look right to you?

build   -c Release -o bin\Release\win-classic      LibationWinForms\LibationWinForms.csproj -p:PublishProfile=LibationWinForms\Properties\PublishProfiles\WindowsProfile.pubxml
build   -c Release -o bin\Release\win-classic      LibationCli\LibationCli.csproj           -p:PublishProfile=LibationCli\Properties\PublishProfiles\WindowsProfile.pubxml
build   -c Release -o bin\Release\win-classic      Hangover\Hangover.csproj                 -p:PublishProfile=Hangover\Properties\PublishProfiles\WindowsProfile.pubxml

build   -c Release -o bin\Release\win-chardonnay   LibationAvalonia\LibationAvalonia.csproj -p:PublishProfile=LibationAvalonia\Properties\PublishProfiles\WindowsProfile.pubxml
build   -c Release -o bin\Release\win-chardonnay   LibationCli\LibationCli.csproj           -p:PublishProfile=LibationCli\Properties\PublishProfiles\WindowsProfile.pubxml
build   -c Release -o bin\Release\win-chardonnay   Hangover\Hangover.csproj                 -p:PublishProfile=Hangover\Properties\PublishProfiles\WindowsProfile.pubxml

publish -c Release -o bin\Release\linux-chardonnay LibationAvalonia\LibationAvalonia.csproj -p:PublishProfile=LibationAvalonia\Properties\PublishProfiles\LinuxProfile.pubxml
publish -c Release -o bin\Release\linux-chardonnay LibationCli\LibationCli.csproj           -p:PublishProfile=LibationCli\Properties\PublishProfiles\LinuxProfile.pubxml

publish -c Release -o bin\Release\macos-chardonnay LibationAvalonia\LibationAvalonia.csproj -p:PublishProfile=LibationAvalonia\Properties\PublishProfiles\MacOSProfile.pubxml
publish -c Release -o bin\Release\macos-chardonnay LibationCli\LibationCli.csproj           -p:PublishProfile=LibationCli\Properties\PublishProfiles\MacOSProfile.pubxml
Mbucari commented 2 years ago

Looks good to me!

rmcrackan commented 2 years ago

New mac version available here - v8.3.1

derekgottlieb commented 2 years ago

I've got some Intel Macs I can test with.

  1. The 8.3.1 Mac zipfile appears to contain the Linux binaries instead of MacOS
    
    $ file Libation
    Libation: ELF 64-bit LSB pie executable, x86-64, version 1 (GNU/Linux), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=b36f4fb458fe7cb88aa0fbcac547a573ead1362e, for GNU/Linux 2.6.32, stripped

$ file LibationCli LibationCli: ELF 64-bit LSB pie executable, x86-64, version 1 (GNU/Linux), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=b36f4fb458fe7cb88aa0fbcac547a573ead1362e, for GNU/Linux 2.6.32, stripped


For comparison, the older 8.3.0 zip contains a Mach-O executable like I'd expect:

$ file Libation Libation: Mach-O 64-bit executable x86_64


2. When running the 8.3.0 Libation executable, I got the expected Mac security warnings I needed to allow due to it being an unsigned binary. That's usually a one-time thing, so not the end of the world if you don't want to go down the road of figuring out how to get a developer signing key registered with Apple and figure out how to sign your builds with it. The surprising thing was I also ran into this warning / need to allow for every dll as it tried to load them.

3. After working through allowing each of those in sequence, it's now bombing with the following error:

$ ./Libation Unhandled exception. System.BadImageFormatException: Could not load file or assembly 'Avalonia.DesktopRuntime, Version=0.10.17.0, Culture=neutral, PublicKeyToken=c8d484a7012f9a8b'. An attempt was made to load a program with an incorrect format.

File name: 'Avalonia.DesktopRuntime, Version=0.10.17.0, Culture=neutral, PublicKeyToken=c8d484a7012f9a8b' at LibationAvalonia.Program.Main() at LibationAvalonia.Program.

() [1] 69724 abort ./Libation

rmcrackan commented 2 years ago

The 8.3.1 Mac zipfile appears to contain the Linux binaries instead of MacOS

This is confusing. I ran the above dotnet commands and the macos profiles are targeting osx-x64 . @Mbucari - how did you build yours?

Mbucari commented 2 years ago

That's how I built it. IDK man.

mkb79 commented 2 years ago

@mkb79 Yes please!

Here you go!

I've got these error message:

Unhandled exception. System.BadImageFormatException: Could not load file or assembly 'Avalonia.DesktopRuntime, Version=0.10.17.0, Culture=neutral, PublicKeyToken=c8d484a7012f9a8b'. An attempt was made to load a program with an incorrect format.

File name: 'Avalonia.DesktopRuntime, Version=0.10.17.0, Culture=neutral, PublicKeyToken=c8d484a7012f9a8b'
   at LibationAvalonia.Program.Main()
   at LibationAvalonia.Program.<Main>()
zsh: abort      ./Libation
Mbucari commented 2 years ago

@rmcrackan The problem appears to be caused by Visual Studio. Those dotnet commands are fine, but visual studio isn't properly cleaning/restoring between builds on different platforms. Even running dotnet clean -c Release before each build/publish command doesn't solve the problem. I'm sure there's a proper way to do this, but I haven't found it yet. The only way I've found to make SURE that these packages build properly on each OS is to delete all obj\ and bin\ directories for all projects before running publish on each different OS.

VirtualBox_Mac_30_07_2022_14_44_07

Also, I painted myself into a corner with the Avalonia code. Over Here I talked about how I made ShowDialog synchronous and added other synchronous methods for working with Avalonia's async-only forms. Well it turns out that does not work on macOS. So I'll have to go through the code and figure out a way to only call ShowDialog asynchronously. That means converting all static MessageBox.Show() methods to async, among other changes.

VirtualBox_Mac_30_07_2022_14_35_57

Mbucari commented 2 years ago

@rmcrackan OK, I solved that one. Now we have a new one. This one's all you!

Locking/unlocking file regions is not supported on this platform. Use FileShare on the entire file instead.

   at System.IO.Strategies.FileStreamHelpers.Lock(SafeFileHandle handle, Boolean canWrite, Int64 position, Int64 length)
   at System.IO.Strategies.OSFileStreamStrategy.Lock(Int64 position, Int64 length)
   at System.IO.Strategies.BufferedFileStreamStrategy.Lock(Int64 position, Int64 length)
   at System.IO.FileStream.Lock(Int64 position, Int64 length)
   at Lucene.Net.Store.NativeFSLock.Obtain()
   at Lucene.Net.Store.Lock.Obtain(Int64 lockWaitTimeout)
   at Lucene.Net.Index.IndexWriter.Init(Directory d, Analyzer a, Boolean create, IndexDeletionPolicy deletionPolicy, Int32 maxFieldLength, IndexingChain indexingChain, IndexCommit commit)
   at Lucene.Net.Index.IndexWriter..ctor(Directory d, Analyzer a, Boolean create, MaxFieldLength mfl)
   at LibationSearchEngine.SearchEngine.CreateNewIndex(IEnumerable`1 library, Boolean overwrite) in D:\OneDrive\Projects\Libation\Source\LibationSearchEngine\SearchEngine.cs:line 192
   at ApplicationServices.SearchEngineCommands.<>c.<FullReIndex>b__7_0(SearchEngine e) in D:\OneDrive\Projects\Libation\Source\ApplicationServices\SearchEngineCommands.cs:line 54
   at ApplicationServices.SearchEngineCommands.update(Action`1 action) in D:\OneDrive\Projects\Libation\Source\ApplicationServices\SearchEngineCommands.cs:line 89
   at ApplicationServices.SearchEngineCommands.performSafeCommand(Action`1 action) in D:\OneDrive\Projects\Libation\Source\ApplicationServices\SearchEngineCommands.cs:line 69
   at ApplicationServices.SearchEngineCommands.FullReIndex() in D:\OneDrive\Projects\Libation\Source\ApplicationServices\SearchEngineCommands.cs:line 53
   at AppScaffolding.LibationScaffolding.<>c.<wireUpSystemEvents>b__24_0(Object _, EventArgs __) in D:\OneDrive\Projects\Libation\Source\AppScaffolding\LibationScaffolding.cs:line 334
   at ApplicationServices.LibraryCommands.finalizeLibrarySizeChange() in D:\OneDrive\Projects\Libation\Source\ApplicationServices\LibraryCommands.cs:line 358
   at ApplicationServices.LibraryCommands.<>c.<importIntoDbAsync>b__18_0() in D:\OneDrive\Projects\Libation\Source\ApplicationServices\LibraryCommands.cs:line 232
   at System.Threading.Tasks.Task.InnerInvoke()
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
--- End of stack trace from previous location ---
   at ApplicationServices.LibraryCommands.importIntoDbAsync(List`1 importItems) in D:\OneDrive\Projects\Libation\Source\ApplicationServices\LibraryCommands.cs:line 232
   at ApplicationServices.LibraryCommands.ImportAccountAsync(Func`2 apiExtendedfunc, Account[] accounts) in D:\OneDrive\Projects\Libation\Source\ApplicationServices\LibraryCommands.cs:line 147
   at LibationAvalonia.Views.MainWindow.scanLibrariesAsync(Account[] accounts) in D:\OneDrive\Projects\Libation\Source\LibationAvalonia\Views\MainWindow\MainWindow.ScanManual.axaml.cs:line 65

Downloading works, but that Lucene error makes Libation pretty much unusable on mac. It crashes after each book is downloaded, presumably because Lucene is trying to re-index and throwing that error. VirtualBox_Mac_30_07_2022_18_09_03

rmcrackan commented 2 years ago

Please see if v8.3.2 acts any better.

Mbucari commented 2 years ago

Please see if v8.3.2 acts any better.

It no longer crashes after updating, but search still doesn't work. You need to change the file lock.

https://github.com/rmcrackan/LuceneNet303r2/blob/74c7175111fab23b550845b2b7485b0cf64950a7/LuceneNet303r2/Store/NativeFSLockFactory.cs#L268-L272

rmcrackan commented 2 years ago

Good call. For now I'm just going to hide those from osx and we'll see how that goes. If need be, I'll replace it with the actual osx recommendation.

rmcrackan commented 2 years ago

v8.3.3 hides this lock from Mac. Let's see if we can get further this time.

Mbucari commented 2 years ago

Everything but mp3 seems to work on mac!

But we really do need to do something about the installation / signing. It's not OK to expect users to disable their system malware protection to be able to use an app.

Check out: https://docs.avaloniaui.net/docs/distribution-publishing/macos

Mbucari commented 2 years ago

@mkb79 @derekgottlieb

Please try the v8.3.4 macOS build.

Also, do either of you have any suggestions for better deployment on macOS to make it more user-friendly? Getting an Apple developer ID and making a .app package is probably out of the question. But short of that, what can/should we do?

My current approach is to run

sudo spctl --master-disable

And then launch Libation from the terminal. There's got to be a better way.

mkb79 commented 2 years ago

Instead of disable GateKeeper you can run for the whole Libation folder:

sudo spctl --add --label "Libation" ./Libation

I could run Libation. But had to chmod +x ./Libation before. I could only add a new user login with external browser. Import from audible-cli raises an exception and default adding does nothing. A lib sync was successful.

Mbucari commented 2 years ago
sudo spctl --add --label "Libation" ./Libation

Thanks!

But had to chmod +x ./Libation before.

That is a problem that I think can only be solved by packaging the bins in a .tar file with execution permissions already set. I'll work with @rmcrackan on that.

Import from audible-cli raises an exception

Can you please share exception details? Maybe post your log file? I was able to use the Import function, so I suspect the problem is that I didn't correctly match/understand your account file's json structure.

default adding does nothing.

I don't understand what you mean. Can you please explain?

mkb79 commented 2 years ago

I don't understand what you mean. Can you please explain?

The default way to add an account does not work for me. I filled out my password as Libation asked for it. But after 1 minute of waiting nothing happens. So I logged in using an external url.

Mbucari commented 2 years ago

@mkb79 I understand.

Can you please post your libation log file? It might help illuminate all of the problems you've been experiencing.

mkb79 commented 2 years ago

@Mbucari pressing the Open Log Folder does not work. Where I can find the logs?

Mbucari commented 2 years ago

Oh gosh, that's a good question. In Linux it inside $HOME/Libation

Is that true on Mac as well?

mkb79 commented 2 years ago

I'm at work now and my Mac is at home. Will try it later.

rmcrackan commented 2 years ago

I have no mac on which to try this. I found this a long time ago for opening url. As seen in Dinah.Core Go.To.Url:

Process.Start("open", url);

Maybe we just have to do Process.Start("open", "/my/mac/path"); or Process.Start("Finder", "/my/mac/path");

Mbucari commented 2 years ago

@rmcrackan I already made a different GoToFolder for Linux.

https://github.com/rmcrackan/Libation/blob/fe2de6ecf725c00576688e27daa11c7d9828aa3f/Source/LibationAvalonia/App.axaml.cs#L37

I'll test Process.Start("Finder with Mac.

rmcrackan commented 2 years ago

Yup, I saw at the //Don't know how to do this for mac yet comment and thought I'd throw in my $0.02

Mbucari commented 2 years ago

@rmcrackan I added and tested the open command and it works. Want to move that code into Dinah?

https://github.com/Mbucari/Libation/commit/d884d34c5b61c95c9341ff2524bc1b701281093f

rmcrackan commented 2 years ago

Yup. That was the plan once the dust settled. Are you happy with this version?

Mbucari commented 2 years ago

I am. It doesn't look like you can open the file explorer to a folder and select a file like you can in windows, but I think this version is as good as I can make it. xdg-open is about as general a solution for this as I could find that should work across many distros.

rmcrackan commented 2 years ago

The 'open log files folder' button should work with the new code. Does anyone want me to create a new version with this in it?

Mbucari commented 2 years ago

The 'open log files folder' button should work with the new code. Does anyone want me to create a new version with this in it?

Yes please, but maybe make it a pre-release. In fact, all of these betas that don't affect windows users should be pre-releases so users aren't notified of updates that are meaningless for them.

rmcrackan commented 2 years ago

Good idea. It surprisingly didn't even take long to add to my automated tool. Here it is. https://github.com/rmcrackan/Libation/releases/tag/v8.3.5

Mbucari commented 2 years ago

@mkb79 version 8.3.5 supports opening the log folder location by clicking the button in settings.

But I can confirm that you will find your logs inside $HOME/Libation

CharlieRussel commented 2 years ago

Modest feature request with all these versions flying fast and furious. Any chance you could add the current version number and Classic/Non-Classic to the bottom border (where it now shows Visible: and on the right hand side, Backups: ?

Would make it easier for those of us trying to follow along, but not wanting to churn every Mac/Linux build...

Thanks!

Charlie. (he, him, his)


From: Mbucari @.> Sent: August 2, 2022 9:08 AM To: rmcrackan/Libation @.> Cc: Subscribed @.***> Subject: Re: [rmcrackan/Libation] Mac beta (Issue #327)

The 'open log files folder' button should work with the new code. Does anyone want me to create a new version with this in it?

Yes please, but maybe make it a pre-release. In fact, all of these betas that don't affect windows users should be pre-releases so users aren't notified of updates that are meaningless for them.

— Reply to this email directly, view it on GitHubhttps://github.com/rmcrackan/Libation/issues/327#issuecomment-1202922561, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AFAHCRDAR7F5EZQK23WAIDLVXFBYNANCNFSM545GNG6A. You are receiving this because you are subscribed to this thread.Message ID: @.***>

rmcrackan commented 2 years ago

@CharlieRussel

Sorry, I'll try to keep the betas marked as 'prerelease' from here on out so you won't keep getting pinged for upgrades.

You can see your version in the settings menu. Classic is the older grey look. Chardonnay is the newer one with more white.

Mbucari commented 2 years ago

@rmcrackan We should probably add that info to the "About" box.

rmcrackan commented 2 years ago

Added. The next release will have this

Screenshot 2022-08-02 14 25 18

Screenshot 2022-08-02 14 29 15

Mbucari commented 2 years ago

@mkb79 version 8.3.5 supports opening the log folder location by clicking the button in settings.

But I can confirm that you will find your logs inside $HOME/Libation

@mkb79

Bumped in case you missed this.

mkb79 commented 2 years ago

@Mbucari I've read this. I only have two days left until my vacation. That's why it's quite stressful right now.

Mbucari commented 2 years ago

I've gone about as far as I can trying to make a Libation app package. Libation.app.zip

My problems are:

  1. The icon will not display. Is that because the package is unsigned?
  2. Libation needs write access to its program files directory to write the appsettings.json file. I can't find any documentation that says a program in an app packages cannot write to its own directory, but that seems to be the case. If I launch Libation by running the app package, it will run setup but then it will exit without creating the appsettings.json file. But if I run Libation executable directly, the appsetting.json file is created and Libation runs.

I think something must be wrong with my Info.plist, but I had to create it manually instead of using Xcode because apparently my VM mac version isn't high enough to install xcode. Damn apple.

derekgottlieb commented 2 years ago

Tested 8.3.5 (shows as 8.3.5.1 in the UI) on an Intel Mac. I was able to get it launched as a new user and think I was able to successfully add my account and log in via the web browser method, but when trying to sync my library it's finding 0 books. Doesn't appear to be much to go on looking in the logs (set to verbose):

2022-08-05 15:09:06.137 -05:00 [INF] (at AudibleUtilities.ApiExtended+<CreateAsync>d__5.MoveNext()) {"LoginType":"ILoginChoiceEager","Account":"AccountId=d[...]k.g[...]b@g[...]l.c[...]m|AccountName=d[...]k.g[...]b@g[...]l.c[...]s|Locale=us","LocaleName":"us"}
 {}2022-08-05 15:09:06.144 -05:00 [INF] (at ApplicationServices.LibraryCommands+<scanAccountAsync>d__17.MoveNext()) ImportLibraryAsync. {"Account":"AccountId=d[...]k.g[...]b@g[...]l.c[...]m|AccountName=d[...]k.g[...]b@g[...]l.c[...]s|Locale=us"}
 {}2022-08-05 15:09:06.147 -05:00 [DBG] (at AudibleUtilities.ApiExtended+<getItemsAsync>d__14.MoveNext()) Beginning library scan.
 {}2022-08-05 15:09:06.502 -05:00 [DBG] (at AudibleUtilities.ApiExtended+<getItemsAsync>d__14.MoveNext()) Library scan complete. Found 0 books and series. Waiting on 0 series episode scans to complete.
 {}2022-08-05 15:09:06.508 -05:00 [DBG] (at AudibleUtilities.ApiExtended+<getItemsAsync>d__14.MoveNext()) Completed library scan.
 {}2022-08-05 15:09:06.516 -05:00 [INF] (at ApplicationServices.LibraryCommands+<ImportAccountAsync>d__15.MoveNext()) GetAllLibraryItems: Total count 0

Re: efforts to make a Libation.app package: I'm not sure if Mac applications typically write settings and such back to the app directory. I think typically they write user-specific settings out to a app-specific subdirectory under ~/Library/Application Support or similar in the user's home directory. But I'll admit I've not tried to create an app package for Mac.

Mbucari commented 2 years ago

@derekgottlieb Audible changed their API and broke Libation. Version 8.3.6 should fix that.

Mbucari commented 2 years ago

@rmcrackan

Based on what @derekgottlieb said about app data locations, I think we should move appsettings.json to Environment.SpecialFolder.ApplicationData or LocalApplicationData