]>
git.ipfire.org Git - people/shoehn/ipfire.org.git/blob - www/pages/torrent/client/ConfigDir.py
1 #written by John Hoffman
3 from inifile
import ini_write
, ini_read
4 from bencode
import bencode
, bdecode
5 from types
import IntType
, LongType
, StringType
, FloatType
6 from CreateIcons
import GetIcons
, CreateIcon
7 from parseargs
import defaultargs
8 from __init__
import product_name
, version_short
10 from time
import time
, strftime
19 realpath
= os
.path
.realpath
22 OLDICONPATH
= os
.path
.abspath(os
.path
.dirname(realpath(sys
.argv
[0])))
24 DIRNAME
= '.'+product_name
26 hexchars
= '0123456789abcdef'
30 x
= hexchars
[(i
&0xF0)/16]+hexchars
[i
&0x0F]
37 r
.append(hexmap
[ord(c
)])
41 r
= [ revmap
[s
[x
:x
+2]] for x
in xrange(0, len(s
), 2) ]
44 def copyfile(oldpath
, newpath
): # simple file copy, all in RAM
46 f
= open(oldpath
,'rb')
58 f
= open(newpath
,'wb')
71 ###### INITIALIZATION TASKS ######
73 def __init__(self
, config_type
= None):
74 self
.config_type
= config_type
76 config_ext
= '.'+config_type
81 y
= os
.path
.expandvars(x
)
82 if y
!= x
and os
.path
.isdir(y
):
86 for d
in ['${APPDATA}', '${HOME}', '${HOMEPATH}', '${USERPROFILE}']:
87 dir_root
= check_sysvars(d
)
91 dir_root
= os
.path
.expanduser('~')
92 if not os
.path
.isdir(dir_root
):
93 dir_root
= os
.path
.abspath(os
.path
.dirname(sys
.argv
[0]))
95 dir_root
= os
.path
.join(dir_root
,DIRNAME
)
96 self
.dir_root
= dir_root
98 if not os
.path
.isdir(self
.dir_root
):
99 os
.mkdir(self
.dir_root
,0700) # exception if failed
101 self
.dir_icons
= os
.path
.join(dir_root
,'icons')
102 if not os
.path
.isdir(self
.dir_icons
):
103 os
.mkdir(self
.dir_icons
)
104 for icon
in GetIcons():
105 i
= os
.path
.join(self
.dir_icons
,icon
)
106 if not os
.path
.exists(i
):
107 if not copyfile(os
.path
.join(OLDICONPATH
,icon
),i
):
108 CreateIcon(icon
,self
.dir_icons
)
110 self
.dir_torrentcache
= os
.path
.join(dir_root
,'torrentcache')
111 if not os
.path
.isdir(self
.dir_torrentcache
):
112 os
.mkdir(self
.dir_torrentcache
)
114 self
.dir_datacache
= os
.path
.join(dir_root
,'datacache')
115 if not os
.path
.isdir(self
.dir_datacache
):
116 os
.mkdir(self
.dir_datacache
)
118 self
.dir_piececache
= os
.path
.join(dir_root
,'piececache')
119 if not os
.path
.isdir(self
.dir_piececache
):
120 os
.mkdir(self
.dir_piececache
)
122 self
.configfile
= os
.path
.join(dir_root
,'config'+config_ext
+'.ini')
123 self
.statefile
= os
.path
.join(dir_root
,'state'+config_ext
)
125 self
.TorrentDataBuffer
= {}
128 ###### CONFIG HANDLING ######
130 def setDefaults(self
, defaults
, ignore
=[]):
131 self
.config
= defaultargs(defaults
)
133 if self
.config
.has_key(k
):
136 def checkConfig(self
):
137 return os
.path
.exists(self
.configfile
)
139 def loadConfig(self
):
141 r
= ini_read(self
.configfile
)['']
144 l
= self
.config
.keys()
145 for k
,v
in r
.items():
146 if self
.config
.has_key(k
):
147 t
= type(self
.config
[k
])
151 elif t
== IntType
or t
== LongType
:
152 self
.config
[k
] = long(v
)
154 self
.config
[k
] = float(v
)
158 if l
: # new default values since last save
162 def saveConfig(self
, new_config
= None):
164 for k
,v
in new_config
.items():
165 if self
.config
.has_key(k
):
168 ini_write( self
.configfile
, self
.config
,
169 'Generated by '+product_name
+'/'+version_short
+'\n'
170 + strftime('%x %X') )
179 ###### STATE HANDLING ######
183 f
= open(self
.statefile
,'rb')
197 def saveState(self
, state
):
199 f
= open(self
.statefile
,'wb')
200 f
.write(bencode(state
))
211 ###### TORRENT HANDLING ######
213 def getTorrents(self
):
215 for f
in os
.listdir(self
.dir_torrentcache
):
216 f
= os
.path
.basename(f
)
218 f
, garbage
= f
.split('.')
224 def getTorrentVariations(self
, t
):
227 for f
in os
.listdir(self
.dir_torrentcache
):
228 f
= os
.path
.basename(f
)
231 garbage
, ver
= f
.split('.')
238 def getTorrent(self
, t
, v
= -1):
241 v
= max(self
.getTorrentVariations(t
)) # potential exception
245 f
= open(os
.path
.join(self
.dir_torrentcache
,t
),'rb')
246 r
= bdecode(f
.read())
255 def writeTorrent(self
, data
, t
, v
= -1):
259 v
= max(self
.getTorrentVariations(t
))+1
265 f
= open(os
.path
.join(self
.dir_torrentcache
,t
),'wb')
266 f
.write(bencode(data
))
276 ###### TORRENT DATA HANDLING ######
278 def getTorrentData(self
, t
):
279 if self
.TorrentDataBuffer
.has_key(t
):
280 return self
.TorrentDataBuffer
[t
]
281 t
= os
.path
.join(self
.dir_datacache
,tohex(t
))
282 if not os
.path
.exists(t
):
286 r
= bdecode(f
.read())
293 self
.TorrentDataBuffer
[t
] = r
296 def writeTorrentData(self
, t
, data
):
297 self
.TorrentDataBuffer
[t
] = data
299 f
= open(os
.path
.join(self
.dir_datacache
,tohex(t
)),'wb')
300 f
.write(bencode(data
))
309 self
.deleteTorrentData(t
)
312 def deleteTorrentData(self
, t
):
314 os
.remove(os
.path
.join(self
.dir_datacache
,tohex(t
)))
318 def getPieceDir(self
, t
):
319 return os
.path
.join(self
.dir_piececache
,tohex(t
))
322 ###### EXPIRATION HANDLING ######
324 def deleteOldCacheData(self
, days
, still_active
= [], delete_torrents
= False):
327 exptime
= time() - (days
*24*3600)
331 for f
in os
.listdir(self
.dir_torrentcache
):
332 p
= os
.path
.join(self
.dir_torrentcache
,f
)
333 f
= os
.path
.basename(f
)
335 f
, garbage
= f
.split('.')
344 names
.setdefault(f
,[]).append(p
)
346 t
= os
.path
.getmtime(p
)
349 times
.setdefault(f
,[]).append(t
)
351 for f
in os
.listdir(self
.dir_datacache
):
352 p
= os
.path
.join(self
.dir_datacache
,f
)
354 f
= unhex(os
.path
.basename(f
))
358 names
.setdefault(f
,[]).append(p
)
360 t
= os
.path
.getmtime(p
)
363 times
.setdefault(f
,[]).append(t
)
365 for f
in os
.listdir(self
.dir_piececache
):
366 p
= os
.path
.join(self
.dir_piececache
,f
)
368 f
= unhex(os
.path
.basename(f
))
372 for f2
in os
.listdir(p
):
373 p2
= os
.path
.join(p
,f2
)
374 names
.setdefault(f
,[]).append(p2
)
376 t
= os
.path
.getmtime(p2
)
379 times
.setdefault(f
,[]).append(t
)
380 names
.setdefault(f
,[]).append(p
)
382 for k
,v
in times
.items():
383 if max(v
) < exptime
and not k
in still_active
:
394 def deleteOldTorrents(self
, days
, still_active
= []):
395 self
.deleteOldCacheData(days
, still_active
, True)
400 def getIconDir(self
):
401 return self
.dir_icons