-
Notifications
You must be signed in to change notification settings - Fork 577
/
paths.py
129 lines (114 loc) · 4.15 KB
/
paths.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
"""
Path related functions
"""
import logging
import os
import re
import sys
from datetime import datetime
from shutil import move
logger = logging.getLogger('default')
# When using py2exe or py2app, the variable frozen is added to the sys
# namespace. This can be used to setup a different code path for
# binary distributions vs source distributions.
frozen = getattr(sys, 'frozen', None)
def lookupExeFolder():
"""Returns executable folder path"""
if frozen:
exeFolder = (
# targetdir/Bitmessage.app/Contents/MacOS/Bitmessage
os.path.dirname(sys.executable).split(os.path.sep)[0]
if frozen == "macosx_app" else os.path.dirname(sys.executable))
elif os.getenv('APPIMAGE'):
exeFolder = os.path.dirname(os.getenv('APPIMAGE'))
elif __file__:
exeFolder = os.path.dirname(__file__)
else:
return ''
return exeFolder + os.path.sep
def lookupAppdataFolder():
"""Returns path of the folder where application data is stored"""
APPNAME = "PyBitmessage"
dataFolder = os.environ.get('BITMESSAGE_HOME')
if dataFolder:
if dataFolder[-1] not in (os.path.sep, os.path.altsep):
dataFolder += os.path.sep
elif sys.platform == 'darwin':
try:
dataFolder = os.path.join(
os.environ['HOME'],
'Library/Application Support/', APPNAME
) + '/'
except KeyError:
sys.exit(
'Could not find home folder, please report this message'
' and your OS X version to the BitMessage Github.')
elif sys.platform.startswith('win'):
dataFolder = os.path.join(os.environ['APPDATA'], APPNAME) + os.path.sep
else:
try:
dataFolder = os.path.join(os.environ['XDG_CONFIG_HOME'], APPNAME)
except KeyError:
dataFolder = os.path.join(os.environ['HOME'], '.config', APPNAME)
# Migrate existing data to the proper location
# if this is an existing install
try:
move(os.path.join(os.environ['HOME'], '.%s' % APPNAME), dataFolder)
logger.info('Moving data folder to %s', dataFolder)
except IOError:
# Old directory may not exist.
pass
dataFolder = dataFolder + os.path.sep
return dataFolder
def codePath():
"""Returns path to the program sources"""
if not frozen:
return os.path.dirname(__file__)
return (
os.environ.get('RESOURCEPATH')
# pylint: disable=protected-access
if frozen == "macosx_app" else sys._MEIPASS)
def tail(f, lines=20):
"""Returns last lines in the f file object"""
total_lines_wanted = lines
BLOCK_SIZE = 1024
f.seek(0, 2)
block_end_byte = f.tell()
lines_to_go = total_lines_wanted
block_number = -1
# blocks of size BLOCK_SIZE, in reverse order starting
# from the end of the file
blocks = []
while lines_to_go > 0 and block_end_byte > 0:
if block_end_byte - BLOCK_SIZE > 0:
# read the last block we haven't yet read
f.seek(block_number * BLOCK_SIZE, 2)
blocks.append(f.read(BLOCK_SIZE))
else:
# file too small, start from begining
f.seek(0, 0)
# only read what was not read
blocks.append(f.read(block_end_byte))
lines_found = blocks[-1].count('\n')
lines_to_go -= lines_found
block_end_byte -= BLOCK_SIZE
block_number -= 1
all_read_text = ''.join(reversed(blocks))
return '\n'.join(all_read_text.splitlines()[-total_lines_wanted:])
def lastCommit():
"""
Returns last commit information as dict with 'commit' and 'time' keys
"""
githeadfile = os.path.join(codePath(), '..', '.git', 'logs', 'HEAD')
result = {}
if os.path.isfile(githeadfile):
try:
with open(githeadfile, 'rt') as githead:
line = tail(githead, 1)
result['commit'] = line.split()[1]
result['time'] = datetime.fromtimestamp(
float(re.search(r'>\s*(.*?)\s', line).group(1))
)
except (IOError, AttributeError, TypeError):
pass
return result