reapack

Package manager for REAPER
Log | Files | Refs | Submodules | README | LICENSE

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 }