admincredible 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. data/Gemfile +12 -0
  2. data/Gemfile.lock +86 -0
  3. data/Rakefile +24 -0
  4. data/Readme.md +121 -0
  5. data/TODOS +1 -0
  6. data/admincredible.gemspec +35 -0
  7. data/developer_notes/README.md +2 -0
  8. data/developer_notes/TODOS.md +0 -0
  9. data/lib/admincredible.rb +1 -0
  10. data/lib/admincredible/client.rb +60 -0
  11. data/lib/admincredible/configuration.rb +125 -0
  12. data/lib/admincredible/connection.rb +30 -0
  13. data/lib/admincredible/core_ext/string.rb +16 -0
  14. data/lib/admincredible/joomla_request.rb +22 -0
  15. data/lib/admincredible/middleware/logger.rb +51 -0
  16. data/lib/admincredible/middleware/step.rb +44 -0
  17. data/lib/admincredible/request.rb +47 -0
  18. data/lib/admincredible/resource.rb +20 -0
  19. data/lib/admincredible/resources/Backup.rb +34 -0
  20. data/lib/admincredible/resources/Compatibility.rb +13 -0
  21. data/lib/admincredible/resources/Extension.rb +37 -0
  22. data/lib/admincredible/resources/Oauth.rb +53 -0
  23. data/lib/admincredible/resources/Setting.rb +21 -0
  24. data/lib/admincredible/resources/Site.rb +9 -0
  25. data/lib/admincredible/resources/Upgrade.rb +64 -0
  26. data/spec/core/client_spec.rb +24 -0
  27. data/spec/core/resource_spec.rb +13 -0
  28. data/spec/fixtures/cassettes/backups/create.yml +73 -0
  29. data/spec/fixtures/cassettes/backups/start.yml +38 -0
  30. data/spec/fixtures/cassettes/backups/step.yml +38 -0
  31. data/spec/fixtures/cassettes/compatibility/added_exceptions.yml +38 -0
  32. data/spec/fixtures/cassettes/compatibility/status.yml +38 -0
  33. data/spec/fixtures/cassettes/extensions/all.yml +38 -0
  34. data/spec/fixtures/cassettes/extensions/update.yml +38 -0
  35. data/spec/fixtures/cassettes/settings/all.yml +38 -0
  36. data/spec/fixtures/cassettes/settings/created.yml +39 -0
  37. data/spec/fixtures/cassettes/settings/first.yml +38 -0
  38. data/spec/fixtures/cassettes/settings/updated.yml +39 -0
  39. data/spec/fixtures/cassettes/site/configuration.yml +41 -0
  40. data/spec/fixtures/cassettes/upgrade/cleanup.yml +38 -0
  41. data/spec/fixtures/cassettes/upgrade/create.yml +249 -0
  42. data/spec/fixtures/cassettes/upgrade/create_restoration_file.yml +38 -0
  43. data/spec/fixtures/cassettes/upgrade/download.yml +38 -0
  44. data/spec/fixtures/cassettes/upgrade/finalize.yml +38 -0
  45. data/spec/fixtures/cassettes/upgrade/info.yml +38 -0
  46. data/spec/fixtures/cassettes/upgrade/start.yml +39 -0
  47. data/spec/fixtures/cassettes/upgrade/step.yml +38 -0
  48. data/spec/resources/backups_spec.rb +36 -0
  49. data/spec/resources/compatibility_spec.rb +25 -0
  50. data/spec/resources/extensions_spec.rb +25 -0
  51. data/spec/resources/setting_spec.rb +47 -0
  52. data/spec/resources/site_spec.rb +14 -0
  53. data/spec/resources/upgrade_spec.rb +91 -0
  54. data/spec/spec_helper.rb +38 -0
  55. metadata +353 -0
@@ -0,0 +1,39 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: http://localhost/joomla_old_testsite_257/components/com_admincredible/direct.php?resource=settings&task=create
6
+ body:
7
+ encoding: UTF-8
8
+ string: ! '{"test_setting":"update"}'
9
+ headers:
10
+ Accept:
11
+ - application/json
12
+ User-Agent:
13
+ - Admincredible Ruby Gem
14
+ Content-Type:
15
+ - application/json
16
+ response:
17
+ status:
18
+ code: 200
19
+ message: OK
20
+ headers:
21
+ Date:
22
+ - Sat, 19 Jan 2013 20:06:04 GMT
23
+ Server:
24
+ - Apache/2.2.21 (Unix) mod_ssl/2.2.21 OpenSSL/0.9.8r DAV/2 PHP/5.3.6
25
+ X-Powered-By:
26
+ - PHP/5.3.6
27
+ Set-Cookie:
28
+ - c90b3f6e23ff46392a42cf27fea67ad4=6a4d0f8ff47d0c0615c2971f9e356085; path=/
29
+ Content-Length:
30
+ - '142'
31
+ Content-Type:
32
+ - application/json;
33
+ body:
34
+ encoding: US-ASCII
35
+ string: ! '{"status":200,"data":{"authentication_method":"debug","authentication_method_custom":null,"test_setting":"updated"},"message":"Saved
36
+ Settings"}'
37
+ http_version:
38
+ recorded_at: Sat, 19 Jan 2013 20:06:07 GMT
39
+ recorded_with: VCR 2.4.0
@@ -0,0 +1,41 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: http://localhost/joomla_old_testsite_257/components/com_admincredible/direct.php?resource=site&task=configuration
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Accept:
11
+ - application/json
12
+ User-Agent:
13
+ - Admincredible Ruby Gem
14
+ Accept-Encoding:
15
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
16
+ response:
17
+ status:
18
+ code: 200
19
+ message: OK
20
+ headers:
21
+ Date:
22
+ - Sat, 19 Jan 2013 20:06:07 GMT
23
+ Server:
24
+ - Apache/2.2.21 (Unix) mod_ssl/2.2.21 OpenSSL/0.9.8r DAV/2 PHP/5.3.6
25
+ X-Powered-By:
26
+ - PHP/5.3.6
27
+ Set-Cookie:
28
+ - c90b3f6e23ff46392a42cf27fea67ad4=16930f3f6e34876b7d8a8e0c0ae3b3ae; path=/
29
+ Content-Length:
30
+ - '1511'
31
+ Content-Type:
32
+ - application/json;
33
+ body:
34
+ encoding: US-ASCII
35
+ string: ! '{"status":200,"data":{"offline":"0","offline_message":"This site
36
+ is down for maintenance.<br \/> Please check back again soon.","display_offline_message":"1","offline_image":"","sitename":"Old
37
+ Joomla 2.5.7","editor":"tinymce","captcha":"0","list_limit":"20","access":"1","debug":"0","debug_lang":"0","dbtype":"mysql","host":"localhost","user":"root","password":"root","db":"test_joomla2.5.7","dbprefix":"cy9c7_","live_site":"","secret":"BxylKjfMsRHtzohg","gzip":"0","error_reporting":"default","helpurl":"http:\/\/help.joomla.org\/proxy\/index.php?option=com_help&amp;keyref=Help{major}{minor}:{keyref}","ftp_host":"127.0.0.1","ftp_port":"21","ftp_user":"","ftp_pass":"","ftp_root":"","ftp_enable":"0","offset":"UTC","mailer":"mail","mailfrom":"bookworm.productions@gmail.com","fromname":"Old
38
+ Joomla 2.5.7","sendmail":"\/usr\/sbin\/sendmail","smtpauth":"0","smtpuser":"","smtppass":"","smtphost":"localhost","smtpsecure":"none","smtpport":"25","caching":"0","cache_handler":"file","cachetime":"15","MetaDesc":"","MetaKeys":"","MetaTitle":"1","MetaAuthor":"1","MetaVersion":"0","robots":"","sef":"1","sef_rewrite":"0","sef_suffix":"0","unicodeslugs":"0","feed_limit":"10","log_path":"\/Users\/kenerickson\/Sites\/joomla_old_testsite_257\/logs","tmp_path":"\/Users\/kenerickson\/Sites\/joomla_old_testsite_257\/tmp","lifetime":"15","session_handler":"database","force_ssl":"0","feed_email":"author","offset_user":"UTC","MetaRights":"","sitename_pagetitles":"0","cookie_domain":"","cookie_path":""},"message":"up"}'
39
+ http_version:
40
+ recorded_at: Sat, 19 Jan 2013 20:06:09 GMT
41
+ recorded_with: VCR 2.4.0
@@ -0,0 +1,38 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: http://localhost/joomla_old_testsite_257/components/com_admincredible/direct.php?resource=upgrade&task=cleanup
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Accept:
11
+ - application/json
12
+ User-Agent:
13
+ - Admincredible Ruby Gem
14
+ Accept-Encoding:
15
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
16
+ response:
17
+ status:
18
+ code: 200
19
+ message: OK
20
+ headers:
21
+ Date:
22
+ - Sun, 20 Jan 2013 00:15:51 GMT
23
+ Server:
24
+ - Apache/2.2.21 (Unix) mod_ssl/2.2.21 OpenSSL/0.9.8r DAV/2 PHP/5.3.6
25
+ X-Powered-By:
26
+ - PHP/5.3.6
27
+ Set-Cookie:
28
+ - c90b3f6e23ff46392a42cf27fea67ad4=7306bffe6c239fe6648c75dc1e3d069f; path=/
29
+ Content-Length:
30
+ - '42'
31
+ Content-Type:
32
+ - application/json;
33
+ body:
34
+ encoding: US-ASCII
35
+ string: ! '{"status":200,"message":"Update Finished"}'
36
+ http_version:
37
+ recorded_at: Sun, 20 Jan 2013 00:15:53 GMT
38
+ recorded_with: VCR 2.4.0
@@ -0,0 +1,249 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: http://localhost/joomla_old_testsite_257/components/com_admincredible/direct.php?resource=upgrade&task=info
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Accept:
11
+ - application/json
12
+ User-Agent:
13
+ - Admincredible Ruby Gem
14
+ Accept-Encoding:
15
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
16
+ response:
17
+ status:
18
+ code: 200
19
+ message: OK
20
+ headers:
21
+ Date:
22
+ - Sat, 19 Jan 2013 23:59:28 GMT
23
+ Server:
24
+ - Apache/2.2.21 (Unix) mod_ssl/2.2.21 OpenSSL/0.9.8r DAV/2 PHP/5.3.6
25
+ X-Powered-By:
26
+ - PHP/5.3.6
27
+ Set-Cookie:
28
+ - c90b3f6e23ff46392a42cf27fea67ad4=4a3292bae7da2400173b0c9394788105; path=/
29
+ Content-Length:
30
+ - '823'
31
+ Content-Type:
32
+ - application/json;
33
+ body:
34
+ encoding: US-ASCII
35
+ string: ! '{"status":200,"data":{"installed":"2.5.7","latest":"2.5.8","object":{"xml_parser":null,"base":{"UPDATES":{"_data":"","UPDATE":{"_data":"","NAME":{"_data":""},"DESCRIPTION":{"_data":""},"ELEMENT":{"_data":""},"TYPE":{"_data":""},"VERSION":{"_data":""},"INFOURL":{"_data":""},"DOWNLOADS":{"_data":"","DOWNLOADURL":{"_data":""}},"TAGS":{"_data":"","TAG":{"_data":""}},"MAINTAINER":{"_data":""},"MAINTAINERURL":{"_data":""},"SECTION":{"_data":""},"TARGETPLATFORM":{"_data":""}}}},"update":{"_data":"\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t\t\n\t"},"downloadurl":{"_data":"http:\/\/joomlacode.org\/gf\/download\/frsrelease\/17716\/77265\/Joomla_2.5.x_to_2.5.8-Stable-Patch_Package.zip","type":"full","format":"zip"},"tag":{"_data":"stable"},"section":{"_data":"Testing"},"updates":{"_data":"\n"}}}}'
36
+ http_version:
37
+ recorded_at: Sun, 20 Jan 2013 00:00:09 GMT
38
+ - request:
39
+ method: get
40
+ uri: http://localhost/joomla_old_testsite_257/components/com_admincredible/direct.php?resource=upgrade&task=download
41
+ body:
42
+ encoding: US-ASCII
43
+ string: ''
44
+ headers:
45
+ Accept:
46
+ - application/json
47
+ User-Agent:
48
+ - Admincredible Ruby Gem
49
+ Accept-Encoding:
50
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
51
+ response:
52
+ status:
53
+ code: 200
54
+ message: OK
55
+ headers:
56
+ Date:
57
+ - Sun, 20 Jan 2013 00:00:10 GMT
58
+ Server:
59
+ - Apache/2.2.21 (Unix) mod_ssl/2.2.21 OpenSSL/0.9.8r DAV/2 PHP/5.3.6
60
+ X-Powered-By:
61
+ - PHP/5.3.6
62
+ Set-Cookie:
63
+ - c90b3f6e23ff46392a42cf27fea67ad4=81a0bd1894a37f2ea2665c77c1965824; path=/
64
+ Content-Length:
65
+ - '37'
66
+ Content-Type:
67
+ - application/json;
68
+ body:
69
+ encoding: US-ASCII
70
+ string: ! '{"status":200,"message":"Downloaded"}'
71
+ http_version:
72
+ recorded_at: Sun, 20 Jan 2013 00:00:29 GMT
73
+ - request:
74
+ method: get
75
+ uri: http://localhost/joomla_old_testsite_257/components/com_admincredible/direct.php?resource=upgrade&task=create_restoration_file
76
+ body:
77
+ encoding: US-ASCII
78
+ string: ''
79
+ headers:
80
+ Accept:
81
+ - application/json
82
+ User-Agent:
83
+ - Admincredible Ruby Gem
84
+ Accept-Encoding:
85
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
86
+ response:
87
+ status:
88
+ code: 200
89
+ message: OK
90
+ headers:
91
+ Date:
92
+ - Sun, 20 Jan 2013 00:00:29 GMT
93
+ Server:
94
+ - Apache/2.2.21 (Unix) mod_ssl/2.2.21 OpenSSL/0.9.8r DAV/2 PHP/5.3.6
95
+ X-Powered-By:
96
+ - PHP/5.3.6
97
+ Set-Cookie:
98
+ - c90b3f6e23ff46392a42cf27fea67ad4=143e64cc3f44d4dc03efb03bd74d4b1b; path=/
99
+ Content-Length:
100
+ - '51'
101
+ Content-Type:
102
+ - application/json;
103
+ body:
104
+ encoding: US-ASCII
105
+ string: ! '{"status":200,"message":"Created Restoration File"}'
106
+ http_version:
107
+ recorded_at: Sun, 20 Jan 2013 00:00:37 GMT
108
+ - request:
109
+ method: get
110
+ uri: http://localhost/joomla_old_testsite_257/components/com_admincredible/direct.php?resource=upgrade&task=start
111
+ body:
112
+ encoding: US-ASCII
113
+ string: ''
114
+ headers:
115
+ Accept:
116
+ - application/json
117
+ User-Agent:
118
+ - Admincredible Ruby Gem
119
+ Accept-Encoding:
120
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
121
+ response:
122
+ status:
123
+ code: 302
124
+ message: Moved
125
+ headers:
126
+ Date:
127
+ - Sun, 20 Jan 2013 00:01:49 GMT
128
+ Server:
129
+ - Apache/2.2.21 (Unix) mod_ssl/2.2.21 OpenSSL/0.9.8r DAV/2 PHP/5.3.6
130
+ X-Powered-By:
131
+ - PHP/5.3.6
132
+ Set-Cookie:
133
+ - c90b3f6e23ff46392a42cf27fea67ad4=f1b6079c171a0a7310669723ac609263; path=/
134
+ Content-Length:
135
+ - '75'
136
+ Content-Type:
137
+ - application/json;
138
+ body:
139
+ encoding: US-ASCII
140
+ string: ! '{"status":302,"data":{"url":""},"message":"You can start your upgrade
141
+ now"}'
142
+ http_version:
143
+ recorded_at: Sun, 20 Jan 2013 00:01:52 GMT
144
+ - request:
145
+ method: get
146
+ uri: http://localhost/joomla_old_testsite_257/components/com_admincredible/direct.php?resource=upgrade&task=step
147
+ body:
148
+ encoding: US-ASCII
149
+ string: ''
150
+ headers:
151
+ Accept:
152
+ - application/json
153
+ User-Agent:
154
+ - Admincredible Ruby Gem
155
+ Accept-Encoding:
156
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
157
+ response:
158
+ status:
159
+ code: 200
160
+ message: OK
161
+ headers:
162
+ Date:
163
+ - Sun, 20 Jan 2013 00:01:49 GMT
164
+ Server:
165
+ - Apache/2.2.21 (Unix) mod_ssl/2.2.21 OpenSSL/0.9.8r DAV/2 PHP/5.3.6
166
+ X-Powered-By:
167
+ - PHP/5.3.6
168
+ Set-Cookie:
169
+ - c90b3f6e23ff46392a42cf27fea67ad4=f1b6079c171a0a7310669723ac609263; path=/
170
+ Content-Length:
171
+ - '196'
172
+ Content-Type:
173
+ - application/json;
174
+ body:
175
+ encoding: US-ASCII
176
+ string: ! "{\"status\":200,\"data\":{\"HasRun\":false,\"Domain\":\"\",\"Step\":\"\",\"Substep\":\"\",\"Error\":false,\"Warnings\":[],\"files\":0,\"bytesIn\":0,\"bytesOut\":0,\"status\":true,\"done\":true},\"message\":\"Site Update Completed\"}"
177
+ http_version:
178
+ recorded_at: Sun, 20 Jan 2013 00:01:52 GMT
179
+ - request:
180
+ method: get
181
+ uri: http://localhost/joomla_old_testsite_257/components/com_admincredible/direct.php?resource=upgrade&task=finalize
182
+ body:
183
+ encoding: US-ASCII
184
+ string: ''
185
+ headers:
186
+ Accept:
187
+ - application/json
188
+ User-Agent:
189
+ - Admincredible Ruby Gem
190
+ Accept-Encoding:
191
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
192
+ response:
193
+ status:
194
+ code: 200
195
+ message: OK
196
+ headers:
197
+ Date:
198
+ - Sun, 20 Jan 2013 00:15:45 GMT
199
+ Server:
200
+ - Apache/2.2.21 (Unix) mod_ssl/2.2.21 OpenSSL/0.9.8r DAV/2 PHP/5.3.6
201
+ X-Powered-By:
202
+ - PHP/5.3.6
203
+ Set-Cookie:
204
+ - c90b3f6e23ff46392a42cf27fea67ad4=6c6fa244db0daa8ac4546b9990a1514c; path=/
205
+ Content-Length:
206
+ - '43'
207
+ Content-Type:
208
+ - application/json;
209
+ body:
210
+ encoding: US-ASCII
211
+ string: ! '{"status":200,"message":"Finalized Update"}'
212
+ http_version:
213
+ recorded_at: Sun, 20 Jan 2013 00:15:51 GMT
214
+ - request:
215
+ method: get
216
+ uri: http://localhost/joomla_old_testsite_257/components/com_admincredible/direct.php?resource=upgrade&task=cleanup
217
+ body:
218
+ encoding: US-ASCII
219
+ string: ''
220
+ headers:
221
+ Accept:
222
+ - application/json
223
+ User-Agent:
224
+ - Admincredible Ruby Gem
225
+ Accept-Encoding:
226
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
227
+ response:
228
+ status:
229
+ code: 200
230
+ message: OK
231
+ headers:
232
+ Date:
233
+ - Sun, 20 Jan 2013 00:15:51 GMT
234
+ Server:
235
+ - Apache/2.2.21 (Unix) mod_ssl/2.2.21 OpenSSL/0.9.8r DAV/2 PHP/5.3.6
236
+ X-Powered-By:
237
+ - PHP/5.3.6
238
+ Set-Cookie:
239
+ - c90b3f6e23ff46392a42cf27fea67ad4=7306bffe6c239fe6648c75dc1e3d069f; path=/
240
+ Content-Length:
241
+ - '42'
242
+ Content-Type:
243
+ - application/json;
244
+ body:
245
+ encoding: US-ASCII
246
+ string: ! '{"status":200,"message":"Update Finished"}'
247
+ http_version:
248
+ recorded_at: Sun, 20 Jan 2013 00:15:53 GMT
249
+ recorded_with: VCR 2.4.0
@@ -0,0 +1,38 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: http://localhost/joomla_old_testsite_257/components/com_admincredible/direct.php?resource=upgrade&task=create_restoration_file
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Accept:
11
+ - application/json
12
+ User-Agent:
13
+ - Admincredible Ruby Gem
14
+ Accept-Encoding:
15
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
16
+ response:
17
+ status:
18
+ code: 200
19
+ message: OK
20
+ headers:
21
+ Date:
22
+ - Sun, 20 Jan 2013 00:00:29 GMT
23
+ Server:
24
+ - Apache/2.2.21 (Unix) mod_ssl/2.2.21 OpenSSL/0.9.8r DAV/2 PHP/5.3.6
25
+ X-Powered-By:
26
+ - PHP/5.3.6
27
+ Set-Cookie:
28
+ - c90b3f6e23ff46392a42cf27fea67ad4=143e64cc3f44d4dc03efb03bd74d4b1b; path=/
29
+ Content-Length:
30
+ - '51'
31
+ Content-Type:
32
+ - application/json;
33
+ body:
34
+ encoding: US-ASCII
35
+ string: ! '{"status":200,"message":"Created Restoration File"}'
36
+ http_version:
37
+ recorded_at: Sun, 20 Jan 2013 00:00:37 GMT
38
+ recorded_with: VCR 2.4.0
@@ -0,0 +1,38 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: http://localhost/joomla_old_testsite_257/components/com_admincredible/direct.php?resource=upgrade&task=download
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Accept:
11
+ - application/json
12
+ User-Agent:
13
+ - Admincredible Ruby Gem
14
+ Accept-Encoding:
15
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
16
+ response:
17
+ status:
18
+ code: 200
19
+ message: OK
20
+ headers:
21
+ Date:
22
+ - Sun, 20 Jan 2013 00:00:10 GMT
23
+ Server:
24
+ - Apache/2.2.21 (Unix) mod_ssl/2.2.21 OpenSSL/0.9.8r DAV/2 PHP/5.3.6
25
+ X-Powered-By:
26
+ - PHP/5.3.6
27
+ Set-Cookie:
28
+ - c90b3f6e23ff46392a42cf27fea67ad4=81a0bd1894a37f2ea2665c77c1965824; path=/
29
+ Content-Length:
30
+ - '37'
31
+ Content-Type:
32
+ - application/json;
33
+ body:
34
+ encoding: US-ASCII
35
+ string: ! '{"status":200,"message":"Downloaded"}'
36
+ http_version:
37
+ recorded_at: Sun, 20 Jan 2013 00:00:29 GMT
38
+ recorded_with: VCR 2.4.0