Advertisement
Scarlet

Screenshot Sorter Source

Nov 3rd, 2018
282
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 18.50 KB | None | 0 0
  1. #pragma once
  2.  
  3. #include <fstream>
  4. using std::ifstream;
  5. using std::ofstream;
  6.  
  7. #include <map>
  8. using std::map;
  9.  
  10. #include <vector>
  11. using std::vector;
  12.  
  13. #include <array>
  14. // Not using std::array since it conflicts with System::array's use
  15.  
  16. #include <filesystem>
  17. using std::experimental::filesystem::path;
  18. using std::experimental::filesystem::recursive_directory_iterator;
  19. using std::experimental::filesystem::create_directories;
  20. using std::experimental::filesystem::exists;
  21. using std::experimental::filesystem::copy;
  22. using std::experimental::filesystem::remove;
  23.  
  24. #include <string>
  25. using std::string;
  26. using std::getline;
  27.  
  28. #include <msclr\marshal_cppstd.h>
  29. using msclr::interop::marshal_as;
  30.  
  31. // Global data because I don't know how forms work
  32. // Change this at some point?
  33. const std::array<char, 9> PROHIBITED_CHARACTERS
  34. {
  35.     '\\', '/', ':', '*', '?', '"', '<', '>', '|'
  36. };
  37.  
  38. string gCurrentScreen;
  39. vector<string> gSkippedScreens;
  40.  
  41. namespace BountyScreenshot {
  42.  
  43.     using namespace System;
  44.     using namespace System::ComponentModel;
  45.     using namespace System::Collections;
  46.     using namespace System::Windows::Forms;
  47.     using namespace System::Data;
  48.     using namespace System::Drawing;
  49.     using namespace System::IO;
  50.     using namespace System::Reflection;
  51.  
  52.     /// <summary>
  53.     /// Summary for Window
  54.     /// </summary>
  55.     public ref class Window : public System::Windows::Forms::Form
  56.     {
  57.     private: Assembly^ _assembly;
  58.  
  59.     public:
  60.         Window(void)
  61.         {
  62.             InitializeComponent();
  63.             //
  64.             //TODO: Add the constructor code here
  65.             //
  66.         }
  67.  
  68.         void ChooseAlbumFolder()
  69.         {
  70.             if (folderBrowserSwitchAlbum->ShowDialog() == System::Windows::Forms::DialogResult::OK)
  71.             {
  72.                 labelAlbumPath->Text = folderBrowserSwitchAlbum->SelectedPath;
  73.             }
  74.         }
  75.  
  76.         void ChooseDestinationFolder()
  77.         {
  78.             if (folderBrowserDestination->ShowDialog() == System::Windows::Forms::DialogResult::OK)
  79.             {
  80.                 labelDestinationPath->Text = folderBrowserDestination->SelectedPath;
  81.             }
  82.         }
  83.  
  84.         void CheckFoldersSelected()
  85.         {
  86.             if (labelAlbumPath->Text       != "No Album Folder Selected" &&
  87.                 labelDestinationPath->Text != "No Destination Folder Selected")
  88.             {
  89.                 buttonStart->Enabled = true;
  90.                 labelAppStatus->Text = "Status: Ready to start";
  91.             }
  92.         }
  93.  
  94.         string OrganiseFiles()
  95.         {
  96.             // Import game list
  97.             map<string, string> gameList;
  98.             ifstream knownGamesIn;
  99.             knownGamesIn.open("GameIDs.txt");
  100.             if (knownGamesIn.is_open())
  101.             {
  102.                 string currentLine, gameID, gameName;
  103.                 int tabPos;
  104.                 while (getline(knownGamesIn, currentLine))
  105.                 {
  106.                     tabPos = currentLine.find('\t');
  107.                     gameID = currentLine.substr(0, tabPos);
  108.                     gameName = currentLine.substr(tabPos + 1);
  109.  
  110.                     gameList[gameID] = gameName;
  111.                 }
  112.  
  113.                 knownGamesIn.close();
  114.             }
  115.  
  116.             string pathString = marshal_as<string>(labelAlbumPath->Text);
  117.  
  118.             path current;
  119.             for (auto& p : recursive_directory_iterator(pathString))
  120.             {
  121.                 current = p;
  122.                 string fileName = current.filename().generic_string();
  123.  
  124.                 if (fileName.size() == 53)  // AAAAAAAAAAAAAAAA-BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB.jpg (or .mp4)
  125.                 {
  126.                     string format = fileName.substr(fileName.size() - 4);
  127.                     string dateInfo = fileName.substr(0, 16);
  128.                     string gameID = fileName.substr(17, 32);
  129.                     string gameName = "";
  130.                     bool skip = false;
  131.  
  132.                     if (gameList.count(gameID) == 0)    // If game ID isn't in list
  133.                     {
  134.                         for (int i = 0; i < gSkippedScreens.size() && !skip; i++)
  135.                         {
  136.                             if (fileName == gSkippedScreens[i]) skip = true;
  137.                         }
  138.  
  139.                         if (!skip)
  140.                         {
  141.                             delete pictureBoxScreenshotView->Image;
  142.  
  143.                             if (format == ".jpg")
  144.                                 pictureBoxScreenshotView->Image = Image::FromFile(marshal_as<System::String^>(current.generic_string()));
  145.  
  146.                             else
  147.                             {
  148.                                 _assembly = Assembly::GetExecutingAssembly();
  149.                                 pictureBoxScreenshotView->Image = Image::FromStream(_assembly->GetManifestResourceStream("Video.png"));
  150.                             }
  151.  
  152.                             gCurrentScreen = fileName;
  153.                             return gameID;
  154.                         }
  155.                     }
  156.  
  157.                     else gameName = gameList[gameID];
  158.  
  159.                     // If current cycle says to skip, don't copy it
  160.                     // Would otherwise be copied directly into the destination folder
  161.                     if (!skip)
  162.                     {
  163.                         // Build directory path, replacing illegal characters from game name with '_'
  164.                         string dir = marshal_as<string>(labelDestinationPath->Text) + "\\" + gameName;
  165.                         for (int i = dir.size() - gameName.size(); i < dir.size(); i++) for (int ch = 0; ch < PROHIBITED_CHARACTERS.size(); ch++) if (dir[i] == PROHIBITED_CHARACTERS[ch]) dir[i] = '_';
  166.                         while (dir[dir.size() - 1] == ' ') dir.pop_back();  // Remove possible spaces from end of folder since folders can't end in a space
  167.  
  168.                                                                             // Build full file path, assumes default Switch screenshot formatting, so no error checking needed here
  169.                         string file = dir + "\\" + dateInfo + format;
  170.  
  171.                         // Create directory if it doesn't exist
  172.                         if (!exists(dir)) create_directories(dir);
  173.  
  174.                         // Copy file if not already copied
  175.                         if (!exists(file))
  176.                         {
  177.                             copy(p, file);
  178.                         }
  179.                     }
  180.                 }
  181.             }
  182.  
  183.             return "FINISH";
  184.         }
  185.  
  186.         void UpdateIDList()
  187.         {
  188.             ofstream knownGamesOut;
  189.             string gameID = marshal_as<string>(labelAppStatus->Text).substr(38);    // Grab the game ID from the label
  190.             string gameName = marshal_as<string>(textBoxNameEntry->Text);           // Grab the name from user input
  191.             string line = gameID + '    ' + gameName + '\n';
  192.  
  193.             knownGamesOut.open("GameIDs.txt", std::ios::app);
  194.             knownGamesOut << line;
  195.             knownGamesOut.close();
  196.  
  197.             // Resume copying
  198.             delete pictureBoxScreenshotView->Image;
  199.             _assembly = Assembly::GetExecutingAssembly();
  200.             pictureBoxScreenshotView->Image = Image::FromStream(_assembly->GetManifestResourceStream("Screenshot-Placeholder.png"));
  201.             labelAppStatus->Text = "Status: Organising screenshots...";
  202.             buttonSubmit->Enabled = false;
  203.             buttonSkip->Enabled = false;
  204.             textBoxNameEntry->Text = "";
  205.             textBoxNameEntry->Enabled = false;
  206.  
  207.             backgroundWorkerOrganiser->RunWorkerAsync();
  208.         }
  209.  
  210.  
  211.  
  212.     protected:
  213.         /// <summary>
  214.         /// Clean up any resources being used.
  215.         /// </summary>
  216.         ~Window()
  217.         {
  218.             if (components)
  219.             {
  220.                 delete components;
  221.             }
  222.         }
  223.     private: System::Windows::Forms::FolderBrowserDialog^  folderBrowserSwitchAlbum;
  224.     private: System::Windows::Forms::Button^  buttonOpenAlbum;
  225.     private: System::Windows::Forms::Label^  labelAlbumPath;
  226.     private: System::Windows::Forms::FolderBrowserDialog^  folderBrowserDestination;
  227.     private: System::Windows::Forms::Button^  buttonDestination;
  228.     private: System::Windows::Forms::Label^  labelDestinationPath;
  229.     private: System::Windows::Forms::PictureBox^  pictureBoxScreenshotView;
  230.     private: System::Windows::Forms::TextBox^  textBoxNameEntry;
  231.  
  232.     private: System::Windows::Forms::Label^  labelAppStatus;
  233.     private: System::Windows::Forms::Label^  labelNameEntry;
  234.     private: System::Windows::Forms::Button^  buttonStart;
  235.  
  236.     private: System::ComponentModel::BackgroundWorker^  backgroundWorkerOrganiser;
  237.  
  238.  
  239.     private: System::Windows::Forms::Button^  buttonSubmit;
  240.     private: System::Windows::Forms::Button^  buttonSkip;
  241.  
  242.  
  243.  
  244.     protected:
  245.  
  246.     private:
  247.         /// <summary>
  248.         /// Required designer variable.
  249.         /// </summary>
  250.         System::ComponentModel::Container ^components;
  251.  
  252. #pragma region Windows Form Designer generated code
  253.         /// <summary>
  254.         /// Required method for Designer support - do not modify
  255.         /// the contents of this method with the code editor.
  256.         /// </summary>
  257.         void InitializeComponent(void)
  258.         {
  259.             System::ComponentModel::ComponentResourceManager^  resources = (gcnew System::ComponentModel::ComponentResourceManager(Window::typeid));
  260.             this->folderBrowserSwitchAlbum = (gcnew System::Windows::Forms::FolderBrowserDialog());
  261.             this->buttonOpenAlbum = (gcnew System::Windows::Forms::Button());
  262.             this->labelAlbumPath = (gcnew System::Windows::Forms::Label());
  263.             this->folderBrowserDestination = (gcnew System::Windows::Forms::FolderBrowserDialog());
  264.             this->buttonDestination = (gcnew System::Windows::Forms::Button());
  265.             this->labelDestinationPath = (gcnew System::Windows::Forms::Label());
  266.             this->pictureBoxScreenshotView = (gcnew System::Windows::Forms::PictureBox());
  267.             this->textBoxNameEntry = (gcnew System::Windows::Forms::TextBox());
  268.             this->labelAppStatus = (gcnew System::Windows::Forms::Label());
  269.             this->labelNameEntry = (gcnew System::Windows::Forms::Label());
  270.             this->buttonStart = (gcnew System::Windows::Forms::Button());
  271.             this->backgroundWorkerOrganiser = (gcnew System::ComponentModel::BackgroundWorker());
  272.             this->buttonSubmit = (gcnew System::Windows::Forms::Button());
  273.             this->buttonSkip = (gcnew System::Windows::Forms::Button());
  274.             (cli::safe_cast<System::ComponentModel::ISupportInitialize^>(this->pictureBoxScreenshotView))->BeginInit();
  275.             this->SuspendLayout();
  276.             //
  277.             // folderBrowserSwitchAlbum
  278.             //
  279.             this->folderBrowserSwitchAlbum->Description = L"Eg. D:\\Nintendo\\Album";
  280.             this->folderBrowserSwitchAlbum->RootFolder = System::Environment::SpecialFolder::MyComputer;
  281.             this->folderBrowserSwitchAlbum->ShowNewFolderButton = false;
  282.             //
  283.             // buttonOpenAlbum
  284.             //
  285.             this->buttonOpenAlbum->Location = System::Drawing::Point(13, 13);
  286.             this->buttonOpenAlbum->Name = L"buttonOpenAlbum";
  287.             this->buttonOpenAlbum->Size = System::Drawing::Size(135, 23);
  288.             this->buttonOpenAlbum->TabIndex = 0;
  289.             this->buttonOpenAlbum->Text = L"Open Album Folder";
  290.             this->buttonOpenAlbum->UseVisualStyleBackColor = true;
  291.             this->buttonOpenAlbum->Click += gcnew System::EventHandler(this, &Window::buttonOpenAlbum_Click);
  292.             //
  293.             // labelAlbumPath
  294.             //
  295.             this->labelAlbumPath->AutoSize = true;
  296.             this->labelAlbumPath->Location = System::Drawing::Point(154, 18);
  297.             this->labelAlbumPath->Name = L"labelAlbumPath";
  298.             this->labelAlbumPath->Size = System::Drawing::Size(130, 13);
  299.             this->labelAlbumPath->TabIndex = 1;
  300.             this->labelAlbumPath->Text = L"No Album Folder Selected";
  301.             //
  302.             // buttonDestination
  303.             //
  304.             this->buttonDestination->Location = System::Drawing::Point(13, 43);
  305.             this->buttonDestination->Name = L"buttonDestination";
  306.             this->buttonDestination->Size = System::Drawing::Size(135, 23);
  307.             this->buttonDestination->TabIndex = 2;
  308.             this->buttonDestination->Text = L"Open Destination Folder";
  309.             this->buttonDestination->UseVisualStyleBackColor = true;
  310.             this->buttonDestination->Click += gcnew System::EventHandler(this, &Window::buttonDestination_Click);
  311.             //
  312.             // labelDestinationPath
  313.             //
  314.             this->labelDestinationPath->AutoSize = true;
  315.             this->labelDestinationPath->Location = System::Drawing::Point(154, 48);
  316.             this->labelDestinationPath->Name = L"labelDestinationPath";
  317.             this->labelDestinationPath->Size = System::Drawing::Size(154, 13);
  318.             this->labelDestinationPath->TabIndex = 3;
  319.             this->labelDestinationPath->Text = L"No Destination Folder Selected";
  320.             //
  321.             // pictureBoxScreenshotView
  322.             //
  323.             this->pictureBoxScreenshotView->Image = (cli::safe_cast<System::Drawing::Image^>(resources->GetObject(L"pictureBoxScreenshotView.Image")));
  324.             this->pictureBoxScreenshotView->InitialImage = (cli::safe_cast<System::Drawing::Image^>(resources->GetObject(L"pictureBoxScreenshotView.InitialImage")));
  325.             this->pictureBoxScreenshotView->Location = System::Drawing::Point(11, 140);
  326.             this->pictureBoxScreenshotView->Name = L"pictureBoxScreenshotView";
  327.             this->pictureBoxScreenshotView->Size = System::Drawing::Size(360, 202);
  328.             this->pictureBoxScreenshotView->SizeMode = System::Windows::Forms::PictureBoxSizeMode::StretchImage;
  329.             this->pictureBoxScreenshotView->TabIndex = 4;
  330.             this->pictureBoxScreenshotView->TabStop = false;
  331.             //
  332.             // textBoxNameEntry
  333.             //
  334.             this->textBoxNameEntry->Enabled = false;
  335.             this->textBoxNameEntry->Location = System::Drawing::Point(11, 114);
  336.             this->textBoxNameEntry->Name = L"textBoxNameEntry";
  337.             this->textBoxNameEntry->Size = System::Drawing::Size(236, 20);
  338.             this->textBoxNameEntry->TabIndex = 5;
  339.             this->textBoxNameEntry->KeyUp += gcnew System::Windows::Forms::KeyEventHandler(this, &Window::textBoxNameEntry_KeyUp);
  340.             //
  341.             // labelAppStatus
  342.             //
  343.             this->labelAppStatus->AutoSize = true;
  344.             this->labelAppStatus->Location = System::Drawing::Point(12, 352);
  345.             this->labelAppStatus->Name = L"labelAppStatus";
  346.             this->labelAppStatus->Size = System::Drawing::Size(198, 13);
  347.             this->labelAppStatus->TabIndex = 6;
  348.             this->labelAppStatus->Text = L"Status: Waiting for folders to be selected";
  349.             //
  350.             // labelNameEntry
  351.             //
  352.             this->labelNameEntry->AutoSize = true;
  353.             this->labelNameEntry->Location = System::Drawing::Point(12, 98);
  354.             this->labelNameEntry->Name = L"labelNameEntry";
  355.             this->labelNameEntry->Size = System::Drawing::Size(177, 13);
  356.             this->labelNameEntry->TabIndex = 7;
  357.             this->labelNameEntry->Text = L"Enter the name of the current game:";
  358.             //
  359.             // buttonStart
  360.             //
  361.             this->buttonStart->Enabled = false;
  362.             this->buttonStart->Location = System::Drawing::Point(13, 72);
  363.             this->buttonStart->Name = L"buttonStart";
  364.             this->buttonStart->Size = System::Drawing::Size(359, 23);
  365.             this->buttonStart->TabIndex = 8;
  366.             this->buttonStart->Text = L"Start Organising";
  367.             this->buttonStart->UseVisualStyleBackColor = true;
  368.             this->buttonStart->Click += gcnew System::EventHandler(this, &Window::buttonStart_Click);
  369.             //
  370.             // backgroundWorkerOrganiser
  371.             //
  372.             this->backgroundWorkerOrganiser->WorkerSupportsCancellation = true;
  373.             this->backgroundWorkerOrganiser->DoWork += gcnew System::ComponentModel::DoWorkEventHandler(this, &Window::backgroundWorkerOrganiser_DoWork);
  374.             this->backgroundWorkerOrganiser->ProgressChanged += gcnew System::ComponentModel::ProgressChangedEventHandler(this, &Window::backgroundWorkerOrganiser_ProgressChanged);
  375.             this->backgroundWorkerOrganiser->RunWorkerCompleted += gcnew System::ComponentModel::RunWorkerCompletedEventHandler(this, &Window::backgroundWorkerOrganiser_RunWorkerCompleted);
  376.             //
  377.             // buttonSubmit
  378.             //
  379.             this->buttonSubmit->Enabled = false;
  380.             this->buttonSubmit->Location = System::Drawing::Point(253, 112);
  381.             this->buttonSubmit->Name = L"buttonSubmit";
  382.             this->buttonSubmit->Size = System::Drawing::Size(56, 23);
  383.             this->buttonSubmit->TabIndex = 11;
  384.             this->buttonSubmit->Text = L"Submit";
  385.             this->buttonSubmit->UseVisualStyleBackColor = true;
  386.             this->buttonSubmit->Click += gcnew System::EventHandler(this, &Window::buttonSubmit_Click);
  387.             //
  388.             // buttonSkip
  389.             //
  390.             this->buttonSkip->Enabled = false;
  391.             this->buttonSkip->Location = System::Drawing::Point(315, 112);
  392.             this->buttonSkip->Name = L"buttonSkip";
  393.             this->buttonSkip->Size = System::Drawing::Size(56, 23);
  394.             this->buttonSkip->TabIndex = 12;
  395.             this->buttonSkip->Text = L"Skip";
  396.             this->buttonSkip->UseVisualStyleBackColor = true;
  397.             this->buttonSkip->Click += gcnew System::EventHandler(this, &Window::buttonSkip_Click);
  398.             //
  399.             // Window
  400.             //
  401.             this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
  402.             this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
  403.             this->ClientSize = System::Drawing::Size(384, 391);
  404.             this->Controls->Add(this->buttonSkip);
  405.             this->Controls->Add(this->buttonSubmit);
  406.             this->Controls->Add(this->buttonStart);
  407.             this->Controls->Add(this->labelNameEntry);
  408.             this->Controls->Add(this->labelAppStatus);
  409.             this->Controls->Add(this->textBoxNameEntry);
  410.             this->Controls->Add(this->pictureBoxScreenshotView);
  411.             this->Controls->Add(this->labelDestinationPath);
  412.             this->Controls->Add(this->buttonDestination);
  413.             this->Controls->Add(this->labelAlbumPath);
  414.             this->Controls->Add(this->buttonOpenAlbum);
  415.             this->MaximizeBox = false;
  416.             this->MaximumSize = System::Drawing::Size(400, 430);
  417.             this->MinimumSize = System::Drawing::Size(400, 430);
  418.             this->Name = L"Window";
  419.             this->Text = L"Switch Screenshot Organiser";
  420.             (cli::safe_cast<System::ComponentModel::ISupportInitialize^>(this->pictureBoxScreenshotView))->EndInit();
  421.             this->ResumeLayout(false);
  422.             this->PerformLayout();
  423.  
  424.         }
  425. #pragma endregion
  426.     private: System::Void buttonOpenAlbum_Click(System::Object^  sender, System::EventArgs^  e)
  427.     {
  428.         ChooseAlbumFolder();
  429.         CheckFoldersSelected();
  430.     }
  431.              
  432.     private: System::Void buttonDestination_Click(System::Object^  sender, System::EventArgs^  e)
  433.     {
  434.         ChooseDestinationFolder();
  435.         CheckFoldersSelected();
  436.     }
  437.  
  438.     private: System::Void backgroundWorkerOrganiser_DoWork(System::Object^  sender, System::ComponentModel::DoWorkEventArgs^  e)
  439.     {
  440.         e->Result = marshal_as<String^>(OrganiseFiles());
  441.     }
  442.  
  443.     private: System::Void backgroundWorkerOrganiser_ProgressChanged(System::Object^  sender, System::ComponentModel::ProgressChangedEventArgs^  e)
  444.     {
  445.  
  446.     }
  447.  
  448.     private: System::Void backgroundWorkerOrganiser_RunWorkerCompleted(System::Object^  sender, System::ComponentModel::RunWorkerCompletedEventArgs^  e)
  449.     {
  450.         string ret = marshal_as<string>(static_cast<String^>(e->Result));
  451.  
  452.         if (ret == "FINISH")
  453.         {
  454.             labelAppStatus->Text = "Status: Finished!";
  455.             buttonOpenAlbum->Enabled = true;
  456.             buttonDestination->Enabled = true;
  457.             buttonStart->Enabled = true;
  458.         }
  459.        
  460.         else
  461.         {
  462.             labelAppStatus->Text = "Status: Waiting for game name for ID \n" + e->Result;
  463.             buttonSubmit->Enabled = true;
  464.             buttonSkip->Enabled = true;
  465.             textBoxNameEntry->Enabled = true;
  466.             textBoxNameEntry->Focus();
  467.         }
  468.     }
  469.  
  470.     private: System::Void buttonStart_Click(System::Object^  sender, System::EventArgs^  e)
  471.     {
  472.         labelAppStatus->Text = "Status: Organising screenshots...";
  473.         buttonOpenAlbum->Enabled = false;
  474.         buttonDestination->Enabled = false;
  475.         buttonStart->Enabled = false;
  476.  
  477.         backgroundWorkerOrganiser->RunWorkerAsync();
  478.     }
  479.  
  480.     private: System::Void buttonSubmit_Click(System::Object^  sender, System::EventArgs^  e)
  481.     {
  482.         if (textBoxNameEntry->Text != "")
  483.         {
  484.             UpdateIDList();
  485.         }
  486.     }
  487.  
  488.     private: System::Void textBoxNameEntry_KeyUp(System::Object^  sender, System::Windows::Forms::KeyEventArgs^  e)
  489.     {
  490.         if (e->KeyCode == Keys::Enter && textBoxNameEntry->Text != "")
  491.         {
  492.             UpdateIDList();
  493.         }
  494.     }
  495.  
  496.     private: System::Void buttonSkip_Click(System::Object^  sender, System::EventArgs^  e)
  497.     {
  498.         gSkippedScreens.push_back(gCurrentScreen);
  499.  
  500.         // Resume copying
  501.         delete pictureBoxScreenshotView->Image;
  502.         _assembly = Assembly::GetExecutingAssembly();
  503.         pictureBoxScreenshotView->Image = Image::FromStream(_assembly->GetManifestResourceStream("Screenshot-Placeholder.png"));
  504.         labelAppStatus->Text = "Status: Organising screenshots...";
  505.         buttonSubmit->Enabled = false;
  506.         buttonSkip->Enabled = false;
  507.         textBoxNameEntry->Text = "";
  508.         textBoxNameEntry->Enabled = false;
  509.  
  510.         backgroundWorkerOrganiser->RunWorkerAsync();
  511.     }
  512. };
  513. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement