Qiniu Sync Ver.I
using System; using System.Collections.Generic; using System.IO; using System.Diagnostics; using System.Windows.Forms; using System.Drawing; using System.Runtime.InteropServices; using System.Text; using System.Xml; using System.Reflection; namespace Qiniu_Sync_Ver.I { internal class Qsvi { private static NotifyIcon notifyIcon = new NotifyIcon(); private static bool Visible = true; private static void Main(string[] args) { notifyIcon.DoubleClick += (s, e) => { Visible = !Visible; SetConsoleWindowVisibility(Visible); }; notifyIcon.Icon = Icon.ExtractAssociatedIcon(Application.ExecutablePath); List<Task> tasks = new List<Task>(); notifyIcon.Visible = true; notifyIcon.Text = Application.ProductName; new ContextMenuStrip().Items.Add(text: "Exit", image: null, onClick: (s, e) => { Application.Exit(); }); notifyIcon.ContextMenuStrip = new ContextMenuStrip(); Console.WriteLine("Qiniu Sync Ver.I"); DarkGreen("Qiniu Sync Ver.I:/# "); Console.WriteLine("-l"); Login(); ShowBuckets(); ShowHelp(); UI(ref tasks); List<FileSystemWatcher> sync = new List<FileSystemWatcher>(); Application.Run(); notifyIcon.Visible = false; } private static void AddTask() { Console.Write("LocalPath: "); StringBuilder LocalPath = new StringBuilder(Console.ReadLine()); if (LocalPath[0] == '"') { LocalPath.Remove(LocalPath.Length - 1, 1); } if(LocalPath[LocalPath.Length-1]=='"') { LocalPath.Remove(LocalPath.Length - 1, 1); } if (LocalPath[LocalPath.Length - 1] == '\\') { LocalPath.Remove(LocalPath.Length - 1, 1); } Console.Write("Bucket: "); string Bucket = Console.ReadLine(); string xmlPath = ConfigPath(); XmlDocument config = new XmlDocument(); config.Load(xmlPath); XmlNode newNode = config.CreateNode(nodeTypeString: "element", name: "Task", namespaceURI: ""); newNode.InnerText = LocalPath.ToString(); ((XmlElement)newNode).SetAttribute(name: "ID", value: TaskLength(config).ToString()); ((XmlElement)newNode).SetAttribute(name: "Bucket", value: Bucket); config.DocumentElement.AppendChild(newChild: newNode); config.Save(filename: xmlPath); } private static string ConfigPath() => $"{Path()}config\\Qiniu Sync Ver.I.xml"; private static int TaskLength(XmlDocument config) => config.SelectNodes(xpath: @"//Task").Count; private static void UI(ref List<Task> tasks) { bool disexit = true; while (disexit) { DarkGreen("Qiniu Sync Ver.I:/# "); string input = Console.ReadLine(); switch (input) { case "-a": AddTask(); break; case "-l": Login(); break; case "-s": disexit = false; StratSync(ref tasks); break; case "-d-b": ShowBuckets(); break; case "-r": break; case "-h": ShowHelp(); break; case "-d-t": break; default: DarkRed("[!] Qiniu Sync Ver.I"); Console.WriteLine(": No argument"); break; } } } private static void DarkRed(string console) { Console.ForegroundColor = ConsoleColor.DarkRed; Console.Write(console); Console.ForegroundColor = ConsoleColor.White; } private static void DarkGreen(string console) { Console.ForegroundColor = ConsoleColor.DarkGreen; Console.Write(console); Console.ForegroundColor = ConsoleColor.White; } private static void ShowHelp() { Console.ForegroundColor = ConsoleColor.DarkBlue; Console.Write(value: $"[*] {Qscvi()}"); Console.ForegroundColor = ConsoleColor.White; Console.WriteLine(": -h"); Console.WriteLine(" Examples :"); Console.WriteLine(""); Console.WriteLine(" Add sync task ..."); Console.WriteLine(" -a"); Console.WriteLine(""); Console.WriteLine(" Login account ..."); Console.WriteLine(" -l"); Console.WriteLine(""); Console.WriteLine(" Start sync tasks ..."); Console.WriteLine(" -s"); Console.WriteLine(""); Console.WriteLine(" Remove sync task ..."); Console.WriteLine(" -r"); Console.WriteLine(""); Console.WriteLine(" Display sync tasks ..."); Console.WriteLine(" -d-t"); Console.WriteLine(""); Console.WriteLine(" Display buckets"); Console.WriteLine(" -d-b"); Console.WriteLine(""); } private static void StratSync(ref List<Task> tasks) { tasks = new List<Task>(); XmlDocument config = new XmlDocument(); config.Load(ConfigPath()); for (int i=0;i<TaskLength(config);++i) { tasks.Add(new Task(i.ToString())); } for(int i=0;i<tasks.Count;++i) { tasks[i].StartSync(); } } private static void Login() { DarkMagenta("Login from [0]AccessKey [1]User: "); try { if(Convert.ToBoolean(Convert.ToByte(Console.ReadLine()))) { LogicByUser(); } else { LogicByAccessKey(); } } catch { Login(); } } private static void LogicByAccessKey(string ak = null, string sk = null) { if (ak == null || sk == null) { DarkMagenta("AccessKey"); Console.Write(": "); ak = Console.ReadLine(); DarkMagenta("SecretKey"); Console.Write(": "); sk = Console.ReadLine(); } QshellCmd(cmd: $"account {ak} {sk}"); } private static void LogicByUser() { DarkMagenta("User"); Console.Write(": "); string user = Console.ReadLine(); DarkMagenta("Passwd"); Console.Write(": "); string pw = Console.ReadLine(); QrsctlCmd($"login {user} {pw}"); QrsctlCmd(cmd: $"appinfo default", isLogin: false); } private static void DarkMagenta(string console) { Console.ForegroundColor = ConsoleColor.DarkMagenta; Console.Write(console); Console.ForegroundColor = ConsoleColor.White; } public static void QshellCmd(string cmd, bool enableOutput = true) => Cmd(cmd: $"\"{Path()}bin\\qshell-windows-x64.exe\" {cmd}", enableOutput: enableOutput); public static string QrsctlCmd(string cmd, bool enableOutput = true, bool isLogin = false) => Cmd(cmd: $"\"{Path()}bin\\qrsctl-v3.2.20170501.exe\" {cmd}", enableOutput: enableOutput); private static string Cmd(string cmd, bool enableOutput = true, bool isLogin = false) { string ans = ""; Process cmdProcess = new Process(); cmdProcess.StartInfo.FileName = "cmd.exe"; cmdProcess.StartInfo.UseShellExecute = false; cmdProcess.StartInfo.RedirectStandardInput = true; cmdProcess.StartInfo.RedirectStandardOutput = true; cmdProcess.StartInfo.RedirectStandardError = true; cmdProcess.StartInfo.CreateNoWindow = true; cmdProcess.Start(); cmdProcess.StandardInput.WriteLine(cmd + " &exit"); cmdProcess.StandardInput.AutoFlush = true; StringBuilder output = new StringBuilder(value: cmdProcess.StandardOutput.ReadToEnd()); cmdProcess.WaitForExit(); cmdProcess.Close(); if (enableOutput) { for (int d = 0; d < 2; output.Remove(startIndex: 0, length: 1)) { if (output[index: 0] == '\"') { ++d; } } output.Remove(startIndex: 0, length: 1); List<StringBuilder> outputStringList = new List<StringBuilder>(); foreach (string o in output.ToString().Split(separator: '\n')) { outputStringList.Add(item: new StringBuilder(value: o)); } for (int i = 1; i < outputStringList.Count; ++i) { outputStringList[index: i].Insert(index: 0, value: $"[*] {outputStringList[0].ToString().Split(' ')[0]}: "); } outputStringList.RemoveAt(index: outputStringList.Count - 1); for (int i = 0; i < 7; ++i) { outputStringList[index: 0].Remove(startIndex: outputStringList[0].Length - 1, length: 1); } outputStringList[0].Insert(0, value: $"[*] {Qscvi()}: "); if (isLogin) { ans = $"{outputStringList[1].ToString().Split(':')[1]} {outputStringList[2].ToString().Split(':')[1]}"; } for (int i=0;i<outputStringList.Count;++i) { Console.ForegroundColor = ConsoleColor.DarkBlue; Console.Write(outputStringList[i].ToString().Split(':')[0]); Console.ForegroundColor = ConsoleColor.White; for(int j=1;j<outputStringList[i].ToString().Split(':').Length;++j) { Console.Write(":"); if(j== outputStringList[i].ToString().Split(':').Length-1) { Console.WriteLine(outputStringList[i].ToString().Split(':')[j]); } else { Console.Write(outputStringList[i].ToString().Split(':')[j]); } } } } return ans; } [DllImport(dllName: "user32.dll")] public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); [DllImport(dllName: "user32.dll")] private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); public static void SetConsoleWindowVisibility(bool visible) { IntPtr hWnd = FindWindow(lpClassName: null, lpWindowName: Console.Title); if (hWnd != IntPtr.Zero) { if (visible) { ShowWindow(hWnd: hWnd, nCmdShow: 1); } else { ShowWindow(hWnd: hWnd, nCmdShow: 0); } } } private static string Qscvi() => "Qiniu Sync Ver.I"; private static void ShowBuckets() => QshellCmd(cmd: "buckets"); public static string Path() => AppDomain.CurrentDomain.SetupInformation.ApplicationBase; public static string GetAttribute(string ID,string Attribute) { XmlDocument config = new XmlDocument(); config.Load(ConfigPath()); return ((XmlElement)config.SelectNodes(xpath: @"//Task[@ID='" + ID + "']")[i: 0]).GetAttribute(name: Attribute); } public static string GetInnerText(string ID) { XmlDocument config = new XmlDocument(); config.Load(ConfigPath()); return ((XmlElement)config.SelectNodes(xpath: @"//Task[@ID='" + ID + "']")[i: 0]).InnerText; } public static string Bucket() => "Bucket"; } public class Task { private string ID; private FileSystemWatcher syncDir; public Task(string ID) { this.ID = ID; syncDir = new FileSystemWatcher() { Path = Qsvi.GetInnerText(ID), Filter = "*.*" }; syncDir.Changed += new FileSystemEventHandler(OnProcess); syncDir.Created += new FileSystemEventHandler(OnProcess); syncDir.Deleted += new FileSystemEventHandler(OnProcess); syncDir.Renamed += new RenamedEventHandler(OnRenamed); syncDir.NotifyFilter = NotifyFilters.Attributes | NotifyFilters.CreationTime | NotifyFilters.DirectoryName | NotifyFilters.FileName | NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.Security | NotifyFilters.Size; syncDir.IncludeSubdirectories = true; } public void StartSync() { Output(); Sync(); syncDir.EnableRaisingEvents = true; } private void Sync() => Qsvi.QshellCmd($"qupload \"{Qsvi.Path()}config\\qupload.{ID.GetHashCode()}.config\""); private string Src_dir(bool content) => content ? $"\"{Qsvi.GetInnerText(ID)}\"" : MethodBase.GetCurrentMethod().Name.ToLower(); private string Bucket(bool content) => content ? $"\"{Qsvi.GetAttribute(ID, MethodBase.GetCurrentMethod().Name)}\"" : MethodBase.GetCurrentMethod().Name.ToLower(); private string Ignore_dir(bool content) => content ? false.ToString().ToLower() : MethodBase.GetCurrentMethod().Name.ToLower(); private string Overwrite(bool content) => content ? true.ToString().ToLower() : MethodBase.GetCurrentMethod().Name.ToLower(); private string Check_exists(bool content) => content ? true.ToString().ToLower() : MethodBase.GetCurrentMethod().Name.ToLower(); private string Check_hash(bool content) => content ? true.ToString().ToLower() : MethodBase.GetCurrentMethod().Name.ToLower(); private string Check_size(bool content) => content ? false.ToString().ToLower() : MethodBase.GetCurrentMethod().Name.ToLower(); private string Rescan_local(bool content) => content ? true.ToString().ToLower() : MethodBase.GetCurrentMethod().Name.ToLower(); private string Log_file(bool content) => content ? $"\"qupload.log\"" : MethodBase.GetCurrentMethod().Name.ToLower(); private string Log_level(bool content) => content ? $"\"debug\"" : MethodBase.GetCurrentMethod().Name.ToLower(); private string Log_rotate(bool content) => content ? "1" : MethodBase.GetCurrentMethod().Name.ToLower(); private string Log_stdout(bool content) => content ? true.ToString().ToLower() : MethodBase.GetCurrentMethod().Name.ToLower(); private string File_type(bool content) => content ? "0" : MethodBase.GetCurrentMethod().Name.ToLower(); private string ConfigPath() => $"{Qsvi.Path()}config\\qupload.{ID.GetHashCode()}.config"; private string Doublize(string raw) { StringBuilder input = new StringBuilder(raw); for(int i=0;i<input.Length;++i) { if(input[i]=='\\') { input.Insert(i, '\\'); ++i; } } return input.ToString(); } private void Output() { StreamWriter writeConfig = new StreamWriter(stream: new FileStream(ConfigPath(), FileMode.Create, FileAccess.Write, FileShare.ReadWrite)); writeConfig.WriteLine("{"); writeConfig.WriteLine($" \"{Src_dir(false)}\":{Doublize(Src_dir(true))},"); writeConfig.WriteLine($" \"{Bucket(false)}\":{Bucket(true)},"); writeConfig.WriteLine($" \"{Ignore_dir(false)}\":{Ignore_dir(true)},"); writeConfig.WriteLine($" \"{Overwrite(false)}\":{Overwrite(true)},"); writeConfig.WriteLine($" \"{Check_exists(false)}\":{Check_exists(true)},"); writeConfig.WriteLine($" \"{Check_hash(false)}\":{Check_hash(true)},"); writeConfig.WriteLine($" \"{Check_size(false)}\":{Check_size(true)},"); writeConfig.WriteLine($" \"{Rescan_local(false)}\":{Rescan_local(true)},"); writeConfig.WriteLine($" \"{Log_file(false)}\":{Log_file(true)},"); writeConfig.WriteLine($" \"{Log_level(false)}\":{Log_level(true)},"); writeConfig.WriteLine($" \"{Log_rotate(false)}\":{Log_rotate(true)},"); writeConfig.WriteLine($" \"{Log_stdout(false)}\":{Log_stdout(true)},"); writeConfig.WriteLine($" \"{File_type(false)}\":{File_type(true)}"); writeConfig.WriteLine("}"); writeConfig.Close(); } private void OnProcess(object source, FileSystemEventArgs e) { if (e.ChangeType == WatcherChangeTypes.Created) { Console.ForegroundColor = ConsoleColor.DarkBlue; Console.Write($"[*] File {e.ChangeType}"); Console.ForegroundColor = ConsoleColor.White; Console.WriteLine($": {e.FullPath}"); OnCreated(source: source, e: e); } else if (e.ChangeType == WatcherChangeTypes.Changed) { Console.ForegroundColor = ConsoleColor.DarkBlue; Console.Write($"[*] File {e.ChangeType}"); Console.ForegroundColor = ConsoleColor.White; Console.WriteLine($": {e.FullPath}"); OnChanged(source: source, e: e); } else if (e.ChangeType == WatcherChangeTypes.Deleted) { Console.ForegroundColor = ConsoleColor.DarkRed; Console.Write($"[!] File {e.ChangeType}"); Console.ForegroundColor = ConsoleColor.White; Console.WriteLine($": {e.FullPath}"); //OnDeleted(source: source, e: e); } } private void OnProcess(object source,RenamedEventArgs e) { Console.ForegroundColor = ConsoleColor.DarkBlue; Console.Write($"[*] File {e.ChangeType}"); Console.ForegroundColor = ConsoleColor.White; Console.WriteLine($": {e.OldFullPath} => {e.FullPath}"); OnRenamed(source, e); } private void OnCreated(object source, FileSystemEventArgs e) => Sync(); private void OnChanged(object source, FileSystemEventArgs e) => Sync(); //private void OnDeleted(object source, FileSystemEventArgs e) => ; private void OnRenamed(object source, RenamedEventArgs e) => Sync(); } }