vendredi 17 juin 2016

How would I read this data structure in Perl? Dictionary/Hash with keys containing lists containing lists. Python::Inline giving me errors

I've been struggling for about 3 weeks on this simple issue. I can't understand why and I would give anything to solve it lol.

I am trying to read values from the data structure below. The docs say it's a dictionary with keys containing lists of results of that type.

Example: I get the master query reply using an eval function. I lookup the key "song_hits" to get that structure. Then I lookup the key 'track' and parse it. The problem is getting to the 'track' part.

When I do it from how Perl docs tell me to, I get Can't locate object method "FIRSTKEY" via package "Inline::Python::Object::Data".

So I'm wondering if there's a way to read the value using the eval function to bypass ObjectData's hash key limitation, another way to read it given I know exact keys, or if I'm just doing this entirely wrong.

{
'album_hits': [
{
    'album':
    {
        'albumArtRef': 'http://lh5.ggpht.com/DVIg4GiD6msHfgPs_Vu_2eRxCyAoz0fF...',
        'albumArtist': 'J.Cole',
        'albumId': 'Bfp2tuhynyqppnp6zennhmf6w3y',
        'artist': 'J.Cole',
        'artistId': ['Ajgnxme45wcqqv44vykrleifpji'],
        'description_attribution':
        {
            'kind': 'sj#attribution',
            'license_title': 'Creative Commons Attribution CC-BY',
            'license_url': 'http://creativecommons.org/licenses/by/4.0/legalcode',
            'source_title': 'Freebase',
            'source_url': ''
        },
        'explicitType': '1',
        'kind': 'sj#album',
        'name': 'Work Out',
        'year': 2011
    },
    'type': '3'
}],
'artist_hits': [
{
    'artist':
    {
        'artistArtRef': 'http://lh3.googleusercontent.com/MJe-cDw9uQ-pUagoLlm...',
        'artistArtRefs': [
        {
            'aspectRatio': '2',
            'autogen': False,
            'kind': 'sj#imageRef',
            'url': 'http://lh3.googleusercontent.com/MJe-cDw9uQ-pUagoLlmKX3x_K...'
        }],
        'artistId': 'Ajgnxme45wcqqv44vykrleifpji',
        'artist_bio_attribution':
        {
            'kind': 'sj#attribution',
            'source_title': 'David Jeffries, Rovi'
        },
        'kind': 'sj#artist',
        'name': 'J. Cole'
    },
    'type': '2'
}],
'playlist_hits': [
{
    'playlist':
    {
        'albumArtRef': [
        {
            'url': 'http://lh3.googleusercontent.com/KJsAhrg8Jk_5A4xYLA68LFC...'
        }],
        'description': 'Workout Plan ',
        'kind': 'sj#playlist',
        'name': 'Workout',
        'ownerName': 'Ida Sarver',
        'shareToken': 'AMaBXyktyF6Yy_G-8wQy8Rru0tkueIbIFblt2h0BpkvTzHDz-fFj6P...',
        'type': 'SHARED'
    },
    'type': '4'
}],
'situation_hits': [
{
    'situation':
    {
        'description': 'Level up and enter beast mode with some loud, aggressive music.',
        'id': 'Nrklpcyfewwrmodvtds5qlfp5ve',
        'imageUrl': 'http://lh3.googleusercontent.com/Cd8WRMaG_pDwjTC_dSPIIuf...',
        'title': 'Entering Beast Mode',
        'wideImageUrl': 'http://lh3.googleusercontent.com/8A9S-nTb5pfJLcpS8P...'
    },
    'type': '7'
}],
'song_hits': [
{
    'track':
    {
        'album': 'Work Out',
        'albumArtRef': [
        {
            'aspectRatio': '1',
            'autogen': False,
            'kind': 'sj#imageRef',
            'url': 'http://lh5.ggpht.com/DVIg4GiD6msHfgPs_Vu_2eRxCyAoz0fFdxj5w...'
        }],
        'albumArtist': 'J.Cole',
        'albumAvailableForPurchase': True,
        'albumId': 'Bfp2tuhynyqppnp6zennhmf6w3y',
        'artist': 'J Cole',
        'artistId': ['Ajgnxme45wcqqv44vykrleifpji', 'Ampniqsqcwxk7btbgh5ycujij5i'],
        'composer': '',
        'discNumber': 1,
        'durationMillis': '234000',
        'estimatedSize': '9368582',
        'explicitType': '1',
        'genre': 'Pop',
        'kind': 'sj#track',
        'nid': 'Tq3nsmzeumhilpegkimjcnbr6aq',
        'primaryVideo':
        {
            'id': '6PN78PS_QsM',
            'kind': 'sj#video',
            'thumbnails': [
            {
                'height': 180,
                'url': 'https://i.ytimg.com/vi/6PN78PS_QsM/mqdefault.jpg',
                'width': 320
            }]
        },
        'storeId': 'Tq3nsmzeumhilpegkimjcnbr6aq',
        'title': 'Work Out',
        'trackAvailableForPurchase': True,
        'trackAvailableForSubscription': True,
        'trackNumber': 1,
        'trackType': '7',
        'year': 2011
    },
    'type': '1'
}],
'station_hits': [
{
    'station':
    {
        'compositeArtRefs': [
        {
            'aspectRatio': '1',
            'kind': 'sj#imageRef',
            'url': 'http://lh3.googleusercontent.com/3aD9mFppy6PwjADnjwv_w...'
        }],
        'contentTypes': ['1'],
        'description': 'These riff-tastic metal tracks are perfect for getting the blood pumping.',
        'imageUrls': [
        {
            'aspectRatio': '1',
            'autogen': False,
            'kind': 'sj#imageRef',
            'url': 'http://lh5.ggpht.com/YNGkFdrtk43e8H941fuAHjflrNZ1CJUeqdoys...'
        }],
        'kind': 'sj#radioStation',
        'name': 'Heavy Metal Workout',
        'seed':
        {
            'curatedStationId': 'Lcwg73w3bd64hsrgarnorif52r',
            'kind': 'sj#radioSeed',
            'seedType': '9'
        },
        'skipEventHistory': [],
        'stationSeeds': [
        {
            'curatedStationId': 'Lcwg73w3bd64hsrgarnorif52r',
            'kind': 'sj#radioSeed',
            'seedType': '9'
        }]
    },
    'type': '6'
}],
'video_hits': [
{
    'score': 629.6226806640625,
    'type': '8',
    'youtube_video':
    {
        'id': '6PN78PS_QsM',
        'kind': 'sj#video',
        'thumbnails': [
        {
            'height': 180,
            'url': 'https://i.ytimg.com/vi/6PN78PS_QsM/mqdefault.jpg',
            'width': 320
        }],
        'title': 'J. Cole - Work Out'
    }
}]

}

Cleaned, but broken code with 3 weeks of different attempts: (I have tried for, foreach, while, but the furthest it would read would be either the entire unicode array, error, or an empty string)

sub search {
    my $query = shift;

    my $uri = 'googlemusic:search:' . $query;

    if (my $result = $cache->get($uri)) {
        return $result;
    }

    my $googleResult;
    my $result = {
        tracks => [],
        albums => [],
        artists => [],
    };        

    eval {
        $googleResult = $googleapi->search($query, $prefs->get('max_search_items'));
    };
    if ($@) {
        $log->error("Not able to search All Access for "$query": $@");
        return;
    }
    #gives not an ARRAY refernce error
    for my $hit (@{$googleResult->{song_hits}}) {
        push @{$result->{tracks}}, to_slim_track($hit->{track});
    }
    #works, but gives an error on the next line, 'newlist' object has no attribute 'album' 
    for my $hit ({$googleResult->{album_hits}}) {
        push @{$result->{albums}}, album_to_slim_album($hit->{album});
    }
    #Perl and others recommended way, but gives  Can't locate object method "FIRSTKEY" via package "Inline::Python::Object::Data"
    for my $hit (%{$googleResult->{artist_hits}}) {
        push @{$result->{artists}}, artist_to_slim_artist($hit->{artist});
    }

    # Add to the cache
    $cache->set($uri, $result, $CACHE_TIME);

    return $result;
}

I have tried reading up, but have gotten so many errors including:

  • 'key' does not exist
  • Can't use string ("track") as a HASH ref while strict refs in use
  • Type of argument to keys on reference must be unblessed hashref or arrayref

My Full Test File: http://pastebin.com/DMnDc56i GoogleApi PM (Python GAPI Hook): https://raw.githubusercontent.com/hechtus/squeezebox-googlemusic/master/GoogleMusic/GoogleAPI.pm

Edit: Info, There were a couple of people who wanted unmaintained old code fixed, so I offered to help and got everything working besides this part.

Old Code Git: https://github.com/hechtus/squeezebox-googlemusic

Google Api Python I use: https://github.com/simon-weber/gmusicapi

Aucun commentaire:

Enregistrer un commentaire