def _sendText(self, receivers, title, content): # 设置email信息 # 邮件内容设置 message = MIMEText(content, 'plain', 'utf-8') # 邮件主题 message['Subject'] = title # 发送方信息 message['From'] = self.sender # 接受方信息 message['To'] = receivers[0] try: smtpObj = smtplib.SMTP_SSL( ) if self.sendType == "ssl" else smtplib.SMTP() # 连接到服务器 smtpObj.connect(self.mailHost, self.mailPort) smtpObj.ehlo() if self.sendType == "tls": smtpObj.starttls() # 登录到服务器 smtpObj.login(self.sender, self.passwd) # 发送 smtpObj.sendmail(self.sender, receivers, message.as_string()) # 退出 smtpObj.quit() Log.i(MailReporter.TAG, 'Mail successfully sent to ' + receivers[0]) except smtplib.SMTPException as e: Log.e(MailReporter.TAG, 'send() error', e)
def _sendWithAttachment(self, receivers, title, content, attachment=None): # 设置eamil信息 # 添加一个MIMEmultipart类,处理正文及附件 message = MIMEMultipart() message['From'] = self.sender message['To'] = receivers[0] message['Subject'] = title part = MIMEApplication(open(attachment, 'rb').read()) part.add_header('Content-Disposition', 'attachment', filename=attachment) # 将内容附加到邮件主体中 message.attach(MIMEText(content, 'plain', 'utf-8')) message.attach(part) # 登录并发送 try: smtpObj = smtplib.SMTP_SSL( ) if self.sendType == "ssl" else smtplib.SMTP() smtpObj.connect(self.mailHost, self.mailPort) smtpObj.ehlo() if self.sendType == "tls": smtpObj.starttls() smtpObj.login(self.sender, self.passwd) smtpObj.sendmail(self.sender, receivers, message.as_string()) Log.i(MailReporter.TAG, 'Mail successfully sent to ' + receivers[0]) smtpObj.quit() except smtplib.SMTPException as e: Log.e(MailReporter.TAG, 'send() error', e)
def write_pid_file(pid_file, pid): import fcntl import stat try: fd = os.open(pid_file, os.O_RDWR | os.O_CREAT, stat.S_IRUSR | stat.S_IWUSR) except OSError as e: Log.w(MAIN_TAG, "exception for write_pid_file()", e) return -1 flags = fcntl.fcntl(fd, fcntl.F_GETFD) assert flags != -1 flags |= fcntl.FD_CLOEXEC r = fcntl.fcntl(fd, fcntl.F_SETFD, flags) assert r != -1 # There is no platform independent way to implement fcntl(fd, F_SETLK, &fl) # via fcntl.fcntl. So use lockf instead try: fcntl.lockf(fd, fcntl.LOCK_EX | fcntl.LOCK_NB, 0, 0, os.SEEK_SET) except IOError: r = os.read(fd, 32) if r: Log.e(MAIN_TAG, 'already started at pid %s' % Utils.to_str(r)) else: Log.e(MAIN_TAG, 'already started') os.close(fd) return -1 os.ftruncate(fd, 0) os.write(fd, Utils.to_bytes(str(pid))) return 0
def daemon_start(pid_file): def handle_exit(signum, _): if signum == signal.SIGTERM: sys.exit(0) sys.exit(1) signal.signal(signal.SIGINT, handle_exit) signal.signal(signal.SIGTERM, handle_exit) # fork only once because we are sure parent will exit pid = os.fork() assert pid != -1 if pid > 0: # parent waits for its child time.sleep(5) sys.exit(0) # child signals its parent to exit ppid = os.getppid() pid = os.getpid() if write_pid_file(pid_file, pid) != 0: Log.e(MAIN_TAG, "write_pid_file() failed, pid = " + str(pid)) os.kill(ppid, signal.SIGINT) sys.exit(1) os.setsid() signal.signal(signal.SIG_IGN, signal.SIGHUP) Log.d(MAIN_TAG, 'started') os.kill(ppid, signal.SIGTERM) sys.stdin.close()
def main(): sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8') configPath = None parentPath = os.environ.get('HOME') if not parentPath: print('can not fetch $HOME') parentPath = "." parentPath += "/airbnb" if not os.path.exists(parentPath): os.mkdir(parentPath, mode=0o755) pidFilePath = parentPath + "/" + PID_FILE_NAME logPath = parentPath + "/all_logs.log" storagePath = parentPath + "/rooms.db" shortopts = 'h:c:d:l:s:v' # 命令行参数简写 longopts = [ 'help', 'storage-file=', 'log-file=', 'version', 'config-file=' ] # 完整体 # 执行动作 start 后台运行,stop 结束后台已经运行的实例 operation = None optlist, args = getopt.getopt(sys.argv[1:], shortopts, longopts) # 拿到命令行参数的key value for key, value in optlist: if key in ('-v', '--version'): print("version: airbnb fetcher 0.1") sys.exit(0) if key in ('-h', '--help'): printHelp() sys.exit(0) if key in ('-c', '--config-file'): configPath = value if key in ('-l', '--log-file'): logPath = value if key in ('-s', '--storage-file'): storagePath = value if key == '-d': operation = value # 配置日志模块 Log.config(logPath, echo=False) if operation == "start": daemon_start(pidFilePath) elif operation == "stop": daemon_stop(pidFilePath) sys.exit(0) if not configPath: Log.e(MAIN_TAG, "config path not provided") sys.exit(0) config = parseConfigFile(configPath) if not config: sys.exit(0) config.localStoragePath = storagePath service = SearchService(config) service.start()
def prepareDB(self, path): conn = sqlite3.connect(path) cursor = conn.cursor() try: # table for room cursor.execute( "CREATE TABLE IF NOT EXISTS room_info (_id INTEGER PRIMARY KEY AUTOINCREMENT,\ room_id INTEGER UNIQUE, person_capacity INTEGER, city VARCHAR(20), beds INTEGER, \ localized_neighborhood VARCHAR(50), price INTEGER, pic VARCHAR(200), update_time INTEGER,\ query_str VARCHAR(100))") # table for reservation cursor.execute( "CREATE TABLE IF NOT EXISTS reservation_info (_id INTEGER PRIMARY KEY AUTOINCREMENT,\ room_id INTEGER, date VARCHAR(20) )") except BaseException as e: Log.e(StorageService._TAG, "prepareDB() failed", e) finally: cursor.close() conn.commit() return conn
def start(self): print("airbnb service start") while True: while True: now = datetime.datetime.now() if now.hour == self._config.startHour and now.minute == self._config.startMinute: dates = self.prepareDate() self.analyzeCollection.clear() self.forExcel.clear() try: for item in dates: self.doQuery(item[0], item[1], item[2]) except BaseException as e: Log.e(SearchService.TAG, "doQuery() failed, ", e) if len(self.analyzeCollection) > 0: self.reportForAnalyzeResult(self.analyzeCollection, self.forExcel) else: Log.w(SearchService.TAG, "no analyze result generated") time.sleep(70) else: time.sleep(10) # in second
#!/usr/bin/env python # -*- coding: utf-8 -*- # 测试日志辅助类 import sys sys.path.append("../") from LogHelper import Log TAG = "Test" Log.d(TAG, "Hello") Log.e(TAG, "World!") Log.i(TAG, "Hehe") Log.w(TAG, "XXXX")
def daemon_stop(pid_file): import errno try: with open(pid_file) as f: buf = f.read() pid = Utils.to_str(buf) if not buf: Log.e(MAIN_TAG, 'not running') except IOError as e: Log.e(MAIN_TAG, "daemon_stop() fail", e) if e.errno == errno.ENOENT: # always exit 0 if we are sure daemon is not running Log.e(MAIN_TAG, 'not running') return sys.exit(1) pid = int(pid) if pid > 0: try: os.kill(pid, signal.SIGTERM) except OSError as e: if e.errno == errno.ESRCH: Log.e(MAIN_TAG, 'not running') # always exit 0 if we are sure daemon is not running return Log.e(MAIN_TAG, "daemon_stop() fail", e) sys.exit(1) else: Log.e(MAIN_TAG, 'pid is not positive: ' + str(pid)) # sleep for maximum 10s for i in range(0, 200): try: # query for the pid os.kill(pid, 0) except OSError as e: if e.errno == errno.ESRCH: break time.sleep(0.05) else: Log.e(MAIN_TAG, 'timed out when stopping pid ' + str(pid)) sys.exit(1) Log.d(MAIN_TAG, 'stopped') os.unlink(pid_file)