All pastes #1663130 Raw Edit

Anonymous

public diff v1 · immutable
#1663130 ·published 2009-11-09 08:48 UTC
rendered paste body
diff --git a/xbmc/FileItem.cpp b/xbmc/FileItem.cppindex 5ad317d..ed7b9cf 100644--- a/xbmc/FileItem.cpp+++ b/xbmc/FileItem.cpp@@ -2215,7 +2215,13 @@ void CFileItemList::Stack()         if (Get(stack[0])->IsRAR())           stackPath = Get(stack[0])->m_strPath;         else-          stackPath = dir.ConstructStackPath(*this, stack);+        {+          CStdString stackTitlePath, commonDir;+          commonDir = Get(stack[0])->m_strPath;+          CUtil::GetCommonPath(commonDir, Get(stack[1])->m_strPath);+          CUtil::AddFileToFolder(commonDir, stackName, stackTitlePath);+          stackPath = dir.ConstructStackPath(*this, stack, stackTitlePath);+        }         item1->m_strPath = stackPath;         // clean up list         for (unsigned k = 1; k < stack.size(); k++)diff --git a/xbmc/FileSystem/StackDirectory.cpp b/xbmc/FileSystem/StackDirectory.cppindex f62c5c7..28f61fd 100644--- a/xbmc/FileSystem/StackDirectory.cpp+++ b/xbmc/FileSystem/StackDirectory.cpp@@ -25,9 +25,8 @@ #include "FileItem.h" #include "StringUtils.h" -#define PRE_2_1_STACK_COMPATIBILITY- using namespace std;+ namespace DIRECTORY {   CStackDirectory::CStackDirectory()@@ -38,6 +37,20 @@ namespace DIRECTORY   {   } +  bool CStackDirectory::GetDirectory(const CStdString& strPath, CFileItemList& items, CStdString& strStackTitlePath)+  {+    CStdStringArray files, tokens;+    StringUtils::SplitString(strPath, " ; ", tokens);+    if (tokens.size() > 1) // 4 capture algo+    {+      strStackTitlePath = tokens[1];+      CUtil::UrlDecode(strStackTitlePath);+    }+    else+      strStackTitlePath = GetStackedTitlePath(tokens[0]);+    return GetDirectory(strPath, items);+  }+   bool CStackDirectory::GetDirectory(const CStdString& strPath, CFileItemList& items)   {     items.Clear();@@ -47,55 +60,74 @@ namespace DIRECTORY     //CStdString folder, file;     //CUtil::Split(strPath, folder, file);     // split files on the single comma-    CStdStringArray files;-    StringUtils::SplitString(strPath, " , ", files);-    if (files.empty())-      return false;   // error in path-    // remove "stack://" from the folder-    for (unsigned int i = 0; i < files.size(); i++)+    CStdStringArray files, tokens;+    StringUtils::SplitString(strPath, " ; ", tokens);+    if (!tokens.empty())     {-      CStdString file = files[i];-      if (i == 0)-        file = file.Mid(8);-#ifdef PRE_2_1_STACK_COMPATIBILITY-      if (i > 0 && file.Find("\\") == -1 && file.Find('/') == -1)+      StringUtils::SplitString(tokens[0], " , ", files);+      if (files.empty())+        return false;   // error in path+      // remove "stack://" from the folder+      for (unsigned int i = 0; i < files.size(); i++)       {-        CStdString strPath;-        CUtil::GetDirectory(items[0]->m_strPath,strPath);-        CStdString strFile = file;-        CUtil::AddFileToFolder(strPath,strFile,file);+        CStdString file = files[i];+        if (i == 0)+          file = file.Mid(8);+        if (tokens.size() > 1) // 4 capture algo+          CUtil::UrlDecode(file);+        else // replace double comma's with single ones.+          file.Replace(",,", ",");+        CFileItemPtr item(new CFileItem(file));+        item->m_strPath = file;+        item->m_bIsFolder = false;+        items.Add(item);       }-#endif-      // replace double comma's with single ones.-      file.Replace(",,", ",");-      CFileItemPtr item(new CFileItem(file));-      //CUtil::AddFileToFolder(folder, file, item->m_strPath);-      item->m_strPath = file;-      item->m_bIsFolder = false;-      items.Add(item);+      return true;     }-    return true;+    return false;   }    CStdString CStackDirectory::GetStackedTitlePath(const CStdString &strPath)   {     CStdString path, file, folder;-    int pos = strPath.Find(" , ");-    // remove "stack://" from the folder-    if (pos > 0)+    CStdStringArray tokens;+    StringUtils::SplitString(strPath, " ; ", tokens);+    if (tokens.size() > 1) // 4 capture stack algo appends the stackedTitlePath and url encodes everything     {-      CUtil::Split(strPath.Left(pos), folder, file);-      file.Replace(",,", ",");-      folder = folder.Mid(8);-      CStdString title, volume;-      CUtil::GetVolumeFromFileName(file, title, volume);-      CUtil::AddFileToFolder(folder, title, path);+      path = tokens[1];+      CUtil::UrlDecode(path);+    }+    else+    {+      int pos = strPath.Find(" , ");+      // remove "stack://" from the folder+      if (pos > 0)+      {+        CUtil::Split(strPath.Left(pos), folder, file);+        file.Replace(",,", ",");+        folder = folder.Mid(8);+        CStdString title, volume;+        CUtil::GetVolumeFromFileName(file, title, volume);+        CUtil::AddFileToFolder(folder, title, path);+      }     }     return path;   }    CStdString CStackDirectory::GetFirstStackedFile(const CStdString &strPath)   {+    CStdString strBikeShed;+    CStdStringArray tokens;+    StringUtils::SplitString(strPath, " ; ", tokens);++    if (tokens.size() > 1) // 4 capture stack algo+    {+      strBikeShed = tokens[0];+      CUtil::UrlDecode(strBikeShed);+    }+    else+      strBikeShed = strPath;+         // the stacked files are always in volume order, so just get up to the first filename     // occurence of " , "     CStdString path, file, folder;@@ -107,56 +139,51 @@ namespace DIRECTORY      // remove "stack://" from the folder     folder = folder.Mid(8);-    file.Replace(",,", ",");+    if (tokens.size() <= 1) // Not 4 capture stack algo+      file.Replace(",,", ",");     CUtil::AddFileToFolder(folder, file, path);      return path;   } -  CStdString CStackDirectory::ConstructStackPath(const CFileItemList &items, const vector<int> &stack)+  CStdString CStackDirectory::ConstructStackPath(const CFileItemList &items, const vector<int> &stack, const CStdString& strStackedFilename)   {-    // no checks on the range of stack here.-    // we replace all instances of comma's with double comma's, then separate-    // the files using " , ".-    CStdString stackedPath = "stack://";-    CStdString folder, file;-    CUtil::Split(items[stack[0]]->m_strPath, folder, file);-    stackedPath += folder;-    // double escape any occurence of commas-    file.Replace(",", ",,");+    CStdString stackedPath("stack://");+    CStdString file(items[stack[0]]->m_strPath);+    CUtil::URLEncode(file);     stackedPath += file;     for (unsigned int i = 1; i < stack.size(); ++i)     {       stackedPath += " , ";       file = items[stack[i]]->m_strPath;--      // double escape any occurence of commas-      file.Replace(",", ",,");+      CUtil::URLEncode(file);       stackedPath += file;     }++    file = strStackedFilename;+    CUtil::URLEncode(file);+    stackedPath += " ; " + file;     return stackedPath;   } -  bool CStackDirectory::ConstructStackPath(const vector<CStdString> &paths, CStdString& stackedPath)+  bool CStackDirectory::ConstructStackPath(const vector<CStdString> &paths, CStdString& stackedPath, const CStdString& strStackedFilename)   {     if (paths.size() < 2)       return false;     stackedPath = "stack://";-    CStdString folder, file;-    CUtil::Split(paths[0], folder, file);-    stackedPath += folder;-    // double escape any occurence of commas-    file.Replace(",", ",,");+    CStdString file = paths[0];+    CUtil::URLEncode(file);     stackedPath += file;     for (unsigned int i = 1; i < paths.size(); ++i)     {       stackedPath += " , ";       file = paths[i];--      // double escape any occurence of commas-      file.Replace(",", ",,");+      CUtil::URLEncode(file);       stackedPath += file;     }+    file = strStackedFilename;+    CUtil::URLEncode(file);+    stackedPath += " ; " + file;     return true;   } }diff --git a/xbmc/FileSystem/StackDirectory.h b/xbmc/FileSystem/StackDirectory.hindex 63eefc9..8be9d15 100644--- a/xbmc/FileSystem/StackDirectory.h+++ b/xbmc/FileSystem/StackDirectory.h@@ -30,11 +30,12 @@ namespace DIRECTORY   public:     CStackDirectory();     ~CStackDirectory();+    virtual bool GetDirectory(const CStdString& strPath, CFileItemList& items, CStdString& strStackTitlePath);     virtual bool GetDirectory(const CStdString& strPath, CFileItemList& items);     virtual bool IsAllowed(const CStdString &strFile) const { return true; };     static CStdString GetStackedTitlePath(const CStdString &strPath);     static CStdString GetFirstStackedFile(const CStdString &strPath);-    CStdString ConstructStackPath(const CFileItemList& items, const std::vector<int> &stack);-    bool ConstructStackPath(const std::vector<CStdString> &paths, CStdString &stackedPath);+    static CStdString ConstructStackPath(const CFileItemList& items, const std::vector<int> &stack, const CStdString& strStackTitlePath);+    static bool ConstructStackPath(const std::vector<CStdString> &paths, CStdString &stackedPath, const CStdString& strStackTitlePath);   }; }diff --git a/xbmc/URL.cpp b/xbmc/URL.cppindex 765edf2..0bd83f6 100644--- a/xbmc/URL.cpp+++ b/xbmc/URL.cpp@@ -526,10 +526,11 @@ CStdString CURL::GetWithoutUserDetails() const   if (m_strProtocol.Equals("stack"))   {     CFileItemList items;-    CStdString strURL2;+    CStdString strURL2,+               stackedTitleName;     strURL2 = Get();     DIRECTORY::CStackDirectory dir;-    dir.GetDirectory(strURL2,items);+    dir.GetDirectory(strURL2,items, stackedTitleName);     vector<CStdString> newItems;     for (int i=0;i<items.Size();++i)     {@@ -537,7 +538,7 @@ CStdString CURL::GetWithoutUserDetails() const       items[i]->m_strPath = url.GetWithoutUserDetails();       newItems.push_back(items[i]->m_strPath);     }-    dir.ConstructStackPath(newItems,strURL);+    dir.ConstructStackPath(newItems,strURL,stackedTitleName);     return strURL;   } diff --git a/xbmc/Util.cpp b/xbmc/Util.cppindex 29b9c6a..3e557b5 100644--- a/xbmc/Util.cpp+++ b/xbmc/Util.cpp@@ -470,6 +470,13 @@ void CUtil::GetCommonPath(CStdString& strParent, const CStdString& strPath)   } } +CStdString CUtil::GetParentPath(const CStdString& strPath)+{+  CStdString strReturn;+  GetParentPath(strPath, strReturn);+  return strReturn;+}+ bool CUtil::GetParentPath(const CStdString& strPath, CStdString& strParent) {   strParent = "";diff --git a/xbmc/Util.h b/xbmc/Util.hindex 2a34380..7355310 100644--- a/xbmc/Util.h+++ b/xbmc/Util.h@@ -75,6 +75,7 @@ public:   static void GetCommonPath(CStdString& strPath, const CStdString& strPath2);   static bool IsDOSPath(const CStdString &path);   static bool IsHD(const CStdString& strFileName);+  static CStdString GetParentPath(const CStdString& strPath);   static bool GetParentPath(const CStdString& strPath, CStdString& strParent);   static void GetQualifiedFilename(const CStdString &strBasePath, CStdString &strFilename);   static void RunShortcut(const char* szPath);diff --git a/xbmc/VideoDatabase.cpp b/xbmc/VideoDatabase.cppindex 95538ae..6d3b37a 100644--- a/xbmc/VideoDatabase.cpp+++ b/xbmc/VideoDatabase.cpp@@ -49,7 +49,7 @@ using namespace XFILE; using namespace DIRECTORY; using namespace VIDEO; -#define VIDEO_DATABASE_VERSION 33+#define VIDEO_DATABASE_VERSION 34 #define VIDEO_DATABASE_OLD_VERSION 3.f #define VIDEO_DATABASE_NAME "MyVideos34.db" @@ -3717,6 +3717,113 @@ bool CVideoDatabase::UpdateOldVersion(int iVersion)       m_pDS->exec("CREATE UNIQUE INDEX ix_setlinkmovie_1 ON setlinkmovie ( idSet, idMovie)\n");       m_pDS->exec("CREATE UNIQUE INDEX ix_setlinkmovie_2 ON setlinkmovie ( idMovie, idSet)\n");     }+    if (iVersion < 34)+    {+      // Load up our REs+      VECCREGEXP  RegExps;+      CRegExp     tempRE(true);+      const CStdStringArray& strRegExps = g_advancedSettings.m_videoStackRegExps;+      CStdStringArray::const_iterator itRegExp = strRegExps.begin();+      while (itRegExp != strRegExps.end())+      {+        tempRE.RegComp(*itRegExp);+        if (tempRE.GetCaptureTotal() == 4)+          RegExps.push_back(tempRE);+        else+          CLog::Log(LOGERROR, "Invalid video stack RE (%s). Must have exactly 4 captures.", itRegExp->c_str());+        itRegExp++;+      }++      // Grab all stack paths and their ID+      m_pDS->query("select idFile,strFilename from files where strFilename like 'stack://%'");+      while (!m_pDS->eof())+      {+        CStackDirectory stack;+        CFileItemList   files;+        CStdString path(m_pDS->fv(1).get_asString());+        stack.GetDirectory(m_pDS->fv(1).get_asString(), files);++        if (files.Size() > 1)+        {+          CStdString  Dir1, File1,+                      Dir2, File2,+                      CommonDir,+                      StackFilename;+          std::pair<std::string::iterator, std::string::iterator> diffs;++          CUtil::Split(files[0]->GetAsUrl().GetWithoutUserDetails(), Dir1, File1);+          CUtil::Split(files[1]->GetAsUrl().GetWithoutUserDetails(), Dir2, File2);+          CommonDir = CUtil::GetParentPath(m_pDS->fv(1).get_asString());++          std::vector<CRegExp>::iterator itRegExp = RegExps.begin();+          size_t offset = 0;++          while (itRegExp != RegExps.end())+          {+            if (itRegExp->RegFind(File1, offset) != -1)+            {+              CStdString Title1     = itRegExp->GetMatch(1),+                         Volume1    = itRegExp->GetMatch(2),+                         Ignore1    = itRegExp->GetMatch(3),+                         Extension1 = itRegExp->GetMatch(4);+              if (offset)+                Title1 = File1.substr(0, itRegExp->GetSubStart(2));+              if (itRegExp->RegFind(File2, offset) != -1)+              {+                CStdString Title2     = itRegExp->GetMatch(1),+                           Volume2    = itRegExp->GetMatch(2),+                           Ignore2    = itRegExp->GetMatch(3),+                           Extension2 = itRegExp->GetMatch(4);+                if (offset)+                  Title2 = File2.substr(0, itRegExp->GetSubStart(2));+                if (Title1.Equals(Title2))+                {+                  if (!Volume1.Equals(Volume2))+                  {+                    if (Ignore1.Equals(Ignore2) && Extension1.Equals(Extension2))+                    {+                      // got it+                      StackFilename = Title1 + Extension1;+                      itRegExp = RegExps.end();+                      break;+                    }+                    else // Invalid stack+                      break;+                  }+                  else // Early match, retry with offset+                  {+                    if (0 < (offset = itRegExp->GetSubStart(3)))+                    {+                      offset = 0;+                      itRegExp++;+                    }+                    continue;+                  }+                }+              }+            }+            offset = 0;+            itRegExp++;+          }++          if (!StackFilename.empty() && !CommonDir.empty())+          {+            std::vector<int> stackIndicies;+            CStdString  StackTitleName = CommonDir + StackFilename,+                        StackPath;++            for (int i = 0; i < files.Size(); i++)+              stackIndicies.push_back(i);++            StackPath = CStackDirectory::ConstructStackPath(files, stackIndicies, StackTitleName);+            CStdString sqlCmd = FormatSQL("update files set strFilename='%s' where idFile=%i",+                                        StackPath.c_str(), m_pDS->fv(0).get_asInt());+            m_pDS2->exec(sqlCmd.c_str());+          }+        }+        m_pDS->next();+      }+    }   }   catch (...)   {