Virtual Folders

Discuss issues related to PS3 Media Server development (only for programmers)

Virtual Folders

Postby Trin » Fri May 28, 2010 3:30 am

I've been using PMS for awhile now and I really love it; so I thought it might be good to give back to the project. I saw this issue (http://code.google.com/p/ps3mediaserver/issues/detail?id=24) on the tracker and decided to add this feature for myself.

Currently, I have them working on my system (Mac OSX) but I have yet to implement a GUI interface for adding/editing them. So at the moment, they must be manual written to the PMS.conf

To give you an idea of how I implemented them, here are a few code snippets: (Note: They are a little quick and dirty atm and need more error checking)

The virtual folders are stored (in the config file) using the syntax:

vfoldername:/path/to/folder1,/path/to/folder2; (Note: these paths are escaped in the real config file, ie \/path\/to\/folder)

This method reads them in: (Based largely off of the loadFolderConf method)

Code: Select all
public VirtualFolder [] loadVirtualFoldersConf(String vfolders) throws IOException {
      if (vfolders == null || vfolders.length() == 0)
         return null;
      ArrayList<VirtualFolder> directories = new ArrayList<VirtualFolder>();
      VirtualFolder vf;
      StringTokenizer st = new StringTokenizer(vfolders, ";"); //$NON-NLS-1$
      while (st.hasMoreTokens()) {
         String line = st.nextToken();
         String[] vfolder = line.split(":");
         if (vfolder.length == 2) {
            vf = new VirtualFolder(vfolder[0],null);
         }
         else {
            PMS.error("Error Parsing Virtual Folders", null);
            continue;
         }
         StringTokenizer stF = new StringTokenizer(vfolder[1], ",");
         while (stF.hasMoreTokens()) {
            String path = stF.nextToken();
            File file = new File(path);
            if (file.exists()) {
               if (file.isDirectory()) {
                  File files [] = file.listFiles();
                  for(File f:files) {
                     vf.addChild(new RealFile(f));   
                  }
               } else
               PMS.error("File " + path + " is not a directory!", null);
            } else {
               PMS.error("File " + path + " does not exists!", null);
            }
         }
         directories.add(vf);
      }
      VirtualFolder f [] = new VirtualFolder[directories.size()];
      for(int j=0;j<f.length;j++)
         f[j] = directories.get(j);
      return f;
   }


This code works pretty well but has some thumbnail issues i need to look into.

This is code I added to manageRoot so that the virtual folders are loaded alongside the regular ones:

Code: Select all
VirtualFolder vfs [] = loadVirtualFoldersConf(configuration.getVirtualFolders());
      if (files == null || files.length == 0) {
         
      }
      else {
         for(VirtualFolder vf:vfs) {
            getRootFolder(renderer).addChild(vf);
         }
      }


I would be happy to add the GUI part and finish it if the devs want to include this.
Trin
 
Posts: 3
Joined: Thu May 27, 2010 7:35 am

Re: Virtual Folders

Postby ExSport » Fri May 28, 2010 7:20 am

Great try, many thanks.
We are waiting for this feature for ages :)
I suppose Shagrath will be glad that somebody did it so he can skip this task from todo list :)
Many thanks!!!
ExSport
 
Posts: 2168
Joined: Mon Jan 19, 2009 5:40 pm

Re: Virtual Folders

Postby ExSport » Sat Jun 05, 2010 9:20 am

Hi trin.
Do you have .dif file for us to test it(GUI not needed for now)?
I will try to integrate it to my test builds if it works because I am waiting for something like this for months.
So many thanks :)
ExSport
 
Posts: 2168
Joined: Mon Jan 19, 2009 5:40 pm

Re: Virtual Folders

Postby ExSport » Sat Jun 05, 2010 5:55 pm

So I used code from Trin, added some needed code and now it works also for me on Windows.
Who is interested, here are changes:
Code: Select all
Index: net/pms/configuration/PmsConfiguration.java
===================================================================
--- net/pms/configuration/PmsConfiguration.java   (revision 410)
+++ net/pms/configuration/PmsConfiguration.java   (working copy)
@@ -145,6 +145,7 @@
    private static final String CONFIGURATION_PATH_MAC = System.getProperty("user.home") + "/Library/Application Support/PS3 Media Server/";
    private static final char LIST_SEPARATOR = ',';
    private static final String KEY_FOLDERS = "folders";
+   private static final String KEY_VFOLDERS = "vfolders";
 
    private final PropertiesConfiguration configuration;
    private final TempFolder tempFolder;
@@ -820,6 +821,10 @@
       PMS.minimal("Configuration saved.");
    }
 
+   public String getVirtualFolders() {
+      return getString(KEY_VFOLDERS, "");
+   }
+   
    public String getFolders() {
       return getString(KEY_FOLDERS, "");
    }
Index: net/pms/PMS.java
===================================================================
--- net/pms/PMS.java   (revision 410)
+++ net/pms/PMS.java   (working copy)
@@ -474,6 +474,16 @@
       File files [] = loadFoldersConf(configuration.getFolders());
       if (files == null || files.length == 0)
          files = File.listRoots();
+      VirtualFolder vfs [] = loadVirtualFoldersConf(configuration.getVirtualFolders());
+         if (files == null || files.length == 0) {
+            
+         }
+         else {
+            for(VirtualFolder vf:vfs) {
+               getRootFolder(renderer).addChild(vf);
+            }
+         }
+        
       if (PMS.get().isWindows()) {
          
       }
@@ -945,7 +955,46 @@
       return f;
    }
 
-   
+   public VirtualFolder [] loadVirtualFoldersConf(String vfolders) throws IOException {
+         if (vfolders == null || vfolders.length() == 0)
+            return null;
+         ArrayList<VirtualFolder> directories = new ArrayList<VirtualFolder>();
+         VirtualFolder vf;
+         StringTokenizer st = new StringTokenizer(vfolders, ";"); //$NON-NLS-1$
+         while (st.hasMoreTokens()) {
+            String line = st.nextToken();
+            String[] vfolder = line.split("\\|");
+            if (vfolder.length == 2) {
+               vf = new VirtualFolder(vfolder[0],null);
+            }
+            else {
+               PMS.error("Error Parsing Virtual Folders", null);
+               continue;
+            }
+            StringTokenizer stF = new StringTokenizer(vfolder[1], ",");
+            while (stF.hasMoreTokens()) {
+               String path = stF.nextToken();
+               File file = new File(path);
+               if (file.exists()) {
+                  if (file.isDirectory()) {
+                     File files [] = file.listFiles();
+                     for(File f:files) {
+                        vf.addChild(new RealFile(f));   
+                     }
+                  } else
+                  PMS.error("File " + path + " is not a directory!", null);
+               } else {
+                  PMS.error("File " + path + " does not exists!", null);
+               }
+            }
+            directories.add(vf);
+         }
+         VirtualFolder f [] = new VirtualFolder[directories.size()];
+         for(int j=0;j<f.length;j++)
+            f[j] = directories.get(j);
+         return f;
+      }
+
    public void reset() throws IOException {
       debug("Waiting 1 seconds..."); //$NON-NLS-1$
       UPNPHelper.sendByeBye();
For non-programmers below is update.jar file attached.
To make it work, add update.jar file where pms.jar sits and add something like this to pms.conf file:
Code: Select all
vfolders = Documents|d:\\video\\documents,e:\\video\\documents,f:\\documents;Fun|c:\\fun,e:\\clips\\fun videos; etc...
I changed syntax used by Trin because on Windows we use ":" for other purposes so "|" is more cross-platform friendly I suppose :)
BUGs:
- Files and dirs are not alphabetically ordered
- Thumbnails not displayed correctly

Is somehow possible to sort it alphabetically?
I tried to use:
Code: Select all
Arrays.sort(files, new Comparator<File>()
   {
      public int compare(File o1, File o2) {
                     return o1.getName().compareToIgnoreCase(o2.getName());
                     }
        });
in code but without success. I am not programmer :mrgreen:
Attachments
VirtualFolders.zip
Unzip update.jar file to PMS dir
(200.08 KiB) Downloaded 269 times
ExSport
 
Posts: 2168
Joined: Mon Jan 19, 2009 5:40 pm

Re: Virtual Folders

Postby Trin » Sat Jun 05, 2010 6:29 pm

I changed syntax used by Trin because on Windows we use ":" for other purposes so "|" is more cross-platform friendly I suppose


Good catch. I forgot about the drive letters on Windows.

BUGs:
- Files and dirs are not alphabetically ordered
- Thumbnails not displayed correctly


These problems are caused by how I add the files to the virtual folder. If I have time this weekend, I'll try and fix these bugs and post my changes.
Trin
 
Posts: 3
Joined: Thu May 27, 2010 7:35 am

Re: Virtual Folders

Postby ExSport » Sat Jun 05, 2010 6:47 pm

Many thanks 8-)
If you will find solution also for sorting it will be great!
ExSport
 
Posts: 2168
Joined: Mon Jan 19, 2009 5:40 pm

Re: Virtual Folders

Postby Trin » Sat Jun 05, 2010 10:10 pm

Here is a quick fix I whipped up real fast to fix the sorting problem. I don't use Java much so I don't know how to make a update.jar off the top of my head so here is a svn patch that will add my code to the latest svn revision.

Code: Select all
Index: net/pms/PMS.java
===================================================================
--- net/pms/PMS.java   (revision 410)
+++ net/pms/PMS.java   (working copy)
@@ -36,6 +36,7 @@
 import java.net.NetworkInterface;

 import java.text.SimpleDateFormat;

 import java.util.ArrayList;

+import java.util.Collections;

 import java.util.Date;

 import java.util.Locale;

 import java.util.StringTokenizer;

@@ -114,6 +115,7 @@
 import net.pms.dlna.RealFile;

 import java.net.URI;

 import java.net.URLDecoder;

+import java.util.Comparator;

 

 

 import static org.hamcrest.MatcherAssert.assertThat;

@@ -479,7 +481,16 @@
       }

       getRootFolder(renderer).browse(files);

       

-      

+      VirtualFolder vfs [] = loadVirtualFoldersConf(configuration.getVirtualFolders());

+      if (files == null || files.length == 0) {

+         

+      }

+      else {

+         for(VirtualFolder vf:vfs) {

+            getRootFolder(renderer).addChild(vf);

+         }

+      }

+         

       File webConf = new File("WEB.conf"); //$NON-NLS-1$

       if (webConf.exists()) {

          try {

@@ -944,6 +955,58 @@
          f[j] = directories.get(j);

       return f;

    }

+   

+   public VirtualFolder [] loadVirtualFoldersConf(String vfolders) throws IOException {

+      if (vfolders == null || vfolders.length() == 0)

+         return null;

+      ArrayList<VirtualFolder> directories = new ArrayList<VirtualFolder>();

+      Comparator<File> byDirThenAlpha = new DirAlphaComparator();

+      VirtualFolder vf;

+      StringTokenizer st = new StringTokenizer(vfolders, ";"); //$NON-NLS-1$

+      while (st.hasMoreTokens()) {

+         String line = st.nextToken();

+         String[] vfolder = line.split("\\|");

+         if (vfolder.length == 2)

+         {

+            vf = new VirtualFolder(vfolder[0],null);

+         }

+         else

+         {

+            PMS.error("Error Parsing Virtual Folder: " + vfolder[0], null);

+            continue;

+         }

+         ArrayList<File> folderFiles = new ArrayList<File>();

+         StringTokenizer stF = new StringTokenizer(vfolder[1], ",");

+         while (stF.hasMoreTokens()) {

+            String path = stF.nextToken();

+            File file = new File(path);

+            if (file.exists()) {

+               if (file.isDirectory()) {

+                  //directories.add(file);

+                  //vf.addChild(new RealFile(file));

+                  File files [] = file.listFiles();

+                  for(File f:files) {

+                     //vf.addChild(new RealFile(f));

+                     folderFiles.add(f);

+                  }

+               } else

+               PMS.error("File " + path + " is not a directory!", null); //$NON-NLS-1$ //$NON-NLS-2$

+            } else {

+               PMS.error("File " + path + " does not exists!", null); //$NON-NLS-1$ //$NON-NLS-2$

+            }

+         }

+         Collections.sort(folderFiles, byDirThenAlpha);

+         for(File f:folderFiles)

+         {

+            vf.addChild(new RealFile(f));

+         }

+         directories.add(vf);

+      }

+      VirtualFolder f [] = new VirtualFolder[directories.size()];

+      for(int j=0;j<f.length;j++)

+         f[j] = directories.get(j);

+      return f;

+   }

 

    

    public void reset() throws IOException {

@@ -1200,3 +1263,22 @@
    }

 

 }

+

+class DirAlphaComparator implements Comparator<File> {

+

+    // Comparator interface requires defining compare method.

+    public int compare(File filea, File fileb) {

+        //... Sort directories before files,

+        //    otherwise alphabetical ignoring case.

+        if (filea.isDirectory() && !fileb.isDirectory()) {

+            return -1;

+

+        } else if (!filea.isDirectory() && fileb.isDirectory()) {

+            return 1;

+

+        } else {

+            return filea.getName().compareToIgnoreCase(fileb.getName());

+        }

+    }

+}

+

Index: net/pms/configuration/PmsConfiguration.java
===================================================================
--- net/pms/configuration/PmsConfiguration.java   (revision 410)
+++ net/pms/configuration/PmsConfiguration.java   (working copy)
@@ -145,6 +145,7 @@
    private static final String CONFIGURATION_PATH_MAC = System.getProperty("user.home") + "/Library/Application Support/PS3 Media Server/";

    private static final char LIST_SEPARATOR = ',';

    private static final String KEY_FOLDERS = "folders";

+   private static final String KEY_VIRTUAL_FOLDERS = "virtual_folders";

 

    private final PropertiesConfiguration configuration;

    private final TempFolder tempFolder;

@@ -826,8 +827,16 @@
    

    public void setFolders(String value) {

       configuration.setProperty(KEY_FOLDERS, value);

-   }   

+   }

    

+   public String getVirtualFolders() {

+      return getString(KEY_VIRTUAL_FOLDERS, "");

+   }

+   

+   public void setVirtualFolders(String value) {

+      configuration.setProperty(KEY_VIRTUAL_FOLDERS, value);

+   }

+   

    public String getNetworkInterface() {

       return getString(KEY_NETWORK_INTERFACE, "");

    }

Attachments
VirtualFolder.zip
SVN Patch
(1.76 KiB) Downloaded 170 times
Trin
 
Posts: 3
Joined: Thu May 27, 2010 7:35 am

Re: Virtual Folders

Postby ExSport » Sat Jun 05, 2010 10:57 pm

Many thanks again!
Now sorting works 8-)
A added update.jar for "non-compilators" below.
In this update syntax was changed for pms.conf file:
Instead of
Code: Select all
vfolders = Documents|d:\\video\\documents,e:\\video\\documents,f:\\documents;Fun|c:\\fun,e:\\clips\\fun videos; etc...
use
Code: Select all
virtual_folders = Documents|d:\\video\\documents,e:\\video\\documents,f:\\documents;Fun|c:\\fun,e:\\clips\\fun videos; etc...

vfolders was changed to virtual_folders
Attachments
VirtualFolders.zip
update.jar with fixed alphabetical sorting
(201.15 KiB) Downloaded 326 times
ExSport
 
Posts: 2168
Joined: Mon Jan 19, 2009 5:40 pm

Re: Virtual Folders

Postby andash » Sun Jun 06, 2010 12:10 pm

Thanks this is great.
Only thing I miss now is an option for either, not showing hidden folders or for hiding specific folders. I know ps3ms originally hides hidden folders so I hope thats not to hard to implement.
andash
 
Posts: 17
Joined: Sat Feb 07, 2009 2:13 am

Re: Virtual Folders

Postby chocolateboy » Sun Jun 06, 2010 5:56 pm

Nice work on this. I haven't played with it yet, but it should be possible to implement it as a plugin rather than patching PMS (a plugin can also provide a GUI by overriding the config method). See here for details, and here for an example.

Trin wrote:Currently, I have them working on my system (Mac OSX)


While you're at it, you might want to take a look at/fix this, as, currently, neither plugins nor update.jar work on Mac OS X.
chocolateboy
Project Member
 
Posts: 2580
Joined: Wed Sep 16, 2009 10:05 am

Next

Return to Developers

Who is online

Users browsing this forum: No registered users and 2 guests