Browse Source

py2app fixes

pull/69/head
Ruud 14 years ago
parent
commit
f70767be28
  1. 204
      CouchPotato.py
  2. 6
      README.md
  3. 18
      couchpotato/core/_base/_core/main.py
  4. 19
      couchpotato/core/_base/desktop/main.py
  5. 2
      couchpotato/environment.py
  6. BIN
      icon.icns
  7. BIN
      icon.ico
  8. 3
      libs/guessit/fileutils.py
  9. 86
      setup.py
  10. 1
      version.py

204
CouchPotato.py

@ -1,63 +1,167 @@
#!/usr/bin/env python from threading import Thread
# -*- coding: utf-8 -*- from wx.lib.softwareupdate import SoftwareUpdate
'''Wrapper for the command line interface.'''
from os.path import dirname
import os import os
import sys import sys
import subprocess import webbrowser
import time import wx
# Root path # Include proper dirs
base_path = dirname(os.path.abspath(__file__)) if hasattr(sys, 'frozen'):
import libs
base_path = os.path.dirname(os.path.dirname(os.path.abspath(libs.__file__)))
print base_path
else:
base_path = os.path.dirname(os.path.abspath(__file__))
# Insert local directories into path lib_dir = os.path.join(base_path, 'libs')
sys.path.insert(0, os.path.join(base_path, 'libs'))
from couchpotato.core.logger import CPLog sys.path.insert(0, base_path)
log = CPLog(__name__) sys.path.insert(0, lib_dir)
# Get options via arg # Get options via arg
from couchpotato.runner import getOptions from couchpotato.runner import getOptions
from couchpotato.core.helpers.variable import getDataDir
options = getOptions(base_path, sys.argv[1:])
data_dir = getDataDir()
def start():
try:
args = [sys.executable] + sys.argv
new_environ = os.environ.copy()
new_environ['cp_main'] = 'true'
if os.name == 'nt':
for key, value in new_environ.iteritems():
if isinstance(value, unicode):
new_environ[key] = value.encode('iso-8859-1')
subprocess.call(args, env = new_environ)
return os.path.isfile(os.path.join(data_dir, 'restart'))
except KeyboardInterrupt, e:
pass
except Exception, e:
log.critical(e)
return 0
from couchpotato.runner import runCouchPotato from couchpotato.runner import runCouchPotato
if __name__ == '__main__':
if os.environ.get('cp_main', 'false') == 'true':
class TaskBarIcon(wx.TaskBarIcon):
TBMENU_OPEN = wx.NewId()
TBMENU_SETTINGS = wx.NewId()
TBMENU_ABOUT = wx.ID_ABOUT
TBMENU_EXIT = wx.ID_EXIT
def __init__(self, frame):
wx.TaskBarIcon.__init__(self)
self.frame = frame
icon = wx.Icon('icon.ico', wx.BITMAP_TYPE_ANY)
self.SetIcon(icon)
self.Bind(wx.EVT_TASKBAR_LEFT_DCLICK, self.onTaskBarActivate)
self.Bind(wx.EVT_MENU, self.onOpen, id = self.TBMENU_OPEN)
self.Bind(wx.EVT_MENU, self.onSettings, id = self.TBMENU_SETTINGS)
self.Bind(wx.EVT_MENU, self.onAbout, id = self.TBMENU_ABOUT)
self.Bind(wx.EVT_MENU, self.onTaskBarClose, id = self.TBMENU_EXIT)
def CreatePopupMenu(self):
menu = wx.Menu()
menu.Append(self.TBMENU_OPEN, "Open")
menu.Append(self.TBMENU_SETTINGS, "Settings")
menu.Append(self.TBMENU_ABOUT, "About")
menu.Append(self.TBMENU_EXIT, "Close")
return menu
def onOpen(self, event):
url = self.frame.parent.getSetting('base_url')
webbrowser.open(url)
def onSettings(self, event):
url = self.frame.parent.getSetting('base_url') + '/settings/'
webbrowser.open(url)
def onAbout(self, event):
print 'onAbout'
def onTaskBarActivate(self, evt):
if not self.frame.IsShown():
self.frame.Show(True)
self.frame.Raise()
def onTaskBarClose(self, evt):
wx.CallAfter(self.frame.Close)
def makeIcon(self, img):
if "wxMSW" in wx.PlatformInfo:
img = img.Scale(16, 16)
elif "wxGTK" in wx.PlatformInfo:
img = img.Scale(22, 22)
icon = wx.IconFromBitmap(img.CopyFromBitmap())
return icon
class MainFrame(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__(self, None)
self.parent = parent
self.tbicon = TaskBarIcon(self)
class WorkerThread(Thread):
def __init__(self, desktop):
Thread.__init__(self)
self._desktop = desktop
self.start()
def run(self):
args = ['--nogit', '--console_log']#, '--quiet']
options = getOptions(base_path, args)
try: try:
runCouchPotato(options, base_path, sys.argv[1:]) runCouchPotato(options, base_path, args, desktop = self._desktop)
except KeyboardInterrupt, e:
raise
except Exception, e: except Exception, e:
log.critical(e) raise
else: finally:
while 1: pass
restart = start()
if not restart:
break class CouchPotatoApp(wx.App, SoftwareUpdate):
from couchpotato.core.event import fireEvent settings = {}
fireEvent('app.crappy_shutdown', single = True) events = {}
time.sleep(1) restart = False
sys.exit()
def OnInit(self):
# Updater
base_url = 'http://couchpotatoapp.com/updates/'
self.InitUpdates(base_url, base_url + 'changelog.txt',
icon = wx.Icon('icon.ico'))
self.frame = MainFrame(self)
self.frame.Bind(wx.EVT_CLOSE, self.onClose)
# CouchPotato thread
self.worker = WorkerThread(self)
return True
def setSettings(self, settings = {}):
self.settings = settings
def getSetting(self, name):
return self.settings.get(name)
def addEvents(self, events = {}):
for name in events.iterkeys():
self.events[name] = events[name]
def onClose(self, event):
onClose = self.events.get('onClose')
if self.events.get('onClose'):
onClose(event)
else:
self.afterShutdown()
def afterShutdown(self, restart = False):
self.frame.Destroy()
self.restart = restart
if __name__ == '__main__':
app = CouchPotatoApp(redirect = False)
app.MainLoop()
#path = os.path.join(sys.path[0].decode(sys.getfilesystemencoding()), sys.argv[0])
#if app.restart:
# wx.Process.Open(sys.executable + ' ' + path)

6
README.md

@ -1,5 +1 @@
CouchPotato Server CouchPotato Desktop
=====
CouchPotato (CP) is an automatic NZB and torrent downloader. You can keep a "movies I want"-list and it will search for NZBs/torrents of these movies every X hours.
Once a movie is found, it will send it to SABnzbd or download the torrent to a specified directory.

18
couchpotato/core/_base/_core/main.py

@ -1,4 +1,3 @@
from couchpotato import app
from couchpotato.api import addApiView from couchpotato.api import addApiView
from couchpotato.core.event import fireEvent, addEvent from couchpotato.core.event import fireEvent, addEvent
from couchpotato.core.helpers.request import jsonified from couchpotato.core.helpers.request import jsonified
@ -7,7 +6,6 @@ from couchpotato.core.logger import CPLog
from couchpotato.core.plugins.base import Plugin from couchpotato.core.plugins.base import Plugin
from couchpotato.environment import Env from couchpotato.environment import Env
from flask import request from flask import request
from flask.helpers import url_for
import os import os
import time import time
import traceback import traceback
@ -29,6 +27,7 @@ class Core(Plugin):
addEvent('app.crappy_restart', self.crappyRestart) addEvent('app.crappy_restart', self.crappyRestart)
addEvent('app.load', self.launchBrowser, priority = 1) addEvent('app.load', self.launchBrowser, priority = 1)
addEvent('app.base_url', self.createBaseUrl) addEvent('app.base_url', self.createBaseUrl)
addEvent('app.api_url', self.createApiUrl)
addEvent('setting.save.core.password', self.md5Password) addEvent('setting.save.core.password', self.md5Password)
@ -43,16 +42,10 @@ class Core(Plugin):
}) })
def crappyShutdown(self): def crappyShutdown(self):
ctx = app.test_request_context() self.urlopen('%sapp.shutdown' % self.createApiUrl())
ctx.push()
self.urlopen('%s%sapp.shutdown' % (fireEvent('app.base_url', single = True), url_for('api.index')))
ctx.pop()
def crappyRestart(self): def crappyRestart(self):
ctx = app.test_request_context() self.urlopen('%sapp.restart' % self.createApiUrl())
ctx.push()
self.urlopen('%s%sapp.restart' % (fireEvent('app.base_url', single = True), url_for('api.index')))
ctx.pop()
def shutdown(self): def shutdown(self):
self.initShutdown() self.initShutdown()
@ -63,6 +56,7 @@ class Core(Plugin):
return 'restarting' return 'restarting'
def initShutdown(self, restart = False): def initShutdown(self, restart = False):
log.info('Shutting down' if not restart else 'Restarting')
fireEvent('app.shutdown') fireEvent('app.shutdown')
@ -122,3 +116,7 @@ class Core(Plugin):
port = Env.setting('port') port = Env.setting('port')
return '%s:%d' % (cleanHost(host).rstrip('/'), int(port)) return '%s:%d' % (cleanHost(host).rstrip('/'), int(port))
def createApiUrl(self):
return '%s/%s/' % (self.createBaseUrl(), Env.setting('api_key'))

19
couchpotato/core/_base/desktop/main.py

@ -7,25 +7,28 @@ log = CPLog(__name__)
if Env.get('desktop'): if Env.get('desktop'):
#import os
#import sys
import wx
class Desktop(Plugin): class Desktop(Plugin):
def __init__(self): def __init__(self):
desktop = Env.get('desktop') desktop = Env.get('desktop')
desktop.setSettings({ desktop.setSettings({
'url': fireEvent('app.base_url', single = True) 'base_url': fireEvent('app.base_url', single = True),
'api_url': fireEvent('app.api_url', single = True),
'api': Env.setting('api'),
}) })
def onClose(event): # Events from desktop
return fireEvent('app.crappy_shutdown') desktop.addEvents({
desktop.close_handler = onClose 'onClose': self.onClose,
})
# Events to desktop
addEvent('app.after_shutdown', desktop.afterShutdown) addEvent('app.after_shutdown', desktop.afterShutdown)
def onClose(self, event):
return fireEvent('app.crappy_shutdown', single = True)
else: else:
class Desktop(Plugin): class Desktop(Plugin):

2
couchpotato/environment.py

@ -14,7 +14,7 @@ class Env(object):
_args = None _args = None
_quiet = False _quiet = False
_deamonize = False _deamonize = False
_version = 0.5 _desktop = None
''' Data paths and directories ''' ''' Data paths and directories '''
_app_dir = "" _app_dir = ""

BIN
icon.icns

Binary file not shown.

BIN
icon.ico

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

3
libs/guessit/fileutils.py

@ -18,7 +18,6 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
import ntpath
import os.path import os.path
@ -45,7 +44,7 @@ def split_path(path):
""" """
result = [] result = []
while True: while True:
head, tail = ntpath.split(path) head, tail = os.path.split(path)
# on Unix systems, the root folder is '/' # on Unix systems, the root folder is '/'
if head == '/' and tail == '': if head == '/' and tail == '':

86
setup.py

@ -0,0 +1,86 @@
from esky import bdist_esky
from setuptools import setup
import sys
import version
import os
# Include proper dirs
base_path = os.path.dirname(os.path.abspath(__file__))
lib_dir = os.path.join(base_path, 'libs')
sys.path.insert(0, base_path)
sys.path.insert(0, lib_dir)
# Windows
if sys.platform == "win32":
import py2exe
FREEZER = 'py2exe'
FREEZER_OPTIONS = dict(
compressed = 0,
optimize = 0,
bundle_files = 3,
dll_excludes = [
'MSVCP90.dll',
'mswsock.dll',
'powrprof.dll',
'USP10.dll',
],
packages = ['couchpotato', 'libs'],
includes = [
'telnetlib',
'xml.etree.ElementTree',
'xml.etree.cElementTree',
'xml.dom',
'xml.dom.minidom',
],
)
exeICON = 'icon.ico'
# OSX
elif sys.platform == "darwin":
import py2app
FREEZER = 'py2app'
FREEZER_OPTIONS = dict(
argv_emulation = False,
iconfile = 'icon.icns',
plist = dict(
LSUIElement = True,
),
packages = ['couchpotato', 'libs'],
includes = [
'telnetlib',
'xml.etree.ElementTree',
'xml.etree.cElementTree',
'xml.dom',
'xml.dom.minidom',
],
)
exeICON = None
# Common
NAME = "CouchPotato"
APP = [bdist_esky.Executable("CouchPotato.py", gui_only = True, icon = exeICON,)]
DATA_FILES = ['icon.ico']
ESKY_OPTIONS = dict(
freezer_module = FREEZER,
freezer_options = FREEZER_OPTIONS,
bundle_msvcrt = True,
)
# Build the app and the esky bundle
setup(
name = NAME,
scripts = APP,
version = version.VERSION,
data_files = DATA_FILES,
options = dict(bdist_esky = ESKY_OPTIONS),
)

1
version.py

@ -0,0 +1 @@
VERSION = '0.5'
Loading…
Cancel
Save