def three(self, **kwargs): """ Accept webserver parms and show Indexers page """ if kwargs: if 'access' in kwargs: cfg.cherryhost.set(kwargs['access']) cfg.enable_https.set(kwargs.get('enable_https', 0)) cfg.autobrowser.set(kwargs.get('autobrowser', 0)) cfg.username.set(kwargs.get('web_user', '')) cfg.password.set(kwargs.get('web_pass', '')) if not cfg.username() or not cfg.password(): sabnzbd.interface.set_auth(cherrypy.config) # Create Indexers page info = self.info.copy() info['num'] = '» %s' % T('Step Three') info['number'] = 3 info['newzbin_user'] = cfg.newzbin_username() info['newzbin_pass'] = cfg.newzbin_password.get_stars() info['newzbin_bookmarks'] = cfg.newzbin_bookmarks() info['newzbin_url'] = cfg.newzbin_url() info['matrix_user'] = cfg.matrix_username() info['matrix_apikey'] = cfg.matrix_apikey() info['T'] = Ttemplate template = Template(file=os.path.join(self.__web_dir, 'three.html'), searchList=[info], compilerSettings=sabnzbd.interface.DIRECTIVES) return template.respond()
def three(self, **kwargs): """ Accept webserver parms and show Indexers page """ if kwargs: if 'access' in kwargs: cfg.cherryhost.set(kwargs['access']) cfg.enable_https.set(kwargs.get('enable_https',0)) cfg.autobrowser.set(kwargs.get('autobrowser',0)) cfg.username.set(kwargs.get('web_user', '')) cfg.password.set(kwargs.get('web_pass', '')) if not cfg.username() or not cfg.password(): sabnzbd.interface.set_auth(cherrypy.config) # Create Indexers page info = self.info.copy() info['num'] = '» %s' % T('Step Three') info['number'] = 3 info['newzbin_user'] = cfg.newzbin_username() info['newzbin_pass'] = cfg.newzbin_password.get_stars() info['newzbin_bookmarks'] = cfg.newzbin_bookmarks() info['newzbin_url'] = cfg.newzbin_url() info['matrix_user'] = cfg.matrix_username() info['matrix_apikey'] = cfg.matrix_apikey() info['T'] = Ttemplate template = Template(file=os.path.join(self.__web_dir, 'three.html'), searchList=[info], compilerSettings=sabnzbd.interface.DIRECTIVES) return template.respond()
def format_source_url(url): """ Format URL suitable for 'Source' stage """ if _HAVE_SSL: prot = 'https' else: prot = 'http:' if url and str(url).isdigit(): return '%s://%s/browse/post/%s/' % (prot, cfg.newzbin_url(), str(url)) else: return url
def run(self, delete=None, force=False): if not (cfg.newzbin_bookmarks() or force): return if not (cfg.newzbin_username() and cfg.newzbin_password()): return headers = { 'User-Agent': 'SABnzbd+/%s' % sabnzbd.__version__, } # Connect to Newzbin try: if _HAVE_SSL: conn = httplib.HTTPSConnection(cfg.newzbin_url()) else: conn = httplib.HTTPConnection(cfg.newzbin_url()) if delete: logging.debug('Trying to delete Newzbin bookmark %s', delete) postdata = { 'username': cfg.newzbin_username(), 'password': cfg.newzbin_password(), 'action': 'delete', \ 'reportids' : delete } else: logging.info('Fetching Newzbin bookmarks') postdata = { 'username': cfg.newzbin_username(), 'password': cfg.newzbin_password(), 'action': 'fetch'} postdata = urllib.urlencode(postdata) headers['Content-type'] = 'application/x-www-form-urlencoded' fetchurl = '/api/bookmarks/' conn.request('POST', fetchurl, postdata, headers) response = conn.getresponse() except: _warn_user('Problem accessing Newzbin server.') logging.info("Traceback: ", exc_info = True) return data = response.read() # Get the status rcode = str(response.status) # Official return codes: # 200 = OK, NZB content follows # 204 = No content # 400 = Bad Request, please supply all parameters # (this generally means reportid or fileid is missing; missing user/pass gets you a 401) # 401 = Unauthorised, check username/password? # 402 = Payment Required, not Premium # 403 = Forbidden (incorrect auth) # 500 = Internal Server Error, please report to Administrator # 503 = Service Unavailable, site is currently down if rcode not in ('500', '503'): _access_ok() if rcode == '204': logging.debug("No bookmarks set") elif rcode in ('401', '403'): logging.warning(Ta('Unauthorised, check your newzbin username/password')) elif rcode in ('402'): logging.warning(Ta('You have no credit on your Newzbin account')) elif rcode in ('500', '503'): _warn_user('Newzbin has a server problem (%s).' % rcode) elif rcode == '200': if delete: if data.startswith('1'): logging.info('Deleted newzbin bookmark %s', delete) if delete in self.bookmarks: self.bookmarks.remove(delete) else: if delete in self.bookmarks: logging.warning(Ta('Could not delete newzbin bookmark %s'), delete) else: for line in data.split('\n'): try: msgid, size, text = line.split('\t', 2) except: msgid = size = text = None if msgid and (msgid not in self.bookmarks): self.bookmarks.append(msgid) logging.info("Found new bookmarked msgid %s (%s)", msgid, text) sabnzbd.add_msgid(int(msgid), None, None, priority=None) else: logging.error(Ta('Newzbin gives undocumented error code (%s)'), rcode) self._save() self.__busy = False
def _grabnzb(msgid): """ Grab one msgid from newzbin """ msg = '' retry = (60, None, None, None) nzo_info = {'msgid': msgid} logging.info('Fetching NZB for Newzbin report #%s', msgid) headers = {'User-agent' : 'SABnzbd+/%s' % sabnzbd.version.__version__} # Connect to Newzbin try: if _HAVE_SSL: conn = httplib.HTTPSConnection(cfg.newzbin_url()) else: conn = httplib.HTTPConnection(cfg.newzbin_url()) postdata = { 'username': cfg.newzbin_username(), 'password': cfg.newzbin_password(), 'reportid': msgid } postdata = urllib.urlencode(postdata) headers['Content-type'] = 'application/x-www-form-urlencoded' fetchurl = '/api/dnzb/' conn.request('POST', fetchurl, postdata, headers) response = conn.getresponse() # Save debug info if we have to data = response.read() except: _warn_user('Problem accessing Newzbin server, wait 1 min.') logging.info("Traceback: ", exc_info = True) return retry # Get the filename rcode = response.getheader('X-DNZB-RCode') rtext = response.getheader('X-DNZB-RText') try: nzo_info['more_info'] = response.getheader('X-DNZB-MoreInfo') except: # Only some reports will generate a moreinfo header pass if not (rcode or rtext): logging.error(T('Newzbin server changed its protocol')) return retry # Official return codes: # 200 = OK, NZB content follows # 400 = Bad Request, please supply all parameters # (this generally means reportid or fileid is missing; missing user/pass gets you a 401) # 401 = Unauthorised, check username/password? # 402 = Payment Required, not Premium # 404 = Not Found, data doesn't exist? # (only working for reportids, see Technical Limitations) # 450 = Try Later, wait <x> seconds for counter to reset # (for an explanation of this, see DNZB Rate Limiting) # 500 = Internal Server Error, please report to Administrator # 503 = Service Unavailable, site is currently down if rcode in ('500', '503'): _warn_user('Newzbin has a server problem (%s, %s), wait 5 min.' % (rcode, rtext)) return retry _access_ok() if rcode == '450': wait_re = re.compile('wait (\d+) seconds') try: wait = int(wait_re.findall(rtext)[0]) except: wait = 60 if wait > 60: wait = 60 logging.debug("Newzbin says we should wait for %s sec", wait) return int(wait+1), None, None, None if rcode in ('402'): msg = Ta('You have no credit on your Newzbin account') return None, None, None, msg if rcode in ('401'): msg = Ta('Unauthorised, check your newzbin username/password') return None, None, None, msg if rcode in ('400', '404'): msg = Ta('Newzbin report %s not found') % msgid return None, None, None, msg if rcode != '200': msg = Ta('Newzbin gives undocumented error code (%s, %s)') % (rcode, rtext) return 60, None, None, msg # Process data report_name = response.getheader('X-DNZB-Name') report_cat = response.getheader('X-DNZB-Category') if not (report_name and report_cat): msg = Ta('Newzbin server fails to give info for %s') % msgid return 60, None, None, msg # sanitize report_name newname = sanitize_foldername(report_name) if len(newname) > 80: newname = newname[0:79].strip('. ') newname += ".nzb" logging.info('Successfully fetched report %s - %s (cat=%s) (%s)', msgid, report_name, report_cat, newname) return (newname, data, report_cat, nzo_info)
def run(self, delete=None, force=False): if not (cfg.newzbin_bookmarks() or force): return if not (cfg.newzbin_username() and cfg.newzbin_password()): return headers = { 'User-Agent': 'SABnzbd+/%s' % sabnzbd.__version__, } # Connect to Newzbin try: if _HAVE_SSL: conn = httplib.HTTPSConnection(cfg.newzbin_url()) else: conn = httplib.HTTPConnection(cfg.newzbin_url()) if delete: logging.debug('Trying to delete Newzbin bookmark %s', delete) postdata = { 'username': cfg.newzbin_username(), 'password': cfg.newzbin_password(), 'action': 'delete', \ 'reportids' : delete } else: logging.info('Fetching Newzbin bookmarks') postdata = { 'username': cfg.newzbin_username(), 'password': cfg.newzbin_password(), 'action': 'fetch' } postdata = urllib.urlencode(postdata) headers['Content-type'] = 'application/x-www-form-urlencoded' fetchurl = '/api/bookmarks/' conn.request('POST', fetchurl, postdata, headers) response = conn.getresponse() except: _warn_user('Problem accessing Newzbin server.') logging.info("Traceback: ", exc_info=True) return data = response.read() # Get the status rcode = str(response.status) # Official return codes: # 200 = OK, NZB content follows # 204 = No content # 400 = Bad Request, please supply all parameters # (this generally means reportid or fileid is missing; missing user/pass gets you a 401) # 401 = Unauthorised, check username/password? # 402 = Payment Required, not Premium # 403 = Forbidden (incorrect auth) # 500 = Internal Server Error, please report to Administrator # 503 = Service Unavailable, site is currently down if rcode not in ('500', '503'): _access_ok() if rcode == '204': logging.debug("No bookmarks set") elif rcode in ('401', '403'): logging.warning( Ta('Unauthorised, check your newzbin username/password')) elif rcode in ('402'): logging.warning(Ta('You have no credit on your Newzbin account')) elif rcode in ('500', '503'): _warn_user('Newzbin has a server problem (%s).' % rcode) elif rcode == '200': if delete: if data.startswith('1'): logging.info('Deleted newzbin bookmark %s', delete) if delete in self.bookmarks: self.bookmarks.remove(delete) else: if delete in self.bookmarks: logging.warning( Ta('Could not delete newzbin bookmark %s'), delete) else: for line in data.split('\n'): try: msgid, size, text = line.split('\t', 2) except: msgid = size = text = None if msgid and (msgid not in self.bookmarks): self.bookmarks.append(msgid) logging.info("Found new bookmarked msgid %s (%s)", msgid, text) sabnzbd.add_msgid(int(msgid), None, None, priority=None) else: logging.error(Ta('Newzbin gives undocumented error code (%s)'), rcode) self._save() self.__busy = False
def _grabnzb(msgid): """ Grab one msgid from newzbin """ msg = '' retry = (60, None, None, None) nzo_info = {'msgid': msgid} logging.info('Fetching NZB for Newzbin report #%s', msgid) headers = {'User-agent': 'SABnzbd+/%s' % sabnzbd.version.__version__} # Connect to Newzbin try: if _HAVE_SSL: conn = httplib.HTTPSConnection(cfg.newzbin_url()) else: conn = httplib.HTTPConnection(cfg.newzbin_url()) postdata = { 'username': cfg.newzbin_username(), 'password': cfg.newzbin_password(), 'reportid': msgid } postdata = urllib.urlencode(postdata) headers['Content-type'] = 'application/x-www-form-urlencoded' fetchurl = '/api/dnzb/' conn.request('POST', fetchurl, postdata, headers) response = conn.getresponse() # Save debug info if we have to data = response.read() except: _warn_user('Problem accessing Newzbin server, wait 1 min.') logging.info("Traceback: ", exc_info=True) return retry # Get the filename rcode = response.getheader('X-DNZB-RCode') rtext = response.getheader('X-DNZB-RText') try: nzo_info['more_info'] = response.getheader('X-DNZB-MoreInfo') except: # Only some reports will generate a moreinfo header pass if not (rcode or rtext): logging.error(T('Newzbin server changed its protocol')) return retry # Official return codes: # 200 = OK, NZB content follows # 400 = Bad Request, please supply all parameters # (this generally means reportid or fileid is missing; missing user/pass gets you a 401) # 401 = Unauthorised, check username/password? # 402 = Payment Required, not Premium # 404 = Not Found, data doesn't exist? # (only working for reportids, see Technical Limitations) # 450 = Try Later, wait <x> seconds for counter to reset # (for an explanation of this, see DNZB Rate Limiting) # 500 = Internal Server Error, please report to Administrator # 503 = Service Unavailable, site is currently down if rcode in ('500', '503'): _warn_user('Newzbin has a server problem (%s, %s), wait 5 min.' % (rcode, rtext)) return retry _access_ok() if rcode == '450': wait_re = re.compile('wait (\d+) seconds') try: wait = int(wait_re.findall(rtext)[0]) except: wait = 60 if wait > 60: wait = 60 logging.debug("Newzbin says we should wait for %s sec", wait) return int(wait + 1), None, None, None if rcode in ('402'): msg = Ta('You have no credit on your Newzbin account') return None, None, None, msg if rcode in ('401'): msg = Ta('Unauthorised, check your newzbin username/password') return None, None, None, msg if rcode in ('400', '404'): msg = Ta('Newzbin report %s not found') % msgid return None, None, None, msg if rcode != '200': msg = Ta('Newzbin gives undocumented error code (%s, %s)') % (rcode, rtext) return 60, None, None, msg # Process data report_name = response.getheader('X-DNZB-Name') report_cat = response.getheader('X-DNZB-Category') if not (report_name and report_cat): msg = Ta('Newzbin server fails to give info for %s') % msgid return 60, None, None, msg # sanitize report_name newname = sanitize_foldername(report_name) if len(newname) > 80: newname = newname[0:79].strip('. ') newname += ".nzb" logging.info('Successfully fetched report %s - %s (cat=%s) (%s)', msgid, report_name, report_cat, newname) return (newname, data, report_cat, nzo_info)
def __init__(self): def check_str(p): return p is None or p == '' or isinstance(p, str) def check_int(p): try: int(p) return True except: return False self.jobs = {} try: defined = config.get_rss().keys() feeds = sabnzbd.load_admin(RSS_FILE_NAME) if type(feeds) == type({}): for feed in feeds: if feed not in defined: logging.debug('Dropping obsolete data for feed "%s"', feed) continue self.jobs[feed] = {} for link in feeds[feed]: data = feeds[feed][link] if type(data) == type([]): # Convert previous list-based store to dictionary new = {} try: new['status'] = data[0] new['title'] = data[1] new['url'] = data[2] new['cat'] = data[3] new['pp'] = data[4] new['script'] = data[5] new['time'] = data[6] new['prio'] = str(NORMAL_PRIORITY) new['rule'] = 0 self.jobs[feed][link] = new except IndexError: del new else: # Consistency check on data try: item = feeds[feed][link] if not isinstance(item, dict) or not isinstance(item.get('title'), unicode): raise IndexError if item.get('status', ' ')[0] not in ('D', 'G', 'B', 'X'): item['status'] = 'X' if not isinstance(item.get('url'), unicode): item['url'] = '' item['url'] = item['url'].replace('www.newzbin.com', cfg.newzbin_url()) if not check_str(item.get('cat')): item['cat'] = '' if not check_str(item.get('orgcat')): item['orgcat'] = '' if not check_str(item.get('pp')): item['pp'] = '3' if not check_str(item.get('script')): item['script'] = 'None' if not check_str(item.get('prio')): item['prio'] = '-100' if not check_int(item.get('rule', 0)): item['rule'] = 0 if not isinstance(item.get('time'), float): item['time'] = time.time() if not check_int(item.get('order', 0)): item.get['order'] = 0 self.jobs[feed][link] = item except (KeyError, IndexError): logging.info('Incorrect entry in %s detected, discarding %s', RSS_FILE_NAME, item) remove_obsolete(self.jobs[feed], self.jobs[feed].keys()) except IOError: logging.debug('Cannot read file %s', RSS_FILE_NAME) # jobs is a NAME-indexed dictionary # Each element is link-indexed dictionary # Each element is another dictionary: # status : 'D', 'G', 'B', 'X' (downloaded, good-match, bad-match, obsolete) # '*' added means: from the initial batch # '-' added to 'D' means downloaded, but not displayed anymore # title : Title # url : URL or MsgId # cat : category # orgcat : category as read from feed # pp : pp # script : script # prio : priority # time : timestamp (used for time-based clean-up) # order : order in the RSS feed self.shutdown = False
def __init__(self): def check_str(p): return p is None or p == '' or isinstance(p, str) def check_int(p): try: int(p) return True except: return False self.jobs = {} try: defined = config.get_rss().keys() feeds = sabnzbd.load_admin(RSS_FILE_NAME) if type(feeds) == type({}): for feed in feeds: if feed not in defined: logging.debug('Dropping obsolete data for feed "%s"', feed) continue self.jobs[feed] = {} for link in feeds[feed]: data = feeds[feed][link] if type(data) == type([]): # Convert previous list-based store to dictionary new = {} try: new['status'] = data[0] new['title'] = data[1] new['url'] = data[2] new['cat'] = data[3] new['pp'] = data[4] new['script'] = data[5] new['time'] = data[6] new['prio'] = str(NORMAL_PRIORITY) new['rule'] = 0 self.jobs[feed][link] = new except IndexError: del new else: # Consistency check on data try: item = feeds[feed][link] if not isinstance( item, dict) or not isinstance( item.get('title'), unicode): raise IndexError if item.get('status', ' ')[0] not in ('D', 'G', 'B', 'X'): item['status'] = 'X' if not isinstance(item.get('url'), unicode): item['url'] = '' item['url'] = item['url'].replace( 'www.newzbin.com', cfg.newzbin_url()) if not check_str(item.get('cat')): item['cat'] = '' if not check_str(item.get('orgcat')): item['orgcat'] = '' if not check_str(item.get('pp')): item['pp'] = '3' if not check_str(item.get('script')): item['script'] = 'None' if not check_str(item.get('prio')): item['prio'] = '-100' if not check_int(item.get('rule', 0)): item['rule'] = 0 if not isinstance(item.get('time'), float): item['time'] = time.time() if not check_int(item.get('order', 0)): item.get['order'] = 0 self.jobs[feed][link] = item except (KeyError, IndexError): logging.info( 'Incorrect entry in %s detected, discarding %s', RSS_FILE_NAME, item) remove_obsolete(self.jobs[feed], self.jobs[feed].keys()) except IOError: logging.debug('Cannot read file %s', RSS_FILE_NAME) # jobs is a NAME-indexed dictionary # Each element is link-indexed dictionary # Each element is another dictionary: # status : 'D', 'G', 'B', 'X' (downloaded, good-match, bad-match, obsolete) # '*' added means: from the initial batch # '-' added to 'D' means downloaded, but not displayed anymore # title : Title # url : URL or MsgId # cat : category # orgcat : category as read from feed # pp : pp # script : script # prio : priority # time : timestamp (used for time-based clean-up) # order : order in the RSS feed self.shutdown = False