2015-04-07 136 views
0

我正在嘗試編寫一個程序來解析和加載我在我的媒體集合中的文件。這個程序將被給予一個目錄,並將開始遞歸掃描並將所有媒體文件(目前只是電視節目)放在一個列表中。我目前遇到的問題是它正確讀取所有文件名和位置。但是,當將信息存儲在列表中時,季節和劇集的信息是錯誤的。季節信息有點正確,因爲它顯示正確的季節數量,但季節數字是錯誤的。這些情節完全錯誤。當只有一個節目被讀入列表時,它會正確讀取所有內容。Python追加一個類到列表

在最後我縮小了我的問題,並嘗試使它更簡單。

例如,當我只在一個節目中閱讀時,這是我打印出列表時得到的內容。

0) Stargate Atlantis 
    -1) Exit 
    What show do you want to look at? 
    0 
    0) Season 2 
    1) Season 4 
    2) Season 1 
    3) Season 3 
    4) Season 5 
    -1) Exit 
    What season do you want to look at? 
    2 
    0) Stargate Atlantis - S05e16 - Brain Storm.mkv 
    1) Stargate Atlantis - S05e17 - Infection.mkv 
    2) Stargate Atlantis - S05e18 - Identity.mkv 
    3) Stargate Atlantis - S05e19 - Vegas.mkv 
    4) Stargate Atlantis - S05e20 - Enemy At The Gate.mkv 
    5) Stargate Atlantis - S05e01 - Search And Rescue.mkv 
    6) Stargate Atlantis - S05e02 - The Seed.mkv 
    7) Stargate Atlantis - S05e03 - Broken Ties.mkv 
    8) Stargate Atlantis - S05e04 - The Daedalus Variations.mkv 
    9) Stargate Atlantis - S05e05 - Ghost In The Machine.mkv 
    10) Stargate Atlantis - S05e06 - The Shrine.mkv 
    11) Stargate Atlantis - S05e07 - Whispers.mkv 
    12) Stargate Atlantis - S05e08 - The Queen.mkv 
    13) Stargate Atlantis - S05e09 - Tracker.mkv 
    14) Stargate Atlantis - S05e10 - First Contact.mkv 
    15) Stargate Atlantis - S05e11 - The Lost Tribe.mkv 
    16) Stargate Atlantis - S05e12 - Outsiders.mkv 
    17) Stargate Atlantis - S05e13 - Inquisition.mkv 
    18) Stargate Atlantis - S05e14 - The Prodigal.mkv 
    19) Stargate Atlantis - S05e15 - Remnants.mkv 
    -1) Exit 
    What episode do you want to look at? 

除了事實os.walk半讀取它們之外,一切都很好。但是當我閱讀更多的電視節目時,它開始搞砸了。這是當我在兩個電視節目中閱讀時發生的事情。

0) Stargate Atlantis 
1) Brooklyn Nine-Nine 
-1) Exit 
What show do you want to look at? 
0 # I selected option 0 (Stargate Atlantis) 
0) Season 1 
1) Season 2 
2) Season 1 
3) Season 3 
4) Season 5 
-1) Exit 
What season do you want to look at? 
0 
0) Brooklyn Nine-Nine - S02E02 - Chocolate Milk.mp4 
1) Brooklyn Nine-Nine - S02E01 - Undercover.mp4 
2) Brooklyn Nine-Nine - S02E04 - Halloween II.mp4 
3) Brooklyn Nine-Nine - S02E03 - The Jimmy Jab Games.mp4 
4) Brooklyn Nine-Nine - S01E01 - Pilot.mkv 
5) Brooklyn Nine Nine - S01E02 - HDTV x264 LOL.mp4 
6) Brooklyn Nine Nine - S01E04 - HDTV x264 LOL.mp4 
7) Brooklyn Nine Nine - S01E07 - 480p HDTV x264mSD.mkv 
8) Brooklyn Nine Nine - S01E08 - 480p HDTV x264mSD.mkv 
9) Brooklyn Nine Nine - S01E09 - 480p HDTV x264mSD.1.2.mkv 
10) Brooklyn Nine Nine - S01E10 - 480p HDTV x264mSD.1.mkv 
11) Brooklyn Nine Nine - S01E11 - 480p HDTV x264mSD.1.2.mkv 
12) Brooklyn Nine-Nine - S01E18 - HDTV x264 KILLERS.mp4 
13) Brooklyn Nine-Nine - S01E13 - HDTV x264 EXCELLENCE.mp4 
14) Brooklyn Nine-Nine - S01E14 - HDTV x264 EXCELLENCE.mp4 
15) Brooklyn Nine-Nine - S01E15 - HDTV x2642HD.mp4 
16) Brooklyn Nine-Nine - S01E16 - REAL HDTV x264 EXCELLENCE.mp4 
17) Brooklyn Nine-Nine - S01E17 - PROPER HDTV x264KILLERS.mp4 
18) Brooklyn Nine-Nine - S01E19 - HDTV x2642HD.mp4 
19) Brooklyn Nine-Nine - S01E20 - PROPER HDTV x2642HD.mp4 
20) Brooklyn Nine-Nine - S01E21 - HDTV x264EXCELLENCE.mp4 
21) Brooklyn Nine-Nine - S01E22 - HDTV x264EXCELLENCE.mp4 
22) NULL 
23) NULL 
24) NULL 
25) NULL 
26) NULL 
27) NULL 
28) NULL 
29) NULL 
30) NULL 
31) NULL 
32) NULL 
33) NULL 
34) NULL 
35) NULL 
36) NULL 
37) NULL 
38) NULL 
39) NULL 
40) NULL 
41) NULL 
42) NULL 
-1) Exit 
What episode do you want to look at? 

有一次,我在更多的電視增加表明事情變得更糟,如果我嘗試查看的第一個賽季它通常會上升到433選項,並用90%的人是NULL。

這是現在

__author__ = "michael" 
import socket, thread, os, time, tvdb_api 

host = "127.0.0.1" 
port = 9876 
connections = 0 


class media(): 
    tv = [] 
    index = {} 
    budget = 0 
    numoftvshows = 0 
    exit = 0 
    # add existing will not add any files that contain these extensions 
    ignore_list = [".html", ".url", ".txt", ".db", ".srt", ".jpg", ".png", ".docx", ".doc", ".rar", ".zip", ".tar", ".7z", ".dat", ".bmp", ".gif", ".psd", ".tga", ".tif", ".pdf", ".xlr", ".xls", ".xlsx", ".jar", ".exe", ".sav", ".rom", ".php", ".part", ".crdownload", ".msi", ".torrent", ".idx", ".sub", ".nfo"] 


class Tvshows(): 
    name = 'NULL' 
    seasons = [] 
    curseason = 0 
    numofseasons = 0 
    nextep = 0 
    showstat = 0 
    rootdir = 'NULL' 


class Seas(): 
    exist = 0 
    complete = 0 
    episodes = [] 
    numofeps = 0 
    realnum = 1 


class epi(): 
    releasedate = [] 
    status = 0 
    filename = 'NULL' 
    realnum = 0 


def initiliazer(mdata): 
    # setting counter variables to 0 
    i = 0 
    j = 0 
    # checks to see if data file is empty 
    # if data file is empty skips loading and goes to menu 
    if os.stat("tvdata.dat").st_size == 0: 
     print "tvdata.dat is empty skipping load" 
     return mdata 
    else: 
     # opens files and uses '|' as a delimeter 
     print "Loading data please wait...." 
     file = open("tvdata.dat", "rw") 
     for line in file: 
      fields = line.split('|') 
      # appends a new show everytime a new one is found 
      mdata.tv.append(Tvshows()) 
      mdata.numoftvshows += 1 
      mdata.tv[j].name = fields[i] 
      mdata.index[mdata.tv[j].name] = j 
      i += 1 
      mdata.tv[j].curseason = int(fields[i]) 
      i += 1 
      mdata.tv[j].numofseasons = int(fields[i]) 
      i += 1 
      mdata.tv[j].nextep = int(fields[i]) 
      i += 1 
      mdata.tv[j].showstat = int(fields[i]) 
      i += 1 
      mdata.tv[j].rootdir = fields[i] 
      i += 1 
      n = 0 
      while n < mdata.tv[j].numofseasons: 
       # appends a new season every time a new one is added 
       mdata.tv[j].seasons.append(Seas()) 
       mdata.tv[j].seasons[n].realnum = int(fields[i]) 
       i += 1 
       mdata.tv[j].seasons[n].numofeps = int(fields[i]) 
       i += 1 
       k = 0 
       while k < mdata.tv[j].seasons[n].numofeps: 
        # appends a new episode every time a new one is added 
        mdata.tv[j].seasons[n].episodes.append(epi()) 
        mdata.tv[j].seasons[n].episodes[k].filename = fields[i] 
        i += 1 
        mdata.tv[j].seasons[n].episodes[k].status = int(fields[i]) 
        i += 1 
        k += 1 
       n += 1 
      j += 1 
    print "Loading data complete" 
    file.close() 
    return mdata 


def printdata(mdata, client): 
    i = 0 
    while i < mdata.numoftvshows: 
     client.send(str(i)) 
     client.send(") ") 
     client.send(mdata.tv[i].name) 
     client.send("\n") 
     i += 1 
    client.send("-1) Exit\n") 
    client.send("What show do you want to look at?\n") 
    showpick = client.recv(4096) 
    showpick = showpick.rstrip() 
    if showpick == "-1": 
     return 
    showpick = int(showpick) 

    i = 0 
    while i < mdata.tv[showpick].numofseasons: 
     client.send(str(i)) 
     client.send(") Season ") 
     client.send(str(mdata.tv[showpick].seasons[i].realnum)) 
     client.send("\n") 
     i += 1 
    client.send("-1) Exit\n") 
    client.send("What season do you want to look at?\n") 
    seaspick = client.recv(4096) 
    seaspick = seaspick.rstrip() 
    if seaspick == "-1": 
     return 
    seaspick = int(seaspick) 

    i = 0 
    while i < mdata.tv[showpick].seasons[seaspick].numofeps - 1: 
     client.send(str(i)) 
     client.send(") ") 
     client.send(mdata.tv[showpick].seasons[seaspick].episodes[i].filename) 
     client.send("\n") 
     i += 1 
    client.send("-1) Exit\n") 
    client.send("What episode do you want to look at?\n") 
    epipick = client.recv(4096) 
    epipick = epipick.rstrip() 
    if epipick == -1: 
     return 
    return 
    epipick = int(epipick) 


def addexistshow(mdata, client): 
    nameofshow = ">>NULL<<" # added the >><< to make sure this never matches a show name 
    seascheck = "Season #" # makes sure this is not found by default 
    client.send("What directory are your files located in?\n") 
    workdir = client.recv(4096) 
    workdir = workdir.rstrip() 
    errnum = 0 
    k = -1 
    for cur, dir, filenames in os.walk(workdir): 
     rootdir = cur 
     if nameofshow not in cur and cur != workdir and cur[0] != '.': 
      strlen = len(workdir) 
      cur = cur[strlen:] 
      if cur[0] == '/': 
       cur = cur[1:] 
      mdata.tv.append(Tvshows()) 
      mdata.numoftvshows += 1 
      k += 1 
      mdata.tv[k].name = cur 
      nameofshow = cur 
      mdata.tv[k].rootdir = rootdir 
      i = -1 
      seascheck = "Season #" 
      client.send(cur) 
      client.send("\n") 
     elif seascheck not in cur and cur != workdir: 
      strlen = len(workdir + '/' + nameofshow + '/') 
      cur = cur[strlen:] 
      if cur != seascheck and "season" in cur.lower(): 
       i += 1 
       mdata.tv[k].seasons.append(Seas()) 
       mdata.tv[k].numofseasons += 1 
       mdata.tv[k].seasons[i].exist = 1 
       mdata.tv[k].seasons[i].realnum = int(cur[7:]) 
       seascheck = cur 
      if "season" in cur.lower(): 
       mdata.tv[mdata.numoftvshows - 1].seasons[i].realnum = int(seascheck[7:]) 
       mdata.tv[mdata.numoftvshows - 1].seasons[i].numofeps += 1 
       mdata.tv[mdata.numoftvshows - 1].seasons[i].exist = 1 
      client.send(cur) 
      client.send("\n") 
     if seascheck in cur: 
      j = 0 
      for line in filenames: 
       good = True 
       for ext in mdata.ignore_list: 
        if ext in line[-6:]: 
         good = False 
         client.send("[*] Skipping ") 
         client.send(ext) 
         client.send(" found in ") 
         client.send(line) 
         client.send("\n") 
       if good is True: 
        try: 
         #print "tv =", k, "season =", i, "episode =", j 
         mdata.tv[k].seasons[i].episodes.append(epi()) 
         epname = line.split(",") 
         realnumbuff = epname[0].split(" - ") 
         realnumbuff = int(realnumbuff[1][4:]) 
         mdata.tv[k].seasons[i].episodes[j].realnum = realnumbuff 
         mdata.tv[k].seasons[i].episodes[j].filename = epname[0] 
         mdata.tv[k].seasons[i].episodes[j].status = 1 
         mdata.tv[k].seasons[i].numofeps += 1 
         client.send(mdata.tv[k].seasons[i].episodes[j].filename) 
         client.send("\n") 
         if mdata.tv[k].seasons[i].episodes[j].filename == "Brooklyn Nine-Nine - S02E03 - The Jimmy Jab Games.mp4": 
          return mdata 
         j += 1 
        except Exception as e: 
         client.send("[!] Error as ") 
         client.send(str(e)) 
         client.send("\n") 
         errnum += 1 
    #print mdata.tv[9].name 
    #print mdata.tv[25].seasons[3].episodes[190].filename 
    if errnum > 0: 
     client.send("\n[!] WARNING - A total of ") 
     client.send(errnum) 
     client.send(" errors were encountered! This could cause problems proceed with caution.\n") 
    return mdata 


def writedatafile(mdata): 
    file = open("tvdata.da", "w") 
    for i in xrange(0, mdata.numoftvshows): 
     file.write(mdata.tv[i].name) 
     file.write("|") 
     file.write(str(mdata.tv[i].curseason)) 
     file.write("|") 
     file.write(str(mdata.tv[i].numofseasons)) 
     file.write("|") 
     file.write(str(mdata.tv[i].nextep)) 
     file.write("|") 
     file.write(str(mdata.tv[i].showstat)) 
     file.write("|") 
     file.write(mdata.tv[i].rootdir) 
     for j in xrange(0, mdata.tv[i].numofseasons): 
      file.write(str(mdata.tv[i].seasons[j].realnum)) 
      file.write("|") 
      file.write(str(mdata.tv[i].seasons[j].numofeps)) 
      file.write("|") 
      for k in xrange(0, mdata.tv[i].seasons[j].numofeps): 
       file.write(mdata.tv[i].seasons[j].episodes[k].filename) 
       file.write("|") 
       file.write(str(mdata.tv[i].seasons[j].episodes[k].status)) 
       file.write("|") 
    return mdata 


def addnewshow(mdata): 
    show = raw_input("What show do you want to add?\n") 



def menu(mdata, client): 
    client.send('----Media Get----\n\n') 
    client.send(' 1) Add a new show 2) Add an existing show\n') 
    client.send(' 3) Print Database 4) Rewrite data file\n') 
    client.send('-1) Exit Menu  -2) Exit program completely\n') 
    pick = client.recv(4096) 
    pick = pick.rstrip() 
    if pick == "1": 
     addnewshow(mdata) 
    elif pick == "2": 
     addexistshow(mdata, client) 
    elif pick == "3": 
     printdata(mdata, client) 
    elif pick == "4": 
     writedatafile(mdata) 
    elif pick == "-1": 
     mdata.exit = 1 
    elif pick == "-2": 
     mdata.exit = 1 
    return mdata 


def t_handle(client, address, s, mdata): 
    while mdata.exit != 1: 
     mdata = menu(mdata, client) 
    client.send("[*] closing connection\n") 
    client.close 
    time.sleep(2) 
    thread.exit() 


def main(): 
    mdata = media() 
    mdata = initiliazer(mdata) 
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
    s.bind((host, port)) 
    s.listen(1) 
    connections = -1 
    while 1: 
     connections += 1 
     print "Number of clients connected", connections 
     client, address = s.accept() 
     thread.start_new_thread(t_handle,(client,address, s, mdata)) 


if __name__ == '__main__': 
    main() 

我的代碼---收窄代碼---

我相信這些問題都在我的類聲明並在我在的數據顯示,從文件中讀取。當我用調試器查看代碼時,所有節目的所有節目都位於相同的內存地址。我認爲這是因爲我將一個類附加到列表錯誤,但我不確定我做錯了什麼。

class media(): 
    tv = [] 
    index = {} 
    budget = 0 
    numoftvshows = 0 
    exit = 0 
    # add existing will not add any files that contain these extensions 
    ignore_list = [".html", ".url", ".txt", ".db", ".srt", ".jpg", ".png", ".docx", ".doc", ".rar", ".zip", ".tar", ".7z", ".dat", ".bmp", ".gif", ".psd", ".tga", ".tif", ".pdf", ".xlr", ".xls", ".xlsx", ".jar", ".exe", ".sav", ".rom", ".php", ".part", ".crdownload", ".msi", ".torrent", ".idx", ".sub", ".nfo"] 


class Tvshows(): 
    name = 'NULL' 
    seasons = [] 
    curseason = 0 
    numofseasons = 0 
    nextep = 0 
    showstat = 0 
    rootdir = 'NULL' 


class Seas(): 
    exist = 0 
    complete = 0 
    episodes = [] 
    numofeps = 0 
    realnum = 1 


class epi(): 
    releasedate = [] 
    status = 0 
    filename = 'NULL' 
    realnum = 0 


def addexistshow(mdata, client): 
    nameofshow = ">>NULL<<" # added the >><< to make sure this never matches a show name 
    seascheck = "Season #" # makes sure this is not found by default 
    client.send("What directory are your files located in?\n") 
    workdir = client.recv(4096) 
    workdir = workdir.rstrip() 
    errnum = 0 
    k = -1 
    for cur, dir, filenames in os.walk(workdir): 
     rootdir = cur 
     if nameofshow not in cur and cur != workdir and cur[0] != '.': 
      strlen = len(workdir) 
      cur = cur[strlen:] 
      if cur[0] == '/': 
       cur = cur[1:] 
      mdata.tv.append(Tvshows()) 
      mdata.numoftvshows += 1 
      k += 1 
      mdata.tv[k].name = cur 
      nameofshow = cur 
      mdata.tv[k].rootdir = rootdir 
      i = -1 
      seascheck = "Season #" 
      client.send(cur) 
      client.send("\n") 
     elif seascheck not in cur and cur != workdir: 
      strlen = len(workdir + '/' + nameofshow + '/') 
      cur = cur[strlen:] 
      if cur != seascheck and "season" in cur.lower(): 
       i += 1 
       mdata.tv[k].seasons.append(Seas()) 
       mdata.tv[k].numofseasons += 1 
       mdata.tv[k].seasons[i].exist = 1 
       mdata.tv[k].seasons[i].realnum = int(cur[7:]) 
       seascheck = cur 
      if "season" in cur.lower(): 
       mdata.tv[mdata.numoftvshows - 1].seasons[i].realnum = int(seascheck[7:]) 
       mdata.tv[mdata.numoftvshows - 1].seasons[i].numofeps += 1 
       mdata.tv[mdata.numoftvshows - 1].seasons[i].exist = 1 
      client.send(cur) 
      client.send("\n") 
     if seascheck in cur: 
      j = 0 
      for line in filenames: 
       good = True 
       for ext in mdata.ignore_list: 
        if ext in line[-6:]: 
         good = False 
         client.send("[*] Skipping ") 
         client.send(ext) 
         client.send(" found in ") 
         client.send(line) 
         client.send("\n") 
       if good is True: 
        try: 
         #print "tv =", k, "season =", i, "episode =", j 
         mdata.tv[k].seasons[i].episodes.append(epi()) 
         epname = line.split(",") 
         realnumbuff = epname[0].split(" - ") 
         realnumbuff = int(realnumbuff[1][4:]) 
         mdata.tv[k].seasons[i].episodes[j].realnum = realnumbuff 
         mdata.tv[k].seasons[i].episodes[j].filename = epname[0] 
         mdata.tv[k].seasons[i].episodes[j].status = 1 
         mdata.tv[k].seasons[i].numofeps += 1 
         client.send(mdata.tv[k].seasons[i].episodes[j].filename) 
         client.send("\n") 
         if mdata.tv[k].seasons[i].episodes[j].filename == "Brooklyn Nine-Nine - S02E03 - The Jimmy Jab Games.mp4": 
          return mdata 
         j += 1 
        except Exception as e: 
         client.send("[!] Error as ") 
         client.send(str(e)) 
         client.send("\n") 
         errnum += 1 
    #print mdata.tv[9].name 
    #print mdata.tv[25].seasons[3].episodes[190].filename 
    if errnum > 0: 
     client.send("\n[!] WARNING - A total of ") 
     client.send(errnum) 
     client.send(" errors were encountered! This could cause problems proceed with caution.\n") 
    return mdata 

該項目的重點是自動合法購買新的電視節目時,他們出來的課堂項目。我相信我在我的課上做錯了事,這導致我一遍又一遍地重寫同一季節列表,而不是每個節目和季節都獲得自己的獨特列表。

我真的很感激任何幫助,你可以給我,如果有更多的信息需要讓我知道,我會補充我所能。

+1

這是一個很大的代碼涉水通過,特別是因爲*我們*可能沒有正確的文件來嘗試它 - 你讀了[如何創建一個最小,完整和可驗證的例子](http://stackoverflow.com/help/mcve)? – wwii

+0

我將問題縮小到代碼的兩個區域,並在我的帖子末尾添加到代碼示例中。 –

+0

@MichaelCarson你爲什麼要聲明這樣的類:'class Seas()'?你應該使用'class Seas(object)'。或者如果你使用Python 3,你可以使用'class Seas'。我看不出爲什麼你會想要空括號。 – MJeffryes

回答

1

這是初始化類的成員走錯了路:

class Tvshows(): 
    name = 'NULL' 
    seasons = [] 
    curseason = 0 
    ... 

這些成員將單個實例類本身的屬性而不是。這將導致可變值的問題:當您稍後調用some_instance.seasons.append(x)時,它將被追加到所有實例共享的列表中。

而應該初始化在__init__方法中的所有成員,這將在單獨的每個實例調用:

class Tvshows(): 
    def __init__(self): 
     self.name = 'NULL' 
     self.seasons = [] 
     self.curseason = 0 
     ... 
+0

謝謝你解決了我的問題。 –