source.cpp (4488B)
1 /* ReaPack: Package manager for REAPER 2 * Copyright (C) 2015-2025 Christian Fillion 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU Lesser General Public License as published by 6 * the Free Software Foundation, either version 3 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public License 15 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 #include "source.hpp" 19 20 #include "errors.hpp" 21 #include "index.hpp" 22 23 #include <boost/algorithm/string/case_conv.hpp> 24 25 auto Source::getSection(const char *name) -> Section 26 { 27 constexpr std::pair<const char *, Section> map[] { 28 {"main", MainSection}, 29 {"midi_editor", MIDIEditorSection}, 30 {"midi_inlineeditor", MIDIInlineEditorSection}, 31 {"midi_eventlisteditor", MIDIEventListEditorSection}, 32 {"mediaexplorer", MediaExplorerSection}, 33 {"true", ImplicitSection}, 34 }; 35 36 for(auto &[key, value] : map) { 37 if(!strcmp(name, key)) 38 return value; 39 } 40 41 return UnknownSection; 42 } 43 44 auto Source::detectSection(const Path &category) -> Section 45 { 46 // this is for compatibility with indexes made for v1.0 47 48 std::string topcategory = category.front(); 49 boost::algorithm::to_lower(topcategory); 50 51 if(topcategory == "midi editor") 52 return MIDIEditorSection; 53 else 54 return MainSection; 55 } 56 57 Source::Source(const std::string &file, const std::string &url, const Version *ver) 58 : m_type(Package::UnknownType), m_file(file), m_url(url), m_sections(0), 59 m_version(ver) 60 { 61 if(m_url.empty()) 62 throw reapack_error("empty source url"); 63 } 64 65 Package::Type Source::type() const 66 { 67 if(m_type) 68 return m_type; 69 else 70 return m_version->package()->type(); 71 } 72 73 const std::string &Source::file() const 74 { 75 if(!m_file.empty()) 76 return m_file; 77 else 78 return m_version->package()->name(); 79 } 80 81 void Source::setSections(int sections) 82 { 83 if(type() != Package::ScriptType) 84 return; 85 else if(sections == ImplicitSection) 86 sections = detectSection(m_version->package()->category()->name()); 87 88 m_sections = sections; 89 } 90 91 Path Source::targetPath() const 92 { 93 Path path; 94 const auto type = this->type(); 95 96 // select the target directory 97 switch(type) { 98 case Package::ScriptType: 99 path += "Scripts"; 100 break; 101 case Package::EffectType: 102 path += "Effects"; 103 break; 104 case Package::DataType: 105 path += "Data"; 106 break; 107 case Package::ExtensionType: 108 path += "UserPlugins"; 109 break; 110 case Package::ThemeType: 111 path += "ColorThemes"; 112 break; 113 case Package::LangPackType: 114 path += "LangPack"; 115 break; 116 case Package::WebInterfaceType: 117 path += "reaper_www_root"; 118 break; 119 case Package::ProjectTemplateType: 120 path += "ProjectTemplates"; 121 break; 122 case Package::TrackTemplateType: 123 path += "TrackTemplates"; 124 break; 125 case Package::MIDINoteNamesType: 126 path += "MIDINoteNames"; 127 break; 128 case Package::AutomationItemType: 129 path += "AutomationItems"; 130 break; 131 case Package::UnknownType: 132 // The package has an unsupported type, so we make an empty path. 133 // The empty path won't be used because the category will reject 134 // this package right away. Maybe the parser should not bother with loading 135 // unsupported packages at all anyway... But then in the future 136 // we might want to display unsupported packages in the interface. 137 break; 138 } 139 140 // append the rest of the path 141 switch(type) { 142 case Package::ScriptType: 143 case Package::EffectType: 144 case Package::AutomationItemType: { 145 const Category *cat = m_version->package()->category(); 146 path += cat->index()->name(); 147 148 // only allow directory traversal up to the index name 149 path += Path(cat->name()) + file(); 150 break; 151 } 152 case Package::ExtensionType: 153 case Package::ThemeType: 154 case Package::DataType: 155 case Package::LangPackType: 156 case Package::WebInterfaceType: 157 case Package::ProjectTemplateType: 158 case Package::TrackTemplateType: 159 case Package::MIDINoteNamesType: 160 path.append(file(), false); // no directory traversal 161 break; 162 case Package::UnknownType: 163 break; 164 } 165 166 return path; 167 }