Skip to content

Commit e5e0a28

Browse files
committed
Move tasks file to wger folder
This is really just needed so as to more easily make the packaged (pypi) version work. The 'invoke' command (which is mapped to 'wger' when packaged or installed via pip) needs a tasks.py file. Since the wger folder gets installed as a python package, it is easier if we just move that file there as well.
1 parent 2c63c61 commit e5e0a28

File tree

11 files changed

+205
-180
lines changed

11 files changed

+205
-180
lines changed

MANIFEST.in

+14-1
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,17 @@ include requirements.txt
77
recursive-include wger *.*
88
recursive-exclude wger *.pyc
99
recursive-exclude wger *.swp
10-
recursive-exclude wger *~
10+
recursive-exclude wger *~
11+
12+
# added by check_manifest.py
13+
include *.rst
14+
include *.txt
15+
recursive-include docs *.bat
16+
recursive-include docs *.py
17+
recursive-include docs *.rst
18+
recursive-include docs Makefile
19+
recursive-include extras *.README
20+
recursive-include extras *.conf
21+
recursive-include extras *.csv
22+
recursive-include extras *.py
23+
recursive-include extras *.txt

README.rst

+1-2
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,8 @@ state.
5353

5454
$ git clone https://github.com/rolandgeider/wger.git
5555
$ cd wger
56-
$ npm install bower
5756
$ pip install -r requirements.txt # or requirements_devel.txt to develop
58-
$ invoke bootstrap_wger
57+
$ invoke --root wger bootstrap_wger
5958

6059
3) Log in as: **admin**, password **admin**
6160

docs/development.rst

+1-2
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@ and populate it with data on the first run::
1414
$ git clone https://github.com/rolandgeider/wger.git
1515
$ cd wger
1616
$ pip install -r requirements_devel.txt
17-
$ npm install bower
18-
$ invoke bootstrap_wger
17+
$ invoke --root wger bootstrap_wger
1918

2019
That's it. You can log in with the default administator user:
2120

extras/docker/apache/Dockerfile

+4-2
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,12 @@ RUN npm install bower \
3030
&& . /home/wger/venv/bin/activate \
3131
&& pip install --upgrade pip \
3232
&& pip install -r requirements.txt \
33-
&& invoke create_settings \
33+
&& invoke --root wger create_settings \
3434
--settings-path /home/wger/src/settings.py \
3535
--database-path /home/wger/db/database.sqlite \
36-
&& invoke bootstrap_wger --settings-path /home/wger/src/settings.py --no-start-server
36+
&& invoke --root wger bootstrap_wger \
37+
--settings-path /home/wger/src/settings.py \
38+
--no-start-server
3739

3840

3941
# Change permissions of some files and folders so the apache process

extras/docker/development/Dockerfile

+7-5
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,18 @@ RUN apt-get install -y vim
2121
# Set up the application
2222
USER wger
2323
RUN git clone https://github.com/rolandgeider/wger.git /home/wger/src
24+
2425
WORKDIR /home/wger/src
2526
RUN virtualenv --python python3 /home/wger/venv
26-
RUN npm install bower \
27-
&& . /home/wger/venv/bin/activate \
27+
RUN . /home/wger/venv/bin/activate \
2828
&& pip install --upgrade pip \
2929
&& pip install -r requirements_devel.txt \
30-
&& invoke create_settings \
30+
&& invoke --root wgercreate_settings \
3131
--settings-path /home/wger/src/settings.py \
3232
--database-path /home/wger/db/database.sqlite \
33-
&& invoke bootstrap_wger --settings-path /home/wger/src/settings.py --no-start-server
33+
&& invoke --root wger bootstrap_wger \
34+
--settings-path /home/wger/src/settings.py \
35+
--no-start-server
3436

3537

36-
CMD ["/bin/bash"]
38+
CMD ["/bin/bash"]

manage.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
from django.core.management import execute_from_command_line
55

6-
from wger.utils.main import (
6+
from wger.tasks import (
77
setup_django_environment,
88
get_user_config_path
99
)

setup.cfg

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
[pep8]
2-
exclude = urls.py,*migrations*,*bower_components*
2+
exclude = urls.py,tasks.py,*migrations*,*bower_components*
33
max-line-length = 100
44
ignore = W503

wger/__main__.py

+8-2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#
1515
# You should have received a copy of the GNU Affero General Public License
1616

17+
import os
1718
import sys
1819
from invoke import run
1920

@@ -23,13 +24,18 @@
2324
command, which does all the work.
2425
'''
2526

27+
# Get the absolute path so we can pass it to invoke. This is only needed
28+
# for the packaged version.
29+
tasks_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'wger')
30+
invoke_cmd = 'invoke --root {} '.format(tasks_path)
31+
2632

2733
def main():
2834
args = sys.argv[1:]
2935
if len(args):
30-
run('invoke ' + ' '.join(args), pty=True)
36+
run(invoke_cmd + ' '.join(args), pty=True)
3137
else:
32-
run('invoke --list')
38+
run(invoke_cmd + '--list')
3339

3440

3541
if __name__ == '__main__':

wger/settings_global.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,12 @@
2525

2626
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
2727
import os
28-
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
28+
BASE_DIR = os.path.abspath(os.path.dirname(__file__))
2929
SITE_ROOT = os.path.realpath(os.path.dirname(__file__))
3030

31+
print(BASE_DIR)
32+
print(SITE_ROOT)
33+
print('===========================')
3134

3235
#
3336
# Application definition
@@ -314,6 +317,8 @@
314317
else:
315318
BOWER_PATH = os.path.join(BASE_DIR, 'node_modules', '.bin', 'bower')
316319

320+
print(BOWER_PATH)
321+
317322
#
318323
# Django Rest Framework
319324
#

tasks.py wger/tasks.py

+162-18
Original file line numberDiff line numberDiff line change
@@ -14,25 +14,35 @@
1414
#
1515
# You should have received a copy of the GNU Affero General Public License
1616

17-
import inspect
18-
import os
1917

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
2137

38+
import django
2239
from django.utils.crypto import get_random_string
2340
from django.core.management import (
2441
call_command,
2542
execute_from_command_line
2643
)
2744

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__)
3646

3747

3848
@task(help={'address': 'Address to bind to. Default: localhost',
@@ -98,6 +108,8 @@ def bootstrap_wger(settings_path=None,
98108
create_or_reset_admin(settings_path=settings_path)
99109

100110
# Download JS libraries with bower
111+
os.chdir(os.path.dirname(os.path.abspath(__file__)))
112+
run('npm install bower')
101113
call_command('bower', 'install')
102114

103115
# Start the webserver
@@ -131,11 +143,10 @@ def create_settings(settings_path=None, database_path=None, url=None, database_t
131143
url = 'http://localhost:8000'
132144

133145
# 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')
137147
with open(settings_template, 'r') as settings_file:
138148
settings_content = settings_file.read()
149+
139150
# The environment variable is set by travis during testing
140151
if database_type == 'postgresql':
141152
dbengine = 'postgresql_psycopg2'
@@ -195,8 +206,10 @@ def create_or_reset_admin(settings_path=None):
195206
except User.DoesNotExist:
196207
print("*** Created default admin user")
197208

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+
200213
path = os.path.join(current_dir, 'core', 'fixtures/')
201214
call_command("loaddata", path + "users.json")
202215

@@ -222,8 +235,10 @@ def load_fixtures(settings_path=None):
222235
# Find the path to the settings and setup the django environment
223236
setup_django_environment(settings_path)
224237

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__))
227242

228243
# Gym
229244
path = os.path.join(current_dir, 'gym', 'fixtures/')
@@ -274,3 +289,132 @@ def config_location():
274289
print('* settings: {0}'.format(get_user_config_path('wger', 'settings.py')))
275290
print('* media folder: {0}'.format(get_user_data_path('wger', 'media')))
276291
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

Comments
 (0)