Skip to main content

ΑΒΡΑΞΑΣ 설치

[설치] 데이터베이스 설치(PostgreSql)

데이터베이스 설치(PostgreSql)

- PostgreSql 설치

    • sudo apt install postgresql

- PostgreSql 외부 접근 허용

    • sudo vi /etc/postgresql/13/main/postgresql.conf
      • listen_addresses = '*'                  # what IP address(es) to listen on;
        #listen_addresses = 'localhost'         # what IP address(es) to listen on;
    • sudo vi /etc/postgresql/13/main/pg_hba.conf
      • # IPv4 local connections:
        #host    all             all             127.0.0.1/32            md5
        host    all             all             0.0.0.0/0            md5
        # IPv6 local connections:
        #host    all             all             ::1/128                 md5
        host    all             all             ::/0                 md5

- 계정만들기

sudo -u postgres psql -c "ALTER ROLE postgres WITH password '여기패스워드'" postgres 계정으로 로그인 패스워드는 '여기패스워드'로 정한 패스워드

- adminer-4.8.1.php 설치

- Database 생성 

  • database만들기.pngdatabase만들기.png

- 사용자 계정 생성 

  • CREATE USER pi PASSWORD 'archiverpw123!@#' SUPERUSER; 
     <--  계정이나 패스워드를 바꾸면 업그레이드 시에  war를 배포 후 tomcat 폴더의 webapps/archiver/WEB-INF/spring/root-context.xml의 DB 접속 정보를 매번 바꾸어야 한다. 

- Table 생성 

테이블생성.png


    테이블생성.png

    실행 sql 파일 createTable.sql 열어서 창에 위와 같이 붙여서 실행

    -- Adminer 4.8.1 PostgreSQL 13.11 (Raspbian 13.11-0+deb11u1) dump
    
    \connect "archiver";
    
    -- public.tb_archiver_sys_info definition
    
    -- Drop table
    
    DROP TABLE public.tb_archiver_sys_info;
    
    CREATE TABLE public.tb_archiver_sys_info (
    	sys_link varchar(500) NOT NULL,
    	sys_context_root varchar(500) NOT NULL,
    	sys_title varchar(100) NOT NULL,
    	sys_name varchar(100) NOT NULL,
    	sys_version varchar(100) NOT NULL,
    	sys_owner varchar(100) NOT NULL,
    	sys_date varchar(100) NOT NULL,
    	sys_manual_link varchar(100) NOT NULL,
    	sys_etc varchar(4000) NULL,
    	sys_message varchar(4000) NULL,
    	sys_storage varchar(1000) NULL,
    	sys_backup_location varchar(4000) NULL,
    	sys_backup_yn varchar(2) NOT NULL DEFAULT 'N'::character varying,
    	sys_backup_date timestamp NULL
    );
    
    
    INSERT INTO "tb_archiver_sys_info" ("sys_link", "sys_context_root", "sys_title", "sys_name", "sys_version", "sys_owner", "sys_date", "sys_manual_link", "sys_etc", "sys_message", "sys_storage", "sys_backup_location", "sys_backup_yn", "sys_backup_date") VALUES
    ('http://web.joang.com:8082',	'archiver',	'ΑΒΡΑΞΑΣ',	'아브라삭스',	'0.5',	'류현수',	'2023.05.28',	'http://web.joang.com:6875/books/abraksas-system',	'관리자 류현수 ',	'관리자 화면 완료 ',	'/media/pi/RaspRefp/data',	'/media/pi/RaspRefp/backup/ArchiverBackup',	'N',	'2023-06-06 07:39:02.571868');
    
    DROP TABLE IF EXISTS "tb_filemanager_meta";
    DROP SEQUENCE IF EXISTS seq_meta;
    CREATE SEQUENCE seq_meta INCREMENT 1 MINVALUE 1 MAXVALUE 9223372036854775807 CACHE 1;
    
    CREATE TABLE public.tb_filemanager_meta (
    	idx int4 NOT NULL DEFAULT nextval('seq_meta'::regclass),
    	user_id varchar(100) NOT NULL,
    	meta varchar(1000) NOT NULL,
    	crea_dtm date NOT NULL,
    	crea_id varchar(100) NOT NULL,
    	del_gb varchar(1) NOT NULL DEFAULT 'N'::character varying
    );
    
    
    DROP TABLE IF EXISTS "tb_filemanager_meta_file";
    DROP SEQUENCE IF EXISTS seq_file;
    CREATE SEQUENCE seq_file INCREMENT 1 MINVALUE 1 MAXVALUE 9223372036854775807 CACHE 1;
    
    -- DROP TABLE public.tb_filemanager_meta_file;
    
    CREATE TABLE public.tb_filemanager_meta_file (
    	idx int4 NOT NULL DEFAULT nextval('seq_file'::regclass),
    	file_title varchar(1000) NOT NULL,
    	file_detail varchar(4000) NOT NULL,
    	original_file_name varchar(500) NOT NULL,
    	stored_file_name varchar(1000) NOT NULL,
    	file_size int8 NOT NULL,
    	file_type varchar(10) NOT NULL,
    	crea_dtm date NOT NULL,
    	crea_id varchar(100) NOT NULL,
    	del_gb varchar(1) NOT NULL DEFAULT 'N'::character varying,
    	down_yn varchar(1) NULL,
    	error varchar(10000) NULL
    );
    
    
    DROP TABLE IF EXISTS "tb_filemanager_meta_mapping";
    DROP SEQUENCE IF EXISTS seq_meta_mapp;
    CREATE SEQUENCE seq_meta_mapp INCREMENT 1 MINVALUE 1 MAXVALUE 9223372036854775807 CACHE 1;
    
    -- DROP TABLE public.tb_filemanager_meta_mapping;
    
    CREATE TABLE public.tb_filemanager_meta_mapping (
    	idx int4 NOT NULL DEFAULT nextval('seq_meta_mapp'::regclass),
    	user_id varchar(100) NOT NULL,
    	meta_idx int4 NOT NULL,
    	file_idx int4 NOT NULL,
    	crea_dtm date NOT NULL,
    	crea_id varchar(100) NOT NULL,
    	del_gb varchar(1) NOT NULL DEFAULT 'N'::character varying
    );
    
    
    DROP TABLE IF EXISTS "tb_filemanager_meta_ref";
    CREATE TABLE public.tb_filemanager_meta_ref (
    	from_idx int4 NOT NULL,
    	to_idx int4 NOT NULL,
    	meta_ref int4 NOT NULL,
    	crea_dtm date NOT NULL,
    	crea_id varchar(100) NOT NULL,
    	del_gb varchar(1) NOT NULL DEFAULT 'N'::character varying,
    	updt_dtm date NULL
    );
    
    
    DROP TABLE IF EXISTS "tb_users";
    CREATE TABLE public.tb_users (
    	username varchar(100) NOT NULL DEFAULT ''::character varying,
    	"name" varchar(500) NOT NULL,
    	"password" varchar(500) NOT NULL,
    	userrole varchar(3) NOT NULL,
    	creadate date NOT NULL,
    	del_gb varchar(1) NOT NULL,
    	message varchar(1000) NOT NULL,
    	main_image_path varchar NOT NULL DEFAULT '/images/ΑΒΡΑΞΑΣ.jpg'::character varying,
    	logindate timestamp NULL
    );
    
    
    DROP TABLE IF EXISTS "tb_users_mapping";
    DROP SEQUENCE IF EXISTS seq_file_user_mapping;
    CREATE SEQUENCE seq_file_user_mapping INCREMENT 1 MINVALUE 1 MAXVALUE 9223372036854775807 CACHE 1;
    
    CREATE TABLE public.tb_users_mapping (
    	idx int4 NOT NULL DEFAULT nextval('seq_file_user_mapping'::regclass),
    	username varchar(100) NOT NULL,
    	file_idx int4 NOT NULL,
    	crea_dtm date NOT NULL,
    	crea_id varchar(100) NOT NULL
    );
    
    COMMENT ON TABLE "public"."tb_users_mapping" IS '파일 공유 사용자 정보';
    
    
    -- 2023-06-07 22:24:57.676591+09
    INSERT INTO public.tb_users
    (username, "name", "password", userrole, creadate, del_gb, message)
    VALUES('guest', 'guest', 'guest', 'gst', '2023-07-17', 'N', 'GUEST 입니다. ');
    
    
    INSERT INTO public.tb_users
    (username, name, "password", userrole, creadate, del_gb, message)
    VALUES('archiveradmin', '관리자', '17xxxx21q', 'adm', '2023-09-04', 'N', '관리자님 안녕하세요  ');
    
    • id : archiveradmin password : archiveradmin <-- 패스워드는 바꾸자

    [설치] Web Application Server 설치 (Tomcat)

    - Java 설치

    • sudo apt install default-jdk

    - Tomcat

    • sudo mkdir -p /app
    • sudo chown -c pi.pi /app <-- 권한을 pi 계정에 주기

    • apache-tomcat-9.0.64.tar.gz를 Download에 받는다

    • mkdir -p /home/pi/Downloads/tomcat <-- 압축을 풀 폴더를 만든다.

    • tar zxvf ./apache-tomcat-9.0.64.tar.gz -C ~/Downloads/tomcat  <-- ~/Downloads/tomcat 폴더에 압축을 푼다.

    • cp -Rf ./apache-tomcat-9.0.64 /app <-- 모두 복사

    - 자동실행 등록

      • 재시작 시에 자동 시작 등록
        sudo vi /etc/systemd/system/tomcat.service
    [UNIT]
    Description=apache-tomcat-9.0.64
    After=syslog.target network.target
    
    [Service]
    Type=forking
    
    Environment="CATALINA_HOME=/app/apache-tomcat-9.0.64"
    Environment="CATALINA_BASE=/app/apache-tomcat-9.0.64"
    Environment="CATALINA_OPTS=-Xms2048M -Xmx2048M -server -XX:+UseParallelGC"
    
    ExecStart=/app/apache-tomcat-9.0.64/bin/startup.sh
    ExecStop=/app/apache-tomcat-9.0.64/bin/shutdown.sh
    
    User=pi
    Group=pi
    UMask=0000
    RestartSec=10
    
    [Install]
    WantedBy=multi-user.target
      • 서비스 등록 
        sudo systemctl enable tomcat.service 
      • catalina.sh를 /app/apache-tomcat-9.0.64/bin 에 복사, 환경 설정을 추가함 아래 내용 참고 
         - UMASK="0027"를 UMASK="0000"
        
           # Achiver ADD 2022.06.30
           JAVA_OPTS="$JAVA_OPTS -Xmx2048m -Xms2048m"

    재시작

    • sudo reboot 

    [설치] Application 설치

     Application 설치

    http://web.joang.com:8082/archiver.war 를 받아서 app/apache-tomcat-9.0.64/webapps에 war 파일 복사 

    재시작을 하지 않아도 되지만 재시작 필요 시에 sudo systemctl restart tomcat.service 명령어 수행

    [설치] 배치 구성하기 (Youtube, 백업)

    Download YouTube

    /home/pi/pythonDownloadCrontab/KKYouTuBeDownloader.py 생성 

    from postgresqlDatabase import Databases
    import yt_dlp
    import datetime
    import os
    import re
    import argparse, logging, logging.config, conf
    
    today = datetime.date.today()
    y = today.year
    m = today.month
    d = today.day
    stored_file_name = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
    base_dir = ""
    dir = "/{year}/{month}/{day}/".format(year=y,month=m,day=d)
    downloadfilename = ""
    metadata = ""
    
    # Log
    logging.config.dictConfig(conf.dictConfig)
    logger = logging.getLogger(__name__)
    
    class CRUD(Databases):
        def insertDB(self,schema,table,colum,data):
            sql = " INSERT INTO {schema}.{table}({colum}) VALUES ('{data}') ;".format(schema=schema,table=table,colum=colum,data=data)
            try:
                self.cursor.execute(sql)
            except Exception as e :
                logger.debug(" insert DB err, e="+str(e)) 
        
        def readDB(self,table,colum, condition):
            sql = " SELECT {colum} from {table} where 1=1 {condition}".format(colum=colum,table=table, condition=condition)
            try:
                self.cursor.execute(sql)
                result = self.cursor.fetchall()
            except Exception as e :
                result = (" read DB err",str(e))
            
            return result
        
        def readDBbySQL(self,sql):
            try:
                self.cursor.execute(sql)
                result = self.cursor.fetchall()
            except Exception as e :
                result = (" read DB err",str(e))
            
            return result
    
        def updateDB(self,table,colum,value,condition):
            sql = " UPDATE {table} SET {colum}='{value}' WHERE 1=1 and {condition}::integer ".format(table=table , colum=colum ,value=value,condition=condition )
            try :
                self.cursor.execute(sql)
            except Exception as e :
                logger.debug(" update DB err , e="+str(e))
    
        def deleteDB(self,schema,table,condition):
            sql = " delete from {schema}.{table} where {condition} ; ".format(schema=schema,table=table,
            condition=condition)
            try :
                self.cursor.execute(sql)
            except Exception as e:
                logger.debug( "delete DB err , e="+str(e))
                
        def commit(self):
            try :
                self.db.commit()
            except Exception as e:
                logger.debug( "delete DB err , e="+str(e))
                
        def downLoadMovieFileByURL(self,downloadurl, idx, file_title):
            global downloadfilename
            logger.debug( ">> Download Movie URL:" + downloadurl)
            ydl_opts = {
                 'verbose': True,  
                 'format': 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/bestvideo+bestaudio/best',
                 'merge_output_format': 'mp4',
                 'outtmpl': base_dir + dir + stored_file_name + file_title + '.%(ext)s'
            }
            try:
                yt_dlp.YoutubeDL(ydl_opts).cache.remove()
                ydl = yt_dlp.YoutubeDL(ydl_opts).extract_info(downloadurl, download=True)
                downloadfilename = ydl["title"] 
                metadata = ydl['description']
                logger.debug(">> Movie file name : " + downloadfilename)
                logger.debug(">> Movie metadata : " + metadata )
                db.updateDB('tb_filemanager_meta_file', 'file_detail', downloadurl+"\n\r"+ metadata.replace("'","\""), 'idx='+idx)
                return True
            except Exception as e:
                logger.debug("Error e="+str(e))
                db.updateDB('tb_filemanager_meta_file', 'down_yn', 'E', 'idx='+idx)
                db.updateDB('tb_filemanager_meta_file', 'error', '@downLoadMovieFileByURL:'+str(e), 'idx='+idx)
                return False
            
        def downLoadMusicFileByURL(self,downloadurl, idx, file_title):
            global downloadfilename
            logger.debug( ">> Download Music URL:" + downloadurl)
            ydl_opts = {
                 'verbose': True,  
                 'format': 'bestaudio/best',
                 'postprocessors': [{
                        'key': 'FFmpegExtractAudio',
                        'preferredcodec': 'mp3',
                        'preferredquality': '192',
                  }, {'key': 'FFmpegMetadata'},],
                 'outtmpl': base_dir + dir + stored_file_name + file_title + '.%(ext)s'
            }
            try:
                yt_dlp.YoutubeDL(ydl_opts).cache.remove()
                ydl = yt_dlp.YoutubeDL(ydl_opts).extract_info(downloadurl, download=True)
                downloadfilename = ydl["title"]
                metadata = ydl['description']
                logger.debug(">> Music file name : " + downloadfilename )
                logger.debug(">> Music metadata : " + metadata )
                db.updateDB('tb_filemanager_meta_file', 'file_detail', downloadurl+"\n\r"+ metadata.replace("'","\""), 'idx='+idx)
                return True
            except Exception as e:
                logger.debug("Error e=" + str(e))
                db.updateDB('tb_filemanager_meta_file', 'down_yn', 'E', 'idx='+idx)
                db.updateDB('tb_filemanager_meta_file', 'error', '@downLoadMusicFileByURL:'+str(e), 'idx='+idx)
                return False
    
        def updateAndRename(self, idx, downloadFileType):
            try:
                logger.debug("> Download Original file name = " + base_dir + dir + downloadfilename + ", type=" + downloadFileType)
                changeOrgFileName = re.sub("'", "", re.sub("[/]", "_", re.sub('[\/:*?"<>|]','',downloadfilename)))
                logger.debug("> Change Original file name = " + base_dir + dir + changeOrgFileName + ", type=" + downloadFileType)
                logger.debug("> Change Store file name = " + base_dir + dir + stored_file_name + ", type=" + downloadFileType)
          
                if(downloadFileType == "mov"):
                    final_changeOrgFileName = changeOrgFileName+'.mp4' 
                    final_stored_file_name = stored_file_name+'.mp4'
                elif(downloadFileType == "muc"):
                    final_changeOrgFileName = changeOrgFileName+'.mp3'
                    final_stored_file_name = stored_file_name+'.mp3'
    
                for filename in os.listdir(base_dir + dir):
                    logger.debug(">> filename = " + filename + " , stored_file_name=" + stored_file_name)
                    if filename.startswith(stored_file_name):
                        logger.debug("> Change file name ("+idx+")= " + base_dir + dir + filename + " to " + base_dir + dir + final_stored_file_name)
                        os.rename(base_dir + dir + filename, base_dir+dir + final_stored_file_name)
                        logger.debug("> Changed file stored name=" + final_stored_file_name)
                        logger.debug("> Changed file Org name=" + final_changeOrgFileName)
                        
                logger.debug("original_file_name ("+idx+")= " + final_changeOrgFileName)
                db.updateDB('tb_filemanager_meta_file', 'original_file_name', final_changeOrgFileName, 'idx='+idx)
                logger.debug("stored_file_name ("+idx+")= " + dir + final_stored_file_name)
                db.updateDB('tb_filemanager_meta_file', 'stored_file_name', dir + final_stored_file_name, 'idx='+idx)
                logger.debug("file_size ("+idx+")= " + base_dir + dir + final_stored_file_name)
                logger.debug("file_size ("+idx+")= " + str(os.path.getsize(base_dir + dir + final_stored_file_name)))
                db.updateDB('tb_filemanager_meta_file', 'file_size', os.path.getsize(base_dir + dir + final_stored_file_name), 'idx='+idx)
                logger.debug("crea_dtm ("+idx+") = NOW()")
                db.updateDB('tb_filemanager_meta_file', 'crea_dtm', 'NOW()', 'idx='+idx)
                logger.debug("crea_dtm ("+idx+") = NOW()")
                return True
            except Exception as e:
                logger.debug("Error e=" + str(e))
                db.updateDB('tb_filemanager_meta_file', 'down_yn', 'E', 'idx='+idx)
                db.updateDB('tb_filemanager_meta_file', 'error', '@updateAndRename:'+str(e), 'idx='+idx)
                return False
            
            
            
        def existDirectory(self,directory):
            logger.debug(">>" + directory)
            isDir = os.path.isdir(directory)
            if(isDir):
                logger.debug(">>> Exist !")
            else:
                logger.debug(">>> Make Dir !")
                os.makedirs(directory, exist_ok=True)
            return isDir
    
    
    
    if __name__ == "__main__":
        db = CRUD()
        result = db.readDB('tb_archiver_sys_info','sys_storage', 'and sys_title=\'ΑΒΡΑΞΑΣ\'')
        if( len(result) == 0 ):
            logger.debug(">> sys_storage result size 0 " )
        else:
            logger.debug(">> sys_storage result size " + str(len(result)) )
            base_dir = result[0][0]
            logger.debug(">> base_dir = " + base_dir)
        
        result = db.readDB('tb_filemanager_meta_file','idx, original_file_name, file_type, file_title', 'and down_yn=\'N\'')
        resultYN = 'N'
        
        if( len(result) == 0 ):
            logger.debug(">> result size 0 " )
        else:
            logger.debug(">> result size " + str(len(result)) )
            row=result[0]
            logger.debug(">> Row detail " + str(row) )
            db.existDirectory(base_dir+dir)
            idx = str(row[0])
            downloadUrl = row[1]
            downloadFileType = row[2]
            file_title = row[3]
            db.updateDB('tb_filemanager_meta_file', 'down_yn', 'D', 'idx='+idx)
            db.commit()
            logger.debug(">>"+idx+" , "+downloadUrl+" , "+downloadFileType)
            if(downloadFileType == "mov"):
                logger.debug("> MOVIE !")
                if(db.downLoadMovieFileByURL(downloadUrl, idx, file_title)):
                    if(db.updateAndRename(idx, downloadFileType)):
                        resultYN = 'Y'
                    else:
                        resultYN = 'E'
                else:
                    resultYN = 'E'
            elif(downloadFileType == "muc"):
                logger.debug("> MUSIC !")
                if(db.downLoadMusicFileByURL(downloadUrl, idx, file_title)):
                    if(db.updateAndRename(idx, downloadFileType)):
                        resultYN = 'Y'
                    else:
                        resultYN = 'E'
                else:
                    resultYN = 'E'
            else:
                logger.debug("> ERROR FILE TYPE !")
                db.updateDB('tb_filemanager_meta_file', 'down_yn', 'E', 'idx='+idx)
                db.updateDB('tb_filemanager_meta_file', 'error', '@DownloadType', 'idx='+idx)
            db.updateDB('tb_filemanager_meta_file', 'down_yn', resultYN, 'idx='+idx)
            if(resultYN == ""):
                db.updateDB('tb_filemanager_meta_file', 'error', 'download done', 'idx='+idx)
            logger.debug(">> "+idx+" UPDATE=" + resultYN)
        db.commit()
    

    Backup :실제 파일이름으로 변환해서 백업 

    /home/pi/pythonDownloadCrontab/KKBackupFiles.py 파일을 생성 

    from postgresqlDatabase import Databases
    import yt_dlp
    import datetime
    import os
    import re
    import argparse, logging, logging.config, conf
    from shutil import copyfile
    
    today = datetime.date.today()
    y = today.year
    m = today.month
    d = today.day
    stored_file_name = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
    dir = "/{year}/{month}/{day}/".format(year=y,month=m,day=d)
    
    # Log
    logging.config.dictConfig(conf.dictConfig)
    logger = logging.getLogger(__name__)
    
    class CRUD(Databases):
       
        def readDB(self,table,colum, condition):
            sql = " SELECT {colum} from {table} where 1=1 {condition}".format(colum=colum,table=table, condition=condition)
            try:
                self.cursor.execute(sql)
                result = self.cursor.fetchall()
            except Exception as e :
                result = (" read DB err",str(e))
            
            return result
     
        def updateDB(self,table,colum,value,condition):
            sql = " UPDATE {table} SET {colum}='{value}', sys_backup_date=NOW() WHERE 1=1 and {condition} ".format(table=table , colum=colum ,value=value,condition=condition )
            try :
                self.cursor.execute(sql)
            except Exception as e :
                logger.debug(" update DB err , e="+str(e))
    
        def backupFile(self,sys_storage, sys_backup_location):
           sql = " SELECT original_file_name, stored_file_name from tb_filemanager_meta_file order by idx  "
           try:
            self.cursor.execute(sql)
            result = self.cursor.fetchall()
           except Exception as e :
            result = (" read DB err",str(e)) 
           for row in result:
            toLocation = row[1].rindex("/", 0)
            #logger.debug(">> row = " + row[1][:toLocation+1] + " = " + str(toLocation))
            #logger.debug(">> row = " + sys_storage + row[1] + " --> TO --> " + sys_backup_location + "/" + row[1][:toLocation]  + row[0])
            self.copyBackupFile(sys_storage + row[1], sys_backup_location + row[1][:toLocation] , row[0])
            
        def copyBackupFile(self, orgFile, destDir, destFile):
            if not os.path.exists(destDir + "/" + destFile):
                logger.debug(">> file not exist = " + destFile)
                # 디렉토리 만들기 
                if not os.path.exists(destDir):
                    logger.debug(">> Make Dir = " + destDir)
                    os.makedirs(destDir)
                # 파일 옮기기 
                logger.debug(">> Copy Files = " + orgFile + " --> " + destDir + "/" + destFile )
                os.system('cp ' + orgFile + ' "' + destDir + "/" + destFile + '"') 
                
            else:
                logger.debug(">> file exist ! -> " + destDir + "/" + destFile)
                
    
    
    if __name__ == "__main__":
        db = CRUD()
        result = db.readDB('tb_archiver_sys_info','SYS_BACKUP_YN, sys_storage, sys_backup_location', 'and SYS_TITLE=\'ΑΒΡΑΞΑΣ\' and SYS_BACKUP_YN=\'Y\'')
        
        if( len(result) == 0 ):
            logger.debug(">> Backup Skip " )
        else:
            logger.debug(">> result size " + str(len(result)) )
            row=result[0]
            logger.debug(">> Row detail " + str(row) )
            if( str(row[0]) == "Y" ):
                logger.debug(">> BACKUP START  ! ")
                db.updateDB('tb_archiver_sys_info', 'SYS_BACKUP_YN', 'P', 'SYS_TITLE=\'ΑΒΡΑΞΑΣ\'')
                db.commit()
                sys_storage = str(row[1])
                sys_backup_location = str(row[2])
                db.backupFile(sys_storage, sys_backup_location)
            db.updateDB('tb_archiver_sys_info', 'SYS_BACKUP_YN', 'N', 'SYS_TITLE=\'ΑΒΡΑΞΑΣ\'')
        db.commit()
    

    Python 공통 

    /home/pi/pythonDownloadCrontab/conf.py 생성 

    
    from pathlib import Path
    
    p = Path("logs")
    if not p.exists():
        p.mkdir()
    
    dictConfig = {
        'version': 1,
        'disable_existing_loggers': True,
        'formatters': {
            'standard': {
                'format': '%(asctime)s [%(levelname)s] %(name)s:: %(message)s',
            },
        },
        'handlers': {
            'default': {
                'level': 'DEBUG',
                'formatter': 'standard',
                'class': 'logging.StreamHandler',
                'stream': 'ext://sys.stdout',
            },
            'file': {
                'class': 'logging.handlers.RotatingFileHandler',
                'level': 'DEBUG',
                'formatter': 'standard',
                'filename': 'logs/logfile.log',
                'mode': 'a',
                'maxBytes': 5_242_880,
                'backupCount': 3,
                'encoding': 'utf-8',
            },
        },
        'loggers': {
            '__main__': {
                'handlers': ['default','file'],
                'level': 'DEBUG',
                'propagate': False,
            },
            'camera': {
                'handlers': ['default', 'file'],
                'level': 'DEBUG',
                'propagate': False,
            },
        }
    }
    

    /home/pi/pythonDownloadCrontab/postgresqlDatabase.py   생성 

    import psycopg2
    
    class Databases():
        def __init__(self):
            self.db = psycopg2.connect(host='localhost', dbname='archiver',user='pi',password='archiverpw123!@#',port=5432)
            self.cursor = self.db.cursor()
    
        def __del__(self):
            self.db.close()
            self.cursor.close()
    
        def execute(self,query,args={}):
            self.cursor.execute(query,args)
            row = self.cursor.fetchall()
            return row
    
        def commit(self):
            self.db.commit()
        
    

    Crontab 설정 

    */10 * * * * /usr/bin/python /home/pi/pythonDownloadCrontab/KKYouTuBeDownloader.py > /home/pi/logs/sysout.log
    */13 * * * * /usr/bin/python /home/pi/pythonDownloadCrontab/KKBackupFiles.py > /home/pi/logs/backup.log
    

    10 분마다 Youtube 다운로드 찾아 다운로드 실행 

    13분마다 백업 여부를 확인하고 백업이 있을 때 배치로 수행 

    실행 

    1. http://localhost:8080/archiver/login.do