summaryrefslogtreecommitdiff
path: root/src/msd/msd_browse.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/msd/msd_browse.py')
-rw-r--r--src/msd/msd_browse.py234
1 files changed, 234 insertions, 0 deletions
diff --git a/src/msd/msd_browse.py b/src/msd/msd_browse.py
new file mode 100644
index 0000000..d0d42dc
--- /dev/null
+++ b/src/msd/msd_browse.py
@@ -0,0 +1,234 @@
+# media-service-demo
+#
+# Copyright (C) 2012 Intel Corporation. All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms and conditions of the GNU Lesser General Public License,
+# version 2.1, as published by the Free Software Foundation.
+#
+# This program is distributed in the hope it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+# for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Mark Ryan <mark.d.ryan@intel.com>
+#
+
+import pygtk
+pygtk.require('2.0')
+import gtk
+import dateutil.parser
+import datetime
+
+from msd_sort_order import *
+from msd_upnp import *
+
+class TreeNode(object):
+
+ filter = ["Artist", "DisplayName", "URLs", "Date", "Path",
+ "Type"]
+ buffer_size = 50
+
+ def __init__(self, props, parent, sort_order):
+ self.__props = props
+ self.__container = None
+ self.__max_items = 0
+ self.__parent = parent
+ self.__sort_order = sort_order
+ if self.is_container():
+ self.__container = Container(props["Path"])
+ try:
+ self.__max_items = self.__container.get_prop("ChildCount")
+ except Exception:
+ pass
+ self.__children = [None] * self.__max_items
+
+ def is_container(self):
+ return self.__props["Type"] == "container"
+
+ def reset_children(self):
+ self.__children = [None] * self.__max_items
+
+ def get_num_children(self):
+ return self.__max_items
+
+ def get_props(self):
+ return self.__props
+
+ def get_parent(self):
+ return self.__parent
+
+ def flush(self):
+ self.__flush_down()
+ if self.__parent:
+ self.__parent.__flush_up(self)
+
+ def __flush_down(self):
+ i = 0;
+ while i < self.__max_items:
+ if self.__children[i]:
+ self.__children[i].__flush_down()
+ self.__children[i] = None
+ i = i + 1
+
+ def __flush_up(self, child):
+ i = 0;
+ while i < self.__max_items:
+ if self.__children[i]:
+ if child != self.__children[i]:
+ self.__children[i].__flush_down()
+ self.__children[i] = None
+ i = i + 1
+ if self.__parent:
+ self.__parent.__flush_up(self)
+
+ def get_child(self, child):
+ retval = None
+ if child < self.__max_items:
+ retval = self.__children[child]
+ if not retval:
+ i = child + 1
+ while (i < self.__max_items and (i - child) <
+ TreeNode.buffer_size and not self.__children[i]):
+ i = i + 1
+ try:
+ sort_descriptor = self.__sort_order.get_upnp_sort_order()
+ try:
+ result = self.__container.list_children(child,
+ i - child,
+ TreeNode.filter,
+ sort_descriptor)
+ except Exception:
+ result = self.__container.list_children(child,
+ i - child,
+ TreeNode.filter)
+ i = child
+ for props in result:
+ self.__children[i] = TreeNode(props, self,
+ self.__sort_order)
+ i = i + 1
+ retval = self.__children[child]
+ except Exception:
+ pass
+
+ return retval
+
+class BrowseModel(gtk.GenericTreeModel):
+ columns = (("DisplayName", str), ("Artist", str), ("Date", str),
+ ("Type",str), ("Path", str), ("URLs", str))
+
+ def __init__(self, root):
+ gtk.GenericTreeModel.__init__(self)
+
+ self.__root = root
+
+ def flush(self):
+ self.__root.flush()
+
+ def on_get_flags(self):
+ return gtk.TREE_MODEL_LIST_ONLY | gtk.TREE_MODEL_ITERS_PERSIST
+
+ def on_get_n_columns(self):
+ return len(BrowseModel.columns)
+
+ def on_get_column_type(self, n):
+ return BrowseModel.columns[n][1]
+
+ def __get_num_of_children(self):
+ num = self.__root.get_num_children()
+ if self.__root.get_parent():
+ num = num + 1
+ return num
+
+ def on_get_iter(self, path):
+ if path[0] >= self.__get_num_of_children():
+ raise ValueError("Invalid Path")
+ return path[0]
+
+ def on_get_path(self, rowref):
+ return (rowref,)
+
+ def adjusted_on_get_value(self, rowref, col):
+ retval = None
+ key = BrowseModel.columns[col][0]
+ node = self.__root.get_child(rowref)
+ props = node.get_props()
+ if key in props:
+ data = props[key]
+ if node.is_container():
+ if col == 0:
+ retval = data
+ else:
+ if col == 2:
+ date = dateutil.parser.parse(data)
+ retval = date.strftime("%x")
+ elif col == 3:
+ data = data[0].upper() + data[1:]
+ period = data.find('.')
+ if period >=0:
+ retval = data[:period]
+ else:
+ retval = data
+ elif col == 5:
+ retval = data[0]
+ else:
+ retval = data
+ elif not node.is_container():
+ if col == 1:
+ retval = "Unknown"
+ elif col == 2:
+ retval = datetime.date.today().strftime("%x")
+ else:
+ retval = ""
+
+ return retval
+
+ def on_get_value(self, rowref, col):
+ if self.__root.get_parent():
+ if rowref == 0:
+ if col == 0:
+ retval = ".."
+ else:
+ retval = ""
+ else:
+ retval = self.adjusted_on_get_value(rowref - 1, col)
+ else:
+ retval = self.adjusted_on_get_value(rowref, col)
+
+ return retval
+
+ def on_iter_next(self, rowref):
+ retval = None
+ rowref = rowref + 1
+ if rowref < self.__get_num_of_children():
+ retval = rowref
+
+ return retval
+
+ def on_iter_children(self, rowref):
+ retval = 0
+ if rowref:
+ retval = None
+ return retval
+
+ def on_iter_has_child(self, rowref):
+ return False
+
+ def on_iter_n_children(self, rowref):
+ retval = 0
+ if not rowref:
+ retval = self.__get_num_of_children()
+ return retval
+
+ def on_iter_nth_child(self, rowref, child):
+ retval = None
+ if not rowref and child < self.__get_num_of_children():
+ retval = child
+ return retval
+
+ def on_iter_parent(self, rowref):
+ return None