Advertisement
Gfy

nzbsrr.py

Gfy
Sep 25th, 2011
287
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 10.32 KB | None | 0 0
  1. #!/usr/bin/env python
  2. # -*- coding: latin-1 -*-
  3.  
  4. # This program is free software: you can redistribute it and/or modify
  5. # it under the terms of the GNU General Public License as published by
  6. # the Free Software Foundation, either version 3 of the License, or
  7. # (at your option) any later version.
  8. #
  9. # This program is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. # GNU General Public License for more details.
  13. #
  14. # You should have received a copy of the GNU General Public License
  15. # along with this program.  If not, see <http://www.gnu.org/licenses/>
  16.  
  17. from xml.dom.minidom import parse, Document
  18. import optparse
  19. import sys
  20. import os
  21. import re
  22. import glob
  23. import unittest
  24.  
  25. # for running the script directly from command line
  26. sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)),'..'))
  27. try:
  28.     from rescene.rescene import merge_srrs
  29. except:
  30.     from rescene import merge_srrs
  31.  
  32. def main(options, args):
  33.     relFileMapping = {}
  34.     fileRelMapping = {}
  35.     unknown = []
  36.  
  37.     def read_nzb(nzb):
  38.         doc = parse(nzb, bufsize=1000)
  39.         for file_node in doc.getElementsByTagName("file"):
  40.             subject = file_node.getAttribute("subject")
  41.             relname, srr = parseSubject(subject)
  42.             if srr == None:
  43.                 unknown.append(subject)
  44.                 if options.unknowns:
  45.                     print(subject)
  46.             else:
  47.                 relname = relname.strip()
  48.                 l = list()
  49.                 l.append(srr)
  50.                 try:
  51.                     relFileMapping[relname] += [srr]
  52.                 except:
  53.                     relFileMapping[relname] = [srr]
  54.                 fileRelMapping[srr] = relname
  55.                    
  56.                 # show info while parsing
  57.                 if options.releases:
  58.                     print(relname)
  59.                 if options.srrs:
  60.                     print(srr)
  61.                    
  62.                 # create new nzb files to download samples
  63.                 if options.separate and relname[0:4] != "Con.":
  64.                     # Con.Artist, Con.Air folders are not possible in Windows
  65.                     newdoc = Document()
  66.                     top_element = doc.createElementNS(
  67.                                         "http://www.newzbin.com/DTD/2003/nzb",
  68.                                         "nzb")
  69.                     newdoc.appendChild(top_element)
  70.                     top_element.appendChild(file_node)
  71.                    
  72.                     try: # when the "release name" has a \
  73.                         f = os.path.join(options.separate, relname + ".nzb")
  74.                         print("Writing nzb %s" % os.path.basename(f))
  75.                         with open(f, "wb") as nzb_file:
  76.                             nzb_file.write(newdoc.toxml("utf-8"))
  77.                     except Exception, e:
  78.                         print(e)
  79.  
  80.     for nzb in args:
  81.         try:
  82.             print("Reading %s" % os.path.basename(nzb))
  83.             read_nzb(nzb)
  84.         except:
  85.             # resolve wild cards
  86.             for path in glob.glob(nzb):
  87.                 print("Reading %s" % os.path.basename(nzb))
  88.                 read_nzb(path)
  89.                
  90.     if options.rename_dir:
  91.         failed = []
  92.         # try to rename all available files in the directory
  93.         # for single SRR files
  94.         for file in os.listdir(options.rename_dir):
  95.             if fileRelMapping.has_key(file):
  96.                 bad = renameSrr(options.rename_dir, file, fileRelMapping[file])
  97.                 if bad:
  98.                     failed.append(bad)
  99.             else:
  100.                 print("File '%s' not in NZB." % file)
  101.  
  102.         printList(failed)
  103.        
  104.     if options.join_dir:
  105.         # join srr files from a multiple cd release before renaming
  106.         failed = []
  107.         failed_join = []
  108.         haveSubs = []
  109.        
  110.         # rel -> srr: "dupe" files (e.g. a repost)
  111.         # srr -> rel: needs to be joined
  112.         for release in relFileMapping.keys():
  113.             # remove duplicates and sort
  114.             files = sorted(set(relFileMapping[release]))
  115.            
  116.             # a file with the name 'subs' or 'extras' in it? put it at the end
  117.             for file in files:
  118.                 if re.match(".*(subs|extras|proof|sample).*", file, re.I):
  119.                     files.remove(file)
  120.                     files.append(file)
  121.                     haveSubs.append(release)
  122.             relFileMapping[release] = files
  123.            
  124.             if len(files) > 1: # join SRR files to renamed one
  125.                 if options.joins:
  126.                     print(release)
  127.                     for srr in files:
  128.                         print("\t%s" % srr)
  129.                 else:
  130.                     bad = joinSrr(options.join_dir, release, files)
  131.                     if bad:
  132.                         failed_join.append(bad)
  133.             else: # rename SRR file
  134.                 bad = renameSrr(options.join_dir, file, release)
  135.                 if bad:
  136.                     failed.append(bad)
  137.        
  138.         print("Failed files: ")
  139.         printList(failed)
  140.         print("Have subs SRR files: ")
  141.         printList(set(haveSubs))
  142.         print("Failed to join files: ")
  143.         printList(failed_join)
  144.        
  145.     # list all SRR files under the release name
  146.     if options.both:
  147.         for release in relFileMapping.keys():
  148.             print(release)
  149.             for srr in relFileMapping[release]:
  150.                 print("\t%s" % srr)    
  151.        
  152.     if options.list_dir:
  153.         # lists all files in the given directory without their extension
  154.         # so it can be used for the list search on srrdb.com
  155.         for file in os.listdir(options.list_dir):  
  156.             if os.path.isfile(os.path.join(options.list_dir, file)):
  157.                 print(file[:-4])
  158.  
  159. def renameSrr(dir, file, releaseName):
  160.     old = os.path.join(dir, file)
  161.     new = os.path.join(dir, "renamed", releaseName + ".srr")
  162.     print(("Renaming %s to %s..." % (old, new))),
  163.     try:
  164.         os.renames(old, new)
  165.         print("done!")
  166.     except:
  167.         print("failed!")
  168.         # move unrenamed files to a separate dir
  169.         new = os.path.join(dir, "unrenamed", file)
  170.         print("Renaming %s to %s..." % (old, new))
  171.         try:
  172.             os.renames(old, new)   
  173.         except: pass
  174.         return file
  175.    
  176. def joinSrr(dir, release, files):
  177.     dir = os.path.abspath(dir)
  178.     try:
  179.         os.makedirs(os.path.join(dir, "joined"))
  180.     except: pass # Path already exists
  181.    
  182.     try:
  183.         merge_srrs([os.path.join(dir, f) for f in files],
  184.                     os.path.join(dir, "joined", release + ".srr"),
  185.                     "pyReScene Merge Script")
  186.         # move original unjoined files
  187.         for f in files:
  188.             os.renames(os.path.join(dir, f),
  189.                        os.path.join(dir, "joined-orig", f))
  190.     except:
  191.         # one of the files was not found
  192.         return files
  193.        
  194. def printList(list):
  195.     for item in list:
  196.         print("\t%s" % item)
  197.                    
  198. def parseSubject(subject): #[#altbin@EFNet]-[FULL]-[RELNAM
  199.     exts = "\.(srr|srs|avi|mkv|par2)"
  200.     patternEfnet = (".*\[.*EFNet\]-(\[(FULL|PART)\]-)?"
  201.                     "\[\s?(?P<release>[^\s\[\]]+?)(\s.*)?\]-?"
  202.                     ".*(&quot;|\")(?P<file>.*" + exts + ")"
  203.                     "(&quot;|\").*")
  204.     patternXvid = ("#alt.binaries.movies.xvid: (?P<release>[^\s]+"
  205.                    ") - (&quot;|\")(?P<file>.*" + exts + ")"
  206.                    "(&quot;|\").*")
  207.                
  208.     m = re.match(patternEfnet, subject, re.IGNORECASE)
  209.     if m:
  210.         return m.group("release", "file")
  211.     m = re.match(patternXvid, subject, re.IGNORECASE)
  212.     if m:
  213.         return m.group("release", "file")
  214.     else:
  215.         return (None, None)
  216.    
  217. class TestParse(unittest.TestCase):
  218.     def test_parse(self):
  219.         teevee = ("""[71733]-[FULL]-[#a.b.teevee@EFNet]-"""
  220.                 "[ RELNAME ]-[23/29] - &quot;"
  221.                 """FILENAME.srr&quot; yEnc (1/1)""")
  222.         teevee2 = ("[42377]-[FULL]-[#a.b.teevee@EFNet]-[ RELNAME ]-[02/29] -"
  223.                 """ "FILENAME.mkv" yEnc (1/100)""")
  224.         moovee = ("[1014]-[FULL]-[#a.b.moovee@EFNet]-[ RELNAME"
  225.                 """ ]- "FILENAME.srr" (1/1)""")
  226.         moovee2 = ("[1060]-[FULL]-[#a.b.moovee@EFNet]-[ RELNAME"
  227.                 """ ] "FILENAME.avi" (39/39)""")
  228.         hdtv = ("[7895]-[a.b.hdtv.x264@EFNet]-RELNAME- "
  229.                 "&quot;FILENAME.mkv&quot; (144/144)")
  230.         moviesdivx = ("[26750]-[#altbin@EFNet]-[FULL]-[RELNAME"
  231.                         "]- &quot;FILENAME.avi&quot;")
  232.         moviesdivx2 = ("[26750]-[#altbin@EFNet]-[FULL]-[RELNAME - Sample"
  233.                         "]- &quot;FILENAME.avi&quot;")
  234.         moviesxvid = ("#alt.binaries.movies.xvid: RELNAME - &quot;"
  235.                         "FILENAME.srr&quot; (1/1))")
  236.        
  237.         self.assertEqual(parseSubject(teevee), ("RELNAME", "FILENAME.srr"))
  238.         self.assertEqual(parseSubject(teevee2), ("RELNAME", "FILENAME.mkv"))
  239.         self.assertEqual(parseSubject(moovee), ("RELNAME", "FILENAME.srr"))
  240.         self.assertEqual(parseSubject(moovee2), ("RELNAME", "FILENAME.avi"))
  241.         self.assertEqual(parseSubject(moviesdivx), ("RELNAME", "FILENAME.avi"))
  242.         self.assertEqual(parseSubject(moviesdivx2), ("RELNAME", "FILENAME.avi"))
  243.         self.assertEqual(parseSubject(moviesxvid), ("RELNAME", "FILENAME.srr"))
  244.  
  245. if __name__ == '__main__':
  246.     parser = optparse.OptionParser(
  247.         usage="Usage: %prog [nzb files] [options]'\n"
  248.         "This tool will list the scene names and the srr name.\n",
  249.         version="%prog 0.2 (2011-10-19)") # --help, --version
  250.    
  251.     parser.add_option("-r", "--releases", help="prints releases",
  252.                      action="store_true", default=False, dest="releases")
  253.     parser.add_option("-s", "--srrs", help="prints SRRs",
  254.                      action="store_true", default=False, dest="srrs")
  255.     parser.add_option("-b", "--both", help="prints both releases and the SRRs",
  256.                      action="store_true", default=False, dest="both")
  257.     parser.add_option("-j", "--joins", help="prints SRRs to be joined"
  258.                      "(no actual joining will occur)",
  259.                      action="store_true", default=False, dest="joins")
  260.     parser.add_option("-u", "--unknowns", help="prints unparseable subjects",
  261.                      action="store_true", default=False, dest="unknowns")
  262.    
  263.     parser.add_option("--rename", help="renames SRR files in DIRECTORY "
  264.                      "(stop using this one)",
  265.                      dest="rename_dir", metavar="DIRECTORY")
  266.     parser.add_option("--join",
  267.                      help="joins before renaming SRR files in DIRECTORY",
  268.                      dest="join_dir", metavar="DIRECTORY")
  269.     parser.add_option("--list", help="list release names of SRR files",
  270.                      dest="list_dir", metavar="DIRECTORY")
  271.     parser.add_option("--separate", dest="separate", metavar="DIRECTORY",
  272.                      help="split NZB to [release name].nzb in DIRECTORY")
  273.    
  274.     parser.add_option("--unittest", help="runs the unit tests", dest="test",
  275.                      action="store_true", default=False)
  276.    
  277.     # no arguments given
  278.     if len(sys.argv) < 2:
  279.         print(parser.format_help())
  280.     else:      
  281.         (options, args) = parser.parse_args()
  282.         if options.test:
  283.             suite = unittest.TestLoader().loadTestsFromTestCase(TestParse)
  284.             unittest.TextTestRunner(verbosity=2).run(suite)
  285.         else:
  286.             main(options, args)
  287.        
  288. """
  289. Shows which lines in new.txt aren't in mine.txt:
  290. cat mine.txt new.txt | sort | uniq -d | cat new.txt - | sort | uniq -u
  291. change -u at the end to -d to get the duplicates
  292.  
  293. grep 'does not exist' all.txt > does_not_exist.txt
  294.  
  295. 19:38 < sha0lin> they have this regex on hdbits, maybe you will get more groups with it
  296. 19:38 < sha0lin> \b(/(C/)Z|AE|AJ8|AJP|Arucard|AW|BBW|BG|BoK|CRiSC|Crow|CtrlHD|D4|DiGG|DiR|DiRTY|disc|DBO|DON|DoNOLi|D/-Z0N3|EbP|ESiR|ETH|fLAMEhd|FPG|FSK|Ft4U|fty|Funner|GMoRK|GoLDSToNE|H2|h264iRMU|HDB|HDC|HDBiRD|HDL|HDxT|H/@M|hymen|HZ|iLL|IMDTHS|iNFLiKTED|iOZO|J4F|JAVLiU|JCH|k2|KTN|KweeK|lulz|M794|MAGiC|MCR|MdM|MMI|Mojo|NaRB|NiX|NWO|OAS|ONYX|PerfectionHD|PHiN|PiNG|Prestige|Prime|PXE|QDP|QXE|Redµx|REPTiLE|RuDE|S26|sJR|SK|SLO|SPeSHaL|SrS|Thora|tK|TM|toho|
  297.  
  298. iconv < file.nfo -f cp437 -t utf8 > file.utf8
  299. """
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement