##// END OF EJS Templates
fixes #51 deleting a repo didn't delete it's dependent db entries....
marcink -
r667:56a8434a beta
parent child Browse files
Show More
@@ -1,173 +1,174 b''
1 ################################################################################
1 ################################################################################
2 ################################################################################
2 ################################################################################
3 # rhodecode - Pylons environment configuration #
3 # rhodecode - Pylons environment configuration #
4 # #
4 # #
5 # The %(here)s variable will be replaced with the parent directory of this file#
5 # The %(here)s variable will be replaced with the parent directory of this file#
6 ################################################################################
6 ################################################################################
7
7
8 [DEFAULT]
8 [DEFAULT]
9 debug = true
9 debug = true
10 ################################################################################
10 ################################################################################
11 ## Uncomment and replace with the address which should receive ##
11 ## Uncomment and replace with the address which should receive ##
12 ## any error reports after application crash ##
12 ## any error reports after application crash ##
13 ## Additionally those settings will be used by rhodecode mailing system ##
13 ## Additionally those settings will be used by rhodecode mailing system ##
14 ################################################################################
14 ################################################################################
15 #email_to = admin@localhost
15 #email_to = admin@localhost
16 #error_email_from = paste_error@localhost
16 #error_email_from = paste_error@localhost
17 #app_email_from = rhodecode-noreply@localhost
17 #app_email_from = rhodecode-noreply@localhost
18 #error_message =
18 #error_message =
19
19
20 #smtp_server = mail.server.com
20 #smtp_server = mail.server.com
21 #smtp_username =
21 #smtp_username =
22 #smtp_password =
22 #smtp_password =
23 #smtp_port =
23 #smtp_port =
24 #smtp_use_tls =
24 #smtp_use_tls =
25
25
26 [server:main]
26 [server:main]
27 ##nr of threads to spawn
27 ##nr of threads to spawn
28 threadpool_workers = 5
28 threadpool_workers = 5
29
29
30 ##max request before
30 ##max request before
31 threadpool_max_requests = 6
31 threadpool_max_requests = 6
32
32
33 ##option to use threads of process
33 ##option to use threads of process
34 use_threadpool = false
34 use_threadpool = false
35
35
36 use = egg:Paste#http
36 use = egg:Paste#http
37 host = 127.0.0.1
37 host = 127.0.0.1
38 port = 5000
38 port = 5000
39
39
40 [app:main]
40 [app:main]
41 use = egg:rhodecode
41 use = egg:rhodecode
42 full_stack = true
42 full_stack = true
43 static_files = true
43 static_files = true
44 lang=en
44 lang=en
45 cache_dir = %(here)s/data
45 cache_dir = %(here)s/data
46
46
47 ####################################
47 ####################################
48 ### BEAKER CACHE ####
48 ### BEAKER CACHE ####
49 ####################################
49 ####################################
50 beaker.cache.data_dir=/%(here)s/data/cache/data
50 beaker.cache.data_dir=/%(here)s/data/cache/data
51 beaker.cache.lock_dir=/%(here)s/data/cache/lock
51 beaker.cache.lock_dir=/%(here)s/data/cache/lock
52 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
52 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
53
53
54 beaker.cache.super_short_term.type=memory
54 beaker.cache.super_short_term.type=memory
55 beaker.cache.super_short_term.expire=10
55 beaker.cache.super_short_term.expire=10
56
56
57 beaker.cache.short_term.type=memory
57 beaker.cache.short_term.type=memory
58 beaker.cache.short_term.expire=60
58 beaker.cache.short_term.expire=60
59
59
60 beaker.cache.long_term.type=memory
60 beaker.cache.long_term.type=memory
61 beaker.cache.long_term.expire=36000
61 beaker.cache.long_term.expire=36000
62
62
63
63
64 beaker.cache.sql_cache_short.type=memory
64 beaker.cache.sql_cache_short.type=memory
65 beaker.cache.sql_cache_short.expire=5
65 beaker.cache.sql_cache_short.expire=5
66
66
67 beaker.cache.sql_cache_med.type=memory
67 beaker.cache.sql_cache_med.type=memory
68 beaker.cache.sql_cache_med.expire=360
68 beaker.cache.sql_cache_med.expire=360
69
69
70 beaker.cache.sql_cache_long.type=file
70 beaker.cache.sql_cache_long.type=file
71 beaker.cache.sql_cache_long.expire=3600
71 beaker.cache.sql_cache_long.expire=3600
72
72
73 ####################################
73 ####################################
74 ### BEAKER SESSION ####
74 ### BEAKER SESSION ####
75 ####################################
75 ####################################
76 ## Type of storage used for the session, current types are
76 ## Type of storage used for the session, current types are
77 ## "dbm", "file", "memcached", "database", and "memory".
77 ## "dbm", "file", "memcached", "database", and "memory".
78 ## The storage uses the Container API
78 ## The storage uses the Container API
79 ##that is also used by the cache system.
79 ##that is also used by the cache system.
80 beaker.session.type = file
80 beaker.session.type = file
81
81
82 beaker.session.key = rhodecode
82 beaker.session.key = rhodecode
83 beaker.session.secret = g654dcno0-9873jhgfreyu
83 beaker.session.secret = g654dcno0-9873jhgfreyu
84 beaker.session.timeout = 36000
84 beaker.session.timeout = 36000
85
85
86 ##auto save the session to not to use .save()
86 ##auto save the session to not to use .save()
87 beaker.session.auto = False
87 beaker.session.auto = False
88
88
89 ##true exire at browser close
89 ##true exire at browser close
90 #beaker.session.cookie_expires = 3600
90 #beaker.session.cookie_expires = 3600
91
91
92
92
93 ################################################################################
93 ################################################################################
94 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
94 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
95 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
95 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
96 ## execute malicious code after an exception is raised. ##
96 ## execute malicious code after an exception is raised. ##
97 ################################################################################
97 ################################################################################
98 #set debug = false
98 #set debug = false
99
99
100 ##################################
100 ##################################
101 ### LOGVIEW CONFIG ###
101 ### LOGVIEW CONFIG ###
102 ##################################
102 ##################################
103 logview.sqlalchemy = #faa
103 logview.sqlalchemy = #faa
104 logview.pylons.templating = #bfb
104 logview.pylons.templating = #bfb
105 logview.pylons.util = #eee
105 logview.pylons.util = #eee
106
106
107 #########################################################
107 #########################################################
108 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
108 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
109 #########################################################
109 #########################################################
110 sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db
110 sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db
111 #sqlalchemy.db1.echo = False
111 #sqlalchemy.db1.echo = False
112 #sqlalchemy.db1.pool_recycle = 3600
112 #sqlalchemy.db1.pool_recycle = 3600
113 sqlalchemy.convert_unicode = true
113 sqlalchemy.convert_unicode = true
114
114
115 ################################
115 ################################
116 ### LOGGING CONFIGURATION ####
116 ### LOGGING CONFIGURATION ####
117 ################################
117 ################################
118 [loggers]
118 [loggers]
119 keys = root, routes, rhodecode, sqlalchemy
119 keys = root, routes, rhodecode, sqlalchemy
120
120
121 [handlers]
121 [handlers]
122 keys = console
122 keys = console
123
123
124 [formatters]
124 [formatters]
125 keys = generic,color_formatter
125 keys = generic,color_formatter
126
126
127 #############
127 #############
128 ## LOGGERS ##
128 ## LOGGERS ##
129 #############
129 #############
130 [logger_root]
130 [logger_root]
131 level = NOTSET
131 level = NOTSET
132 handlers = console
132 handlers = console
133
133
134 [logger_routes]
134 [logger_routes]
135 level = DEBUG
135 level = DEBUG
136 handlers = console
136 handlers = console
137 qualname = routes.middleware
137 qualname = routes.middleware
138 # "level = DEBUG" logs the route matched and routing variables.
138 # "level = DEBUG" logs the route matched and routing variables.
139 propagate = 0
139
140
140 [logger_rhodecode]
141 [logger_rhodecode]
141 level = DEBUG
142 level = DEBUG
142 handlers = console
143 handlers = console
143 qualname = rhodecode
144 qualname = rhodecode
144 propagate = 0
145 propagate = 0
145
146
146 [logger_sqlalchemy]
147 [logger_sqlalchemy]
147 level = ERROR
148 level = ERROR
148 handlers = console
149 handlers = console
149 qualname = sqlalchemy.engine
150 qualname = sqlalchemy.engine
150 propagate = 0
151 propagate = 0
151
152
152 ##############
153 ##############
153 ## HANDLERS ##
154 ## HANDLERS ##
154 ##############
155 ##############
155
156
156 [handler_console]
157 [handler_console]
157 class = StreamHandler
158 class = StreamHandler
158 args = (sys.stderr,)
159 args = (sys.stderr,)
159 level = NOTSET
160 level = NOTSET
160 formatter = color_formatter
161 formatter = color_formatter
161
162
162 ################
163 ################
163 ## FORMATTERS ##
164 ## FORMATTERS ##
164 ################
165 ################
165
166
166 [formatter_generic]
167 [formatter_generic]
167 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
168 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
168 datefmt = %Y-%m-%d %H:%M:%S
169 datefmt = %Y-%m-%d %H:%M:%S
169
170
170 [formatter_color_formatter]
171 [formatter_color_formatter]
171 class=rhodecode.lib.colored_formatter.ColorFormatter
172 class=rhodecode.lib.colored_formatter.ColorFormatter
172 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
173 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
173 datefmt = %Y-%m-%d %H:%M:%S No newline at end of file
174 datefmt = %Y-%m-%d %H:%M:%S
@@ -1,173 +1,174 b''
1 ################################################################################
1 ################################################################################
2 ################################################################################
2 ################################################################################
3 # rhodecode - Pylons environment configuration #
3 # rhodecode - Pylons environment configuration #
4 # #
4 # #
5 # The %(here)s variable will be replaced with the parent directory of this file#
5 # The %(here)s variable will be replaced with the parent directory of this file#
6 ################################################################################
6 ################################################################################
7
7
8 [DEFAULT]
8 [DEFAULT]
9 debug = true
9 debug = true
10 ################################################################################
10 ################################################################################
11 ## Uncomment and replace with the address which should receive ##
11 ## Uncomment and replace with the address which should receive ##
12 ## any error reports after application crash ##
12 ## any error reports after application crash ##
13 ## Additionally those settings will be used by rhodecode mailing system ##
13 ## Additionally those settings will be used by rhodecode mailing system ##
14 ################################################################################
14 ################################################################################
15 #email_to = admin@localhost
15 #email_to = admin@localhost
16 #error_email_from = paste_error@localhost
16 #error_email_from = paste_error@localhost
17 #app_email_from = rhodecode-noreply@localhost
17 #app_email_from = rhodecode-noreply@localhost
18 #error_message =
18 #error_message =
19
19
20 #smtp_server = mail.server.com
20 #smtp_server = mail.server.com
21 #smtp_username =
21 #smtp_username =
22 #smtp_password =
22 #smtp_password =
23 #smtp_port =
23 #smtp_port =
24 #smtp_use_tls = false
24 #smtp_use_tls = false
25
25
26 [server:main]
26 [server:main]
27 ##nr of threads to spawn
27 ##nr of threads to spawn
28 threadpool_workers = 5
28 threadpool_workers = 5
29
29
30 ##max request before thread respawn
30 ##max request before thread respawn
31 threadpool_max_requests = 2
31 threadpool_max_requests = 2
32
32
33 ##option to use threads of process
33 ##option to use threads of process
34 use_threadpool = true
34 use_threadpool = true
35
35
36 use = egg:Paste#http
36 use = egg:Paste#http
37 host = 127.0.0.1
37 host = 127.0.0.1
38 port = 8001
38 port = 8001
39
39
40 [app:main]
40 [app:main]
41 use = egg:rhodecode
41 use = egg:rhodecode
42 full_stack = true
42 full_stack = true
43 static_files = false
43 static_files = false
44 lang=en
44 lang=en
45 cache_dir = %(here)s/data
45 cache_dir = %(here)s/data
46
46
47 ####################################
47 ####################################
48 ### BEAKER CACHE ####
48 ### BEAKER CACHE ####
49 ####################################
49 ####################################
50 beaker.cache.data_dir=/%(here)s/data/cache/data
50 beaker.cache.data_dir=/%(here)s/data/cache/data
51 beaker.cache.lock_dir=/%(here)s/data/cache/lock
51 beaker.cache.lock_dir=/%(here)s/data/cache/lock
52 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
52 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
53
53
54 beaker.cache.super_short_term.type=memory
54 beaker.cache.super_short_term.type=memory
55 beaker.cache.super_short_term.expire=10
55 beaker.cache.super_short_term.expire=10
56
56
57 beaker.cache.short_term.type=memory
57 beaker.cache.short_term.type=memory
58 beaker.cache.short_term.expire=60
58 beaker.cache.short_term.expire=60
59
59
60 beaker.cache.long_term.type=memory
60 beaker.cache.long_term.type=memory
61 beaker.cache.long_term.expire=36000
61 beaker.cache.long_term.expire=36000
62
62
63
63
64 beaker.cache.sql_cache_short.type=memory
64 beaker.cache.sql_cache_short.type=memory
65 beaker.cache.sql_cache_short.expire=5
65 beaker.cache.sql_cache_short.expire=5
66
66
67 beaker.cache.sql_cache_med.type=memory
67 beaker.cache.sql_cache_med.type=memory
68 beaker.cache.sql_cache_med.expire=360
68 beaker.cache.sql_cache_med.expire=360
69
69
70 beaker.cache.sql_cache_long.type=file
70 beaker.cache.sql_cache_long.type=file
71 beaker.cache.sql_cache_long.expire=3600
71 beaker.cache.sql_cache_long.expire=3600
72
72
73 ####################################
73 ####################################
74 ### BEAKER SESSION ####
74 ### BEAKER SESSION ####
75 ####################################
75 ####################################
76 ## Type of storage used for the session, current types are
76 ## Type of storage used for the session, current types are
77 ## dbm, file, memcached, database, and memory.
77 ## dbm, file, memcached, database, and memory.
78 ## The storage uses the Container API
78 ## The storage uses the Container API
79 ##that is also used by the cache system.
79 ##that is also used by the cache system.
80 beaker.session.type = file
80 beaker.session.type = file
81
81
82 beaker.session.key = rhodecode
82 beaker.session.key = rhodecode
83 beaker.session.secret = g654dcno0-9873jhgfreyu
83 beaker.session.secret = g654dcno0-9873jhgfreyu
84 beaker.session.timeout = 36000
84 beaker.session.timeout = 36000
85
85
86 ##auto save the session to not to use .save()
86 ##auto save the session to not to use .save()
87 beaker.session.auto = False
87 beaker.session.auto = False
88
88
89 ##true exire at browser close
89 ##true exire at browser close
90 #beaker.session.cookie_expires = 3600
90 #beaker.session.cookie_expires = 3600
91
91
92
92
93 ################################################################################
93 ################################################################################
94 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
94 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
95 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
95 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
96 ## execute malicious code after an exception is raised. ##
96 ## execute malicious code after an exception is raised. ##
97 ################################################################################
97 ################################################################################
98 set debug = false
98 set debug = false
99
99
100 ##################################
100 ##################################
101 ### LOGVIEW CONFIG ###
101 ### LOGVIEW CONFIG ###
102 ##################################
102 ##################################
103 logview.sqlalchemy = #faa
103 logview.sqlalchemy = #faa
104 logview.pylons.templating = #bfb
104 logview.pylons.templating = #bfb
105 logview.pylons.util = #eee
105 logview.pylons.util = #eee
106
106
107 #########################################################
107 #########################################################
108 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
108 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
109 #########################################################
109 #########################################################
110 sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db
110 sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db
111 #sqlalchemy.db1.echo = False
111 #sqlalchemy.db1.echo = False
112 #sqlalchemy.db1.pool_recycle = 3600
112 #sqlalchemy.db1.pool_recycle = 3600
113 sqlalchemy.convert_unicode = true
113 sqlalchemy.convert_unicode = true
114
114
115 ################################
115 ################################
116 ### LOGGING CONFIGURATION ####
116 ### LOGGING CONFIGURATION ####
117 ################################
117 ################################
118 [loggers]
118 [loggers]
119 keys = root, routes, rhodecode, sqlalchemy
119 keys = root, routes, rhodecode, sqlalchemy
120
120
121 [handlers]
121 [handlers]
122 keys = console
122 keys = console
123
123
124 [formatters]
124 [formatters]
125 keys = generic,color_formatter
125 keys = generic,color_formatter
126
126
127 #############
127 #############
128 ## LOGGERS ##
128 ## LOGGERS ##
129 #############
129 #############
130 [logger_root]
130 [logger_root]
131 level = INFO
131 level = INFO
132 handlers = console
132 handlers = console
133
133
134 [logger_routes]
134 [logger_routes]
135 level = INFO
135 level = INFO
136 handlers = console
136 handlers = console
137 qualname = routes.middleware
137 qualname = routes.middleware
138 # "level = DEBUG" logs the route matched and routing variables.
138 # "level = DEBUG" logs the route matched and routing variables.
139 propagate = 0
139
140
140 [logger_rhodecode]
141 [logger_rhodecode]
141 level = DEBUG
142 level = DEBUG
142 handlers = console
143 handlers = console
143 qualname = rhodecode
144 qualname = rhodecode
144 propagate = 0
145 propagate = 0
145
146
146 [logger_sqlalchemy]
147 [logger_sqlalchemy]
147 level = ERROR
148 level = ERROR
148 handlers = console
149 handlers = console
149 qualname = sqlalchemy.engine
150 qualname = sqlalchemy.engine
150 propagate = 0
151 propagate = 0
151
152
152 ##############
153 ##############
153 ## HANDLERS ##
154 ## HANDLERS ##
154 ##############
155 ##############
155
156
156 [handler_console]
157 [handler_console]
157 class = StreamHandler
158 class = StreamHandler
158 args = (sys.stderr,)
159 args = (sys.stderr,)
159 level = NOTSET
160 level = NOTSET
160 formatter = color_formatter
161 formatter = color_formatter
161
162
162 ################
163 ################
163 ## FORMATTERS ##
164 ## FORMATTERS ##
164 ################
165 ################
165
166
166 [formatter_generic]
167 [formatter_generic]
167 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
168 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
168 datefmt = %Y-%m-%d %H:%M:%S
169 datefmt = %Y-%m-%d %H:%M:%S
169
170
170 [formatter_color_formatter]
171 [formatter_color_formatter]
171 class=rhodecode.lib.colored_formatter.ColorFormatter
172 class=rhodecode.lib.colored_formatter.ColorFormatter
172 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
173 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
173 datefmt = %Y-%m-%d %H:%M:%S No newline at end of file
174 datefmt = %Y-%m-%d %H:%M:%S
@@ -1,173 +1,174 b''
1 ################################################################################
1 ################################################################################
2 ################################################################################
2 ################################################################################
3 # rhodecode - Pylons environment configuration #
3 # rhodecode - Pylons environment configuration #
4 # #
4 # #
5 # The %(here)s variable will be replaced with the parent directory of this file#
5 # The %(here)s variable will be replaced with the parent directory of this file#
6 ################################################################################
6 ################################################################################
7
7
8 [DEFAULT]
8 [DEFAULT]
9 debug = true
9 debug = true
10 ################################################################################
10 ################################################################################
11 ## Uncomment and replace with the address which should receive ##
11 ## Uncomment and replace with the address which should receive ##
12 ## any error reports after application crash ##
12 ## any error reports after application crash ##
13 ## Additionally those settings will be used by rhodecode mailing system ##
13 ## Additionally those settings will be used by rhodecode mailing system ##
14 ################################################################################
14 ################################################################################
15 #email_to = admin@localhost
15 #email_to = admin@localhost
16 #error_email_from = paste_error@localhost
16 #error_email_from = paste_error@localhost
17 #app_email_from = rhodecode-noreply@localhost
17 #app_email_from = rhodecode-noreply@localhost
18 #error_message =
18 #error_message =
19
19
20 #smtp_server = mail.server.com
20 #smtp_server = mail.server.com
21 #smtp_username =
21 #smtp_username =
22 #smtp_password =
22 #smtp_password =
23 #smtp_port =
23 #smtp_port =
24 #smtp_use_tls = false
24 #smtp_use_tls = false
25
25
26 [server:main]
26 [server:main]
27 ##nr of threads to spawn
27 ##nr of threads to spawn
28 threadpool_workers = 5
28 threadpool_workers = 5
29
29
30 ##max request before thread respawn
30 ##max request before thread respawn
31 threadpool_max_requests = 10
31 threadpool_max_requests = 10
32
32
33 ##option to use threads of process
33 ##option to use threads of process
34 use_threadpool = true
34 use_threadpool = true
35
35
36 use = egg:Paste#http
36 use = egg:Paste#http
37 host = 127.0.0.1
37 host = 127.0.0.1
38 port = 5000
38 port = 5000
39
39
40 [app:main]
40 [app:main]
41 use = egg:rhodecode
41 use = egg:rhodecode
42 full_stack = true
42 full_stack = true
43 static_files = true
43 static_files = true
44 lang=en
44 lang=en
45 cache_dir = %(here)s/data
45 cache_dir = %(here)s/data
46 app_instance_uuid = ${app_instance_uuid}
46 app_instance_uuid = ${app_instance_uuid}
47
47
48 ####################################
48 ####################################
49 ### BEAKER CACHE ####
49 ### BEAKER CACHE ####
50 ####################################
50 ####################################
51 beaker.cache.data_dir=/%(here)s/data/cache/data
51 beaker.cache.data_dir=/%(here)s/data/cache/data
52 beaker.cache.lock_dir=/%(here)s/data/cache/lock
52 beaker.cache.lock_dir=/%(here)s/data/cache/lock
53 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
53 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
54
54
55 beaker.cache.super_short_term.type=memory
55 beaker.cache.super_short_term.type=memory
56 beaker.cache.super_short_term.expire=10
56 beaker.cache.super_short_term.expire=10
57
57
58 beaker.cache.short_term.type=memory
58 beaker.cache.short_term.type=memory
59 beaker.cache.short_term.expire=60
59 beaker.cache.short_term.expire=60
60
60
61 beaker.cache.long_term.type=memory
61 beaker.cache.long_term.type=memory
62 beaker.cache.long_term.expire=36000
62 beaker.cache.long_term.expire=36000
63
63
64 beaker.cache.sql_cache_short.type=memory
64 beaker.cache.sql_cache_short.type=memory
65 beaker.cache.sql_cache_short.expire=5
65 beaker.cache.sql_cache_short.expire=5
66
66
67 beaker.cache.sql_cache_med.type=memory
67 beaker.cache.sql_cache_med.type=memory
68 beaker.cache.sql_cache_med.expire=360
68 beaker.cache.sql_cache_med.expire=360
69
69
70 beaker.cache.sql_cache_long.type=file
70 beaker.cache.sql_cache_long.type=file
71 beaker.cache.sql_cache_long.expire=3600
71 beaker.cache.sql_cache_long.expire=3600
72
72
73 ####################################
73 ####################################
74 ### BEAKER SESSION ####
74 ### BEAKER SESSION ####
75 ####################################
75 ####################################
76 ## Type of storage used for the session, current types are
76 ## Type of storage used for the session, current types are
77 ## dbm, file, memcached, database, and memory.
77 ## dbm, file, memcached, database, and memory.
78 ## The storage uses the Container API
78 ## The storage uses the Container API
79 ##that is also used by the cache system.
79 ##that is also used by the cache system.
80 beaker.session.type = file
80 beaker.session.type = file
81
81
82 beaker.session.key = rhodecode
82 beaker.session.key = rhodecode
83 beaker.session.secret = ${app_instance_secret}
83 beaker.session.secret = ${app_instance_secret}
84 beaker.session.timeout = 36000
84 beaker.session.timeout = 36000
85
85
86 ##auto save the session to not to use .save()
86 ##auto save the session to not to use .save()
87 beaker.session.auto = False
87 beaker.session.auto = False
88
88
89 ##true exire at browser close
89 ##true exire at browser close
90 #beaker.session.cookie_expires = 3600
90 #beaker.session.cookie_expires = 3600
91
91
92
92
93 ################################################################################
93 ################################################################################
94 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
94 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
95 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
95 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
96 ## execute malicious code after an exception is raised. ##
96 ## execute malicious code after an exception is raised. ##
97 ################################################################################
97 ################################################################################
98 set debug = false
98 set debug = false
99
99
100 ##################################
100 ##################################
101 ### LOGVIEW CONFIG ###
101 ### LOGVIEW CONFIG ###
102 ##################################
102 ##################################
103 logview.sqlalchemy = #faa
103 logview.sqlalchemy = #faa
104 logview.pylons.templating = #bfb
104 logview.pylons.templating = #bfb
105 logview.pylons.util = #eee
105 logview.pylons.util = #eee
106
106
107 #########################################################
107 #########################################################
108 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
108 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
109 #########################################################
109 #########################################################
110 sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db
110 sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db
111 #sqlalchemy.db1.echo = False
111 #sqlalchemy.db1.echo = False
112 #sqlalchemy.db1.pool_recycle = 3600
112 #sqlalchemy.db1.pool_recycle = 3600
113 sqlalchemy.convert_unicode = true
113 sqlalchemy.convert_unicode = true
114
114
115 ################################
115 ################################
116 ### LOGGING CONFIGURATION ####
116 ### LOGGING CONFIGURATION ####
117 ################################
117 ################################
118 [loggers]
118 [loggers]
119 keys = root, routes, rhodecode, sqlalchemy
119 keys = root, routes, rhodecode, sqlalchemy
120
120
121 [handlers]
121 [handlers]
122 keys = console
122 keys = console
123
123
124 [formatters]
124 [formatters]
125 keys = generic,color_formatter
125 keys = generic,color_formatter
126
126
127 #############
127 #############
128 ## LOGGERS ##
128 ## LOGGERS ##
129 #############
129 #############
130 [logger_root]
130 [logger_root]
131 level = INFO
131 level = INFO
132 handlers = console
132 handlers = console
133
133
134 [logger_routes]
134 [logger_routes]
135 level = INFO
135 level = INFO
136 handlers = console
136 handlers = console
137 qualname = routes.middleware
137 qualname = routes.middleware
138 # "level = DEBUG" logs the route matched and routing variables.
138 # "level = DEBUG" logs the route matched and routing variables.
139 propagate = 0
139
140
140 [logger_rhodecode]
141 [logger_rhodecode]
141 level = DEBUG
142 level = DEBUG
142 handlers = console
143 handlers = console
143 qualname = rhodecode
144 qualname = rhodecode
144 propagate = 0
145 propagate = 0
145
146
146 [logger_sqlalchemy]
147 [logger_sqlalchemy]
147 level = ERROR
148 level = ERROR
148 handlers = console
149 handlers = console
149 qualname = sqlalchemy.engine
150 qualname = sqlalchemy.engine
150 propagate = 0
151 propagate = 0
151
152
152 ##############
153 ##############
153 ## HANDLERS ##
154 ## HANDLERS ##
154 ##############
155 ##############
155
156
156 [handler_console]
157 [handler_console]
157 class = StreamHandler
158 class = StreamHandler
158 args = (sys.stderr,)
159 args = (sys.stderr,)
159 level = NOTSET
160 level = NOTSET
160 formatter = color_formatter
161 formatter = color_formatter
161
162
162 ################
163 ################
163 ## FORMATTERS ##
164 ## FORMATTERS ##
164 ################
165 ################
165
166
166 [formatter_generic]
167 [formatter_generic]
167 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
168 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
168 datefmt = %Y-%m-%d %H:%M:%S
169 datefmt = %Y-%m-%d %H:%M:%S
169
170
170 [formatter_color_formatter]
171 [formatter_color_formatter]
171 class=rhodecode.lib.colored_formatter.ColorFormatter
172 class=rhodecode.lib.colored_formatter.ColorFormatter
172 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
173 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
173 datefmt = %Y-%m-%d %H:%M:%S No newline at end of file
174 datefmt = %Y-%m-%d %H:%M:%S
@@ -1,138 +1,140 b''
1 from rhodecode.model.meta import Base
1 from rhodecode.model.meta import Base
2 from sqlalchemy import *
2 from sqlalchemy import *
3 from sqlalchemy.orm import relation, backref
3 from sqlalchemy.orm import relation, backref
4 from sqlalchemy.orm.session import Session
4 from sqlalchemy.orm.session import Session
5 from vcs.utils.lazy import LazyProperty
5 from vcs.utils.lazy import LazyProperty
6 import logging
6 import logging
7 log = logging.getLogger(__name__)
7 log = logging.getLogger(__name__)
8
8
9 class RhodeCodeSettings(Base):
9 class RhodeCodeSettings(Base):
10 __tablename__ = 'rhodecode_settings'
10 __tablename__ = 'rhodecode_settings'
11 __table_args__ = (UniqueConstraint('app_settings_name'), {'useexisting':True})
11 __table_args__ = (UniqueConstraint('app_settings_name'), {'useexisting':True})
12 app_settings_id = Column("app_settings_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True)
12 app_settings_id = Column("app_settings_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True)
13 app_settings_name = Column("app_settings_name", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
13 app_settings_name = Column("app_settings_name", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
14 app_settings_value = Column("app_settings_value", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
14 app_settings_value = Column("app_settings_value", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
15
15
16 class RhodeCodeUi(Base):
16 class RhodeCodeUi(Base):
17 __tablename__ = 'rhodecode_ui'
17 __tablename__ = 'rhodecode_ui'
18 __table_args__ = {'useexisting':True}
18 __table_args__ = {'useexisting':True}
19 ui_id = Column("ui_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True)
19 ui_id = Column("ui_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True)
20 ui_section = Column("ui_section", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
20 ui_section = Column("ui_section", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
21 ui_key = Column("ui_key", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
21 ui_key = Column("ui_key", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
22 ui_value = Column("ui_value", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
22 ui_value = Column("ui_value", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
23 ui_active = Column("ui_active", BOOLEAN(), nullable=True, unique=None, default=True)
23 ui_active = Column("ui_active", BOOLEAN(), nullable=True, unique=None, default=True)
24
24
25
25
26 class User(Base):
26 class User(Base):
27 __tablename__ = 'users'
27 __tablename__ = 'users'
28 __table_args__ = (UniqueConstraint('username'), UniqueConstraint('email'), {'useexisting':True})
28 __table_args__ = (UniqueConstraint('username'), UniqueConstraint('email'), {'useexisting':True})
29 user_id = Column("user_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True)
29 user_id = Column("user_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True)
30 username = Column("username", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
30 username = Column("username", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
31 password = Column("password", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
31 password = Column("password", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
32 active = Column("active", BOOLEAN(), nullable=True, unique=None, default=None)
32 active = Column("active", BOOLEAN(), nullable=True, unique=None, default=None)
33 admin = Column("admin", BOOLEAN(), nullable=True, unique=None, default=False)
33 admin = Column("admin", BOOLEAN(), nullable=True, unique=None, default=False)
34 name = Column("name", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
34 name = Column("name", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
35 lastname = Column("lastname", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
35 lastname = Column("lastname", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
36 email = Column("email", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
36 email = Column("email", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
37 last_login = Column("last_login", DATETIME(timezone=False), nullable=True, unique=None, default=None)
37 last_login = Column("last_login", DATETIME(timezone=False), nullable=True, unique=None, default=None)
38
38
39 user_log = relation('UserLog')
39 user_log = relation('UserLog')
40 user_perms = relation('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id")
40 user_perms = relation('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id")
41
41
42 @LazyProperty
42 @LazyProperty
43 def full_contact(self):
43 def full_contact(self):
44 return '%s %s <%s>' % (self.name, self.lastname, self.email)
44 return '%s %s <%s>' % (self.name, self.lastname, self.email)
45
45
46 def __repr__(self):
46 def __repr__(self):
47 return "<User('id:%s:%s')>" % (self.user_id, self.username)
47 return "<User('id:%s:%s')>" % (self.user_id, self.username)
48
48
49 def update_lastlogin(self):
49 def update_lastlogin(self):
50 """Update user lastlogin"""
50 """Update user lastlogin"""
51 import datetime
51 import datetime
52
52
53 try:
53 try:
54 session = Session.object_session(self)
54 session = Session.object_session(self)
55 self.last_login = datetime.datetime.now()
55 self.last_login = datetime.datetime.now()
56 session.add(self)
56 session.add(self)
57 session.commit()
57 session.commit()
58 log.debug('updated user %s lastlogin', self.username)
58 log.debug('updated user %s lastlogin', self.username)
59 except Exception:
59 except Exception:
60 session.rollback()
60 session.rollback()
61
61
62
62
63 class UserLog(Base):
63 class UserLog(Base):
64 __tablename__ = 'user_logs'
64 __tablename__ = 'user_logs'
65 __table_args__ = {'useexisting':True}
65 __table_args__ = {'useexisting':True}
66 user_log_id = Column("user_log_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True)
66 user_log_id = Column("user_log_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True)
67 user_id = Column("user_id", INTEGER(), ForeignKey(u'users.user_id'), nullable=False, unique=None, default=None)
67 user_id = Column("user_id", INTEGER(), ForeignKey(u'users.user_id'), nullable=False, unique=None, default=None)
68 repository_id = Column("repository_id", INTEGER(length=None, convert_unicode=False, assert_unicode=None), ForeignKey(u'repositories.repo_id'), nullable=False, unique=None, default=None)
68 repository_id = Column("repository_id", INTEGER(length=None, convert_unicode=False, assert_unicode=None), ForeignKey(u'repositories.repo_id'), nullable=False, unique=None, default=None)
69 repository_name = Column("repository_name", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
69 repository_name = Column("repository_name", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
70 user_ip = Column("user_ip", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
70 user_ip = Column("user_ip", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
71 action = Column("action", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
71 action = Column("action", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
72 action_date = Column("action_date", DATETIME(timezone=False), nullable=True, unique=None, default=None)
72 action_date = Column("action_date", DATETIME(timezone=False), nullable=True, unique=None, default=None)
73
73
74 user = relation('User')
74 user = relation('User')
75 repository = relation('Repository')
75 repository = relation('Repository')
76
76
77 class Repository(Base):
77 class Repository(Base):
78 __tablename__ = 'repositories'
78 __tablename__ = 'repositories'
79 __table_args__ = (UniqueConstraint('repo_name'), {'useexisting':True},)
79 __table_args__ = (UniqueConstraint('repo_name'), {'useexisting':True},)
80 repo_id = Column("repo_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True)
80 repo_id = Column("repo_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True)
81 repo_name = Column("repo_name", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None)
81 repo_name = Column("repo_name", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None)
82 repo_type = Column("repo_type", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=False, unique=False, default=None)
82 repo_type = Column("repo_type", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=False, unique=False, default=None)
83 user_id = Column("user_id", INTEGER(), ForeignKey(u'users.user_id'), nullable=False, unique=False, default=None)
83 user_id = Column("user_id", INTEGER(), ForeignKey(u'users.user_id'), nullable=False, unique=False, default=None)
84 private = Column("private", BOOLEAN(), nullable=True, unique=None, default=None)
84 private = Column("private", BOOLEAN(), nullable=True, unique=None, default=None)
85 description = Column("description", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
85 description = Column("description", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
86 fork_id = Column("fork_id", INTEGER(), ForeignKey(u'repositories.repo_id'), nullable=True, unique=False, default=None)
86 fork_id = Column("fork_id", INTEGER(), ForeignKey(u'repositories.repo_id'), nullable=True, unique=False, default=None)
87
87
88 user = relation('User')
88 user = relation('User')
89 fork = relation('Repository', remote_side=repo_id)
89 fork = relation('Repository', remote_side=repo_id)
90 repo_to_perm = relation('RepoToPerm', cascade='all')
90 repo_to_perm = relation('RepoToPerm', cascade='all')
91 stats = relation('Statistics', cascade='all')
92
91
93
92 def __repr__(self):
94 def __repr__(self):
93 return "<Repository('id:%s:%s')>" % (self.repo_id, self.repo_name)
95 return "<Repository('id:%s:%s')>" % (self.repo_id, self.repo_name)
94
96
95 class Permission(Base):
97 class Permission(Base):
96 __tablename__ = 'permissions'
98 __tablename__ = 'permissions'
97 __table_args__ = {'useexisting':True}
99 __table_args__ = {'useexisting':True}
98 permission_id = Column("permission_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True)
100 permission_id = Column("permission_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True)
99 permission_name = Column("permission_name", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
101 permission_name = Column("permission_name", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
100 permission_longname = Column("permission_longname", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
102 permission_longname = Column("permission_longname", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
101
103
102 def __repr__(self):
104 def __repr__(self):
103 return "<Permission('%s:%s')>" % (self.permission_id, self.permission_name)
105 return "<Permission('%s:%s')>" % (self.permission_id, self.permission_name)
104
106
105 class RepoToPerm(Base):
107 class RepoToPerm(Base):
106 __tablename__ = 'repo_to_perm'
108 __tablename__ = 'repo_to_perm'
107 __table_args__ = (UniqueConstraint('user_id', 'repository_id'), {'useexisting':True})
109 __table_args__ = (UniqueConstraint('user_id', 'repository_id'), {'useexisting':True})
108 repo_to_perm_id = Column("repo_to_perm_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True)
110 repo_to_perm_id = Column("repo_to_perm_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True)
109 user_id = Column("user_id", INTEGER(), ForeignKey(u'users.user_id'), nullable=False, unique=None, default=None)
111 user_id = Column("user_id", INTEGER(), ForeignKey(u'users.user_id'), nullable=False, unique=None, default=None)
110 permission_id = Column("permission_id", INTEGER(), ForeignKey(u'permissions.permission_id'), nullable=False, unique=None, default=None)
112 permission_id = Column("permission_id", INTEGER(), ForeignKey(u'permissions.permission_id'), nullable=False, unique=None, default=None)
111 repository_id = Column("repository_id", INTEGER(), ForeignKey(u'repositories.repo_id'), nullable=False, unique=None, default=None)
113 repository_id = Column("repository_id", INTEGER(), ForeignKey(u'repositories.repo_id'), nullable=False, unique=None, default=None)
112
114
113 user = relation('User')
115 user = relation('User')
114 permission = relation('Permission')
116 permission = relation('Permission')
115 repository = relation('Repository')
117 repository = relation('Repository')
116
118
117 class UserToPerm(Base):
119 class UserToPerm(Base):
118 __tablename__ = 'user_to_perm'
120 __tablename__ = 'user_to_perm'
119 __table_args__ = (UniqueConstraint('user_id', 'permission_id'), {'useexisting':True})
121 __table_args__ = (UniqueConstraint('user_id', 'permission_id'), {'useexisting':True})
120 user_to_perm_id = Column("user_to_perm_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True)
122 user_to_perm_id = Column("user_to_perm_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True)
121 user_id = Column("user_id", INTEGER(), ForeignKey(u'users.user_id'), nullable=False, unique=None, default=None)
123 user_id = Column("user_id", INTEGER(), ForeignKey(u'users.user_id'), nullable=False, unique=None, default=None)
122 permission_id = Column("permission_id", INTEGER(), ForeignKey(u'permissions.permission_id'), nullable=False, unique=None, default=None)
124 permission_id = Column("permission_id", INTEGER(), ForeignKey(u'permissions.permission_id'), nullable=False, unique=None, default=None)
123
125
124 user = relation('User')
126 user = relation('User')
125 permission = relation('Permission')
127 permission = relation('Permission')
126
128
127 class Statistics(Base):
129 class Statistics(Base):
128 __tablename__ = 'statistics'
130 __tablename__ = 'statistics'
129 __table_args__ = (UniqueConstraint('repository_id'), {'useexisting':True})
131 __table_args__ = (UniqueConstraint('repository_id'), {'useexisting':True})
130 stat_id = Column("stat_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True)
132 stat_id = Column("stat_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True)
131 repository_id = Column("repository_id", INTEGER(), ForeignKey(u'repositories.repo_id'), nullable=False, unique=True, default=None)
133 repository_id = Column("repository_id", INTEGER(), ForeignKey(u'repositories.repo_id'), nullable=False, unique=True, default=None)
132 stat_on_revision = Column("stat_on_revision", INTEGER(), nullable=False)
134 stat_on_revision = Column("stat_on_revision", INTEGER(), nullable=False)
133 commit_activity = Column("commit_activity", BLOB(), nullable=False)#JSON data
135 commit_activity = Column("commit_activity", BLOB(), nullable=False)#JSON data
134 commit_activity_combined = Column("commit_activity_combined", BLOB(), nullable=False)#JSON data
136 commit_activity_combined = Column("commit_activity_combined", BLOB(), nullable=False)#JSON data
135 languages = Column("languages", BLOB(), nullable=False)#JSON data
137 languages = Column("languages", BLOB(), nullable=False)#JSON data
136
138
137 repository = relation('Repository')
139 repository = relation('Repository', single_parent=True)
138
140
General Comments 0
You need to be logged in to leave comments. Login now