changeset 13:f5ffc34f045a

manage DB.
author pyon@macmini
date Wed, 14 Nov 2018 19:43:40 +0900
parents 240752cbe11b
children c1dc1fcee7fe
files app.conf dist.bat doc/Todo doc/memo.txt go/client.go go/crypto.go go/extsql.go go/server.go include/id.h include/main.h include/mngdb.h include/net.h include/rsearcher.h src/main.cpp src/mngdb.cpp src/net.cpp src/rsearcher.cpp
diffstat 17 files changed, 246 insertions(+), 98 deletions(-) [+]
line wrap: on
line diff
--- a/app.conf	Tue Nov 13 21:11:20 2018 +0900
+++ b/app.conf	Wed Nov 14 19:43:40 2018 +0900
@@ -10,6 +10,9 @@
 proxy_address=
 proxy_port=
 
+[DBManage]
+dbdir=C:\\MinGW\\msys\\1.0\\home\\muto\\wx\\rsearcher\\searcher03db
+
 [Misc]
 splash=-1
 ;unlock_key=054fa2ab56938fc46ed69eb7ad93fa4828e4963b8a82f9514c3e2e86940510ed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dist.bat	Wed Nov 14 19:43:40 2018 +0900
@@ -0,0 +1,20 @@
+@echo off
+title ★こ☆ぴ★ぃ☆ー★ー☆
+
+set org_dir=C:\MinGW\msys\1.0\home\muto\wx\rsearcher
+set tgt_dir=E:\rsearcher
+
+call :file_copy grsearcher.exe
+call :file_copy manual.pdf
+rem file_copy client.exe
+rem file_copy crytpo.exe
+
+goto end
+
+:file_copy
+copy /y %org_dir%\%1 %tgt_dir%\%1 > nul
+exit /b 0
+
+:end
+pause
+
--- a/doc/Todo	Tue Nov 13 21:11:20 2018 +0900
+++ b/doc/Todo	Wed Nov 14 19:43:40 2018 +0900
@@ -1,23 +1,17 @@
 ** client.exe の機能 ************************************************************
-* 手動によりバージョンアップ
-    * verup.bat をダブルクリック
-    # verup.bat
-    client -r 192.168.0.1:3910
-    # GET /release/grsearcher.exe, /release/crypto.exe, /release/client1.exe
-    copy client1.exe client.exe
 
 * client で画像取得
 	> client.exe 192.168.0.1:3910 0800012345 20170105
 
 * client でアップロード
-	> client.exe -a 192.168.0.1:3910 localfile
+	> client.exe -a 192.168.0.1:3910 localfile  # /upload へ
+	> client.exe -m 192.168.0.1:3910 localfile	# /db ヘ
 
 * バージョンアップ
     + パスワード機能を追加 ( ver1.11 )
     + ヘッダ拒否機能を追加 ( ver1.2 )
 
 ** crypto/crypto.exe の機能 *****************************************************
-* crypto.go 作成
 	+ auth 用 ( ハッシュ化 )
 		* -a で plaintext を暗号化	# server/client
 			> crypto.exe -a plaintext -s salt
@@ -35,6 +29,12 @@
 		* -f で 認証チェック		# gui
 			> crypto.exe -f hhs.db hhs key
 			+ hhs/key が一致したら hhs の情報を返す
+		* -o で ファイル出力
+
+** extsql.exe の機能 ************************************************************
+	searcher03.exe で作成される hhs.db と index.db から
+	re:searcher 用の hhs.db と index.db を作成する.
+	client.exe(guiから) でサーバにアップロードする.
 
 ** imgtgz の機能 ****************************************************************
 * jpeg を 1.jpg, ..., 5.jpg とリネームし tgz にする.
@@ -66,11 +66,11 @@
 * server ( FreeBSD )
  server_root/server, crypto, imgtgz
             + db/auth.db, hhs.db, index.db
-            + release/grsearcher.exe, client.exe
+            + release/grsearcher.exe, client.exe, crypto.exe, manual.pdf
             + images/20180707/0800012345.tgz, ...
 
 * client ( Windows )
- rsearcher_root/grsearcher.exe, client.exe, crypto.exe
+ rsearcher_root/grsearcher.exe, client.exe, crypto.exe (, sqlite3.exe, extsql.exe )
                 auth.db, hhs.db, index.db
                + .cache/20180707_1, ...
                + image/*.png, *.jpg
@@ -85,5 +85,12 @@
     # GET /db/auth.db, /db/hhs.db, /db/index.db (14day) 
 	+ GUI(grsearcher) 終了時に auth.db と hhs.db は削除
 	* auth.db は任意の、hhs.db は月一のアップデートだが、漏洩防止のため毎回削除
-    * 毎月14日と28日に index.db を取得
+    * 毎月13日と28日に index.db を取得
 
+* 自動バージョンアップ
+    # upgrade.bat
+    client -r 192.168.0.1:3910
+    # GET /release/grsearcher.exe, /release/crypto.exe, /release/client1.exe
+	#     /release/manual.pdf
+    copy client1.exe client.exe
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/memo.txt	Wed Nov 14 19:43:40 2018 +0900
@@ -0,0 +1,12 @@
+== DONE ==
+* Management
+ 繝繝シ繧ソ繝吶シ繧ケ縺ッ CSV 縺九i JSON 縺ォ螟画鋤縺 GZIP 縺ァ蝨ァ邵ョ縺励※繧「繝繝励Ο繝シ繝会シ
+ 繝帙Ρ繧、繝医Μ繧ケ繝(繧ウ繝シ繝牙沂繧∬セシ縺ソ) 縺ァ繧「繧ッ繧サ繧ケ蛻カ蠕。シ
+
+* Server
+ [usage] $ ./rsearcher -d      # 繝ュ繝シ繧ォ繝ォ IP 繝昴シ繝 8080 縺ァ繝ェ繧ケ繝ウシ
+ [usage] $ ./rsearcher -D      # 繝繝舌ャ繧ー繝「繝シ繝 localhost:8080 縺ァ繝ェ繧ケ繝ウシ
+
+
+== TODO ==
+ [todo] 繝繝舌ャ繧ー繝「繝シ繝峨〒 3[min] 縺ァ繧ソ繧、繝繧「繧ヲ繝茨シ
--- a/go/client.go	Tue Nov 13 21:11:20 2018 +0900
+++ b/go/client.go	Wed Nov 14 19:43:40 2018 +0900
@@ -1,7 +1,7 @@
 /*
  client.go  : client-program.
- Version    : 1.3
- Last Change: 2018-11-13 轣ォ 12:03:00.
+ Version    : 1.3a
+ Last Change: 2018-11-14 豌エ 16:58:29.
 
  install to: rsearcher_root/
 
@@ -13,7 +13,7 @@
                + hhs.db  ( temporary )
                + index.db ( 14 days )
                + image/*.png, *.jpg
-               + doc/
+               + manual.pdf
                + .cache/* ( temporary )
 
  $ client.exe -r 192.168.0.1:3910                   # get new release
@@ -43,11 +43,11 @@
 var version string
 
 func init() {
-	version = "1.3"	// manage-db version
+	version = "1.3a"	// manual.pdf version
 }
 
 func main() {
-    var upgrade  = flag.Bool( "r", false, "get new release" )    // get grsearcher.exe, crypto.exe client.exe
+    var upgrade  = flag.Bool( "r", false, "get new release" )    // get grsearcher.exe, crypto.exe client.exe manual.pdf
     var update   = flag.Bool( "u", false, "get new DBs" )        // get auth.db, hhs.db, index.db(14,28)
     var managedb = flag.Bool( "m", false, "upload to /db" )      // management db
     var upload   = flag.Bool( "a", false, "upload to /upload" )  // post somefile
@@ -72,7 +72,7 @@
         host := flag.Args()[0]
         file := flag.Args()[1]
         fmt.Printf( "Sending %s...", file )
-		if message, err := post_file( host, "/upload", file ); err != nil {
+		if message, err := post_file( host, "/upload/", file ); err != nil {
 			log.Fatal( err )
 		} else {
 			fmt.Println( string( message ) )
@@ -108,19 +108,25 @@
             fmt.Fprint( os.Stderr, "bad remote host.\n" )
             os.Exit( 1 )
         }
-        fmt.Print( "Getting grsearcher.exe..." )
         host := flag.Args()[0]
-        if _, err := get_file( host, "/release/grsearcher.exe", "grsearcher.exe" ); err != nil {
+
+        fmt.Print( "Getting client.exe..." )
+        if _, err := get_file( host, "/release/client.exe", "client1.exe" ); err != nil {
             log.Fatal( err )
         }
         fmt.Print( "Getting crypto.exe..." )
         if _, err := get_file( host, "/release/crypto.exe", "crypto.exe" ); err != nil {
             log.Fatal( err )
         }
-        fmt.Print( "Getting client.exe..." )
-        if _, err := get_file( host, "/release/client.exe", "client1.exe" ); err != nil {
+        fmt.Print( "Getting grsearcher.exe..." )
+        if _, err := get_file( host, "/release/grsearcher.exe", "grsearcher.exe" ); err != nil {
             log.Fatal( err )
         }
+        fmt.Print( "Getting manual.pdf..." )
+        if _, err := get_file( host, "/release/manual.pdf", "manual.pdf" ); err != nil {
+            log.Fatal( err )
+        }
+
 		if *cnttime {
 			fmt.Println( "---", time.Now().Sub( st ) )
 		}
--- a/go/crypto.go	Tue Nov 13 21:11:20 2018 +0900
+++ b/go/crypto.go	Wed Nov 14 19:43:40 2018 +0900
@@ -1,7 +1,7 @@
 /*
  crypto.go  : crypto-program.
- Version    : 0.0
- Last Change: 2018-10-19 驥 15:58:10.
+ Version    : 1.1
+ Last Change: 2018-11-14 豌エ 13:27:48.
 
  install to: rsearcher_root/
              server_root/
@@ -26,7 +26,7 @@
 var version string
 
 func init() {
-	version = "1.0"
+	version = "1.1"	// output file version
 }
 
 func main() {
@@ -40,6 +40,8 @@
 	decr := flag.String( "d", "", "decrypt hhs." )
 	ghhs := flag.String( "f", "", "get hhs info." )
 
+	opf  := flag.String( "o", "", "output file." )
+
 	pver := flag.Bool( "v", false, "print version." )
 
 	flag.Parse()
@@ -138,7 +140,8 @@
 		stream := cipher.NewCTR( block, iv )
 		stream.XORKeyStream( ciphertext[ aes.BlockSize: ], plaintext )
 
-		fmt.Printf( "%s", ciphertext )
+		//fmt.Printf( "%s", ciphertext )
+		output( *opf, string( ciphertext ) )
 		os.Exit( 0 )
 	}
 
@@ -154,7 +157,8 @@
 		stream := cipher.NewCTR( block, iv )
 		stream.XORKeyStream( plaintext, ciphertext[ aes.BlockSize: ] )
 
-		fmt.Printf( "%s", plaintext )
+		//fmt.Printf( "%s", plaintext )
+		output( *opf, string( plaintext ) )
 		os.Exit( 0 )
 	}
 
@@ -175,3 +179,18 @@
 	return fmt.Sprintf( "%x", h.Sum( nil ) )
 }
 
+/* Output Function */
+func output( file, str string ) {
+	if file == "" {
+		fmt.Fprint( os.Stdout, str )
+	} else {
+		os.Remove( file )
+		f, err := os.OpenFile( file, os.O_RDWR|os.O_CREATE, 0644 )
+		if err != nil {
+			log.Fatal( err )
+		}
+		defer f.Close()
+		fmt.Fprint( f, str )
+	}
+}
+
--- a/go/extsql.go	Tue Nov 13 21:11:20 2018 +0900
+++ b/go/extsql.go	Wed Nov 14 19:43:40 2018 +0900
@@ -1,7 +1,7 @@
 /*
  extsql.go   : manipulate sqlite3.
  Version    : 0.1
- Last Change: 2018-11-13 轣ォ 15:22:56.
+ Last Change: 2018-11-14 豌エ 13:48:23.
 
  install to: rsearcher_root/
 */
@@ -30,7 +30,7 @@
 
 	// print version
 	if *printver {
-		fmt.Println( "mngdb [ ver", version, "]" )
+		fmt.Println( "extsql [ ver", version, "]" )
 		os.Exit( 0 )
 	}
 
@@ -70,7 +70,7 @@
 		log.Fatal( err )
 	}
 
-	f, _ = os.Create( "hhs.csv" )
+	f, _ = os.Create( "hhs.csv.tmp" )
 	for _, cols := range strings.Split( string( hhsdb ), "\n" ) {
 		col := strings.Split( cols, "|" )
 		if _, ok := m[ col[0] ]; ok == true {
--- a/go/server.go	Tue Nov 13 21:11:20 2018 +0900
+++ b/go/server.go	Wed Nov 14 19:43:40 2018 +0900
@@ -1,7 +1,7 @@
 /*
  server.go  : server-program.
  Version    : 1.3
- Last Change: 2018-11-13 轣ォ 08:19:52.
+ Last Change: 2018-11-14 豌エ 17:03:30.
 
  install to: server_root/
 
@@ -55,9 +55,9 @@
 
 	// start Web-server
 	fmt.Println( "server start [", server, "] ( program version", version, ")" )
-	http.HandleFunc( "/",       handler        )
-	http.HandleFunc( "/upload", upload_handler )
-	http.HandleFunc( "/mngdb/", mngdb_handler  )
+	http.HandleFunc( "/",        handler        )
+	http.HandleFunc( "/upload/", upload_handler )
+	http.HandleFunc( "/mngdb/",  mngdb_handler  )
 	log.Fatal( http.ListenAndServe( server, nil ) )
 }
 
--- a/include/id.h	Tue Nov 13 21:11:20 2018 +0900
+++ b/include/id.h	Wed Nov 14 19:43:40 2018 +0900
@@ -1,5 +1,5 @@
 // Filename   : id.h
-// Last Change: 2018-11-09 金 10:54:21.
+// Last Change: 2018-11-14 水 13:54:49.
 //
 
 #ifndef __ID_H__
@@ -7,8 +7,8 @@
 
 #include <wx/wx.h>
 
-#define RSVER "1.5"
-#define RSRELEASE "2018.11.12"
+#define RSVER "1.6a"
+#define RSRELEASE "2018.11.19"
 
 enum {
 	/* for mainframe */
@@ -21,12 +21,14 @@
 	ID_SPLIT,
 
 	// invisible for shortcut-key
+	ID_DLMAN,
 	ID_SLDR,
 	ID_FOCUS,
 	ID_PZOOM,
 	ID_MZOOM,
 	ID_SWIN,
 	ID_DARK,
+	ID_UPIDX,
 	ID_TIMER,
 	ID_LOGOUT,
 
--- a/include/main.h	Tue Nov 13 21:11:20 2018 +0900
+++ b/include/main.h	Wed Nov 14 19:43:40 2018 +0900
@@ -1,5 +1,5 @@
 // Filename   : main.h
-// Last Change: 2018-11-09 金 09:43:03.
+// Last Change: 2018-11-14 水 11:32:46.
 //
 #include <wx/wx.h>
 #include <wx/config.h>
@@ -20,6 +20,7 @@
 		wxString      unlock_key;
 		wxString	  m_serveraddr;
 		int     	  m_serverport;
+		wxString	  m_dbdir;
         bool          develop;
 
 	public:
--- a/include/mngdb.h	Tue Nov 13 21:11:20 2018 +0900
+++ b/include/mngdb.h	Wed Nov 14 19:43:40 2018 +0900
@@ -1,5 +1,5 @@
 // Filename   : mngdb.h
-// Last Change: 2018-11-09 金 09:02:17.
+// Last Change: 2018-11-14 水 13:53:29.
 //
 
 #ifndef __MNGDB_H__
@@ -44,9 +44,9 @@
 		void OnUpload( wxCommandEvent& event );
 		void OnExit( wxCommandEvent& event );
 
+		void SetDBdir( wxString dir );
+		void SetServer( wxString server ) { m_server = server; };
 		void Upload( wxString file );
-		void ClearServer( void );
-		void UpdateDB( void );
 };
 
 #endif //__MNGDB_H__
--- a/include/net.h	Tue Nov 13 21:11:20 2018 +0900
+++ b/include/net.h	Wed Nov 14 19:43:40 2018 +0900
@@ -1,5 +1,5 @@
 // Filename   : net.h
-// Last Change: 2018-11-09 驥 09:31:59.
+// Last Change: 2018-11-14 豌エ 10:05:44.
 //
 
 #ifndef __NET_H__
@@ -20,7 +20,7 @@
 
 		void SetServer( wxString server, int port ) { m_server = server; m_port = port; };
 		bool Get( wxString url, wxString file );
-		bool GetDB();
+		bool GetDB( int a, int h, int i);
 		int  GetImagesSize( wxString hhs, wxString date );
 		void GetImages( wxString hhs, wxString date );
 		void GetImages2Memory( wxString hhs, wxString date );
--- a/include/rsearcher.h	Tue Nov 13 21:11:20 2018 +0900
+++ b/include/rsearcher.h	Wed Nov 14 19:43:40 2018 +0900
@@ -1,5 +1,5 @@
 // Filename   : rsearcher.h
-// Last Change: 2018-11-08 木 13:51:59.
+// Last Change: 2018-11-14 水 11:34:55.
 //
 
 #ifndef __RSEARCH_H__
@@ -110,6 +110,7 @@
 		bool		  startup = true;
 		wxString	  m_server;
 		wxString	  m_hhs;
+		wxString	  m_dbdir;
 		wxString	  m_user;
 		wxArrayString m_index;
 		wxTimer       m_timer;
@@ -158,6 +159,8 @@
 		wxButton*           m_buttonMzoom;
 		wxButton*           m_buttonDark;
 		wxButton*           m_buttonSatellite;
+		wxButton*           m_buttonUpdateIndex;
+		wxButton*           m_buttonDLMan;
 		wxButton*           m_buttonHelp;
 		wxButton*           m_buttonClose;
 		wxButton*           m_buttonLogout;
@@ -166,8 +169,9 @@
 		MainFrame( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT( "Searcher Remote" ), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 500,300 ), long style = wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL );
 		~MainFrame();
 
-		void SetServer( wxString addr, int port ) { http.SetServer( addr, port ); m_server = wxString::Format(wxT("%s:%d"),addr,port);};
-		bool GetDB( void ) { return http.GetDB(); };
+		void SetServer( wxString addr, int port ) { http.SetServer( addr, port ); m_server = wxString::Format(wxT("%s:%d"),addr,port); };
+		void SetDBdir( wxString dir ) { m_dbdir = dir; };
+		bool GetDB( int a, int h, int i ) { return http.GetDB( a, h, i ); };
 		void SetUser( wxString user ) { m_user = user; WriteLog( wxT( "[login] " ) + m_user ); };
 		void CreateControls( void );
 		void SetAccelerator( void );
@@ -175,6 +179,7 @@
 		void Search( void );
 		void PasteSearch( void );
 		void LoadDB( void );
+		void UpdateIndex( void );
         bool LoadBitmap( wxScrolledWindow* sc, MyStaticBitmap* sb, wxString file );
         bool LoadBitmaps( wxString date, bool reload );
 		void ChangeCZoom( int z );
@@ -205,6 +210,8 @@
         void OnMinusZoom( wxCommandEvent& event );
         void OnDark( wxCommandEvent& event );
         void OnSatellite( wxCommandEvent& event );
+        void OnUpdateIndex( wxCommandEvent& event );
+        void OnDownloadManual( wxCommandEvent& event );
         void OnHelp( wxCommandEvent& event );
         void OnLogout( wxCommandEvent& event );
 };
--- a/src/main.cpp	Tue Nov 13 21:11:20 2018 +0900
+++ b/src/main.cpp	Wed Nov 14 19:43:40 2018 +0900
@@ -1,5 +1,5 @@
 // Filename   : main.cpp
-// Last Change: 2018-11-09 驥 11:54:20.
+// Last Change: 2018-11-14 豌エ 12:54:16.
 //
 
 #include <wx/socket.h>
@@ -51,8 +51,9 @@
 	// Main Window
 	MainFrame *mainframe = new MainFrame( NULL, ID_MAIN, wxEmptyString, wxPoint( rect.x, rect.y ), rect.GetSize(), wxDEFAULT_FRAME_STYLE );
 	mainframe->SetServer( m_serveraddr, m_serverport );
+	mainframe->SetDBdir( m_dbdir );
 	mainframe->InDevelop( true );
-	if ( !mainframe->GetDB() ) {
+	if ( !mainframe->GetDB( 1, 1, 1 ) ) {
 		mainframe->Destroy();
 		return true;
 	}
@@ -124,6 +125,9 @@
 
 int MyApp::OnExit()
 {
+	RemoveFile( wxT( "hhs.csv.tmp" ) );
+	RemoveFile( wxT( "hhs.csv" ) );
+	RemoveFile( wxT( "index.db.tmp" ) );
 	RemoveFile( wxT( "auth.db" ) );
 	RemoveFile( wxT( "hhs.db" ) );
 	RemoveFile( wxT( ".cache/*" )  );
@@ -142,6 +146,9 @@
     config->Read( wxT( "w" ), &rect.width );
     config->Read( wxT( "h" ), &rect.height );
 
+    config->SetPath( wxT( "/DBManage" ) );
+    config->Read( wxT( "dbdir" ), &m_dbdir );
+
     config->SetPath( wxT( "/Server" ) );
     config->Read( wxT( "proxy_address" ), &m_serveraddr );
     config->Read( wxT( "proxy_port" ),    &m_serverport );
--- a/src/mngdb.cpp	Tue Nov 13 21:11:20 2018 +0900
+++ b/src/mngdb.cpp	Wed Nov 14 19:43:40 2018 +0900
@@ -1,13 +1,16 @@
 // Filename   : mngdeb.cpp
-// Last Change: 2018-11-09 驥 13:35:54.
+// Last Change: 2018-11-14 豌エ 13:48:58.
 //
 
+#include <wx/datetime.h>
+#include <wx/textfile.h>
 #include "id.h"
 #include "mngdb.h"
 
 ManageDBFrame::ManageDBFrame( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) 
 	: wxFrame( parent, id, title, pos, size, style )
 {
+	this->SetBackgroundColour( wxColour( 140, 240, 140 ) );
 	this->SetSizeHints( wxDefaultSize, wxDefaultSize );
 	
 	wxBoxSizer* bSizerTop = new wxBoxSizer( wxVERTICAL );
@@ -19,19 +22,19 @@
 	m_staticTextDate = new wxStaticText( this, wxID_ANY, wxT( "Date" ), wxDefaultPosition, wxDefaultSize, 0 );
 	fgSizer->Add( m_staticTextDate, 0, wxALL|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 5 );
 	
-	m_datePicker = new wxDatePickerCtrl( this, wxID_ANY, wxDefaultDateTime, wxDefaultPosition, wxDefaultSize, wxDP_DROPDOWN|wxDP_SHOWCENTURY );
+	m_datePicker = new wxDatePickerCtrl( this, wxID_ANY, wxDefaultDateTime, wxDefaultPosition, wxSize( 180, -1 ), wxDP_DROPDOWN|wxDP_SHOWCENTURY );
 	fgSizer->Add( m_datePicker, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
 	
 	m_staticTextHhs = new wxStaticText( this, wxID_ANY, wxT( "HHS" ), wxDefaultPosition, wxDefaultSize, 0 );
 	fgSizer->Add( m_staticTextHhs, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT, 5 );
 	
-	m_filePickerHhs = new wxFilePickerCtrl( this, wxID_ANY, wxEmptyString, wxT( "Select a file" ), wxT( "*.db" ), wxDefaultPosition, wxDefaultSize, wxFLP_FILE_MUST_EXIST|wxFLP_OPEN|wxFLP_SMALL|wxFLP_USE_TEXTCTRL );
+	m_filePickerHhs = new wxFilePickerCtrl( this, wxID_ANY, wxEmptyString, wxT( "Select a file" ), wxT( "*.db" ), wxDefaultPosition, wxSize( 180, -1 ), wxFLP_FILE_MUST_EXIST|wxFLP_OPEN|wxFLP_SMALL|wxFLP_USE_TEXTCTRL );
 	fgSizer->Add( m_filePickerHhs, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
 	
 	m_staticTextCcn = new wxStaticText( this, wxID_ANY, wxT( "CCN" ), wxDefaultPosition, wxDefaultSize, 0 );
 	fgSizer->Add( m_staticTextCcn, 0, wxALL|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 5 );
 	
-	m_filePickerCcn = new wxFilePickerCtrl( this, wxID_ANY, wxEmptyString, wxT( "Select a file" ), wxT( "*.db" ), wxDefaultPosition, wxDefaultSize, wxFLP_FILE_MUST_EXIST|wxFLP_OPEN|wxFLP_SMALL|wxFLP_USE_TEXTCTRL );
+	m_filePickerCcn = new wxFilePickerCtrl( this, wxID_ANY, wxEmptyString, wxT( "Select a file" ), wxT( "*.db" ), wxDefaultPosition, wxSize( 180, -1 ), wxFLP_FILE_MUST_EXIST|wxFLP_OPEN|wxFLP_SMALL|wxFLP_USE_TEXTCTRL );
 	fgSizer->Add( m_filePickerCcn, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
 	
 	bSizerTop->Add( fgSizer, 0, wxALIGN_CENTER_HORIZONTAL, 5 );
@@ -57,6 +60,7 @@
 	this->Layout();
 	
 	this->Centre( wxBOTH );
+	m_buttonUpld->Enable( false );
 }
 
 ManageDBFrame::~ManageDBFrame()
@@ -73,15 +77,51 @@
 // Event Handler
 void ManageDBFrame::OnBuild( wxCommandEvent& WXUNUSED(event) )
 {
+	wxString hhs = m_filePickerHhs->GetPath();
+	wxString ccn = m_filePickerCcn->GetPath();
+	wxDateTime dt = m_datePicker->GetValue();
+	wxString ymd = dt.Format( wxT( "%Y%m%d" ) );
+
+	// index.db.tmp, hhs.csv.tmp(utf-8)
+	wxArrayString args;
+	args.Add( wxT( "extsql.exe" ) );
+	args.Add( hhs );
+	args.Add( ccn );
+	args.Add( ymd );
+	wxExecute( wxJoin( args, ' ', '\\' ), wxEXEC_SYNC|wxEXEC_HIDE_CONSOLE );
+
+	// hhs.csv(cp932)
+    wxCSConv cust( wxT( "cp932" ) );
+	wxTextFile input( wxT( "hhs.csv.tmp" ) );
+	wxTextFile output( wxT( "hhs.csv" ) );
+    input.Open();
+    output.Create();
+    for ( wxString buf = input.GetFirstLine(); !input.Eof(); buf = input.GetNextLine() )
+		output.AddLine( buf );
+    input.Close();
+	output.Write( wxTextFileType_Dos, cust );
+    output.Close();
+
+	// hhs.db(encryptoed)
+	wxString key = wxT( "12345678900123456789abcdefabcdef" );
+	args.Clear();
+	args.Add( wxT( "crypto.exe" ) );
+	args.Add( wxT( "-e" ) );
+	args.Add( wxT( "hhs.csv" ) );
+	args.Add( wxT( "-k" ) );
+	args.Add( key );
+	args.Add( wxT( "-o" ) );
+	args.Add( wxT( "hhs.db" ) );
+	wxExecute( wxJoin( args, ' ', '\\' ), wxEXEC_SYNC|wxEXEC_HIDE_CONSOLE );
+
 	wxMessageBox( wxT( "build done." ) );
+	m_buttonUpld->Enable( true );
 }
 
 void ManageDBFrame::OnUpload( wxCommandEvent& WXUNUSED(event) )
 {
-	ClearServer();
 	Upload( wxT( "index.db" ) );
 	Upload( wxT( "hhs.db" ) );
-	UpdateDB();
 	wxMessageBox( wxT( "upload done." ) );
 }
 
@@ -96,31 +136,19 @@
 {
 	wxArrayString args;
 	args.Add( wxT( "client.exe" ) );
-	args.Add( wxT( "-a" ) );
+	args.Add( wxT( "-m" ) );
 	args.Add( m_server );
 	args.Add( file );
 
-	wxExecute( wxJoin( args, ' ', '\\' ) );
+	wxExecute( wxJoin( args, ' ', '\\' ), wxEXEC_SYNC|wxEXEC_HIDE_CONSOLE );
 }
 
-void ManageDBFrame::ClearServer( void )
+void ManageDBFrame::SetDBdir( wxString dir )
 {
-// go-server get /clean -> rm -f upload/*
-	wxArrayString args;
-	args.Add( wxT( "client.exe" ) );
-	args.Add( m_server );
-
-	wxExecute( wxJoin( args, ' ', '\\' ) );
+	wxDateTime dt;
+	dt.ParseFormat( wxT( "20160401" ), wxT( "%Y%m%d") );
+	m_datePicker->SetValue( dt );
+	m_filePickerHhs->SetPath( dir + wxFILE_SEP_PATH + wxT( "hhs.db") );
+	m_filePickerCcn->SetPath( dir + wxFILE_SEP_PATH + wxT( "ccn.db") );
 }
 
-void ManageDBFrame::UpdateDB( void )
-{
-// go-server get /mangedb -> mv upload/xxx db/index.db
-//                           mv upload/yyy db/hhs.db
-	wxArrayString args;
-	args.Add( wxT( "client.exe" ) );
-	args.Add( m_server );
-
-	wxExecute( wxJoin( args, ' ', '\\' ) );
-}
-
--- a/src/net.cpp	Tue Nov 13 21:11:20 2018 +0900
+++ b/src/net.cpp	Wed Nov 14 19:43:40 2018 +0900
@@ -1,5 +1,5 @@
 // Filename   : net.cpp
-// Last Change: 2018-11-09 驥 09:32:56.
+// Last Change: 2018-11-14 豌エ 10:46:24.
 //
 
 #include <wx/datetime.h>
@@ -39,14 +39,14 @@
 	return ret;
 }
 
-bool RsHttp::GetDB( void )
+bool RsHttp::GetDB( int a, int h, int i )
 {
 	bool ret = false;
-	ret = Get( wxT( "/db/auth.db"), wxT( "auth.db") );
-	ret = Get( wxT( "/db/hhs.db"),  wxT( "hhs.db") );
+	if ( a == 1 ) ret = Get( wxT( "/db/auth.db"), wxT( "auth.db") );
+	if ( h == 1 ) ret = Get( wxT( "/db/hhs.db"),  wxT( "hhs.db") );
 	wxDateTime now = wxDateTime::Now();
-	if ( now.GetDay() % 14 == 0 ) 
-		Get( wxT( "/db/index.db"),  wxT( "index.db" ) );
+	if ( i == 2 || now.GetDay() % 13 == 0 || now.GetDay() % 28 == 0 ) 
+		Get( wxT( "/db/index.db"), wxT( "index.db" ) );
 	return ret;
 }
 
--- a/src/rsearcher.cpp	Tue Nov 13 21:11:20 2018 +0900
+++ b/src/rsearcher.cpp	Wed Nov 14 19:43:40 2018 +0900
@@ -1,5 +1,5 @@
 // Filename   : rsearcher.cpp
-// Last Change: 2018-11-09 驥 09:01:40.
+// Last Change: 2018-11-14 豌エ 14:06:25.
 //
 
 #include <wx/arrstr.h> 
@@ -290,6 +290,8 @@
 	EVT_BUTTON( ID_MZOOM, MainFrame::OnMinusZoom )
 	EVT_BUTTON( ID_DARK, MainFrame::OnDark )
 	EVT_BUTTON( ID_SWIN, MainFrame::OnSatellite )
+	EVT_BUTTON( ID_UPIDX, MainFrame::OnUpdateIndex )
+	EVT_BUTTON( ID_DLMAN, MainFrame::OnDownloadManual )
 	EVT_BUTTON( wxID_HELP, MainFrame::OnHelp )
 	EVT_BUTTON( wxID_CLOSE, MainFrame::OnBClose )
 	EVT_BUTTON( ID_LOGOUT, MainFrame::OnLogout )
@@ -427,6 +429,19 @@
 	stl->Show();
 }
 
+void MainFrame::OnUpdateIndex( wxCommandEvent& WXUNUSED(event ) )
+{
+	GetDB( 0, 0, 2 );
+	UpdateIndex();
+	wxMessageBox( wxT( "update index done." ) );
+}
+
+void MainFrame::OnDownloadManual( wxCommandEvent& WXUNUSED(event) )
+{
+	wxString execmd = wxT( "cmd /c start manual.pdf" );
+	wxExecute( execmd );
+}
+
 void MainFrame::OnHelp( wxCommandEvent& WXUNUSED(event) )
 {
 	wxString version, build;
@@ -572,6 +587,10 @@
 	m_buttonDark->Hide();
 	m_buttonSatellite = new wxButton( this, ID_SWIN, wxT( "Satellite" ), wxDefaultPosition, wxDefaultSize, 0 );
 	m_buttonSatellite->Hide();
+	m_buttonDLMan = new wxButton( this, ID_DLMAN, wxT( "Manual" ), wxDefaultPosition, wxDefaultSize, 0 );
+	m_buttonDLMan->Hide();
+	m_buttonUpdateIndex = new wxButton( this, ID_UPIDX, wxT( "Update Index" ), wxDefaultPosition, wxDefaultSize, 0 );
+	m_buttonUpdateIndex->Hide();
 	m_buttonClose = new wxButton( this, wxID_CLOSE, wxT( "Close" ), wxDefaultPosition, wxDefaultSize, 0 );
 	m_buttonClose->Hide();
 	m_buttonHelp = new wxButton( this, wxID_HELP, wxT( "Help" ), wxDefaultPosition, wxDefaultSize, 0 );
@@ -595,17 +614,19 @@
 
 void MainFrame::SetAccelerator( void )
 {
-	wxAcceleratorEntry entries[9];
-	entries[0].Set( wxACCEL_CTRL,   (int)'P', wxID_PRINT );
-	entries[1].Set( wxACCEL_NORMAL, WXK_F1,   wxID_HELP );
-	entries[2].Set( wxACCEL_NORMAL, WXK_F4,   ID_FOCUS );
-	entries[3].Set( wxACCEL_NORMAL, (int)'Z', ID_PZOOM );
-	entries[4].Set( wxACCEL_NORMAL, (int)'X', ID_MZOOM );
-	entries[5].Set( wxACCEL_NORMAL, (int)'D', ID_DARK );
-	entries[6].Set( wxACCEL_CTRL,   (int)'Q', wxID_CLOSE );
-	entries[7].Set( wxACCEL_SHIFT,  (int)'W', ID_SWIN );
-	entries[8].Set( wxACCEL_SHIFT,  (int)'L', ID_DARK );	// now building ( logout )
-	wxAcceleratorTable accel( 8, entries );
+	wxAcceleratorEntry entries[11];
+	entries[0].Set(  wxACCEL_CTRL,   (int)'P', wxID_PRINT );
+	entries[1].Set(  wxACCEL_NORMAL, WXK_F1,   wxID_HELP );
+	entries[2].Set(  wxACCEL_NORMAL, WXK_F2,   ID_DLMAN );
+	entries[3].Set(  wxACCEL_NORMAL, WXK_F4,   ID_FOCUS );
+	entries[4].Set(  wxACCEL_NORMAL, (int)'Z', ID_PZOOM );
+	entries[5].Set(  wxACCEL_NORMAL, (int)'X', ID_MZOOM );
+	entries[6].Set(  wxACCEL_NORMAL, (int)'D', ID_DARK );
+	entries[7].Set(  wxACCEL_CTRL,   (int)'Q', wxID_CLOSE );
+	entries[8].Set(  wxACCEL_SHIFT,  (int)'W', ID_SWIN );
+	entries[9].Set(  wxACCEL_SHIFT,  (int)'R', ID_UPIDX );
+	entries[10].Set( wxACCEL_SHIFT,  (int)'L', ID_DARK );	// now building ( logout )
+	wxAcceleratorTable accel( 10, entries );
 	SetAcceleratorTable( accel );
 }
 
@@ -629,9 +650,12 @@
 		return;
     }
 
-    if ( cmd.IsSameAs( wxT( "3915" ), true ) ) {
+    if ( cmd.IsSameAs( wxT( "3915" ), true ) && m_user.IsSameAs( wxT( "root" ) ) ) {
 		ManageDBFrame *mngframe = new ManageDBFrame( this, wxID_ANY, wxT( "Management Window" ), wxDefaultPosition, wxSize( 300, 180 ), wxCAPTION|wxTAB_TRAVERSAL );
+		mngframe->SetDBdir( m_dbdir );
+		mngframe->SetServer( m_server );
 		mngframe->Show();
+		m_searchCtrl->Clear();
         return;
 	}
 
@@ -872,12 +896,7 @@
     pd.SetSize( wxSize( 320, 140 ) );
 	
 	// index
-	wxTextFile file;
-	file.Open( wxT( "index.db" ) );
-	for ( int i = 0; i < file.GetLineCount(); i++ )
-		m_index.Add( file.GetLine( i ) );
-	file.Close();
-	m_index.Sort( true );
+	UpdateIndex();
 
 	// decrypto
 	wxString key = wxT( "12345678900123456789abcdefabcdef" );
@@ -905,6 +924,23 @@
 	}
 }
 
+void MainFrame::UpdateIndex( void )
+{
+	wxString oldest = wxT( "30001231" );
+	wxString newest = wxT( "20000401" );
+	wxTextFile file;
+	file.Open( wxT( "index.db" ) );
+	for ( int i = 0; i < file.GetLineCount(); i++ ) {
+		wxArrayString buf = wxSplit( file.GetLine( i ), ':', '\\' );
+		if ( oldest.Cmp( buf[1] ) ==  1 ) oldest = buf[1];
+		if ( newest.Cmp( buf[1] ) == -1 ) newest = buf[1];
+		m_index.Add( file.GetLine( i ) );
+	}
+	file.Close();
+	m_index.Sort( true );
+	m_textCtrlLog->SetValue( wxT( "Index: " ) + oldest + wxT( " - " ) + newest );
+}
+
 void MainFrame::PasteSearch( void )
 {
 	wxString s;