123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195 |
- #!/usr/bin/env python
- # -*- coding: utf-8 -*-
- #
- # Copyright (C) 2012 Mike Sheldon <elleo@gnu.org>
- #
- # Licensed under the Apache License, Version 2.0 (the "License");
- # you may not use this file except in compliance with the License.
- # You may obtain a copy of the License at
- #
- # http://www.apache.org/licenses/LICENSE-2.0
- #
- # Unless required by applicable law or agreed to in writing, software
- # distributed under the License is distributed on an "AS IS" BASIS,
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- # See the License for the specific language governing permissions and
- # limitations under the License.
- from PySide import QtCore, QtGui, QtDeclarative
- import xml.etree.cElementTree as etree
- import sys, os, os.path, signal, shutil
- import subprocess, zipfile
- class Tizmee:
- def __init__(self):
- self.app = QtGui.QApplication(sys.argv)
- self.app.setApplicationName("Tizmee")
- signal.signal(signal.SIGINT, signal.SIG_DFL)
- self.cacheDir = QtGui.QDesktopServices.storageLocation(QtGui.QDesktopServices.CacheLocation)
- if not os.path.exists(self.cacheDir):
- os.mkdir(self.cacheDir)
- if os.path.exists("/home/user/MyDocs/"):
- # Maemo/Harmattan
- self.appDir = "/home/user/MyDocs/TizenApps"
- else:
- self.appDir = os.path.join(os.path.expanduser("~"), 'TizenApps')
- if not os.path.exists(self.appDir):
- os.mkdir(self.appDir)
- self.appsModel = AppsModel()
- self.view = QtDeclarative.QDeclarativeView()
- self.view.setSource("/opt/tizmee/qml/Tizmee.qml")
- self.rootObject = self.view.rootObject()
- self.context = self.view.rootContext()
- self.context.setContextProperty('appsModel', self.appsModel)
- self.rootObject.openFile("Launcher.qml")
- self.rootObject.quit.connect(sys.exit)
- self.rootObject.launch.connect(self.launch)
- self.view.showFullScreen()
- self.populate_apps()
- sys.exit(self.app.exec_())
- def populate_apps(self):
- for filename in os.listdir(self.appDir):
- wgtPath = os.path.join(self.appDir, filename)
- if zipfile.is_zipfile(wgtPath):
- appPath = os.path.join(self.cacheDir, filename)
- if not os.path.exists(appPath):
- os.mkdir(appPath)
- zapp = zipfile.ZipFile(wgtPath)
- config = zapp.open("config.xml")
- tree = etree.parse(config)
- root = tree.getroot()
- name = root.findtext("{http://www.w3.org/ns/widgets}name")
- icon = root.find("{http://www.w3.org/ns/widgets}icon").get("src")
- if icon:
- iconPath = os.path.join(appPath, icon)
- zapp.extract(icon, appPath)
- icon = iconPath
- try:
- startfile = root.find("{http://www.w3.org/ns/widgets}content").get("src")
- except:
- startfile = "index.html"
- app = App(name, wgtPath, appPath, startfile, icon)
- self.appsModel.add(app)
- if self.appsModel.rowCount() == 0:
- self.rootObject.showExitMessage("No Tizen apps installed", "You don't currently have any Tizen apps installed. To install an app place its .wgt file in %s." % self.appDir)
- def launch(self, wgtPath, path, startfile):
- zapp = zipfile.ZipFile(wgtPath)
- zapp.extractall(path)
- tjspath = os.path.join(path, "tizenjs")
- if os.path.exists(tjspath):
- shutil.rmtree(tjspath)
- shutil.copytree("/opt/tizmee/www/js/", tjspath)
- # HACK: Inject our JavaScript for implementing the Tizen API
- # TODO: Find a way to automatically do this on file load
- for filename in os.listdir(path):
- if filename[-4:].lower() == 'html' or filename[-3:].lower() == 'htm':
- htmlfile = open(os.path.join(path, filename), 'r')
- html = htmlfile.read()
- htmlfile.close()
- htmlfile = open(os.path.join(path, filename), 'w')
- html = html.replace("<head>", """<head>
- <script language='javascript' type='text/javascript' src='tizenjs/cordova.js'></script>
- <script language='javascript' type='text/javascript' src='tizenjs/cordova.qt.js'></script>
- <script language='javascript' type='text/javascript' src='tizenjs/tizensysteminfo.js'></script>
- """)
- if 'data-framework-viewport-scale="true"' not in html and "data-framework-viewport-scale='true'" not in html:
- # Handle scaling if the Tizen libs aren't doing it for us
- html = html.replace("<head>", """<head>
- <meta name="viewport" content="width=720; height=1280; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;"/>
- <style>
- body {
- zoom: 0.74;
- }
- </style>
- """)
- htmlfile.write(html)
- htmlfile.close()
- subprocess.Popen(["/usr/bin/invoker", "-S", "/opt/tizmee/tizmee-splash.png", "--type=e", "/opt/tizmee/bin/cordovaqt", path, startfile])
- class App(QtCore.QObject):
- def __init__(self, name, wgtPath, path, startfile, icon):
- self.name = name
- self.wgtPath = wgtPath
- self.path = path
- self.startfile = startfile
- self.icon = icon
- class AppsModel(QtCore.QAbstractListModel):
- NAME_ROLE = QtCore.Qt.UserRole + 1
- WGTPATH_ROLE = QtCore.Qt.UserRole + 2
- PATH_ROLE = QtCore.Qt.UserRole + 3
- STARTFILE_ROLE = QtCore.Qt.UserRole + 4
- ICON_ROLE = QtCore.Qt.UserRole + 5
- def __init__(self, parent=None):
- super(AppsModel, self).__init__(parent)
- self._data = []
- keys = {}
- keys[AppsModel.NAME_ROLE] = 'name'
- keys[AppsModel.WGTPATH_ROLE] = 'wgtpath'
- keys[AppsModel.PATH_ROLE] = 'path'
- keys[AppsModel.STARTFILE_ROLE] = 'startfile'
- keys[AppsModel.ICON_ROLE] = 'icon'
- self.setRoleNames(keys)
- def rowCount(self, index=0):
- return len(self._data)
- def data(self, index, role):
- app = self._data[index.row()]
- if role == AppsModel.NAME_ROLE:
- return app.name
- elif role == AppsModel.WGTPATH_ROLE:
- return app.wgtPath
- elif role == AppsModel.PATH_ROLE:
- return app.path
- elif role == AppsModel.STARTFILE_ROLE:
- return app.startfile
- elif role == AppsModel.ICON_ROLE:
- return app.icon
- else:
- return None
- def add(self, app):
- self.beginInsertRows(QtCore.QModelIndex(), 0, 0) #notify view about upcoming change
- self._data.insert(0, app)
- self.endInsertRows() #notify view that change happened
- def addToEnd(self, app):
- count = len(self._data)
- self.beginInsertRows(QtCore.QModelIndex(), count, count)
- self._data.insert(count, app)
- self.endInsertRows()
- if __name__ == "__main__":
- Tizmee()
|