aboutsummaryrefslogtreecommitdiff
path: root/src/sources/spotify.rs
blob: e4bf19ce687ba42b2c6ffc99153b573a8933f773 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
use std::ffi::CStr;
use std::io::Result;

use cocoa::{base::{nil, id}, foundation::NSString};
use objc::{class, msg_send, sel, sel_impl, runtime::{Class, Object}};
use objc_id::Id;

use crate::Track;

use super::LyricsSource;

pub struct Spotify;

impl Spotify {
    pub fn new() -> Self {
        Spotify
    }
}

impl LyricsSource for Spotify {

    fn name(&self) -> String {
        "spotify".to_string()
    }

    fn current_track(&self) -> Option<Track> {
        unsafe {
            let app: Id<Object> = {
                let cls = class!(SBApplication);
                let bundle_identifier = NSString::alloc(nil).init_str("com.spotify.Client"); 

                let workspace_class = Class::get("NSWorkspace").unwrap();
                let shared_workspace: id = msg_send![workspace_class, sharedWorkspace];
                let app_url: id = msg_send![shared_workspace, URLForApplicationWithBundleIdentifier:bundle_identifier];

                if app_url != nil {
                    let app: *mut Object = msg_send![cls, applicationWithBundleIdentifier:bundle_identifier];
                    Id::from_ptr(app)
                } else {
                    return None
                }
            };

            if msg_send![app, isRunning] {
                let current_track: *mut Object = msg_send![app, currentTrack];
                if !current_track.is_null() {
                    let name_raw: *mut Object = msg_send![current_track, name];
                    let artist_raw: *mut Object = msg_send![current_track, artist];

                    let name_ptr: *const i8 = msg_send![name_raw, UTF8String];
                    let artist_ptr: *const i8 = msg_send![artist_raw, UTF8String];

                    let name = CStr::from_ptr(name_ptr).to_string_lossy().into_owned();
                    let artist = CStr::from_ptr(artist_ptr).to_string_lossy().into_owned();


                    return Some(Track {
                        name,
                        artist
                    })
                }
            }
        }
        None
    }

    fn disable(&self) -> Result<()> {
        Ok(())
    }

    fn enable(&self) -> Result<()> {
        Ok(())
    }

    fn reset(&self) -> Result<()> {
        Ok(())
    }
}