7
\$\begingroup\$

I have my movie folders formatted:

  1. ~: no sub included

  2. {}: already watched

  3. nothing: sub included, ready to watch

the program asks for the movie directory; extracts the name and searches IMDb for the name; renames the given directory to the first IMDb search result.

finally saves what you'd see when the first result is clicked as a .html file in the given directory. Example

import urllib
import requests
import os
import re
from bs4 import BeautifulSoup

# write response page in tmp.html
def movNameSearch(path, movie):
    print('Fetching...\n')
    url = "https://www.imdb.com/find?ref_=nv_sr_fn&q=" + movie + "&s=tt"
    response = requests.get(url) #get response
    resTxt = response.text
    soup = BeautifulSoup(resTxt, 'html.parser') #parsed response
    findList = soup.find_all('td', class_ = 'result_text') #all founded movies
    someList = []
    for i in range(10):
        theRes = findList[i].contents[1].contents[0] + findList[i].contents[2]
        someList.append(theRes)

    for j in range(len(someList)):
        print(str(j+1) + '. ' + someList[j])

    selection = int(input('\nWhich is the desired result? '))
    rec = findList[selection-1].contents #first found result - recommended
    recText = rec[1].contents[0] #movie name
    fullName = recText + rec[2] #movie year
    suggestion = 'Confirm ' + fullName + '? (y/n) '
    accept = input(suggestion)
    if accept == 'y':
        print('Renaming the folder...')
        #rename folder
        pathArray = path.split(sep='/')
        if pathArray[-1] == '': # / at the end
            pathArray.pop()
            pathArray.pop()
        else: #no / at the end
            pathArray.pop()
        pathArray.append(fullName)
        src = path
        dst = '/'.join(pathArray)
        os.rename(src, dst)
        print('Renamed to ' + fullName)

        #generate info into info.txt
        imdbUrl = 'https://www.imdb.com'
        toAdd = list(rec[1].parent.contents[1].attrs.values())[0]
        imdbUrl = imdbUrl + toAdd
        result = [imdbUrl, dst]
        return result
    else:
        print('K bye')


def getInfo(url, path):
    print('Fetching extra info...')
    response = requests.get(url)
    resTxt = response.text
    soup = BeautifulSoup(resTxt, 'html.parser')
    print('Generating extra info...')
    f = open(path + '/info.html', 'w+')
    f.write(resTxt)
    print('Complete.')
    return True

#/home/name/some/~{}folder
# open directory =>
# get path 
mainPath = str(input("Enter movie directory: "))
movName = re.split("/", mainPath)
if movName[-1] == '':
    movName = movName[-2]
else:
    movName = movName[-1]

# remove extra chars
movName = re.sub("[~{}]", "", movName).capitalize()


# check
accept = input("Confirm " + movName + " ? (y/n) ")
if accept == "y":
    result = movNameSearch(mainPath, movName)
    if len(result) == 2:
        stat = getInfo(result[0], result[1])
        if stat == True:
            print('Success! Quitting now.')
    else:
        print('K Bye')

else:
    print("K bye")
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Wouldn't it be easier to have an imdb.txt and a watched.txt in each folder? \$\endgroup\$
    – C. Harley
    Commented May 10, 2020 at 17:00

1 Answer 1

1
\$\begingroup\$

Things I would change:

  1. The code is not written in Python conventions - functions names need to be with underscore like mov_name_search, get_info and also the variables need to be with underscore.

  2. Function too big/complex - I think that movNameSearch is too big and needs to be separated into a number of functions; this will ease the reading of the code and will allow better unit testing.

  3. Move the code that is not in function to a function - most of the code needs to be in a function, so it will be easier for testing and understanding.

  4. Use type hinting - read about it in Google, this will allow linter & IDE to detect errors and will also make the code easier to read.

  5. String concatenation - in most case it's recommended to use f-string, so:

     "part one " + str(num) + " part two"
    

    will be:

     f"part one {num} part two"
    

    There is an exception for the case where the string will not always be needed like:

     if error:
         logger.error("part one %i part two", num)
    
  6. Don't do string concatenation on a URL - use a URL builder.

  7. Check for errors and communicate them - Your need to check for error/unexpected data in cases like:

     requests.get
    
     soup.find_all
    

    and others. Log the errors.

There are more, but start with those.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.