14
14
#
15
15
# You should have received a copy of the GNU Affero General Public License
16
16
17
- import inspect
18
- import os
19
17
20
- from invoke import task
18
+ import sys
19
+ #
20
+ # This is an ugly and terrible hack, please don't do this!
21
+ #
22
+ # The reason we do this is that during django's setup later in this script, it
23
+ # tries to load the standard library's "mail" module which collides with our
24
+ # (perhaps unluckily named) app with the same name. Since this script is only
25
+ # used for installation and does not depend on anything from wger proper, it
26
+ # is kind of OK to change the system path.
27
+ sys .path = sys .path [1 :]
28
+
29
+ import time
30
+ import logging
31
+ import threading
32
+ import webbrowser
33
+ import os
34
+ import ctypes
35
+ import socket
36
+ from invoke import task , run
21
37
38
+ import django
22
39
from django .utils .crypto import get_random_string
23
40
from django .core .management import (
24
41
call_command ,
25
42
execute_from_command_line
26
43
)
27
44
28
- from wger .utils .main import (
29
- get_user_data_path ,
30
- get_user_config_path ,
31
- detect_listen_opts ,
32
- setup_django_environment ,
33
- database_exists ,
34
- start_browser
35
- )
45
+ logger = logging .getLogger (__name__ )
36
46
37
47
38
48
@task (help = {'address' : 'Address to bind to. Default: localhost' ,
@@ -98,6 +108,8 @@ def bootstrap_wger(settings_path=None,
98
108
create_or_reset_admin (settings_path = settings_path )
99
109
100
110
# Download JS libraries with bower
111
+ os .chdir (os .path .dirname (os .path .abspath (__file__ )))
112
+ run ('npm install bower' )
101
113
call_command ('bower' , 'install' )
102
114
103
115
# Start the webserver
@@ -131,11 +143,10 @@ def create_settings(settings_path=None, database_path=None, url=None, database_t
131
143
url = 'http://localhost:8000'
132
144
133
145
# Fill in the config file template
134
-
135
- # os.chdir(os.path.dirname(inspect.stack()[0][1]))
136
- settings_template = os .path .join (os .getcwd (), 'wger' , 'settings.tpl' )
146
+ settings_template = os .path .join (os .path .dirname (os .path .abspath (__file__ )), 'settings.tpl' )
137
147
with open (settings_template , 'r' ) as settings_file :
138
148
settings_content = settings_file .read ()
149
+
139
150
# The environment variable is set by travis during testing
140
151
if database_type == 'postgresql' :
141
152
dbengine = 'postgresql_psycopg2'
@@ -195,8 +206,10 @@ def create_or_reset_admin(settings_path=None):
195
206
except User .DoesNotExist :
196
207
print ("*** Created default admin user" )
197
208
198
- os .chdir (os .path .dirname (inspect .stack ()[0 ][1 ]))
199
- current_dir = os .path .join (os .getcwd (), 'wger' )
209
+ # os.chdir(os.path.dirname(inspect.stack()[0][1]))
210
+ # current_dir = os.path.join(os.getcwd(), 'wger')
211
+ current_dir = os .path .dirname (os .path .abspath (__file__ ))
212
+
200
213
path = os .path .join (current_dir , 'core' , 'fixtures/' )
201
214
call_command ("loaddata" , path + "users.json" )
202
215
@@ -222,8 +235,10 @@ def load_fixtures(settings_path=None):
222
235
# Find the path to the settings and setup the django environment
223
236
setup_django_environment (settings_path )
224
237
225
- os .chdir (os .path .dirname (inspect .stack ()[0 ][1 ]))
226
- current_dir = os .path .join (os .getcwd (), 'wger' )
238
+
239
+ # os.chdir(os.path.dirname(inspect.stack()[0][1]))
240
+ # current_dir = os.path.join(os.getcwd(), 'wger')
241
+ current_dir = os .path .dirname (os .path .abspath (__file__ ))
227
242
228
243
# Gym
229
244
path = os .path .join (current_dir , 'gym' , 'fixtures/' )
@@ -274,3 +289,132 @@ def config_location():
274
289
print ('* settings: {0}' .format (get_user_config_path ('wger' , 'settings.py' )))
275
290
print ('* media folder: {0}' .format (get_user_data_path ('wger' , 'media' )))
276
291
print ('* database path: {0}' .format (get_user_data_path ('wger' , 'database.sqlite' )))
292
+
293
+
294
+ #
295
+ #
296
+ # Helper functions
297
+ #
298
+ # Note: these functions were originally in wger/utils/main.py but were moved
299
+ # here because of different import problems (the packaged pip-installed
300
+ # packaged has a different sys path than the local one)
301
+ #
302
+
303
+
304
+ def get_user_data_path (* args ):
305
+ if sys .platform == "win32" :
306
+ return win32_get_app_data_path (* args )
307
+
308
+ data_home = os .environ .get (
309
+ 'XDG_DATA_HOME' , os .path .join (
310
+ os .path .expanduser ('~' ), '.local' , 'share' ))
311
+
312
+ return os .path .join (data_home , * args )
313
+
314
+
315
+ def get_user_config_path (* args ):
316
+ if sys .platform == "win32" :
317
+ return win32_get_app_data_path (* args )
318
+
319
+ config_home = os .environ .get (
320
+ 'XDG_CONFIG_HOME' , os .path .join (os .path .expanduser ('~' ), '.config' ))
321
+
322
+ return os .path .join (config_home , * args )
323
+
324
+
325
+ def win32_get_app_data_path (* args ):
326
+ shell32 = ctypes .WinDLL ("shell32.dll" )
327
+ SHGetFolderPath = shell32 .SHGetFolderPathW
328
+ SHGetFolderPath .argtypes = (
329
+ ctypes .c_void_p , ctypes .c_int , ctypes .c_void_p , ctypes .c_uint32 ,
330
+ ctypes .c_wchar_p )
331
+ SHGetFolderPath .restype = ctypes .c_uint32
332
+
333
+ CSIDL_LOCAL_APPDATA = 0x001c
334
+ MAX_PATH = 260
335
+
336
+ buf = ctypes .create_unicode_buffer (MAX_PATH )
337
+ res = SHGetFolderPath (0 , CSIDL_LOCAL_APPDATA , 0 , 0 , buf )
338
+ if res != 0 :
339
+ raise Exception ("Could not deterime APPDATA path" )
340
+
341
+ return os .path .join (buf .value , * args )
342
+
343
+
344
+ def detect_listen_opts (address , port ):
345
+ if address is None :
346
+ try :
347
+ address = socket .gethostbyname (socket .gethostname ())
348
+ except socket .error :
349
+ address = "127.0.0.1"
350
+
351
+ if port is None :
352
+ # test if we can use port 80
353
+ s = socket .socket ()
354
+ port = 80
355
+ try :
356
+ s .bind ((address , port ))
357
+ s .listen (- 1 )
358
+ except socket .error :
359
+ port = 8000
360
+ finally :
361
+ s .close ()
362
+
363
+ return address , port
364
+
365
+
366
+ def setup_django_environment (settings_path ):
367
+ '''
368
+ Setup the django environment
369
+ '''
370
+
371
+ # Use default settings if the user didn't specify something else
372
+ if settings_path is None :
373
+ settings_path = get_user_config_path ('wger' , 'settings.py' )
374
+ print ('*** No settings given, using {0}' .format (settings_path ))
375
+
376
+ # Find out file path and fine name of settings and setup django
377
+ settings_file = os .path .basename (settings_path )
378
+ settings_module_name = "" .join (settings_file .split ('.' )[:- 1 ])
379
+ if '.' in settings_module_name :
380
+ print ("'.' is not an allowed character in the settings-file" )
381
+ sys .exit (1 )
382
+ settings_module_dir = os .path .dirname (settings_path )
383
+ sys .path .append (settings_module_dir )
384
+ os .environ [django .conf .ENVIRONMENT_VARIABLE ] = '%s' % settings_module_name
385
+ django .setup ()
386
+
387
+
388
+ def database_exists ():
389
+ """Detect if the database exists"""
390
+
391
+ # can't be imported in global scope as they already require
392
+ # the settings module during import
393
+ from django .db import DatabaseError
394
+ from django .core .exceptions import ImproperlyConfigured
395
+ from wger .manager .models import User
396
+
397
+ try :
398
+ # TODO: Use another model, the User could be deactivated
399
+ User .objects .count ()
400
+ except DatabaseError :
401
+ return False
402
+ except ImproperlyConfigured :
403
+ print ("Your settings file seems broken" )
404
+ sys .exit (0 )
405
+ else :
406
+ return True
407
+
408
+
409
+ def start_browser (url ):
410
+ '''
411
+ Start the web browser with the given URL
412
+ '''
413
+ browser = webbrowser .get ()
414
+
415
+ def function ():
416
+ time .sleep (1 )
417
+ browser .open (url )
418
+
419
+ thread = threading .Thread (target = function )
420
+ thread .start ()
0 commit comments