#------------------------------------------------------------------------------------
# torrentParser1.02,用于解析torrent文件
# 增加函数getStructure,getFilepathname
# 2018年5月9日
#------------------------------------------------------------------------------------
from bencode import bdecode
import time

#-------------------------------------
# torrentParser类
#-------------------------------------
class torrentParser(object):
    # 构造函数
    def __init__(self,filePathname):
        self.filePathname=filePathname
        with open(filePathname,'rb') as fObj:
            self.fileDic=bdecode(fObj.read()) 

    # 得到文件路径名
    def getFilepathname(self):
        return self.filePathname

    # 得到所有键值
    def getKeys(self):
        return self.fileDic.keys()

    # 得到全部内容
    def getAllContent(self):
        return self.fileDic;

    # 得到文件结构
    def getStructure(self):
        retval=''
        layer=0

        for key in self.fileDic.keys():
            value=self.fileDic[key]
            retval=retval+self.getNextNode(key,value,layer)

        return retval

    # 向下递归查找文件结构,
    def getNextNode(self,key,value,layer):
        retval="";
        layer+=1

        if type(value)==type({}) and len(value.keys())>0:
            for i in range(1,layer+1):
                retval=retval+"\t"
            retval=retval+str(key)+"\n"

            for k in value.keys():
                v=value[k]
                retval=retval+ self.getNextNode(k,v,layer)
        elif type(value)==type([]) and len(value)>0:
            for i in range(1,layer+1):
                retval=retval+"\t"
            retval=retval+str(key)+"\n"

            arr=value

            for it in arr:
                if type(it)==type({}) and len(it.keys())>0:
                    for nk in it.keys():
                        nv=it[nk]
                        retval=retval+ self.getNextNode(nk,nv,layer)
        else:
            for i in range(1,layer+1):
                retval=retval+"\t"

            retval=retval+str(key)+"\n"

        return retval

    # 获得tracker服务器的URL
    def getAnnounce(self):
        if 'announce' in self.fileDic:
            return self.fileDic['announce'].decode('utf-8')
        return ''

    # 获得tracker服务器的URL列表
    def getAnnounceList(self):
        retval=[]

        if 'announce-list' in self.fileDic:
            arr=self.fileDic['announce-list']

            for childArr in arr:

                if type(childArr)==type([]):
                    for item in childArr:
                        retval.append(item.decode('utf-8'))
                else:
                    retval.append(childArr.decode('utf-8'))

        return retval

    # 得到制作日期
    def getCreateTime(self):
        if 'creation date' in self.fileDic:
            unixTimestamp=self.fileDic['creation date']
            firmalTime = time.localtime(unixTimestamp)
            dt = time.strftime('%Y-%m-%d %H:%M:%S', firmalTime)

            return dt
        else:
            return ''

    # 获得编码方式
    def getEncoding(self):
        if 'encoding' in self.fileDic:
            return self.fileDic['encoding'].decode('utf-8') #去掉字符串前面的b'
        return ''

    # 是否包含多个文件
    def hasMultiFiles(self):
        if 'files' in self.fileDic['info']:
            return True
        else:
            return False

    # 获得文件名
    def getTitle(self):
        arr=[]
        info = self.fileDic['info'] 

        if 'name.utf-8' in info:
            arr=info['name.utf-8']
        else:
            arr = info['name'] 

        #print(str(arr))

        return arr.decode('utf-8') # \x 开头编码的数据解码成中文

    # 获得备注(可选项)
    def getComment(self):
        if 'comment' in self.fileDic:
            return self.fileDic['comment'].decode('utf-8')
        return ''

    # 获得创建者(可选项)
    def getCreatedBy(self):
        if 'created by' in self.fileDic:
            return self.fileDic['created by'].decode('utf-8')
        return ''

    # 多文件的情况下,得到多个文件的个数
    def getFileCount(self):
        return len(self.fileDic['info']['files'])

    # 多文件的情况下,获得所有文件,返回为:dic
    def getFiles(self):
        files=[]

        for item in self.fileDic['info']['files']:
            file={}

            for key in item.keys():
                value=item.get(key)

                if key=='path':
                    path=value[0].decode()
                    value=path
                if key=='path.utf-8':
                    path=value[0].decode()
                    value=path

                file[key]=value

            files.append(file)

        return files

    # 单文件情况下,取文件名
    def getSingleFileName(self):
        #print(str(self.fileDic['info']['name']))
        #return str(self.fileDic['info']['name'],'utf-8')
        return self.getTitle();

    # 单文件情况下,取文件长度
    def getSingleFileLength(self):
        return self.fileDic['info']['length']

    # 单文件情况下,取文件md5sum
    def getSingleFileMd5sum(self):
        if 'md5sum' in self.fileDic['info']:
            return str(self.fileDic['info']['md5sum'],'utf-8')
        else:
            return ''

    # 单文件情况下,取文件长度
    def getSingleFilePieceLength(self):
        return self.fileDic['info']['piece length']

    # 单文件情况下,取文件pieces
    def getSingleFilePieces(self):
        return self.fileDic['info']['pieces']

    # 得到文件简报
    def getBrief(self):
        retval=""
        retval=retval+"File:"+self.filePathname+"\n"
        retval=retval+"announce:"+self.getAnnounce()+"\n"

        arr=self.getAnnounceList()
        if(len(arr)>0):
            retval=retval+"announce list:"+"\n"

            for it in arr:
                retval=retval+"\t"+it+"\n"    

        retval=retval+"Create time:"+self.getCreateTime()+"\n"
        retval=retval+"Ecoding:"+self.getEncoding()+"\n"
        retval=retval+"Title:"+self.getTitle()+"\n"
        retval=retval+"Comment:"+self.getComment()+"\n"
        retval=retval+"Created by:"+self.getCreatedBy()+"\n"

        hasMulti=self.hasMultiFiles()
        retval=retval+"has multi files:"+str(hasMulti)+"\n"
        if hasMulti==True:
            retval=retval+"[多文件结构]"+"\n"

            retval=retval+"包含文件个数为:"+str(self.getFileCount())+"\n"
            retval=retval+"Files:"+"\n"

            files=self.getFiles();
            index=1
            for item in files:
                retval=retval+"\tfile#"+str(index)+"\n"    

                for key in item.keys():
                    value=item.get(key)
                    retval=retval+"\t\t"+str(key)+":"+str(value)+"\n"
                retval=retval+"\n"    

                index=index+1
        else:
            retval=retval+"[单文件结构]"+"\n"
            retval=retval+"文件名为:"+self.getSingleFileName()+"\n"
            retval=retval+"文件长度:"+str(self.getSingleFileLength())+"byte\n"
            retval=retval+"文件md5sum:"+self.getSingleFileMd5sum()+"\n"
            retval=retval+"文件块长度:"+str(self.getSingleFilePieceLength())+"byte\n"

        return retval

#-------------------------------------
# 入口
#-------------------------------------
def main():
    tp=torrentParser(filePathname='./6.torrent')
    print('文件名='+tp.getFilepathname())
    print('文件结构:\n'+tp.getStructure())
    print('文件内容:\n'+str(tp.getAllContent()))

# Start
main()

2018年5月9日11点18分

【Python】torrentParser1.02的更多相关文章

  1. 【Python】torrentParser1.04 增加获得磁力链URI功能

    代码: #------------------------------------------------------------------------------------ # torrentP ...

  2. 【Python】torrentParser1.01

    在昨天的版本上做了一些改进,如增加getAll,修改getSingleFileName等 代码: #-------------------------------------------------- ...

  3. 【Python】torrentParser1.00

    代码: #------------------------------------------------------------------------------------ # torrentP ...

  4. 【python】insertDB1.02

    #------------------------------------------------------------------------------------ # insertDB1.02 ...

  5. 【Python】torrentParser1.03

    #------------------------------------------------------------------------------------ # torrentParse ...

  6. 【Python】 零碎知识积累 II

    [Python] 零碎知识积累 II ■ 函数的参数默认值在函数定义时确定并保存在内存中,调用函数时不会在内存中新开辟一块空间然后用参数默认值重新赋值,而是单纯地引用这个参数原来的地址.这就带来了一个 ...

  7. 【python】列出http://www.cnblogs.com/xiandedanteng中所有博文的标题

    代码: # 列出http://www.cnblogs.com/xiandedanteng中所有博文的标题 from bs4 import BeautifulSoup import requests u ...

  8. 【python】redis基本命令和基本用法详解

    [python]redis基本命令和基本用法详解 来自http://www.cnblogs.com/wangtp/p/5636872.html 1.redis连接 redis-py提供两个类Redis ...

  9. 【Python②】python之首秀

       第一个python程序 再次说明:后面所有代码均为Python 3.3.2版本(运行环境:Windows7)编写. 安装配置好python后,我们先来写第一个python程序.打开IDLE (P ...

随机推荐

  1. 百度外卖接口调试 C#版

    主类 class Program    {        static void Main(string[] args)        {            string cmdStr = &qu ...

  2. TCP编程的迷惑

    server : ip -- 192.168.96.132 client: ip--192.168.96.131 在服务端,accept函数的其中一个入参是listen-socket,会返回一个新的c ...

  3. [转]LRU缓存实现(Java)

    LRU Cache的LinkedHashMap实现 LRU Cache的链表+HashMap实现 LinkedHashMap的FIFO实现 调用示例 LRU是Least Recently Used 的 ...

  4. android:活动的最佳实践

    2.6.1    知晓当前是在哪一个活动 这个技巧将教会你,如何根据程序当前的界面就能判断出这是哪一个活动.可能你会觉 得挺纳闷的,我自己写的代码怎么会不知道这是哪一个活动呢?很不幸的是,在你真正进入 ...

  5. SpringMVC方法传递集合数组

    背景:实体集合作为参数   数据准备: 1.实体类 class A {private int id; private String name; } 2.集合json字符串 [{"id&quo ...

  6. 关于面试总结8-http协议相关面试题

    前言 在PC浏览器的地址栏输入一串URL,然后按Enter键这个页面渲染出来,这个过程中都发生了什么事?这个是很多面试官喜欢问的一个问题 如果测试只是停留在表面上点点点,不知道背后的逻辑,是无法发现隐 ...

  7. 为网卡配置多个IP地址(windows)

    转自:https://jingyan.baidu.com/article/fcb5aff7e0fd76edaa4a71d3.html 为电脑配置多个IP,免去到不同地点需要更改IP的烦恼. 譬如电脑在 ...

  8. 都市侠盗第一季/全集Leverage迅雷下载

    第一季 Leverage Season 1 (2008)看点:Nate Ford(蒂莫西·赫顿 Timothy Hutton 饰)曾当过保险调查员,为自己的老板挽回过数百万美元的损失,是个忠心耿耿的雇 ...

  9. Eclipse给安卓应用签名

  10. 《图解CSS3:核心技术与案例实战》

    <图解CSS3:核心技术与案例实战> 基本信息 作者: 大漠 丛书名: Web开发技术丛书 出版社:机械工业出版社 ISBN:9787111469209 上架时间:2014-7-2 出版日 ...