def mark_episode(self, task, entry, opener): """Mark episode as acquired. Required entry fields: - series_name - series_season - series_episode Raises: PluginWarning if operation fails """ if 'series_season' not in entry or 'series_episode' not in entry or 'series_name' not in entry: raise plugin.PluginWarning( 'Can\'t mark entry `%s` in myepisodes without series_season, series_episode and series_name fields' % entry['title'], log) if not self.lookup_myepisodes_id(entry, opener, session=task.session): raise plugin.PluginWarning('Couldn\'t get myepisodes id for `%s`' % entry['title'], log) myepisodes_id = entry['myepisodes_id'] season = entry['series_season'] episode = entry['series_episode'] if task.options.test: log.info('Would mark %s of `%s` as acquired.' % (entry['series_id'], entry['series_name'])) else: baseurl2 = request.Request( 'http://www.myepisodes.com/myshows.php?action=Update&showid=%s&season=%s&episode=%s&seen=0' % (myepisodes_id, season, episode)) opener.open(baseurl2) log.info('Marked %s of `%s` as acquired.' % (entry['series_id'], entry['series_name']))
def on_task_output(self, task, config): """Mark all accepted episodes as acquired on MyEpisodes""" if not task.accepted: # Nothing accepted, don't do anything return username = config['username'] password = config['password'] cookiejar = http.cookiejar.CookieJar() opener = request.build_opener(request.HTTPCookieProcessor(cookiejar)) baseurl = request.Request('http://www.myepisodes.com/login.php?') loginparams = parse.urlencode({'username': username, 'password': password, 'action': 'Login'}) try: logincon = opener.open(baseurl, loginparams) loginsrc = logincon.read() except URLError as e: log.error('Error logging in to myepisodes: %s' % e) return if str(username) not in loginsrc: raise plugin.PluginWarning(('Login to myepisodes.com failed, please check ' 'your account data or see if the site is down.'), log) for entry in task.accepted: try: self.mark_episode(task, entry, opener) except plugin.PluginWarning as w: log.warning(str(w))
def lookup_myepisodes_id(self, entry, opener, session): """Populates myepisodes_id field for an entry, and returns the id. Call will also set entry field `myepisode_id` if successful. Return: myepisode id Raises: LookupError if entry does not have field series_name """ # Don't need to look it up if we already have it. if entry.get('myepisodes_id'): return entry['myepisodes_id'] if not entry.get('series_name'): raise LookupError('Cannot lookup myepisodes id for entries without series_name') series_name = entry['series_name'] # First check if we already have a myepisodes id stored for this series myepisodes_info = session.query(MyEpisodesInfo).\ filter(MyEpisodesInfo.series_name == series_name.lower()).first() if myepisodes_info: entry['myepisodes_id'] = myepisodes_info.myepisodes_id return myepisodes_info.myepisodes_id # Get the series name from thetvdb to increase match chance on myepisodes if entry.get('tvdb_series_name'): query_name = entry['tvdb_series_name'] else: try: series = lookup_series(name=series_name, tvdb_id=entry.get('tvdb_id')) query_name = series.seriesname except LookupError as e: log.warning('Unable to lookup series `%s` from tvdb, using raw name.' % series_name) query_name = series_name baseurl = request.Request('http://www.myepisodes.com/search.php?') params = parse.urlencode({'tvshow': query_name, 'action': 'Search myepisodes.com'}) try: con = opener.open(baseurl, params) txt = con.read() except URLError as e: log.error('Error searching for myepisodes id: %s' % e) matchObj = re.search(r'&showid=([0-9]*)">' + query_name + '</a>', txt, re.MULTILINE | re.IGNORECASE) if matchObj: myepisodes_id = matchObj.group(1) db_item = session.query(MyEpisodesInfo).filter(MyEpisodesInfo.myepisodes_id == myepisodes_id).first() if db_item: log.info('Changing name to `%s` for series with myepisodes_id %s' % (series_name.lower(), myepisodes_id)) db_item.series_name = series_name.lower() else: session.add(MyEpisodesInfo(series_name.lower(), myepisodes_id)) entry['myepisodes_id'] = myepisodes_id return myepisodes_id
def send_request(self, method, params=None): req = request.Request(self.url) data = {'jsonrpc': '1.0', 'id': self.id, 'method': method} if params is not None: data['params'] = params query = bytes(json.dumps(data), encoding='utf-8') with closing(request.urlopen(req, query)) as conn: return json.load(codecs.getreader('utf-8')(conn), parse_float=util.parse_value)['result']
def get(self, url, params={}, headers={}, charset='UTF-8'): '''''HTTP GET 方法''' if params: url += '?' + urllib.parse.urlencode(params) req = request.Request(url) for k, v in headers.items(): req.add_header(k, v) # 为特定的 request 添加指定的 headers try: response = request.urlopen(req) except urllib.error.HTTPError as e: self.__error(e) else: return self.__decode(response.read(), charset)
def _sendWithUrlib(url, data): data = json.dumps(data).encode() clen = len(data) req = urllib_request.Request(url, data, { 'Content-Type': 'application/json', 'Content-Length': clen }) try: f = urllib_request.urlopen(req) except urllib_error.URLError: return None res = f.read() f.close() return res
def post(self, url, params={}, headers={}, charset='UTF-8'): '''''HTTP POST 方法''' params = urllib.parse.urlencode(params) req = request.Request( url, data=params.encode(charset)) # 带 data 参数的 request 被认为是 POST 方法。 for k, v in headers.items(): req.add_header(k, v) try: response = request.urlopen(req) data = self.__decode(response.read(), charset) except Exception as e: self.__error(e) else: return data
def load_defaults(service): try: default_url = urlparse.urlparse(service.DEFAULTS_URL) if default_url.scheme not in ['http', 'https', 'file']: raise Exception("Invalid scheme: {}".format(default_url.scheme)) proxy_handler = urllib.ProxyHandler({}) if service.proxy_uri: proxy_handler = urllib.ProxyHandler({ 'http': service.proxy_uri, 'https': service.proxy_uri }) opener = urllib.build_opener(proxy_handler) req = urllib.Request(service.DEFAULTS_URL) with opener.open(req, timeout=CONNECTION_TIMEOUT) as f: data = f.read() service.defaults = json.loads(data.decode()) except Exception as e: logging.getLogger(service.__module__).error( "Failed to load up to date defaults, using offline copy: {}". format(e)) service.defaults = service.OFFLINE_DEFAULTS
def _put(self, url, param_dict=None, securityHandler=None, additional_headers=None, proxy_url=None, proxy_port=80, compress=True): """ Performs a put operation on a URL. Inputs: param_dict - key/preParams pair of values that will be turned into a json string ex: {"foo": "bar"} securityHandler - object that handles the token or other site security. It must inherit from the base security class. ex: arcrest.AGOLSecurityHandler("SomeUsername", "SOMEPASSWORD") additional_headers - are additional key/preParams headers that a user wants to pass during the operation. ex: {"accept-encoding": "gzip"} proxy_url - url of the proxy proxy_port - default 80, port number of the proxy compress - default true, determines if gzip should be used of not for the web operation. Output: returns dictionary or string depending on web operation. """ # ensure that no spaces are in the url url = url.replace(" ", "%20") if param_dict is None: param_dict = {} if additional_headers is None: additional_headers = {} if self._verify == False and \ sys.version_info[0:3] >= (2, 7, 9) and \ hasattr(ssl, 'create_default_context'): ctx = ssl.create_default_context() ctx.check_hostname = False ctx.verify_mode = ssl.CERT_NONE headers = { "User-Agent": self.useragent, 'Accept': '*/*', 'Content-type': 'application/json' } if securityHandler and securityHandler.referer_url: headers['referer'] = securityHandler.referer_url # opener = None # return_value = None handlers = [RedirectHandler()] param_dict, handler, cj = self._processHandler(securityHandler, param_dict) if handler is not None: handlers.append(handler) if cj is not None: handlers.append(request.HTTPCookieProcessor(cj)) if compress: headers['Accept-Encoding'] = 'gzip' else: headers['Accept-Encoding'] = '' for k, v in additional_headers.items(): headers[k] = v del k, v hasContext = 'context' in self._has_context(request.urlopen) if self._verify == False and \ sys.version_info[0:3] >= (2, 7, 9) and \ hasattr(ssl, 'create_default_context'): ctx = ssl.create_default_context() ctx.check_hostname = False ctx.verify_mode = ssl.CERT_NONE opener = request.build_opener(*handlers) opener.addheaders = [(k, v) for k, v in headers.items()] request.install_opener(opener) data = urlencode(param_dict) if self.PY3: data = data.encode('ascii') data = json.dumps(param_dict) opener.data = data # request.get_method = lambda: 'PUT' req = request.Request("{}?token={}".format( self._asString(url), self._securityHandler.token), data=data, headers=headers) req.get_method = lambda: 'PUT' for k, v in headers.items(): req.add_header(k, v) if hasContext and self._verify == False: resp = request.urlopen(req, context=ctx) else: resp = request.urlopen(req) self._last_code = resp.getcode() self._last_url = resp.geturl() return_value = self._process_response(resp=resp) if isinstance(return_value, dict): if "error" in return_value and \ 'message' in return_value['error']: if return_value['error']['message'].lower( ) == 'request not made over ssl': if url.startswith('http://'): url = url.replace('http://', 'https://') return self._put(url, param_dict, securityHandler, additional_headers, proxy_url, proxy_port, compress) return return_value else: return return_value return return_value