Importing python libraries to run script but which libraries?

Do you have questions about writing plugins or scripts in Python? Meet the coders here.
User avatar
kgschlosser
Site Admin
Posts: 5146
Joined: Fri Jun 05, 2015 5:43 am
Location: Rocky Mountains, Colorado USA

Re: Importing python libraries to run script but which libraries?

Post by kgschlosser » Tue May 08, 2018 9:14 pm

I am not sure what the author is thinking. This script is purly for iterating through the movies listed in emby. Then going to the directory where the movie is located and it check to see if there are trailers in that folder. And if there is not then it goes and downlosds the trailer from YouTube. It appends -trailer onto the file name. And leaves the extension as is. And then saves the trailer. So I am pretty confused then as to what the purpose of this script is for. Because without specifying a source directory and a destination directory the script does absoutly nothing.

I think I am going to have to check out Emby and see what it is all about.

In all honesty if all you are interested in is scraping trailers you can do this by using only requests and it is really very easy to do. But if you are scraping movie data. May as well grab trailers, background, jackets.

Personally I do not even bother with all of that.

I used the largest movie database on the internet. And no it's not imdb.

Mymovies.de
They have a really nice movie database software. Works with WMC, Kodi, MediaPortal. It grabs everything for you.

It does require some dicipline and because of the number of remakesbof movies all you need do is name the folder with the movie title and the year it was made.
If you like the work I have been doing then feel free to Image

jachin99
Experienced User
Posts: 612
Joined: Sat Feb 13, 2016 8:39 pm

Re: Importing python libraries to run script but which libraries?

Post by jachin99 » Tue May 08, 2018 11:13 pm

In order to be recognized as a trailer, the file has to have trailer formatted at the end of it in a specific way. See here: https://github.com/MediaBrowser/Wiki/wiki/Trailers Newer emby apps actually play the trailer live from the internet but Emby for WMC has a problem with the URL being too long if the trailer isn't stored locally. Also Emby for WMC only sees local trailers for my movies. If it werent for that problem, I wouldnt even need this. I tried My Movies, and in its heyday it had a really nice WMC plugin, and it supported disc changers. Since they didnt include WMC in Win 10, most of the cool things My Movies did in WMC have gone away. Emby does pretty good with metadata, and downloads all of the common stuff like cover art, backgrounds, etc. There is actually a plugin that will do exactly what this script does but if I'm ever going to learn how to script things, I need to start learning someday, which is why I'm using it. I figure it makes me learn a bit about EG, Python, and the Emby API. Something I love about emby in particular is it gives me Video backdrops for my movies via a plugin. These are separate from trailers but can be replaced by them also.

User avatar
kgschlosser
Site Admin
Posts: 5146
Joined: Fri Jun 05, 2015 5:43 am
Location: Rocky Mountains, Colorado USA

Re: Importing python libraries to run script but which libraries?

Post by kgschlosser » Wed May 09, 2018 5:14 am

OK so you have deep sixed the use of WMC. I didn't know if you were still using it. that is why i suggested MyMovies. Tho MyMovies has the easiest to use back end that does everything for you. it creates any necessary metadata files. it downloads whatever it is you want it to. it's one of those set it and forget it things.

The nice thing about it tho is with DVD/BD movie (on disc) it read the ESN for the movie off the disc when it is inserted. and it will populate the meta data real time. which is pretty nice if you ask me. You can have it do the same for movies you download and put into the directory. and the fact that it pulls the data from the largest source. MyMovies.de (same company)
If you like the work I have been doing then feel free to Image

jachin99
Experienced User
Posts: 612
Joined: Sat Feb 13, 2016 8:39 pm

Re: Importing python libraries to run script but which libraries?

Post by jachin99 » Wed May 09, 2018 10:53 pm

It looks like my library import worked but I'm getting an error telling me there is no JSON object. I asked about the web address on their forums. I still use WMC, I just have to change or add quite a bit to it in order to get things how I like them.

jachin99
Experienced User
Posts: 612
Joined: Sat Feb 13, 2016 8:39 pm

Re: Importing python libraries to run script but which libraries?

Post by jachin99 » Thu May 10, 2018 1:08 am

I'll look at my libraries again but in the mean time, here is my first error.

Code: Select all

   Traceback (most recent call last):
     File "17", line 39, in <module>
     File "C:\Program Files (x86)\EventGhost\lib27\site-packages\requests\models.py", line 812, in json
       return complexjson.loads(self.text, **kwargs)
     File "json\__init__.pyc", line 339, in loads
     File "json\decoder.pyc", line 364, in decode
     File "json\decoder.pyc", line 382, in raw_decode
   ValueError: No JSON object could be decoded

User avatar
kgschlosser
Site Admin
Posts: 5146
Joined: Fri Jun 05, 2015 5:43 am
Location: Rocky Mountains, Colorado USA

Re: Importing python libraries to run script but which libraries?

Post by kgschlosser » Thu May 10, 2018 9:24 pm

ok so use this one. It is going to print out what is going on.

Code: Select all

# you need to change these variable below to they proper values.
# the last 2 copy andpaste the directory right from file explorer 
# and paste it between the single quotes. 
# you have to leave the "r" in front. 
emby_url = 'API URL'
emby_api_key = 'API KEY'
emby_user = 'SOME USER NAME'
emby_source_directory = r'SOURCE DIRECTORY'
emby_destination_directory = r'DESTINATION DIRECTORY'

import requests
import os
import traceback
from pytube import YouTube


url = (
    '{emby_url}/Users/{emby_user}/Items?'
    'IncludeItemTypes=Movie&'
    'Recursive=true&'
    'StartIndex=0&format=json&'
    'fields=RemoteTrailers,Path'
).format(emby_url=emby_url, emby_user=emby_user)

headers = {
    'content-type':         'application/json',
    'Authorization':        'MediaBrowser',
    'UserId':               emby_user,
    'Client':               'EmbyTrailers',
    'Device':               'Python Script',
    'DeviceId':             'xxx',
    'Version':              '1.0.0.0',
    'X-MediaBrowser-Token': emby_api_key,
}

try:
    response = requests.get(url, headers=headers)
    films = response.json()
except requests.HTTPError:
    traceback.print_exc()
    eg.StopMacro()
    eg.Exit()
except ValueError:
    print response.status_code
    print response
    eg.StopMacro()
    eg.Exit()
else:
    if 'Name' not in films['Items'][0]:
        eg.PrintNotice("No Films Found")
        eg.StopMacro()
        eg.Exit()

    questionable_trailers = 0
    missing_trailers = 0
    successful_trailer_downloads = 0
    failed_trailer_downloads = 0
    for film in films['Items']:
        if film['LocalTrailerCount'] == 0:
            questionable_trailers += 1

            film_path = film['Path'].encode('utf-8')
            if None not in (emby_source_directory, emby_destination_directory):
                film_path = film_path.replace(
                    emby_source_directory,
                    emby_destination_directory,
                    1
                )
                film_path = os.path.normpath(film_path.replace('\\', os.sep))

            film_base_path = os.path.basename(film_path)
            film_directory_name = os.path.dirname(film_path)
            film_name = os.path.splitext(film_base_path)[0]
            if film_name[-3:-1] == 'CD':
                film_name = film_name[:-4]

            for f in os.listdir(film_directory_name):
                if f.startswith(film_name + '-trailer'):
                    break
            else:
                missing_trailers += 1
                for trailer in film['RemoteTrailers']:
                    trailer_url = trailer['Url'].encode('utf-8')

                    try:
                        you_tube = YouTube(trailer_url)
                        you_tube.set_filename(film_name + '-trailer')
                        video = you_tube.filter('mp4')[-1]
                        video.download(film_directory_name)
                        successful_trailer_downloads += 1
                        break
                    except:
                        eg.PrintError(
                            '{0} - {1}'.format(film_name, trailer_url)
                        )
                        traceback.print_exc()
                else:
                    failed_trailer_downloads += 1

    eg.Print(
        'Emby thinks %d Films are Missing Trailers' % questionable_trailers
    )
    eg.Print('%d Films Actually Missing Trailers' % missing_trailers)
    eg.Print('Downloaded %d Trailers' % successful_trailer_downloads)
    eg.Print('Unable to Download %d Trailers' % failed_trailer_downloads)
If you like the work I have been doing then feel free to Image

User avatar
kgschlosser
Site Admin
Posts: 5146
Joined: Fri Jun 05, 2015 5:43 am
Location: Rocky Mountains, Colorado USA

Re: Importing python libraries to run script but which libraries?

Post by kgschlosser » Thu May 10, 2018 9:44 pm

ok so scratch the last script.
This one is going to automatically locate the Emby Server and get the url for it. so no need to worry about that anymore.
It is also going to create a proper session with the server

Code: Select all

# you need to change these variable below to they proper values.
# the last 2 copy and paste the directory right from file explorer 
# and paste it between the single quotes. 
# you have to leave the "r" in front. 
emby_api_key = 'API KEY'
emby_user = 'SOME USER NAME'
emby_source_directory = r'SOURCE DIRECTORY'
emby_destination_directory = r'DESTINATION DIRECTORY'

import requests
import os
import traceback
import socket
import json
from uuid import uuid4 as GUID
from pytube import YouTube


client_id = str(GUID())

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, True)
sock.settimeout(2.0)
broadcast_address = ('255.255.255.255', 7359)
sock.sendto('who is EmbyServer?', broadcast_address)
sock.settimeout(2.0)

try:
    data = sock.recv(4096)
except socket.timeout:
    eg.PrintError('Could not find an Emby Server')
    eg.StopMacro()
    eg.Exit()

data = json.loads(data.decode('utf-8'))

eg.Print('Found Emby Server')
eg.Print('Name: ' + data['Name'])
eg.Print('Address: ' + data['Address'])
eg.Print('Id: ' + data['Id'])

headers = {
    'Content-Type': "application/json",
    'Accept':       "application/json",
    'x-emby-authorization': 'MediaBrowser',
    'Client':               'EmbyTrailers',
    'Device':               'Python Script',
    'DeviceId':             client_id,
    'Version':              '1.0.0.0',
}

emby_url = data['Address']
session_url = '{0}\Sessions'.format(emby_url)
params = dict(api_key=emby_api_key)

try:
    response = requests.get(session_url, headers=headers, params=params)
except requests.HTTPError:
    traceback.print_exc()
    eg.StopMacro()
    eg.Exit()

url = (
    '{emby_url}/Users/{emby_user}/Items?'
    'IncludeItemTypes=Movie&'
    'Recursive=true&'
    'StartIndex=0&format=json&'
    'fields=RemoteTrailers,Path'
).format(emby_url=emby_url, emby_user=emby_user)

params['DeviceId'] = client_id

try:
    response = requests.get(url, headers=headers, params=params)
    films = response.json()
except requests.HTTPError:
    traceback.print_exc()
    eg.StopMacro()
    eg.Exit()
except ValueError:
    print response.status_code
    print response
    eg.StopMacro()
    eg.Exit()
else:
    if 'Name' not in films['Items'][0]:
        eg.PrintNotice("No Films Found")
        eg.StopMacro()
        eg.Exit()

    questionable_trailers = 0
    missing_trailers = 0
    successful_trailer_downloads = 0
    failed_trailer_downloads = 0
    for film in films['Items']:
        if film['LocalTrailerCount'] == 0:
            questionable_trailers += 1

            film_path = film['Path'].encode('utf-8')
            if None not in (emby_source_directory, emby_destination_directory):
                film_path = film_path.replace(
                    emby_source_directory,
                    emby_destination_directory,
                    1
                )
                film_path = os.path.normpath(film_path.replace('\\', os.sep))

            film_base_path = os.path.basename(film_path)
            film_directory_name = os.path.dirname(film_path)
            film_name = os.path.splitext(film_base_path)[0]
            if film_name[-3:-1] == 'CD':
                film_name = film_name[:-4]

            for f in os.listdir(film_directory_name):
                if f.startswith(film_name + '-trailer'):
                    break
            else:
                missing_trailers += 1
                for trailer in film['RemoteTrailers']:
                    trailer_url = trailer['Url'].encode('utf-8')

                    try:
                        you_tube = YouTube(trailer_url)
                        you_tube.set_filename(film_name + '-trailer')
                        video = you_tube.filter('mp4')[-1]
                        video.download(film_directory_name)
                        successful_trailer_downloads += 1
                        break
                    except:
                        eg.PrintError(
                            '{0} - {1}'.format(film_name, trailer_url)
                        )
                        traceback.print_exc()
                else:
                    failed_trailer_downloads += 1

    eg.Print(
        'Emby thinks %d Films are Missing Trailers' % questionable_trailers
    )
    eg.Print('%d Films Actually Missing Trailers' % missing_trailers)
    eg.Print('Downloaded %d Trailers' % successful_trailer_downloads)
    eg.Print('Unable to Download %d Trailers' % failed_trailer_downloads)

If you like the work I have been doing then feel free to Image

User avatar
kgschlosser
Site Admin
Posts: 5146
Joined: Fri Jun 05, 2015 5:43 am
Location: Rocky Mountains, Colorado USA

Re: Importing python libraries to run script but which libraries?

Post by kgschlosser » Fri May 11, 2018 8:25 am

OK so i mapped out the whole Emby API

The code block below shows how the layout is

Code: Select all

API TYPE
    http method {get, post} url suffix
        [optional parameters]
anything that you see in curly braces {} is a required item.
if the required item is simply {id} then the id for that API grouping is required. in the example below the id that is needed is the "item id"

Code: Select all

get Items/{id}/PlaybackInfo
if a grouping needs the user id then that will be specified as {user_id}

Code: Select all

get Notifications/{user_id}/Summary
if there is a grouping id and also another id that is needed then they will be identified as such

Code: Select all

get Users/{user_id}/Items/{item_id}

Code: Select all

                Shows
                    get Shows/{series_id}/Seasons 
                        [UserId, Fields, IsMissing, IsVirtualUnaired, IsSpecialSeason]
                    get Shows/{series_id}/Episodes 
                        [UserId, Fields, Limit, StartIndex, Season, SeasonId, StartItemId, IsMissing, IsVirtualUnaired]
                    get Shows/Upcoming 
                        [UserId, Fields, ImageTypeLimit, EnableImageTypes, EnableImages, StartIndex, Limit]

                MetaData
                    get Persons
                    get Genres
                    get Studios
                    get Artists
                    get Artists/AlbumArtists

                Users
                    get Users 
                        [IsHidden, IsDisabled]
                    get Users/Public
                    get Users/{id}
                    get Users/{id}/Views
                    get Users/{id}/Items/Root
                    get Users/{user_id}/Items/{item_id}
                    get Users/{user_id}/Items/{item_id}/SpecialFeatures
                    get Users/{user_id}/Items/{item_id}/LocalTrailers
                    get Users/{user_id}/Items/{item_id}/Intros

                Localization
                    get Localization/Countries
                    get Localization/Cultures
                    get Localization/ParentalRatings

                Plugins
                    get Plugins

                System
                    post System/Restart
                    get System/Info
                    get System/Info/Public
                    get System/Configuration
                    get System/Configuration/devices
                    get System/Endpoint

                ScheduledTasks
                    get ScheduledTasks
                    get ScheduledTasks/{id}

                DisplayPreferences
                    get DisplayPreferences/{id}

                Notifications
                    get Notifications/{user_id} 
                        [ItemIds, StartIndex, Limit]
                    post Notifications/{user_id}/Read 
                        [Ids]
                    post Notifications/{user_id}/Unread  
                        [Ids]
                    get Notifications/{user_id}/Summary

                Search
                    get Search/Hints 
                        [MediaTypes, IsSports, IsSeries, IsNews, IsMovie, IsKids, IncludeItemTypes,
                         ExcludeItemTypes, IncludeStudios, IncludePeople, IncludeMedia, IncludeGenres, 
                         IncludeArtists, Limit, StartIndex, ParentId, UserId, SearchTerm]
                         
                Games
                    get Games/PlayerIndex 
                        [UserId]
                    get Games/SystemSummaries

                Movies
                    get Movies/Recommendations 
                        [Fields, CategoryLimit, ItemLimit, ParentId, UserId]

                LiveStream
                    post OpenLiveStream

                Items
                    Optional parameters available to all of the Items API
                        [AiredDuringSeason, IsVirtualUnaired, IsUnaired, IsMissing, ExcludeLocationTypes, LocationTypes, 
                        AlbumArtistStartsWithOrGreater, NameStartsWithOrGreater,  MaxPlayers, MinPlayers, 
                        MinCommunityRating, MinCriticRating, SearchTerm, HasParentalRating, IsHD, ParentIndexNumber, 
                        Years, PersonTypes, PersonIds, IsInBoxSet, IsPlayed, ArtistIds, IncludeItemTypes, ExcludeItemTypes,
                        StudioIds, Ids, Genres, MediaTypes, CollapseBoxSetItems, ImageTypeLimit, EnableImageTypes,
                        EnableImages, MinIndexNumber, Recursive, MaxOfficialRating, MinOfficialRating, AirDays, VideoTypes, 
                        Is3D, ImageTypes, Filters, Fields, SeriesStatuses, SortOrder, EnableTotalRecordCount, SortBy, Limit,
                        StartIndex, ParentId, InheritFromParent, UserId]

                    get Items 
                    get Items/Counts
                    get Items/YearIndex
                    get Items/{id}/PlaybackInfo
                    get Items/{id}/CriticReviews
                    get Items/{id}/ThemeVideos
                    get Items/{id}/ThemeSong
                    get Items/{id}/ThemeMedia

                Sessions
                    get Sessions
                        [ControllableByUserId, DeviceId]
                    post Sessions/Capabilities/Full
                    post Sessions/{id}/Playing/{Stopped, }
                    post Sessions/Playing/Progress
                    post Sessions/Logout
                    post Sessions/{id}/Playing 
                        [ItemIds, StartPositionTicks, PlayCommand]
                        
                    post Sessions/{id}/Command
                        [SetVolume 
                            [Volume]
                        SetSubtitleStreamIndex 
                            )[Index]
                        SetAudioStreamIndex 
                            [Index]
                        SendString 
                            [String]
                        DisplayMessage 
                            [Header, Text, Timeout]
                        DisplayContent
                            [ItemType, ItemId, ItemName]
                        MoveUp
                        MoveDown
                        MoveLeft
                        MoveRight
                        PageUp
                        PageDown
                        PreviousLetter
                        NextLetter
                        ToggleOsd
                        ToggleContextMenu
                        Select
                        Back
                        SendKey
                        GoHome
                        GoToSettings
                        VolumeUp
                        VolumeDown
                        Mute
                        Unmute
                        ToggleMute
                        GoToSearch
                        SetRepeatMode
                        ChannelUp
                        ChannelDown
                        PlayMediaSource]

                Videos
                    get Videos/{id}/AdditionalParts
                        [UserId]

                Channels
                    get Channels/{id}/Features
                    get Channels/{id}/Items
                        [SortOrder, SortBy, Filters, Fields, FolderId, Limit, StartIndex, UserId]
                    get Channels
                        [IsFavorite, Limit, StartIndex, SupportsLatestItems, UserId]

                LiveTv
                    get LiveTv/Info
                    get LiveTv/GuideInfo
                    get LiveTv/Recordings
                        [UserId, UserId, GroupId, Id, SeriesTimerId, IsInProgress, StartIndex, Limit, EnableTotalRecordCount]
                    get LiveTv/Recordings/{id}
                        [userId]
                    get LiveTv/Recordings/Groups
                        [UserId]
                    get LiveTv/Recordings/Groups/{id}
                        [userId]
                    get LiveTv/Channels 
                       [UserId, StartIndex, Limit, IsFavorite, IsLiked, IsDisliked, EnableFavoriteSorting, ChannelType]
                    get LiveTv/Channels/{id} [userId]
                    get LiveTv/Programs 
                        [ChannelIds, EnableTotalRecordCount, UserId, MinStartDate, MinEndDate, MaxStartDate, MaxEndDate]
                    get LiveTv/Programs/{id}
                        [userId]
                    get LiveTv/Programs/Recommended 
                       [EnableTotalRecordCount, IsAiring, HasAired, Limit, UserId]
If you like the work I have been doing then feel free to Image

jachin99
Experienced User
Posts: 612
Joined: Sat Feb 13, 2016 8:39 pm

Re: Importing python libraries to run script but which libraries?

Post by jachin99 » Fri May 11, 2018 3:28 pm

Thanks again but I have a few questions about the directories. For emby source directory, this would be the network location I have pointed emby to for my movies library correct? For the destination directory, each found trailer should go somewhere different, I.E. nested inside of that movie's folder. Would I still use the network location of my movie library, and let this script find the correct folder to put each trailer in or do I need a variable for that value because each destination will be different? I ran the latest trailer script to see what happens, and got this error message BUT EG gives log events that find the name of the PC, the address/port, and the GUID correctly:

Code: Select all

   Traceback (most recent call last):
     Python script "2", line 57, in <module>
       response = requests.get(session_url, headers=headers, params=params)
     File "C:\Program Files (x86)\EventGhost\lib27\site-packages\requests\api.py", line 71, in get
       return request('get', url, params=params, **kwargs)
     File "C:\Program Files (x86)\EventGhost\lib27\site-packages\requests\api.py", line 57, in request
       return session.request(method=method, url=url, **kwargs)
     File "C:\Program Files (x86)\EventGhost\lib27\site-packages\requests\sessions.py", line 461, in request
       prep = self.prepare_request(req)
     File "C:\Program Files (x86)\EventGhost\lib27\site-packages\requests\sessions.py", line 394, in prepare_request
       hooks=merge_hooks(request.hooks, self.hooks),
     File "C:\Program Files (x86)\EventGhost\lib27\site-packages\requests\models.py", line 295, in prepare
       self.prepare_url(url, params)
     File "C:\Program Files (x86)\EventGhost\lib27\site-packages\requests\models.py", line 349, in prepare_url
       raise InvalidURL(*e.args)
   InvalidURL: Failed to parse: 192.168.29.195:8096\Sessions

User avatar
kgschlosser
Site Admin
Posts: 5146
Joined: Fri Jun 05, 2015 5:43 am
Location: Rocky Mountains, Colorado USA

Re: Importing python libraries to run script but which libraries?

Post by kgschlosser » Fri May 11, 2018 7:07 pm

here is a new version of the script.

this version should properly handle network paths. you were having an issue because the original author didn't have enough forward thinking to realize that replacing any \'s in the path would cause issue if the drive is a network path. there is no need to do this because the os module handles all of that stuff internally as was an unnecessary thing to do. On windows a network path starts with \\ so by replacing them is probably what caused you some issues.

Also i believe his use of the username and not the user id to obtain the films list was incorrect. I have changed this

It handles all of the directory BS and the user name as well. all you need do it enter the API key. it will properly place the trailer file where it needs to go with the proper filename.

DVD rips and BD rips the trailers have to be handled differently. and this is taken care of.

I removed the entry of the username. as this is no longer needed. the script obtains a list of users from the server. and in that list are the id's of the users. and I am able to query the server for movies associated with each individual user.

I also added one other check to see if the movie is located on the file system. and if it is not then to continue along it's merry way.

Code: Select all

# only the API key is needed

emby_api_key = 'API KEY'


import requests
import os
import traceback
import socket
import json
from uuid import uuid4 as GUID
from pytube import YouTube


client_id = str(GUID())

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, True)
sock.settimeout(2.0)
broadcast_address = ('255.255.255.255', 7359)
sock.sendto('who is EmbyServer?', broadcast_address)
sock.settimeout(2.0)

try:
    data = sock.recv(4096)
except socket.timeout:
    eg.PrintError('Could not find an Emby Server')
    eg.StopMacro()
    eg.Exit()

data = json.loads(data.decode('utf-8'))

eg.Print('Found Emby Server')
eg.Print('Name: ' + data['Name'])
eg.Print('Address: ' + data['Address'])
eg.Print('Id: ' + data['Id'])

headers = {
    'Content-Type': "application/json",
    'Accept':       "application/json",
    'x-emby-authorization': 'MediaBrowser',
    'Client':               'EmbyTrailers',
    'Device':               'Python Script',
    'DeviceId':             client_id,
    'Version':              '1.0.0.0',
}

emby_url = data['Address']

If 'http' not in emby_url.lower():
    emby_url = 'http:\\' + emby_url
session_url = '{0}\Sessions'.format(emby_url)
params = dict(api_key=emby_api_key)

try:
    response = requests.get(session_url, headers=headers, params=params)
except requests.HTTPError:
    traceback.print_exc()
    eg.StopMacro()
    eg.Exit()
    
    
params.update(dict(DeviceId=client_id, Format='json'))

users_url = '{emby_url}/Users'.format(emby_url=emby_url)
items_url = '{emby_url}/Items'.format(emby_url=emby_url)

log_output = 'Emby Trailer Download Stats\n'

try:
    response = requests.get(users_url, headers=headers, params=params)
    users = response.json()
except requests.HTTPError:
    traceback.print_exc()
    eg.StopMacro()
    eg.Exit()
except ValueError:
    print response.status_code
    print response
    eg.StopMacro()
    eg.Exit()
else:
    params.update(
        dict(
            IncludeItemTypes='Movie',
            Recursive=True,
            StartIndex=0,
            Fields='RemoteTrailers, Path'
        )
    )
    
    for user in users:
        params['UserId'] = user['Id']
        try:
            response = requests.get(
                items_url, 
                headers=headers,
                params=params
            )
            films = response.json()
        except requests.HTTPError:
            traceback.print_exc()
            eg.StopMacro()
            eg.Exit()
        except ValueError:
            print response.status_code
            print response
            eg.StopMacro()
            eg.Exit()
        else:
            questionable_trailers = 0
            missing_trailers = 0
            successful_trailer_downloads = 0
            failed_trailer_downloads = 0
            for film in films['Items']:
                if not film['LocationType'] == 'FileSystem':
                    continue
                    
                if film['LocalTrailerCount'] == 0:
                    questionable_trailers += 1
        
                    film_path = film['Path'].encode('utf-8')
        
                    film_file_name = os.path.basename(film_path)
                    film_directory_name = os.path.dirname(film_path)
                    film_name = os.path.splitext(film_file_name)[0]
                    if film_name[-3:-1] == 'CD':
                        film_name = film_name[:-4]
        
                    def download_trailer(trailer_file_name):
                        global missing_trailers
                        global successful_trailer_downloads
                        global failed_trailer_downloads
        
                        missing_trailers += 1
                        for trailer in film['RemoteTrailers']:
                            trailer_url = trailer['Url'].encode('utf-8')
                            
                            try:
                                you_tube = YouTube(trailer_url)
                                you_tube.set_filename(trailer_file_name)
                                video = you_tube.filter('mp4')[-1]
                                video.download(film_directory_name)
                                successful_trailer_downloads += 1
                                break
                            except:
                                eg.PrintError(
                                    '{0} - {1}'.format(film_name, trailer_url)
                                )
                                traceback.print_exc()
                        else:
                            failed_trailer_downloads += 1
        
                    film_directory_contents = os.listdir(film_directory_name)
        
                    if (
                        'VIDEO_TS' in film_directory_contents or
                        'BDMV' in film_directory_contents
                    ):
                        film_directory_name = os.path.join(
                            film_directory_name,
                            'trailers'
                        )
                        if not os.path.exists(film_directory_name):
                            os.mkdir(film_directory_name)
        
                        for f in os.listdir(film_directory_name):
                            if f.startswith('trailer'):
                                break
                        else:
                            download_trailer('trailer')
        
                    else:
                        for f in os.listdir(film_directory_name):
                            if f.startswith(film_name + '-trailer'):
                                break
                        else:
                            download_trailer(film_name + '-trailer')
        
            film_output_template = (
                'User: {0}\n'
                '    Reported Download Count: {1}\n'
                '    Actual Download Count: {2}\n'
                '    Successful Downloads: {3}\n'
                '    Failed Downloads: {4}\n\n'
            )
            log_output += film_output_template.format(
                user.Name,
                questionable_trailers,
                missing_trailers,
                successful_trailer_downloads,
                failed_trailer_downloads
            )
            
eg.Print(log_output)
     
If you like the work I have been doing then feel free to Image

jachin99
Experienced User
Posts: 612
Joined: Sat Feb 13, 2016 8:39 pm

Re: Importing python libraries to run script but which libraries?

Post by jachin99 » Wed May 16, 2018 12:48 am

I finally had time to post my newest error.

Code: Select all

Traceback (most recent call last):
        Python script "0", line 53, in <module>
          response = requests.get(session_url, headers=headers, params=params)
        File "C:\Program Files (x86)\EventGhost\lib27\site-packages\requests\api.py", line 71, in get
          return request('get', url, params=params, **kwargs)
        File "C:\Program Files (x86)\EventGhost\lib27\site-packages\requests\api.py", line 57, in request
          return session.request(method=method, url=url, **kwargs)
        File "C:\Program Files (x86)\EventGhost\lib27\site-packages\requests\sessions.py", line 461, in request
          prep = self.prepare_request(req)
        File "C:\Program Files (x86)\EventGhost\lib27\site-packages\requests\sessions.py", line 394, in prepare_request
          hooks=merge_hooks(request.hooks, self.hooks),
        File "C:\Program Files (x86)\EventGhost\lib27\site-packages\requests\models.py", line 295, in prepare
          self.prepare_url(url, params)
        File "C:\Program Files (x86)\EventGhost\lib27\site-packages\requests\models.py", line 349, in prepare_url
          raise InvalidURL(*e.args)
      InvalidURL: Failed to parse: 192.168.29.195:8096\Sessions

User avatar
kgschlosser
Site Admin
Posts: 5146
Joined: Fri Jun 05, 2015 5:43 am
Location: Rocky Mountains, Colorado USA

Re: Importing python libraries to run script but which libraries?

Post by kgschlosser » Wed May 16, 2018 2:42 am

I updated the script. So try it again. This time let me know what prints out in the log.
If you like the work I have been doing then feel free to Image

jachin99
Experienced User
Posts: 612
Joined: Sat Feb 13, 2016 8:39 pm

Re: Importing python libraries to run script but which libraries?

Post by jachin99 » Wed May 16, 2018 4:22 pm

It looks like its getting right past your header declaration, and then throwing an error. Here is a copy

Code: Select all

   Error compiling script.
   Traceback (most recent call last):
   SyntaxError: invalid syntax (13, line 51)


Around line 51 there is this bit of code

Code: Select all

emby_url = data['Address']

If 'http' not in emby_url.lower():
    emby_url = 'http:\\' + emby_url
session_url = '{0}\Sessions'.format(emby_url)
params = dict(api_key=emby_api_key)
Line 51 on my text editor starts the if http statement, and for clarity, I'm using this script

Code: Select all

emby_api_key = 'API KEY'

import requests
import os
import traceback
import socket
import json
from uuid import uuid4 as GUID
from pytube import YouTube


client_id = str(GUID())

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, True)
sock.settimeout(2.0)
broadcast_address = ('255.255.255.255', 7359)
sock.sendto('who is EmbyServer?', broadcast_address)
sock.settimeout(2.0)

try:
    data = sock.recv(4096)
except socket.timeout:
    eg.PrintError('Could not find an Emby Server')
    eg.StopMacro()
    eg.Exit()

data = json.loads(data.decode('utf-8'))

eg.Print('Found Emby Server')
eg.Print('Name: ' + data['Name'])
eg.Print('Address: ' + data['Address'])
eg.Print('Id: ' + data['Id'])

headers = {
    'Content-Type': "application/json",
    'Accept':       "application/json",
    'x-emby-authorization': 'MediaBrowser',
    'Client':               'EmbyTrailers',
    'Device':               'Python Script',
    'DeviceId':             client_id,
    'Version':              '1.0.0.0',
}

emby_url = data['Address']

If 'http' not in emby_url.lower():
    emby_url = 'http:\\' + emby_url
session_url = '{0}\Sessions'.format(emby_url)
params = dict(api_key=emby_api_key)

try:
    response = requests.get(session_url, headers=headers, params=params)
except requests.HTTPError:
    traceback.print_exc()
    eg.StopMacro()
    eg.Exit()
    
    
params.update(dict(DeviceId=client_id, Format='json'))

users_url = '{emby_url}/Users'.format(emby_url=emby_url)
items_url = '{emby_url}/Items'.format(emby_url=emby_url)

log_output = 'Emby Trailer Download Stats\n'

try:
    response = requests.get(users_url, headers=headers, params=params)
    users = response.json()
except requests.HTTPError:
    traceback.print_exc()
    eg.StopMacro()
    eg.Exit()
except ValueError:
    print response.status_code
    print response
    eg.StopMacro()
    eg.Exit()
else:
    params.update(
        dict(
            IncludeItemTypes='Movie',
            Recursive=True,
            StartIndex=0,
            Fields='RemoteTrailers, Path'
        )
    )
    
    for user in users:
        params['UserId'] = user['Id']
        try:
            response = requests.get(
                items_url, 
                headers=headers,
                params=params
            )
            films = response.json()
        except requests.HTTPError:
            traceback.print_exc()
            eg.StopMacro()
            eg.Exit()
        except ValueError:
            print response.status_code
            print response
            eg.StopMacro()
            eg.Exit()
        else:
            questionable_trailers = 0
            missing_trailers = 0
            successful_trailer_downloads = 0
            failed_trailer_downloads = 0
            for film in films['Items']:
                if not film['LocationType'] == 'FileSystem':
                    continue
                    
                if film['LocalTrailerCount'] == 0:
                    questionable_trailers += 1
        
                    film_path = film['Path'].encode('utf-8')
        
                    film_file_name = os.path.basename(film_path)
                    film_directory_name = os.path.dirname(film_path)
                    film_name = os.path.splitext(film_file_name)[0]
                    if film_name[-3:-1] == 'CD':
                        film_name = film_name[:-4]
        
                    def download_trailer(trailer_file_name):
                        global missing_trailers
                        global successful_trailer_downloads
                        global failed_trailer_downloads
        
                        missing_trailers += 1
                        for trailer in film['RemoteTrailers']:
                            trailer_url = trailer['Url'].encode('utf-8')
                            
                            try:
                                you_tube = YouTube(trailer_url)
                                you_tube.set_filename(trailer_file_name)
                                video = you_tube.filter('mp4')[-1]
                                video.download(film_directory_name)
                                successful_trailer_downloads += 1
                                break
                            except:
                                eg.PrintError(
                                    '{0} - {1}'.format(film_name, trailer_url)
                                )
                                traceback.print_exc()
                        else:
                            failed_trailer_downloads += 1
        
                    film_directory_contents = os.listdir(film_directory_name)
        
                    if (
                        'VIDEO_TS' in film_directory_contents or
                        'BDMV' in film_directory_contents
                    ):
                        film_directory_name = os.path.join(
                            film_directory_name,
                            'trailers'
                        )
                        if not os.path.exists(film_directory_name):
                            os.mkdir(film_directory_name)
        
                        for f in os.listdir(film_directory_name):
                            if f.startswith('trailer'):
                                break
                        else:
                            download_trailer('trailer')
        
                    else:
                        for f in os.listdir(film_directory_name):
                            if f.startswith(film_name + '-trailer'):
                                break
                        else:
                            download_trailer(film_name + '-trailer')
        
            film_output_template = (
                'User: {0}\n'
                '    Reported Download Count: {1}\n'
                '    Actual Download Count: {2}\n'
                '    Successful Downloads: {3}\n'
                '    Failed Downloads: {4}\n\n'
            )
            log_output += film_output_template.format(
                user.Name,
                questionable_trailers,
                missing_trailers,
                successful_trailer_downloads,
                failed_trailer_downloads
            )
            
eg.Print(log_output)
     



     


User avatar
kgschlosser
Site Admin
Posts: 5146
Joined: Fri Jun 05, 2015 5:43 am
Location: Rocky Mountains, Colorado USA

Re: Importing python libraries to run script but which libraries?

Post by kgschlosser » Wed May 16, 2018 6:10 pm

change the line

Code: Select all

If 'http' not in emby_url.lower():
to

Code: Select all

if 'http' not in emby_url.lower():

sorry about that. I made the change when i was on my cellphone and those things like to capitalize every new line. I didn't catch it.
If you like the work I have been doing then feel free to Image

jachin99
Experienced User
Posts: 612
Joined: Sat Feb 13, 2016 8:39 pm

Re: Importing python libraries to run script but which libraries?

Post by jachin99 » Wed May 16, 2018 7:53 pm

Here is this next error

Code: Select all

   Traceback (most recent call last):
     Python script "3", line 56, in <module>
       response = requests.get(session_url, headers=headers, params=params)
     File "C:\Program Files (x86)\EventGhost\lib27\site-packages\requests\api.py", line 71, in get
       return request('get', url, params=params, **kwargs)
     File "C:\Program Files (x86)\EventGhost\lib27\site-packages\requests\api.py", line 57, in request
       return session.request(method=method, url=url, **kwargs)
     File "C:\Program Files (x86)\EventGhost\lib27\site-packages\requests\sessions.py", line 461, in request
       prep = self.prepare_request(req)
     File "C:\Program Files (x86)\EventGhost\lib27\site-packages\requests\sessions.py", line 394, in prepare_request
       hooks=merge_hooks(request.hooks, self.hooks),
     File "C:\Program Files (x86)\EventGhost\lib27\site-packages\requests\models.py", line 295, in prepare
       self.prepare_url(url, params)
     File "C:\Program Files (x86)\EventGhost\lib27\site-packages\requests\models.py", line 349, in prepare_url
       raise InvalidURL(*e.args)
   InvalidURL: Failed to parse: 192.168.29.195:8096\Sessions
Line 56 reads

Code: Select all

response = requests.get(session_url, headers=headers, params=params)
Around line 56 is this

Code: Select all

if 'http' not in emby_url.lower():
    emby_url = 'http:\\' + emby_url
session_url = '{0}\Sessions'.format(emby_url)
params = dict(api_key=emby_api_key)

try:
    response = requests.get(session_url, headers=headers, params=params)
except requests.HTTPError:
    traceback.print_exc()
    eg.StopMacro()
    eg.Exit()
    

Post Reply