WebServer에서 사용률 체크하기

CSharp, Database
홈페이지를 만들고 나서 사용률이 저조하면은 상당히 힘이 빠지는 일입니다. 더욱이 정부에서 사용을 하라고 하는데 제작을 할때는 사람들이 요구사항이 상당히 많이 발생하고 좀 더 자기에게 유리하게 만들기 위해서 시간과 노력을 투자 하지만 일단 정부에서 대금이 지급되고 나서는 시들해지기 마련입니다. 하지만 정부도 바보가 아닌 이상 몇년간 사용을 해야 하는데 사람들이 일이 늘어나서 사용하지 않는다는것을 알고 있어서 조금은 강제로 사용 현황을 수집하고 있습니다. 정부 사이트에 현황을 볼 수 있는 사이트가 있지만 매일 들어가서 보기 힘들고 어차피 우리가 만들어준 시스템에서 자료를 가지고 통계를 전송하기에 해당 부분에 착안해서 먼저 우리가 시스템에서 데이터를 통계를 내서 메일을 발송하기로 하였습니다. 상태 표시 화면 이렇게 매일 실행을 해서 상태를 확인 후 우리가 정한 상한선 보다 낮을 경우에 메일을 발송을 해서 경각심을 가지고 해야 합니다. 정부는 몇달간 모았다가 갑자기 감사를 나오기 때문에 미리 미리 해 놓아야 합니다. 메일 발송 내역…
Read More

HTML를 PDF로 만들기

WWW
웹브라우저에서 HTML를 그대로 PDF로 만들기 위해서 찾아 보게 되었습니다. 위 사진은 웹페이지 그대로 화면은 캡쳐한 부분입니다. 해당 화면을 가지고 그대로 PDF로 만들어야 하는 상태 입니다. background로 제작을 하면 되지만 고객이 일단 화면에 먼저 보여지기를 원해서 View를 만들고 그다음에 PDF로 제작을 해야 되는 조건이 붙었습니다. 이렇게 VIew 에서 PDF로 다운 받아서 그대로 확인을 할 수 있도록 만들기 위해서 html2pdf 라이브러리를 사용을 하여서 제작을 하게 되었습니다. 일단든 보여지는 그대로 나오기 때문에 그다지 어렵지는 않았습니다. // Get the element. var element = document.getElementById('PDFROOT'); // Generate the PDF. // orientation는 출력 방항 ( 가로 세로 ), // scale 는 확대 html2pdf().from(element).set({ filename: '<?=$mainResData['reportNo'];?>', html2canvas: { scale: 1 }, jsPDF: {orientation: 'portrait', unit: 'mm', format: 'A4', compressPDF: true} }).save(); Javascript 코드는 위와 같이 처리를 하면은 됩니다. 좀 더 자세한 사항은 html2pdf 옵션을 찾아 보면은 자세하게…
Read More

1년동안 주차와 전년도 주차와 비교하기

PHP
고객이 검색한 년도의 1년동안의 매월 주를 계산을 하고 나서 기간에 따른 Row 갯수를 그래프에 표현을 하고 싶어 하기에 작성하게 된 것입니다. 조금은 난해하게 보이지만은 조건 검사가 많은 편이지 그다지 복잡한 코드는 아닙니다. $end_yearmonthday = date("Y-m-d", strtotime($_GET['end_year'].'-'.$_GET['end_month'].'-'.$_GET['end_day'])); // 이전년도 $agoTime = date('Y-m-d', strtotime(date('Y-01-01', strtotime($end_yearmonthday)).' -1 years')); $agoMaxWeek = date('W', strtotime(date('Y-12-31', strtotime($end_yearmonthday)).' -1 years')); $monthCnt = 0; $historyMonth = 0; for($w = 0; $w <= $agoMaxWeek; $w++) { $thisWeek = date('W', strtotime( $agoTime .' +'.$w.' week') ); $thisYear = date('Y', strtotime( $agoTime .' +'.$w.' week') ); $thisMonth = date('m', strtotime( $agoTime .' +'.$w.' week') ); $thisDay = date('d', strtotime( $agoTime .' +'.$w.' week') ); $dayOfTheWeek = date('w',mktime(0,0,0,$thisMonth,$thisDay,$thisYear)); // 해당주차의 시작 날짜 $today_week_sday1 = mktime(0,0,0,$thisMonth,$thisDay-$dayOfTheWeek,$thisYear); $today_week_sday2 = date("Y-m-d",$today_week_sday1); // 해당주차의 종료 날짜 $today_week_eday1 = mktime(23,59,59,$thisMonth,$thisDay+(6-$dayOfTheWeek),$thisYear); $today_week_eday2 = date("Y-m-d",$today_week_eday1); // if( $historyMonth == $thisMonth)…
Read More

MySQL 정렬 특정 단어를 우선순위에 두기

Database
MySQL을 이용할 경우에 정렬을 사용할때가 있습니다. 문자를 숫자로 변형해서 하기도 하고 Abc순으로 할 수도 있고 가나다 방법등 다양하게 사용을 할 수 있습니다. 보통의 방법으로 오름차순, 내림차순 정렬을 사용하면은 원하는 결과물에 대해서 정렬을 해서 목록을 만들수 있습니다. 하지만, 특정 단어가 목록중에서 가장 최상단에 와야 하는 경우라는 보통의 방법으로는 할 경우에는 WHERE 조건후에 다른것까지 붙이다 보면은 원하는 정렬이 되지 않아서 고생을 하게 됩니다. ORDER BY CASE WHEN 정렬컬럼명 = '정렬단어A' THEN 1 WHEN 정렬컬럼명 = '정렬단어B' THEN 2 WHEN 정렬컬럼명 = '정렬단어C' THEN 3 WHEN 정렬컬럼명 = '정렬단어D' THEN 4 ELSE 10 END , 정렬컬럼명2 ASC 위에 예제를 이용 할 경우에는 1차적으로 정렬컬럼명을 통해서 정렬을 시도하고 정렬컬럼명2를 통해서 정렬을 하기 때문에 원하는 단어를 문저 올려서 처리를 할 수 있습니다. 잘 사용을 하지 않지만은 꼭 필요할때 유용하게 사용을 할 수 있을것 같아서 글을…
Read More

MySQL 시간정보로 조회

Database
// 1분전 데이터 조회 SELECT * FROM 테이블명 WHERE 시간칼럼명 >= DATE_ADD(NOW(), INTERVAL -1 MINUTE) // 10분전 데이터 조회 SELECT * FROM 테이블명 WHERE 시간칼럼명 >= DATE_ADD(NOW(), INTERVAL -10 MINUTE); // 한시간전 데이터 조회 SELECT * FROM 테이블명 WHERE 시간칼럼명 >= DATE_ADD(NOW(), INTERVAL -1 HOUR); // 하루전 데이터 조회 SELECT * FROM 테이블명 WHERE 시간칼럼명 >= DATE_ADD(NOW(), INTERVAL -1 DAY); // 한달전 데이터 조회 SELECT * FROM 테이블명 WHERE 시간칼럼명 >= DATE_ADD(NOW(), INTERVAL -1 MONTH); DBMS에서 자동적으로 현재 시간을 기준으로 정보를 조회를 할때 사용을 할 수 있습니다. 다른 프로그램에서 SQL문으로 조회를 할때야 시간 정보를 알아서 조합을 할 수 있지만, SQL로만 할 경우에는 이렇게 하면은 시간을 정해서 내용이 조회가 가능 합니다.
Read More

서버의 파일 내용 찾기

CSharp, 프로그램
어느정도 보안을 위해서 모자이크 처리를 하였습니다. 리눅스 서버에 바로 접속해서 파일 내용을 지정해서 찾을수 있는 간단한 프로그램 입니다. 전체적으로 단어 변경이나 할 일이 있으면은 서버에 접속해서 어느 파일에 있는지 찾아야 하는 일이 요즘 빈번이 일어나고 있어서 만들게 되었습니다. 비록 최근에 만든 파일들은 쉽게 기억을 하지만 기억이 나지 않는 부분까지 모두 찾으려고 하니 CLI 에서 하나하나 기입하기도 귀차니즘이 발동해서 만든것입니다.
Read More

MySQL 스키마 변경 프로그램

CSharp, Database
웹 개발을 하다 보면은 동일한 내용을 DBTable를 생성하고 복제를 하는 일이 많이 발생을 하기 마련입니다. 모든 사이트가 동일하지는 않지만 관리를 위해서라도 서버마다 다를수 있어서 한번에 변경할려니 DB툴을 가지고 하는것도 작업 시간이 늘어나는 일이 이고 해서 한번에 바꿀수 있도록 만들게 되었습니다. 개발자에 따라서 여러가지 프로그램으로 제작을 하지만 저는 C#을 이용하여서 GUI 화면에서 보면서 지금것은 어떤지 실시간으로 보기도 하고 변경도 하고 싶어서 만들게 되었습니다. 프로그램에 제가 접속을 해야 하는 서버들이나 DB를 기록을 해 놓은곳에서 가져오는것인지 SQL 자체는 상당히 간단한 편입니다. 컬럼을 변경할 경우에 사용하는 SQL ALTER TABLE `대상DB`.`대상TABLE` CHANGE COLUMN `변경할컬럼` `변경할컬럼명` 형식 NULL여부 DEFAULT '기본값' COMMENT '코멘트'; 컬럼을 추가할 경우에 사용하는 SQL ALTER TABLE `대상DB`.`대상TABLE` ADD COLUMN `추가할컬럼명` 형식 NULL여부 DEFAULT '기본값' COMMENT '코멘트' AFTER `대상컬럼`; 컬럼을 삭제할 경우에 사용하는 SQL ALTER TABLE `대상DB`.`대상TABLE` DROP COLUMN `지울컬럼명`; 이렇게 SQL 명령어만 조건에…
Read More

안드로이드 웹뷰에서 화면 캡쳐하기

Android
아래의 코드는 테스트 코드 입니다. 현재 화면 전체를 캡쳐를 할 수가 없어서 지금 계속 테스트 중에 중간 저장을 위해서 코드를 기록을 해 놓습니다. wvPrint.loadUrl(Url); wvPrint.enableSlowWholeDocumentDraw(); wvPrint.setWebViewClient(new WebViewClient() { public boolean shouldOverrideUrlLoading(WebView view, String url) { return false; } @Override public void onPageFinished(WebView view, String url) { Log.i("deneb::", "page finished loading " + url); float scale = wvPrint.getScale(); int height = (int) (wvPrint.getContentHeight() * scale + 0.5); Bitmap bitmap = Bitmap.createBitmap(780, height, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); wvPrint.draw(canvas); // 파일 저장 String strFilePath = context.getCacheDir().toString(); Log.d("deneb::", "경로 :: " + context.getCacheDir().toString()); File fileCacheItem = new File(strFilePath, "print_page.png"); OutputStream out = null; try { fileCacheItem.createNewFile(); out = new FileOutputStream(fileCacheItem); bitmap.compress(Bitmap.CompressFormat.PNG, 100, out); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { out.close(); double…
Read More

C# Debug / Release 체크해서 코드 실행하기

CSharp
C#으로 개발을 하다 보면은 Debug에서만 작동해서 테스트를 위할 때가 있습니다. Release와 동일하게 하면 좋지만은 겨우 확인을 위해서만 필요한 사항인데, 빌드할때 빼먹으면은 남기도 하고 하는등이 피폐한 부분이 있어서 조금은 코드를 찾아보니 좋은 조건문이 있어서 기록을 합니다. #if DEBUG Console.WriteLine("Mode=Debug"); #else Console.WriteLine("Mode=Release"); #endif 이제 그냥 디버그와 릴리즈 일때 구분하지 않고 코드를 나두고 작업을 합니다. 물론 최종 출시전에는 위에 코드가 없는편이 깔끔하고 좋지만은 한창 개발중인 기능에 대해서는 긴급하게 업데이트도 필요하기 때문에 나두면은 좋습니다. 물론 실행을 막아주기도 하는등의 좋은 기능도 있습니다. 주석을 잘 남기는것도 좋지만 확실히 디버그 일때와 릴리즈 모드에 대해서도 구분을 하고 개발을 하면 좋을것 같습니다.
Read More

윈도우 시간 동기화

CSharp
프로그램을 개발하면서 윈도우의 시간동기화가 필수적으로 필요하게 되었습니다. 당연히 윈도우가 자동으로 잘 동기화를 하고 있겠지만은 그렇지 않은 경우에는 강제로 동기화를 해야 하는데, 컴퓨터가 그냥 자동으로 작업을 할 경우에 시간에 예약이 있을 경우에 시간이 동기화가 되지 않으면은 작업이 늦어지기에 한번씩 동기화를 해줘야 합니다. /// <summary> /// Gets the current DateTime from time-a.nist.gov. /// </summary> /// <returns>A DateTime containing the current time.</returns> public static DateTime GetNetworkTime() {     return GetNetworkTime("time.windows.com"); // time-a.nist.gov }   /// <summary> /// Gets the current DateTime from <paramref name="ntpServer"/>. /// </summary> /// <param name="ntpServer">The hostname of the NTP server.</param> /// <returns>A DateTime containing the current time.</returns> public static DateTime GetNetworkTime(string ntpServer) {     IPAddress[] address = Dns.GetHostEntry(ntpServer).AddressList;       if (address == null || address.Length == 0)         throw new ArgumentException("Could not resolve ip address from '" + ntpServer + "'.", "ntpServer");…
Read More

$(document).ready 보다 실행이 늦은 $(window).load

JavaScript
<script> $(window).load(function() { alert(2); }); $(document).ready(function() { alert(1); }); </script> WebPage를 작업하다 보면은 모든것을 Loading이 끝나고 실행해야 하는 상태가 있습니다. 보통은 ready를 사용하지만은 DOM 객체만 loading이 되면은 바로 실행이 됩니다.이렇게 DOM 객체 상관없이 외부이미지 리소스 모두 loading를 하고 실행이 되어야 할 경우에는 load를 사용하면 됩니다.위에 예제처럼 2개의 사용방법이 다르니 한번 살펴보시기 바랍니다.
Read More

안드로이드 웹뷰 기능 제작중

Android
package com.sihwawon.android import android.R.attr import android.R.attr.* import android.annotation.SuppressLint import android.app.AlertDialog import android.app.Dialog import android.content.DialogInterface import android.content.Intent import android.graphics.Bitmap import android.net.Uri import android.net.http.SslError import android.os.Build import android.os.Bundle import android.os.Environment import android.os.Message import android.provider.MediaStore import android.util.Log import android.view.View import android.view.ViewGroup import android.webkit.* import android.widget.ProgressBar import androidx.appcompat.app.AppCompatActivity import java.io.File import java.util.* import java.util.UUID import android.widget.Toast import android.view.Gravity import android.webkit.WebView import android.webkit.WebViewClient import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import android.webkit.ValueCallback import java.io.IOException import java.text.SimpleDateFormat import android.app.Activity import android.content.Intent.ACTION_VIEW import android.content.res.Configuration import android.text.TextUtils import android.webkit.WebChromeClient import android.os.Parcelable import androidx.core.content.FileProvider import android.webkit.WebChromeClient.FileChooserParams import androidx.annotation.RequiresApi import android.print.PrintAttributes import android.print.PrintManager import android.view.KeyEvent import kotlin.time.days class MainActivity : AppCompatActivity() { private lateinit var mWebView: WebView private var pWebView: WebView? = null private lateinit var mProgressBar: ProgressBar private var thisUrl: String? = null private var barcode: String? = "" private var popup: Boolean? =…
Read More

Javascript 3자리 콤마 및 소수점 2자리 입력 받기

JavaScript
웹페이지를 개발하다 보면은 사용자가 보이기 편하도록 단위마다 콤마도 붙여줘야 하고 소수점도 받아야 합니다. 하지만, 숫자외에 입력을 받다보면은 문제가 생길수 있어서 아래의 코드를 적용하면은 숫자외에는 입력을 받지 않기 때문에 사용자의 입력을 제한 할 수 있습니다. <!DOCTYPE html> <html> <body> <input type="text" id="input1" placeholder="숫자를 입력해주세요" onKeyUp="removeChar(event);inputNumberFormat(this);" onKeyDown="inputNumberFormat(this);" > <script> //문자 제거 function removeChar(event) { event = event || window.event; var keyID = (event.which) ? event.which : event.keyCode; if (keyID == 8 || keyID == 46 || keyID == 37 || keyID == 39) return; else //숫자와 소수점만 입력가능 event.target.value = event.target.value.replace(/[^-\.0-9]/g, ""); } //콤마 찍기 function comma(obj) { var regx = new RegExp(/(-?\d+)(\d{3})/); var bExists = obj.indexOf(".", 0);//0번째부터 .을 찾는다. var strArr = obj.split('.'); while (regx.test(strArr[0])) {//문자열에 정규식 특수문자가 포함되어 있는지 체크 //정수 부분에만 콤마 달기 strArr[0] = strArr[0].replace(regx, "$1,$2");//콤마추가하기 } if…
Read More

WebView 기능을 이용한 앱 개발중

Android
오랜만에 기술적인 내용이 아닌 일반적인 내용을 작성을 하게 되었습니다. 이번에 새롭게 공부를 시작하면서 Web과 App을 이용한 하이브리드(?) 용으로 App을 개발하게 되었습니다. 아직 시작 단계이지만 순항을 하는중이라고 생각을 합니다. 현재는 안드로이드의 기능중 WebView를 이용해서 순서 Web에 대한 표시를 하고, 웹에 포함된 기능중 일부에 대해서는 App과 사용작용으로 작동하는 기능을 개발중에 있습니다. 해당 기능이 되면은 말 그대로 하이브리드 형식이되지 않을까 싶습니다. 순수하게 웹으로만 작동하는것도 아니고, App만으로도 작동하지 않지만 서로가 상호 보완을 통해서 기능이 작동을 하리라고 생각이 됩니다. 아직 내용을 정리하기에는 부족하고 정리가 미흡하지만 조만간 해당 내용에 대해서 글을 작성하지 않을까 싶습니다. 카테고리를 만들고 나서 예고 차원에서 일단 기술적인 내용이 없는 글을 먼저 작성을 해서 신규 카테고리가 있다는것도 알리고 카테고리의 글을 하나씩 채워 나갈 생각 입니다. 잘하시는 분들이 볼 경우에는 많이 미흡할 수 있지만 이런 내용이 있다는 정도로 제가 정리해서 남기기 위한 글입니다. 이번에…
Read More

개인 소스 관리를 시작 하였습니다.

프로그램
회사에서는 이미 Gitlab를 통해서 개발코드에 대한 형상관리를 하고 있습니다. 하지만 개인적으로는 그다지 필요가 없다고 생각을 해서 하지 않던것을 이번에 모두 정리해서 등록하는데 꽤 시간을 할애해서 작업을 진행하였습니다. 그래도 개인적으로 연습삼아 한 일에 대해서는 모두 올리려고 하니 너무 많아서 조금 간추리는 작업을 해서 어느정도 남에게 공개한 프로그램들에 한해서만 하는것도 꽤 시간이 걸리는 작업을 하게 되었습니다. 그래도 이제 개인적인 저장소에서 FTP를 통해서 소스 관리하던것을 올리고 나서 보니 여러가지 일을 하였고, 여러가시 소소한것이 많다는 생각을 하였습니다. 시작하고 마무리 하지 않은 일도 계획만 잡아 두거나 혹은 다른 사람의 코드를 연구하기 위해서 만들어 놓은것들이 한둘이 아니라서 정리가 꽤 애를 먹었습니다. 그래도 큰맘 먹고 정리를 하니 디렉토리도 정리가 되고 한결 찾기가 수월해져서 좋은듯 합니다. 그동안에 소스 형상관리를 어느곳에 이용할까 혹은 개인 서버를 만들까 하면서 고민을 많이 하였습니다. 솔직히 오픈소스로 공개할 정도가 되지 않으니 github를 이용하기도 조금…
Read More