#------------------------------------------------------------------------------------
# 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. 「GIT SourceTree冲突」解决方案

    现在程序猿标配GIT作为代码管理,但是从SVN到GIT学习中,其中GIT的冲突是一个难点,常常会导致Push不上去,Pull不下来,很尴尬的地步,还不知道自己写的代码被覆盖没,废话不多说,直接上干货! ...

  2. Delphi把一张PNG横向分割成N张透明通道的图片

    Delphi新版本虽然集成了PngImage但是分割复制什么的却非常难用.稍微封装了一下.可以把一张PNG横向分割成N张.透明通道什么的都可以保持不变.typeTPngArray = array of ...

  3. layoutSubviews 在什么情况下会被触发

    layoutSubviews在以下情况下会被调用: 1.init初始化不会触发layoutSubviews 2.addSubview会触发layoutSubviews 3.设置view的Frame会触 ...

  4. Android中的Audio播放:竞争Audio之Audio Focus的应用

    from://http://blog.csdn.net/thl789/article/details/7422931 Android是多任务系统,Audio系统是竞争资源.Android2.2之前,没 ...

  5. ArrayList 排序方法的性能对比

    20000=>ZXP 二分法 getSeriesMinSort2(list) Time is 67000 20000=>循环 getSeriesMinSortFor(list) Time ...

  6. Easyui 搜索框的折叠与展开方法

    HTML 文件: <div id="searchForm" region="north" title="XXXX查询" collaps ...

  7. 安装部署 Kubernetes 集群

    安装部署 Kubernetes 集群 阅读目录: 准备工作 部署 Master 管理节点 部署 Minion 工作节点 部署 Hello World 应用 安装 Dashboard 插件 安装 Hea ...

  8. Svg.Js 简介(转)

    什么是SVG? SVG 指可伸缩矢量图形 (Scalable Vector Graphics) SVG 用来定义用于网络的基于矢量的图形 SVG 使用 XML 格式定义图形 SVG 图像在放大或改变尺 ...

  9. JVM编译优化

    在部分的商用虚拟机中,Java 程序最初是通过解释器(Interpreter )进行解释执行的,当虚拟机发现某个方法或代码块的运行特别频繁的时候,就会把这些代码认定为“热点代码”.为了提高热点代码的执 ...

  10. logistic回归算法及其matlib实现

    一般来说,回归不用在分类问题上,因为回归是连续型模型,而且受噪声影响比较大.如果非要使用回归算法,可以使用logistic回归. logistic回归本质上是线性回归,只是在特征到结果的映射中多加入了 ...