summaryrefslogtreecommitdiffstats
path: root/pyload/datatypes/PyFile.py
diff options
context:
space:
mode:
authorGravatar RaNaN <Mast3rRaNaN@hotmail.de> 2013-06-09 18:10:22 +0200
committerGravatar RaNaN <Mast3rRaNaN@hotmail.de> 2013-06-09 18:10:23 +0200
commit16af85004c84d0d6c626b4f8424ce9647669a0c1 (patch)
tree025d479862d376dbc17e934f4ed20031c8cd97d1 /pyload/datatypes/PyFile.py
parentadapted to jshint config (diff)
downloadpyload-16af85004c84d0d6c626b4f8424ce9647669a0c1.tar.xz
moved everything from module to pyload
Diffstat (limited to 'pyload/datatypes/PyFile.py')
-rw-r--r--pyload/datatypes/PyFile.py268
1 files changed, 268 insertions, 0 deletions
diff --git a/pyload/datatypes/PyFile.py b/pyload/datatypes/PyFile.py
new file mode 100644
index 000000000..ba5208795
--- /dev/null
+++ b/pyload/datatypes/PyFile.py
@@ -0,0 +1,268 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+###############################################################################
+# Copyright(c) 2008-2012 pyLoad Team
+# http://www.pyload.org
+#
+# This file is part of pyLoad.
+# pyLoad is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# Subjected to the terms and conditions in LICENSE
+#
+# @author: RaNaN
+###############################################################################
+
+from time import sleep, time
+from ReadWriteLock import ReadWriteLock
+
+from pyload.Api import ProgressInfo, DownloadProgress, FileInfo, DownloadInfo, DownloadStatus
+from pyload.utils import lock, read_lock
+
+statusMap = {
+ "none": 0,
+ "offline": 1,
+ "online": 2,
+ "queued": 3,
+ "paused": 4,
+ "finished": 5,
+ "skipped": 6,
+ "failed": 7,
+ "starting": 8,
+ "waiting": 9,
+ "downloading": 10,
+ "temp. offline": 11,
+ "aborted": 12,
+ "decrypting": 13,
+ "processing": 14,
+ "custom": 15,
+ "unknown": 16,
+}
+
+
+class PyFile(object):
+ """
+ Represents a file object at runtime
+ """
+ __slots__ = ("m", "fid", "_name", "_size", "filestatus", "media", "added", "fileorder",
+ "url", "pluginname", "hash", "status", "error", "packageid", "ownerid",
+ "lock", "plugin", "waitUntil", "abort", "statusname",
+ "reconnected", "pluginclass")
+
+ @staticmethod
+ def fromInfoData(m, info):
+ f = PyFile(m, info.fid, info.name, info.size, info.status, info.media, info.added, info.fileorder,
+ "", "", "", DownloadStatus.NA, "", info.package, info.owner)
+ if info.download:
+ f.url = info.download.url
+ f.pluginname = info.download.plugin
+ f.hash = info.download.hash
+ f.status = info.download.status
+ f.error = info.download.error
+
+ return f
+
+ def __init__(self, manager, fid, name, size, filestatus, media, added, fileorder,
+ url, pluginname, hash, status, error, package, owner):
+
+ self.m = manager
+
+ self.fid = int(fid)
+ self._name = name
+ self._size = size
+ self.filestatus = filestatus
+ self.media = media
+ self.added = added
+ self.fileorder = fileorder
+ self.url = url
+ self.pluginname = pluginname
+ self.hash = hash
+ self.status = status
+ self.error = error
+ self.ownerid = owner
+ self.packageid = package
+ # database information ends here
+
+ self.lock = ReadWriteLock()
+
+ self.plugin = None
+
+ self.waitUntil = 0 # time() + time to wait
+
+ # status attributes
+ self.abort = False
+ self.reconnected = False
+ self.statusname = None
+
+
+ @property
+ def id(self):
+ self.m.core.log.debug("Deprecated attr .id, use .fid instead")
+ return self.fid
+
+ def setSize(self, value):
+ self._size = int(value)
+
+ # will convert all sizes to ints
+ size = property(lambda self: self._size, setSize)
+
+ def getName(self):
+ try:
+ if self.plugin.req.name:
+ return self.plugin.req.name
+ else:
+ return self._name
+ except:
+ return self._name
+
+ def setName(self, name):
+ """ Only set unicode or utf8 strings as name """
+ if type(name) == str:
+ name = name.decode("utf8")
+
+ self._name = name
+
+ name = property(getName, setName)
+
+ def __repr__(self):
+ return "<PyFile %s: %s@%s>" % (self.id, self.name, self.pluginname)
+
+ @lock
+ def initPlugin(self):
+ """ inits plugin instance """
+ if not self.plugin:
+ self.pluginclass = self.m.core.pluginManager.getPlugin(self.pluginname)
+ self.plugin = self.pluginclass(self)
+
+ @read_lock
+ def hasPlugin(self):
+ """Thread safe way to determine this file has initialized plugin attribute"""
+ return hasattr(self, "plugin") and self.plugin
+
+ def package(self):
+ """ return package instance"""
+ return self.m.getPackage(self.packageid)
+
+ def setStatus(self, status):
+ self.status = statusMap[status]
+ # needs to sync so status is written to database
+ self.sync()
+
+ def setCustomStatus(self, msg, status="processing"):
+ self.statusname = msg
+ self.setStatus(status)
+
+ def getStatusName(self):
+ if self.status not in (13, 14) or not self.statusname:
+ return self.m.statusMsg[self.status]
+ else:
+ return self.statusname
+
+ def hasStatus(self, status):
+ return statusMap[status] == self.status
+
+ def sync(self):
+ """sync PyFile instance with database"""
+ self.m.updateFile(self)
+
+ @lock
+ def release(self):
+ """sync and remove from cache"""
+ if hasattr(self, "plugin") and self.plugin:
+ self.plugin.clean()
+ del self.plugin
+
+ self.m.releaseFile(self.fid)
+
+
+ def toInfoData(self):
+ return FileInfo(self.fid, self.getName(), self.packageid, self.ownerid, self.getSize(), self.filestatus,
+ self.media, self.added, self.fileorder, DownloadInfo(
+ self.url, self.pluginname, self.hash, self.status, self.getStatusName(), self.error
+ )
+ )
+
+ def getPath(self):
+ pass
+
+ def move(self, pid):
+ pass
+
+ @read_lock
+ def abortDownload(self):
+ """abort pyfile if possible"""
+ # TODO: abort timeout, currently dead locks
+ while self.id in self.m.core.threadManager.processingIds():
+ self.abort = True
+ if self.plugin and self.plugin.req:
+ self.plugin.req.abortDownloads()
+ sleep(0.1)
+
+ self.abort = False
+ if self.plugin and self.plugin.req:
+ self.plugin.req.abortDownloads()
+
+ self.release()
+
+ def finishIfDone(self):
+ """set status to finish and release file if every thread is finished with it"""
+
+ if self.id in self.m.core.threadManager.processingIds():
+ return False
+
+ self.setStatus("finished")
+ self.release()
+ self.m.checkAllLinksFinished()
+ return True
+
+ def checkIfProcessed(self):
+ self.m.checkAllLinksProcessed(self.id)
+
+ def getSpeed(self):
+ """ calculates speed """
+ try:
+ return self.plugin.req.speed
+ except:
+ return 0
+
+ def getETA(self):
+ """ gets established time of arrival / or waiting time"""
+ try:
+ if self.status == DownloadStatus.Waiting:
+ return self.waitUntil - time()
+
+ return self.getBytesLeft() / self.getSpeed()
+ except:
+ return 0
+
+ def getBytesArrived(self):
+ """ gets bytes arrived """
+ try:
+ return self.plugin.req.arrived
+ except:
+ return 0
+
+ def getBytesLeft(self):
+ """ gets bytes left """
+ try:
+ return self.plugin.req.size - self.plugin.req.arrived
+ except:
+ return 0
+
+ def getSize(self):
+ """ get size of download """
+ try:
+ if self.plugin.req.size:
+ return self.plugin.req.size
+ else:
+ return self.size
+ except:
+ return self.size
+
+ def getProgressInfo(self):
+ return ProgressInfo(self.pluginname, self.name, self.getStatusName(), self.getETA(),
+ self.getBytesArrived(), self.getSize(),
+ DownloadProgress(self.fid, self.packageid, self.getSpeed(), self.status))