async def verify_email_by_link(self, link: UUID) -> bool: sql = 'SELECT "email" FROM email_verify_links WHERE link = $1;' async with self.pool.acquire() as con: # type: Connection row = await con.fetchrow(sql, link) if row is None or row["email"] is None or row["email"] == "": logger.debug('Verify ID: "' + link.__str__() + '" was not associated with any email') return False email = row["email"] sql = 'INSERT INTO verified_emails ("email") VALUES ($1);' try: async with self.pool.acquire() as con: # type: Connection await con.execute(sql, email) except Exception as e: logger.error('Failed to insert email "' + email + '" into database table "verified_emails"') logger.error(str(e)) return False logger.debug('E-mail: "' + email + '" was verified') sql = 'DELETE FROM email_verify_links WHERE "email" = $1;' async with self.pool.acquire() as con: # type: Connection await con.execute(sql, email) return True
def callback_attack(self, future: concurrent.futures.Future): # called when the future is done or cancelled try: exception = future.exception() except concurrent.futures.CancelledError as cancelled_error: exception = None if exception is not None: logger.exception(repr(exception), exc_info=False) job_id = id(future) lock = self.locks.pop(job_id, None) if lock is None: logger.error("Could not find lock for job {}".format(job_id)) return with lock: if future.cancelled(): lock.set_status(TaskInfoStatus.CANCELLED) else: lock.set_status(TaskInfoStatus.COMPLETED) if exception is not None: if isinstance(exception, CancelledError): lock.set_status(TaskInfoStatus.CANCELLED) else: lock.set_status(repr(exception)) lock.finish() update_dict = lock.update_dict() task_id = lock.task_id UploadedTask.query.filter_by(id=task_id).update(update_dict) db.session.commit() self.locks_onetime.append(lock)
def testcase_edit(testcase_id): test_case_obj = TestInterfacecase.get_by_id(testcase_id) if request.method == "GET": form = populate_interface_testcase(test_case_obj) return render_template( "test_cases/test_case.html", form=form, runner_setting=SystemSetting.get_runner_setting(), title=u"编辑") else: form = TestInterfaceCaseFrom(request.form) data_type = request.form.get("data_type") if form.validate(): test_case_obj.interface_url = form.interface_url.data test_case_obj.testcase_name = form.testcase_name.data test_case_obj.testcase_method = form.testcase_method.data test_case_obj.module = form.module.data test_case_obj.testcase_header = init_field_data( form.testcase_header.data) test_case_obj.testcase_query = init_field_data( form.testcase_query.data) if (data_type == "JSON_data_select"): test_case_body = form.testcase_json.data else: test_case_body = init_field_data(form.testcase_data.data) test_case_obj.testcase_body = test_case_body test_case_obj.testcase_verification = init_verification_data( form.testcase_verification.data) db.session.add(test_case_obj) db.session.commit() return success() else: logger.error(form.errors) return fail(2, error=form.errors)
def fetch_status(self, first): url = self.status_prefix.format(self.account.nickname, first) status_list = [] try: response = yield self.load_page(url, {'Cookie': self.cookie}) if not response: return False soup = self.get_lxml_bs4(response.body) status_table = soup.find('table', class_='table_text') for row in status_table.children: if row.name != 'tr': continue if row.get('class') and 'table_header' in row.get('class'): continue td_text = [td.text for td in row.children] status = { 'type': DataType.Submit, 'account': self.account, 'status': submit.SubmitStatus.BROKEN, 'run_id': td_text[0], 'submit_time': td_text[1], 'result': td_text[2], 'pro_id': td_text[3], 'run_time': td_text[4][:-2], 'memory': td_text[5][:-1], 'lang': td_text[7], 'code': None } status_list.append(status) return status_list except Exception as ex: logger.error(ex) logger.error('{} fetch status account: {} first: {}'.format(self.TAG, self.account, first))
def get_status(self, handle, start=1, length=50): is_gym = lambda cid: len(str(cid)) >= 6 url = self.status_prefix.format(handle, start, length) try: response = yield self.load_page(url) if not response: return False response_data = json.loads(response.body.decode()) if response_data['status'] != 'OK': return False result = response_data['result'] for row in result: if is_gym(row['contestId']): continue pro_id = '{0}{1}'.format(row['contestId'], row['problem']['index']) submit_at = datetime.fromtimestamp(row['creationTimeSeconds']) code = yield self.get_code(row['contestId'], row['id']) status = { 'pro_id': pro_id, 'run_id': row['id'], 'submit_time': submit_at, 'run_time': row['timeConsumedMillis'], 'memory': row['memoryConsumedBytes'] // 1024, 'lang': row['programmingLanguage'], 'code': code, 'result': row['verdict'] } print(status) except Exception as e: logger.error(e)
def configure_application(options: WebAppOptions): ioloop = tornado.ioloop.IOLoop.current() webapp = tornado.web.Application( [ (r"/", MainHandler), (r"/sign-in", SignInHandler), (r"/sign-out", SignOutHandler), (r"/sign-up", SignUpHandler), (r"/login", tornado.web.RedirectHandler, dict(url=r"/sign-in")), ], cookie_secret=options.cookie_secret, template_path=os.path.join(os.path.dirname(__file__), "..", "..", "templates"), static_path=os.path.join(os.path.dirname(__file__), "..", "..", "static"), login_url="/sign-in", xsrf_cookies=options.xsrf, ioloop=ioloop, debug=options.debug) if options.https is True: cert_file = os.path.abspath(options.cert_file) private_file = os.path.abspath(options.private_file) if os.path.isfile(cert_file) is False: logger.error( "Path specified in config for certification points to a non-file: " + cert_file) raise FileNotFoundError("Given path is not a file: " + cert_file) if os.path.isfile(private_file) is False: logger.error( "Path specified in config for private key points to a non-file: " + private_file) raise FileNotFoundError("Given path is not a file: " + private_file) ssl_ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) ssl_ctx.load_cert_chain(cert_file, private_file) http_server = tornado.httpserver.HTTPServer(webapp, ssl_options=ssl_ctx) http_server.listen(options.port) db = init_db(options) if db is not None: webapp.db = asyncio.get_event_loop().run_until_complete(db) else: webapp.db = None return http_server else: webapp.listen(options.port) db = init_db(options) if db is not None: webapp.db = asyncio.get_event_loop().run_until_complete(db) else: webapp.db = None return webapp
def wrapper(*args, **kwargs): left_times = times call_state, ret = False, None while left_times > 0 and call_state is False: try: if left_times != times: logger.warn('重试第 {0} 次 ===> {1}({2})'.format( times - left_times, function.__name__, args)) ret = yield function(*args, **kwargs) if isinstance(ret, bool): call_state = ret elif not ret: call_state = False else: call_state = True if not call_state: yield gen.sleep(duration) except Exception as e: logger.error(e) finally: left_times -= 1 if call_state is False: message = '<After try {0} times> def {1}({2}) call fail'.format( times, function.__name__, args) logger.error(message) return ret
def _valid(self, schema, value, depth=0): if depth > MAX_DEPTH: logger.warning( f"Dict is too deep. Exceeded the given value {MAX_DEPTH}") raise False if not schema["rules"](value): logger.error(f"Wrong value {value}") raise False if schema["field_type"] in [list, dict]: for sub_value in value: if schema["sub"]["field_type"] != dict: if not schema["sub"]["rules"](sub_value): logger.error("Not validation") raise False else: for sub_key in schema["sub"].keys(): if sub_key == "field_type": continue if sub_key in sub_value: self._valid(schema["sub"][sub_key], sub_value[sub_key], depth) depth += 1
def fetch_status(self, first=''): url = self.status_prefix.format('Raychat', first) status_list = [] try: response = yield self.load_page(url) if not response: return False soup = self.get_lxml_bs4(response.body) status_table = soup.find('table', class_='a') for row in status_table.children: if row.name != 'tr': continue if row.get('class') and 'in' in row.get('class'): continue td_text = [td.text for td in row.children if td.name == 'td'] code = yield self.get_code(td_text[0]) run_time = td_text[5][:-2] or '-1' memory = td_text[4][:-1] or '-1' status = { 'run_id': td_text[0], 'submit_time': td_text[8], 'result': td_text[3], 'pro_id': td_text[2], 'run_time': run_time, 'memory': memory, 'lang': td_text[6], 'code': code } status_list.append(status) return status_list except Exception as ex: logger.error(ex) logger.error('{} fetch status => user_id: {} top: {}'.format(self.TAG, 'Raychat', first))
def is_valid(self, content): if self.schema: acceptable_sections = self.schema.keys() for section_name, section_value in content.items(): if not section_name in acceptable_sections: logger.error(f"Unacceptable section: {section_name}") return False for schema_key, schema_value in self.schema[ section_name].items(): try: if type(section_value) is list: for s_value in section_value: self._check_item(schema_key, schema_value, s_value) else: self._check_item(schema_key, schema_value, section_value) except: return False return True return False
def read_hashcat_brain_password(): if not HASHCAT_BRAIN_PASSWORD_PATH.exists(): logger.error("Hashcat brain password file does not exist. Generating a random password.") HASHCAT_BRAIN_PASSWORD_PATH.write_text(secrets.token_hex(16)) with open(HASHCAT_BRAIN_PASSWORD_PATH) as f: brain_password = f.readline().rstrip() return brain_password
def spider_runner(idx): logger.info('[SpiderRunner #{0}] start running'.format(idx)) while True: cur_account = yield AccountQueue.get() logger.info( '[SpiderRunner #{0}] {1} <=== account_queue(size={2})'.format( idx, cur_account, AccountQueue.qsize())) # let spider.run() worker = yield SpiderFactory[cur_account.oj_name].get() worker.account = cur_account try: yield worker.run() cur_account.set_status(account.AccountStatus.NORMAL) except LoginException as ex: logger.error(ex) cur_account.set_status(account.AccountStatus.ACCOUNT_ERROR) yield gen.sleep(60 * 2) except Exception as ex: logger.error(ex) cur_account.set_status(account.AccountStatus.UPDATE_ERROR) yield gen.sleep(60 * 2) finally: cur_account.save() # work done logger.info('[SpiderRunner #{0}] {1} work done'.format( idx, cur_account)) SpiderFactory[cur_account.oj_name].task_done() AccountQueue.task_done() yield SpiderFactory[cur_account.oj_name].put(worker)
def process_task(taskId): with app.app_context(): try: task = db.session.query(Task).filter(Task.id == taskId).one() task.status = 'deploying' db.session.commit() steps = Step.query.filter(Step.taskId == taskId).all() returncode = 0 for step in steps: returncode = worker.process(step.content, step.id) logger.info("returncode for step %s is %s" % (step.id, returncode)) step.log = worker.logs.get(step.id, '') logger.info(worker.logs) if worker.logs.has_key(step.id): worker.logs.pop(step.id) if returncode != 0: step.status = 'failed' else: step.status = 'success' db.session.commit() if step.status == 'failed': break if returncode != 0: task.status = 'failed' else: task.status = 'success' db.session.commit() # del process_tasks[task.id] except Exception, e: logger.error('error while process task %s' % task.id) logger.error(traceback.format_exc())
def fetch_status(self, first): url = self.status_prefix.format('Raychat', first) status_list = [] try: response = yield self.load_page(url, {'cookie': self.cookie}) if not response: return False soup = self.get_lxml_bs4(response.body) status_table = soup.find('table', class_='table_text') for row in status_table.children: if row.name != 'tr': continue if row.get('class') and 'table_header' in row.get('class'): continue td_text = [td.text for td in row.children] code = yield self.get_code(td_text[0]) status = { 'run_id': td_text[0], 'submit_time': td_text[1], 'result': td_text[2], 'pro_id': td_text[3], 'run_time': td_text[4][:-2], 'memory': td_text[5][:-1], 'lang': td_text[7], 'code': code } status_list.append(status) return status_list except Exception as ex: logger.error('{} fetch status nickname: {} first: {}'.format(self.TAG, 'Raychat', first), ex)
def run_app(): from subprocess import Popen import sys os.chdir(os.path.abspath(os.path.dirname(__file__))) path = os.path.join(os.path.abspath(os.path.dirname(__file__)), "manage.py") args = [sys.executable, path, "db"] if not os.path.exists(os.path.join(config.DATA_DIR, "plexivity.db")): from app import db db.create_all() args.append("stamp") args.append("head") else: args.append("upgrade") Popen(args) helper.startScheduler() if config.USE_SSL: helper.generateSSLCert() try: from OpenSSL import SSL context = SSL.Context(SSL.SSLv23_METHOD) context.use_privatekey_file(os.path.join(config.DATA_DIR, "plexivity.key")) context.use_certificate_file(os.path.join(config.DATA_DIR, "plexivity.crt")) app.run(host="0.0.0.0", port=config.PORT, debug=False, ssl_context=context) except: logger.error("plexivity should use SSL but OpenSSL was not found, starting without SSL") app.run(host="0.0.0.0", port=config.PORT, debug=False) else: app.run(host="0.0.0.0", port=config.PORT, debug=False)
def get_submits(self): try: post_body = parse.urlencode(self._gen_status_params()) response = yield self.fetch(self.status_url, method=HttpMethod.POST, body=post_body) res = json.loads(response.body.decode('utf-8')) status_data = res['data'] if len(status_data) == 0: return submits_list = [] for row in status_data: submit_at = datetime.fromtimestamp(int(str(row[8])[:-3])) code = yield self.get_code(row[0]) status = { 'run_id': row[0], 'pro_id': row[12], 'lang': row[6], 'run_time': row[5], 'memory': row[4], 'submit_time': submit_at, 'result': row[3], 'code': code } submits_list.append(status) except Exception as e: logger.error(e)
def fetch_status(self, first=''): url = self.status_prefix.format('Raychat', first) status_list = [] try: response = yield self.load_page(url) if not response: return False soup = self.get_lxml_bs4(response.body) status_table = soup.find('table', class_='a') for row in status_table.children: if row.name != 'tr': continue if row.get('class') and 'in' in row.get('class'): continue td_text = [td.text for td in row.children if td.name == 'td'] code = yield self.get_code(td_text[0]) run_time = td_text[5][:-2] or '-1' memory = td_text[4][:-1] or '-1' status = { 'run_id': td_text[0], 'submit_time': td_text[8], 'result': td_text[3], 'pro_id': td_text[2], 'run_time': run_time, 'memory': memory, 'lang': td_text[6], 'code': code } status_list.append(status) return status_list except Exception as ex: logger.error(ex) logger.error('{} fetch status => user_id: {} top: {}'.format( self.TAG, 'Raychat', first))
def __init__(self): try: module_path = f"app.api.validation.schemas.{self.name}" module = __import__(module_path, fromlist=[self.name]) self.schema = module.schema except: self.schema = None logger.error("Schema not found")
def get_by_url_method(cls, url, method): interface = None try: interface = cls.query.filter_by(interface_url=url, interface_method=method).one() except NoResultFound: logger.error("没有找到!") return interface
def load_page(url, headers=None): response = None try: response = yield Spider.fetch(url, headers=headers) except httpclient.HTTPError as ex: logger.error('加载 {} 失败: {}'.format(url, ex)) raise LoadPageException('加载 {} 失败: {}'.format(url, ex)) finally: return response
def get_code(self, run_id): url = self.code_url_prefix.format(run_id) try: response = yield self.load_page(url, {'cookie': self.cookie}) soup = self.get_lxml_bs4(response.body) code = soup.find('pre', class_='sh-c').text return code except Exception as e: logger.error(e)
def get_flush_session(): session = __Session() try: yield session session.flush() except Exception as e: app_logger.error("Error during flush session: {}".format(str(e))) session.rollback() raise
def send_notification(message): logger.info(u"sending notification to Pushbullet: %s" % message) args = {"type": "note", "title": message, "body": message} status = requests.post("https://api.pushbullet.com/v2/pushes", auth=(config.PUSHBULLET_KEY, ""), data=args) if status.ok: logger.info(u"Notification to Pushbullet successfully send: %s" % status.content) return True else: logger.error(u"unable to send notification to pushbullet: %s" % status.content) return False
def send_notification(message): logger.info(u"sending notification to Boxcar: %s" % message) args = {'notification[long_message]': message, 'notification[title]': "plexivity", 'notification[sound]': 'bird-1', 'user_credentials': config.BOXCAR_TOKEN} status = requests.post("https://new.boxcar.io/api/notifications", data=args, timeout=2) if status.ok: logger.info(u"Notification to Boxcar successfully send: %s" % status.content) return True else: logger.error(u"unable to send notication to boxcar %s" % status.content) return False
def handle_invalid_usage(err: Exception) -> Dict: """ This method will handle the exceptions if any type of invalid access is reported. :param err: Any kind of exception :return: A JSON response with essential information and an error message """ logger.error(traceback.print_exc()) return error(message=err)
def send_notification(message): logger.info(u"sending notification to Pushover: %s" % message) args = {"token": config.PUSHOVER_TOKEN, "user": config.PUSHOVER_USER, "message": message} status = requests.post("https://api.pushover.net/1/messages.json", data=args) if status.ok and status.json()["status"] == 1: logger.info(u"Notification to Pushover successfully send with response %s" % status.content) return True else: logger.error(u"Unable to send notification to pushover: %s" % status.content) return False
def send_notification(message): logger.info(u"sending notification mail: %s" % message) msg = Message("plexivity notification", recipients=[config.MAIL_RECIPIENT], sender=config.MAIL_FROM) msg.body = message if mail.send(msg): logger.info(u"Notification mail successfully send") return True else: logger.error(u"unable to send mail notification") return False
def get_commit_session(): session = __Session() try: yield session session.commit() except Exception as e: app_logger.error("Error during commit session: {}".format(str(e))) session.rollback() finally: session.close() __Session.remove()
async def update_user(self, user_id: UUID, name: str, email: str, password: str = None) -> Union[User, None]: user = await self.get_user_by_id(user_id) if email != user.email: email_dao = EmailDao(self.pool) await email_dao.remove_verify_link_for_email(user.email) await email_dao.unverify_email(user.email) await self.unverify_user_by_email(user.email) if password is not None: hashed = hashpw(password.encode("utf8"), gensalt()).decode("utf8") sql = "UPDATE users SET name = $1, email = $2, password = $3 WHERE id = $4" try: async with self.pool.acquire() as con: # type: Connection await con.execute(sql, name, email, hashed, user_id) except Exception as e: logger.error("Failed to update user: "******"UPDATE users SET name = $1, email = $2 WHERE id = $3" try: async with self.pool.acquire() as con: # type: Connection await con.execute(sql, name, email, user_id) except Exception as e: logger.error("Failed to update user: "******"TornadoBase: New e-mail address", "Account with username: '******' has specified this e-mail as it's new e-mail address.", True, link) sql = "SELECT id, name, email, created FROM users WHERE id = $1" async with self.pool.acquire() as con: # type: Connection row = await con.fetchrow(sql, user_id) user = User() user.id = row["id"] user.name = row["name"] user.email = row["email"] user.created = row["created"] return user
def __create_snapshot(self): try: snap = self.api.VM.snapshot(self.vm_obj, self.vm_name) logger.info('Created snapshot {}'.format(self.vm_name)) return snap except Exception as e: error = 'Creating VM {} snapshot error; cause: {}'.format( self.vm_name, str(e)) logger.error(error) raise Exception(error)
def get_code(self, run_id): url = self.source_code_prefix.format(run_id) try: response = yield self.load_page(url, {'cookie': self.cookie}) if not response: return False soup = self.get_lxml_bs4(response.body) code = soup.find('textarea', id='usercode').text return code except Exception as ex: logger.error('{} fetch {}\'s {} code error'.format(self.TAG, 'Raychat', run_id), ex)
def verify_products_attribute(self, category_name): no_errors = True category = self.product_category[category_name] for product in self.category_products(category): title = product.find_element(*get_value(category).category_product_title).text price = self.get_price(product, category) # print(f'Title: {title}\tPrice {price}') if not title or not price: logger.error(f"Product has no Title or Price: '{title}' - '{price}'") no_errors = False assert no_errors, "Product(s) doesn't have title ot price"
def get_code(self, contest_id, run_id): url = self.code_prefix.format(contest_id, run_id) try: response = yield self.load_page(url) if not response: return None soup = self.get_lxml_bs4(response.body) code = soup.find('pre', class_='program-source').text return code except Exception as e: logger.error(e)
def connect(): try: connection = pymysql.connect(host=envString("DB_HOST"), port=envInt("DB_PORT"), user=envString("DB_USERNAME"), password=envString("DB_PASSWORD"), db=envString("DB_DATABASE"), cursorclass=pymysql.cursors.DictCursor) return connection except Exception as error: logger.error(str(error)) return None
def __init__(self, response: requests.Response, hint: str = None, description: str = None, message: str = None): super().__init__(response.status_code, hint, description, message) logger.error( f"[PostgREST] Error {response.status_code} - {response.url}") self.response = response # NOTE: Maybe this is bad? We are redifining error_body with a new value self.error_body = self.postgres_error_details(self.response, self.error_body)
def consume_product(): logger.info('consume_product()') stock = svc.get_stock() stock_products = sorted( [sp for sp in stock.stock_products if sp.amount > 0], key=lambda sp: sp.product.name, ) for stock_product in stock_products: stock_product.manufacturer = svc.get_manufacturer_by_lot_number( stock_product.lot_number) form_context = { 'stock_products': stock_products, } form = forms.ConsumeProductForm(**form_context) if form.validate_on_submit(): logger.info('POSTing a valid form to consume_product') logger.info('Creating a new SUB Transaction') try: selected_stock_product = StockProduct.query.get( form.stock_product_id.data) logger.info('Retrieving info from selected_stock_product') product = selected_stock_product.product lot_number = selected_stock_product.lot_number amount = form.amount.data stock.subtract(product, lot_number, amount) logger.info('Commiting subtraction') consumer_user = User.query.filter_by( id=form.consumer_id.data).first() db.session.commit() logger.info('Creating sub-transaction') svc.create_sub_transaction(consumer_user, product, lot_number, amount, stock) flash( '{} unidades de {} removidas do estoque com sucesso!'.format( form.amount.data, selected_stock_product.product.name), 'success', ) return redirect(url_for('.consume_product')) except ValueError as err: logger.error(err) form.amount.errors.append( 'Não há o suficiente desse reativo em estoque.') except Exception: flash('Erro inesperado, contate o administrador.', 'danger') return render_template('main/consume-product.html', form=form)
def get_solved(self): url = self.user_info_prefix.format('Rayn') try: response = yield self.load_page(url) if not response: return False ret = json.loads(response.body.decode()) if ret['status'] != 'OK': return False user_info = ret['result'][0] return { 'rating': user_info['rating'], 'maxRating': user_info['maxRating'] } except Exception as e: logger.error(e)
def get_code(self, run_id): url = self.source_code_prefix.format(run_id) print(url) try: response = yield self.load_page(url, {'cookie': self.cookie}) if not response: return False soup = self.get_lxml_bs4(response.body) pre_node = soup.find('pre') if not pre_node: return False logger.debug("fetch code {} success".format(run_id)) return pre_node.text except Exception as ex: logger.error(ex) logger.error('{} fetch {}\'s {} code error'.format(self.TAG, 'Raychat', run_id))
def save(self, key, detail, dbredis, expired=0): """ Function for saving data redis """ try: dbredis = self.__dbredis if not self.redis: logger.error('Redis not connected.') raise ValueError('Redis not connected.') detail = json.dumps(detail) # Set data redis self.redis.set(REDIS_SETTING['prefix'] + ":" + key, detail, expired) except Exception as error: return False
def get_rating(self): url = self.user_url_prefix.format('Raychat') try: response = yield self.load_page(url, {'cookie': self.cookie}) if not response: return False soup = self.get_lxml_bs4(response.body) profile_heading = soup.find('div', id='profile-heading') if profile_heading: ratings = profile_heading.find_all('span', class_='bigggger') if len(ratings) == 2: return {'solved': ratings[1].text, 'submitted': ratings[0].text} except Exception as ex: logger.error(ex) logger.error('{} {} get Rating error'.format(self.TAG, self.account))
def get_solved(self): url = self.user_url_prefix.format('Raychat') try: response = yield self.load_page(url) if not response: return False soup = self.get_lxml_bs4(response.body) # solved count solved_count = soup.find('a', href=re.compile("^status\?result=0")).text submitted_count = soup.find('a', href=re.compile("^status\?user_id")).text # solved list solved_list = self._get_solved_list(soup) return { 'solved': solved_count, 'submitted': submitted_count, 'solved_list': solved_list } except Exception as ex: logger.error('{} {} get Solved/Submitted error: {}'.format(self.TAG, self.account, ex)) raise ex
def _request(self, url, args=dict()): if self.token: args["X-Plex-Token"] = self.token try: result = self.session.get("%s%s" % (self.url, url), params=args) logger.debug(u"PLEX => requested url: %(url)s" % {"url": url}) logger.debug(u"PLEX => requests args: %s" % args) if result.status_code == 401 and config.PMS_USER != "username" and config.PMS_PASS != "password": logger.debug(u"PLEX => request failed, trying with auth") self.session.headers.update({'X-Plex-Client-Identifier': 'plexivity'}) self.session.headers.update({'Content-Length': 0}) self.session.auth = (config.PMS_USER, config.PMS_PASS) x = self.session.post("https://my.plexapp.com/users/sign_in.xml") if x.ok: json = xml2json(x.content, strip_ns=False) self.token = json["user"]["authentication-token"] args["X-Plex-Token"] = self.token logger.debug(u"PLEX => auth successfull, requesting url %(url)s again" % {"url": url}) result = self.session.get("%s%s" % (self.url, url), params=args) else: return False if result and "xml" in result.headers['content-type']: import xml.etree.ElementTree as ET #json = xml2json(result.content, strip_ns=False) json = ET.fromstring(result.content) return json elif result.ok: return result.content else: logger.error(u"PLEX => there was an error with the request") return False except requests.ConnectionError: logger.error(u"PLEX => could not connect to Server!!!") return False
def get_solved(self): url = self.user_url_prefix.format('Raychat') try: response = yield self.load_page(url, {'cookie': self.cookie}) if not response: return False soup = self.get_lxml_bs4(response.body) # solved count count = soup.find_all('td', text=['Problems Submitted', 'Problems Solved']) submitted_count = count[0].next_sibling.text solved_count = count[1].next_sibling.text # solved list solved_list = self._get_solved_list(soup) return { 'solved': solved_count, 'submitted': submitted_count, 'solved_list': solved_list } except Exception as ex: logger.error('{} {} get Solved/Submitted error: {}'.format(self.TAG, self.account, ex)) raise ex
def send_notification(message): auth = tweepy.OAuthHandler("T4NRPcEtUrCEU58FesRmRtkdW", "zmpbytgPpSbro6RZcXsKgYQoz24zLH3vYZHOHAAs5j33P4eoRg") auth.set_access_token(config.TWITTER_ACCESS_TOKEN, config.TWITTER_ACCESS_TOKEN_SECRET) api = tweepy.API(auth) try: api.auth.get_username() except: logger.error(u"check your twitter credits!") return False logger.info(u"sending notification to twitter: %s" % message) if config.TWITTER_USE_DM: status = api.send_direct_message(user=config.TWITTER_DM_USER, text=message) else: status = api.update_status(status=message) if status: logger.info(u"Notification to twitter successfully send: %s" % status.text) return True else: logger.error(u"unable to send twitter notification: %s" % status) return False
def task(): p = plex.Server(config.PMS_HOST, config.PMS_PORT) live = p.currentlyPlaying() started = get_started() playing = dict() recentlyAdded = p.recentlyAdded() if len(recentlyAdded): logger.debug("processing recently added media") for x in recentlyAdded: check = db.session.query(models.RecentlyAdded).filter(models.RecentlyAdded.item_id == x.get("ratingKey")).first() if check: logger.debug("already notified for recently added '%s'" % check.title) continue if x.get("type") == "season" or x.get("type") == "epsiode": fullseason = p.episodes(x.get("ratingKey")) for ep in fullseason: if x.get("addedAt") == ep.get("addedAt"): xml = p.getInfo(ep.get("ratingKey")).find("Video") else: xml = p.getInfo(x.get('ratingKey')).find("Video") if not xml: logger.error("error loading xml for recently added entry") continue info = info_from_xml(xml, "recentlyadded", 1, 1, 0) info["added"] = datetime.datetime.fromtimestamp(float(x.get("addedAt"))).strftime("%Y-%m-%d %H:%M") if notify(info): logger.info(u"adding %s to recently added table" % info["title"]) new = models.RecentlyAdded() new.item_id = x.get("ratingKey") new.time = datetime.datetime.now() new.filename = xml.find("Media").find("Part").get("file") new.title = info["title"] new.debug = "%s" % info db.session.merge(new) db.session.commit() else: logger.debug("nothing was recently added") if live and not len(live): logger.debug("seems like nothing is currently played") for session in live: #logger.debug(session.tostring()) userID = session.find('User').get('id') if not userID: userID = "Local" db_key = "%(id)s_%(key)s_%(userid)s" % { "id": session.get('sessionKey'), "key": session.get('key'), "userid": userID } playing[db_key] = 1 logger.debug(playing) did_unnotify = 0 un_done = get_unnotified() if un_done: logger.debug("processing unnotified entrys from database") for k in un_done: start_epoch = k.time stop_epoch = k.stopped if not stop_epoch: stop_epoch = datetime.datetime.now() ntype = "stop" if k.session_id in playing: ntype = "start" paused = get_paused(k.session_id) info = info_from_xml(k.xml, ntype, start_epoch, stop_epoch, paused) logger.debug(info) logger.debug("sending notification for: %s : %s" % (info["user"], info["orig_title_ep"])) #TODO: fix this.... for now just dont notify again! if notify(info): k.notified = 1 #make sure we have a stop time if we are not playing this anymore! if ntype == "stop": k.stopped = stop_epoch k.progress = int(info["percent_complete"]) db.session.commit() set_notified(k.session_id) did_unnotify = 1 else: logger.info("nothing found to send (new) notifications for") did_unnotify = 1 ## notify stopped ## redo this! currently everything started is set to stopped? if did_unnotify: logger.info("processing recently started entrys from db and checking for stopped") #started = get_started() for k in started: logger.debug("checking if %s is still in playling list" % k.session_id) if not k.session_id in playing: logger.debug("%s is stopped!" % k.session_id) start_epoch = k.time stop_epoch = datetime.datetime.now() xml = ET.fromstring(k.xml) xml.find("Player").set('state', 'stopped') process_update(xml, k.session_id) paused = get_sec_paused(k.session_id) info = info_from_xml(k.xml, "stop", start_epoch, stop_epoch, paused) k.stopped = datetime.datetime.now() k.paused = None k.notified = 0 #set_stopped(started[k.session_id, stop_epoch) #https://github.com/ljunkie/plexWatch/blob/master/plexWatch.pl#L552 info["decoded"] = 1 if notify(info): k.notified = 1 k.progress = info['percent_complete'] db.session.merge(k) db.session.commit() ## notify start/now playing logger.debug("processing live content") was_started = dict() for k in live: if k.get('librarySectionID') in config.EXCLUDE_SECTIONS: logger.info("Watching something from section: %s which is in EXCLUDE_SECTIONS: %s" % (k.get('librarySectionID'), config.EXCLUDE_SECTIONS)) continue if k.get('type') == "clip": logger.info("Skipping Video-Clip like trailers, specials, scenes, interviews etc..") continue start_epoch = datetime.datetime.now() stop_epoch = None #not stopped yet xml_string = ET.tostring(k) info = info_from_xml(k, "start", start_epoch, stop_epoch, 0) info["decoded"] = 1 # logger.debug(info) userID = info["userID"] if not userID: userID = "Local" db_key = "%(id)s_%(key)s_%(userid)s" % { "id": k.get('sessionKey'), "key": k.get('key'), "userid": userID } logger.debug("plex returned a live element: %s " % db_key) ## ignore content already been notified #TODO: get_startet should return a dict accessable by db_key #so we can check: if x in startet: check for change, if not mark as started now #first go through all started stuff and check for status change if started: logger.debug("we still have not stopped entrys in our database checking for matches") for x in started: logger.debug("checking if db entry '%s' is in live content " % x.session_id) state_change = False if x.session_id == db_key: logger.debug("that was a match! check for status changes") #already in database only check for status changes! state_change = process_update(k, db_key) was_started[db_key] = x if state_change: info["ntype"] = state_change logger.debug("%s: %s: state changed [%s] notify called" % (info["user"], info["title"], info["state"])) notify(info) else: logger.debug("all entrys in our database have been set to stopped") #also check if there is a element in the db which may be a resumed play from up to 24 hours ago if not db_key in was_started: logger.debug("trying to search for similar plays which stopped in the last 24 hours") view_offset = k.get("viewOffset") max_time = datetime.datetime.now() - datetime.timedelta(hours=24) like_what = "%" + k.get('key') + "_" + userID restarted = db.session.query(models.Processed).filter(models.Processed.session_id.like(like_what)).filter(models.Processed.time > max_time).filter(models.Processed.view_offset <= view_offset).filter(models.Processed.stopped != None).first() if restarted: logger.debug("seems like someone repeated an stopped play, updating db key from %s to %s" % (restarted.session_id, db_key)) restarted.session_id = db_key restarted.stopped = None db.session.commit() state_change = process_update(k, db_key) was_started[db_key] = restarted info["ntype"] = "resume" notify(info) else: #if still not processed till now, its a new play! logger.debug("we got those entrys which already where in the database: %s " % was_started) logger.info("seems like this is a new entry: %s" % db_key) #unnotified insert to db and notify process_start(xml_string, db_key, info) if notify(info): set_notified(db_key)
def notify(info): if "orig_user" in info and info["orig_user"] in config.EXCLUDE_USERS: logger.info("'%s' is set as an EXCLUDE_USER, i'm not sending a notification!" % info["orig_user"]) return True #notify all providers with the given stuff... if info["ntype"] == "recentlyadded" and config.NOTIFY_RECENTLYADDED: try: message = config.RECENTLYADDED_MESSAGE % info except KeyError: logger.error("Unable to map info to your recently added notification string. Please check your settings!") elif info["ntype"] == "start" and config.NOTIFY_START: try: message = config.START_MESSAGE % info except KeyError: logger.error("Unable to map info to your start notification string. Please check your settings!") elif info["ntype"] == "stop" and config.NOTIFY_STOP: try: message = config.STOP_MESSAGE % info except KeyError: logger.error("Unable to map info to your stop notification string. Please check your settings!") elif info["ntype"] == "pause" and config.NOTIFY_PAUSE: try: message = config.PAUSE_MESSAGE % info except KeyError: logger.error("Unable to map info to your pause notification string. Please check your settings!") elif info["ntype"] == "resume" and config.NOTIFY_RESUME: try: message = config.RESUME_MESSAGE % info except KeyError: logger.error("Unable to map info to your resume notification string. Please check your settings!") elif info["ntype"] == "test": message = "plexivity notification test" else: message = False status = False if message and config.USE_PPSCRIPTS: from app.providers import scripts scripts.run_scripts(info, message) if message: #only log notify args if it actually calls notify! logger.debug("notify called with args: %s" % info) if config.NOTIFY_PUSHOVER: from app.providers import pushover status = pushover.send_notification(message) if config.NOTIFY_PUSHBULLET: from app.providers import pushbullet status = pushbullet.send_notification(message) if config.NOTIFY_MAIL: from app.providers import mail status = mail.send_notification(message) if config.NOTIFY_BOXCAR: from app.providers import boxcar status = boxcar.send_notification(message) if config.NOTIFY_TWITTER: from app.providers import twitter status = twitter.send_notification(message) return status return False