#------------------------------------------------------------------------------------
# torrentParser1.03,用于解析torrent文件
# 修改了函数getStructure,增加其节点值显示
# 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"

            showValue=str(value)[0:50] # 显示的值

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

        return retval

    # 获得tracker服务器的URL
    def getAnnounce(self):
        if 'announce' in self.fileDic:
            return self.fileDic['announce'].decode('utf-8','ignore')
        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','ignore'))
                else:
                    retval.append(childArr.decode('utf-8','ignore'))

        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','ignore')
        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','ignore') 

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

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

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

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

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

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

                if key=='path':
                    #print('1.'+str(value))
                    #print('10.'+str(value[0]))
                    path=value[0].decode('utf8','ignore')
                    value=path
                if key=='path.utf-8':
                    #print('2.'+str(value))
                    #print('20.'+str(value[0]))
                    path=value[0].decode('utf8','ignore')
                    value=path

                file[key]=value

            files.append(file)

        return files

    # 单文件情况下,取文件名
    def getSingleFileName(self):
        return self.getTitle();

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

    # 单文件情况下,取文件md5sum
    def getSingleFileMd5sum(self):
        if 'md5sum' in self.fileDic['info']:
            return self.fileDic['info']['md5sum'].decode('utf-8','ignore')
        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='./8.torrent')
    print('文件名='+tp.getFilepathname())
    print('文件结构:\n'+tp.getStructure())
    print('文件简报:\n'+str(tp.getBrief()))
    print('文件内容:\n'+str(tp.getAllContent()))

# Start
main()

2018年5月9日

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

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

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

  2. 【Python】torrentParser1.01

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

  3. 【Python】torrentParser1.00

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

  4. 【Python】torrentParser1.02

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

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

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

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

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

  7. 【python】下载中国大学MOOC的视频

    [python]下载中国大学MOOC的视频 脚本目标: 输入课程id和cookie下载整个课程的视频文件,方便复习时候看 网站的反爬机制分析: 分析数据包的目的:找到获取m3u8文件的路径 1. 从第 ...

  8. 【python】M3U8下载器脚本

    [python]M3U8下载器脚本 脚本目标: 1. 输入M3U8文件的链接,得到视频 2.使用异步操作,这样可以快很多,不加锁,因为懒得写,而且影响不大 已知条件: 1.m3u8文件其实就是一个记录 ...

  9. 【Python②】python之首秀

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

随机推荐

  1. delphi版本修改PE头源码

    //VC++6外衣 1 OEPCODEFIVE: THEAD = ($55, $8B, $EC, $6A, $FF, $68, $00, $00, $00, $00, $68, $00, $00, $ ...

  2. Eclipse 保存文件时自动格式化代码

    很多同学不知道Eclipse有个很有用的功能,就是自动格式源代码的功能,一般大家都是直接Ctrl+Shift+F手动格式化,多浪费时间. 其实Eclipse里已经带有自动格式化功能了,默认是没有代开该 ...

  3. 无耻之徒(美版)第一季/全集Shameless US迅雷下载

    第一季 Shameless Season 1 (2011)看点:本以为美版<无耻之徒>(Shameless)是小众剧(诸多儿童不宜),但是试播集98.2万的收视人次竟然创下了Showtim ...

  4. 嘻哈帝国第一季/全集Empire迅雷下载

    英文译名Empire,第1季(2015-01-08)FOX.本季看点:<嘻哈帝国>卢西奥斯·莱恩是一名超级音乐明星兼Empire娱乐公司的创始人,故事讲述了他如何在困境和失败中运营公司的故 ...

  5. 真探第一季/全集True Detective1迅雷下载

    真探 第一季 True Detective Season 1 (2014)真相如探 / 真爱如探本季看点:这部剧采用多视角叙事,伍迪·哈里森与马修·麦康纳饰演两名侦探搭档,他们一起调查一桩17年前的悬 ...

  6. Java生成8位随机邀请码,不重复

    public static String[] chars = new String[] { "a", "b", "c", "d&q ...

  7. [Android Pro] AndroidStudio IDE界面插件开发(进阶篇之Action机制)

    转载请注明出处:[huachao1001的专栏:http://blog.csdn.net/huachao1001/article/details/53883500] 从上一篇<AndroidSt ...

  8. SQL文件的BOM问题导致的invalid character错误及解决

    最近在做数据的搬运工,将Oracle中的数据搬运到ES中,方案很成熟了,使用Logstash的jdbc-input执行SQL,然后将结果输出到ES中.这么简单的问题,在测试环境中测试也一帆风顺,可一上 ...

  9. 02 如何创建线程 线程并发与synchornized

    所有程序运行结果 请自行得出 创建线程方式一:继承Thread类 步骤: 1,定义一个类继承Thread类. 2,覆盖Thread类中的run方法. 3,直接创建Thread的子类对象创建线程. 4, ...

  10. 6.2 dubbo在spring中自定义xml标签源码解析

    在6.1 如何在spring中自定义xml标签中我们看到了在spring中自定义xml标签的方式.dubbo也是这样来实现的. 一 META_INF/dubbo.xsd 比较长,只列出<dubb ...