backup 2.3.1 → 2.3.2.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. data/CHANGELOG +16 -1
  2. data/README.textile +42 -177
  3. data/bin/backup +14 -17
  4. data/generators/backup/templates/config/backup.rb +26 -6
  5. data/generators/backup/templates/migrations/create_backup_tables.rb +3 -2
  6. data/generators/backup/templates/tasks/backup.rake +14 -17
  7. data/generators/backup_update/backup_update_generator.rb +50 -0
  8. data/generators/backup_update/templates/migrations/update_backup_tables.rb +27 -0
  9. data/lib/backup.rb +31 -30
  10. data/lib/backup/adapters/archive.rb +19 -54
  11. data/lib/backup/adapters/base.rb +55 -35
  12. data/lib/backup/adapters/custom.rb +15 -53
  13. data/lib/backup/adapters/mysql.rb +24 -55
  14. data/lib/backup/adapters/postgresql.rb +19 -54
  15. data/lib/backup/adapters/sqlite.rb +25 -0
  16. data/lib/backup/command_helper.rb +11 -0
  17. data/lib/backup/configuration/adapter.rb +4 -11
  18. data/lib/backup/configuration/adapter_options.rb +3 -14
  19. data/lib/backup/configuration/attributes.rb +19 -0
  20. data/lib/backup/configuration/base.rb +26 -9
  21. data/lib/backup/configuration/mail.rb +3 -9
  22. data/lib/backup/configuration/smtp.rb +3 -14
  23. data/lib/backup/configuration/storage.rb +3 -12
  24. data/lib/backup/connection/s3.rb +3 -1
  25. data/lib/backup/environment/unix.rb +4 -4
  26. data/lib/backup/mail/base.rb +8 -2
  27. data/lib/backup/mail/mail.txt +3 -3
  28. data/lib/backup/record/base.rb +65 -0
  29. data/lib/backup/record/ftp.rb +10 -69
  30. data/lib/backup/record/local.rb +26 -0
  31. data/lib/backup/record/s3.rb +9 -63
  32. data/lib/backup/record/scp.rb +9 -64
  33. data/lib/backup/record/sftp.rb +10 -68
  34. data/lib/backup/storage/ftp.rb +3 -1
  35. data/lib/backup/storage/local.rb +24 -0
  36. data/lib/backup/storage/s3.rb +3 -1
  37. data/lib/backup/storage/scp.rb +3 -1
  38. data/lib/backup/storage/sftp.rb +3 -1
  39. data/setup/backup.rb +27 -6
  40. data/setup/backup.sqlite3 +0 -0
  41. metadata +130 -60
  42. data/.document +0 -5
  43. data/.gitignore +0 -5
  44. data/Rakefile +0 -70
  45. data/backup.gemspec +0 -111
data/CHANGELOG CHANGED
@@ -1,3 +1,18 @@
1
+ === 2.?.? ====================================
2
+
3
+ - Added Storage Method: Local
4
+ - Added Adapter: SQLite
5
+ - exclude option added for Archive Adapter
6
+ - Internal cleanup
7
+ - Will try to automatically determine the path to mysqldump and pg_dump utilities
8
+ - Added spec/tests
9
+
10
+ MINOR UPDATE
11
+ === 2.3.1 ======================================
12
+
13
+ - Added Feature: Email notifications
14
+
15
+
1
16
  PATCH
2
17
  === 2.3.0.3 ====================================
3
18
 
@@ -59,4 +74,4 @@ MAJOR RELEASE
59
74
  - Uses a SINGLE ruby file for "all" configuration (config/backup.rb) using elegant block notations!
60
75
  - Uses a SINGLE rake task to handle the initialization of any backup setting.
61
76
  - Can now configure an unlimited amount of customizable backup settings and run them each "individually"!
62
- - HIGHLY IMPROVED USABILITY!
77
+ - HIGHLY IMPROVED USABILITY!
data/README.textile CHANGED
@@ -2,150 +2,51 @@ h1. Backup
2
2
 
3
3
  h2. A Backup Ruby Gem
4
4
 
5
- Backup is a Ruby Gem written for Unix and Rails environments. It can be used both with and without the Ruby on Rails framework! This gem offers a quick and simple solution to backing up databases such as MySQL/PostgreSQL and Files/Folders. All backups can be transferred to Amazon S3 or any remote server you have access to, using either SCP, SFTP or regular FTP. Backup handles Compression, Archiving, Encryption and Backup Cleaning (Cycling).
5
+ Backup is a Ruby Gem written for Unix and Rails environments. It can be used both with and without the Ruby on Rails framework! This gem offers a quick and simple solution to backing up databases such as MySQL/PostgreSQL and Files/Folders. All backups can be transferred to Amazon S3 or any remote server you have access to, using either SCP, SFTP or regular FTP. Backup handles Compression, Archiving, Encryption, Backup Cleaning (Cycling) and supports Email Notifications.
6
6
 
7
- h2. Email Notification as of 2.3.1!
7
+ h2. Authors/Maintainers
8
8
 
9
- The first thing you will notice when you re-generate a new copy of the default "backup.rb" template, will be this:
9
+ * "Meskyanichi - Michael van Rooijen":http://github.com/meskyanichi
10
+ * "Fernandoluizao - Fernando Migliorini Luizão":http://github.com/fernandoluizao
10
11
 
11
- bc.. notifier_settings do
12
-
13
- to "example1@gmail.com"
14
- from "example2@gmail.com"
15
-
16
- smtp do
17
- host "smtp.gmail.com"
18
- port "587"
19
- username "example1@gmail.com"
20
- password "example1password"
21
- authentication "plain"
22
- domain "localhost.localdomain"
23
- tls true
24
- end
25
-
26
- end
27
-
28
-
29
-
30
-
31
-
32
- p. This is disabled by default. You must uncomment it. Once you uncomment it, fill in your credentials. By default I setup a "gmail"-based configuration.
33
- Once you've filled in your smtp credentials, all you have to do is set "notify false" to "notify true" inside each *backup* block you wish to be notified of on each successful backup.
34
-
35
-
36
- bc.. backup 'mysql-backup-s3' do
37
-
38
- adapter :mysql do
39
- ...
40
- end
41
-
42
- storage :s3 do
43
- ...
44
- end
45
-
46
- keep_backups 25
47
- encrypt_with_password 'password'
48
- notify false # set this to "true"
49
-
50
- end
51
-
52
-
53
-
54
-
55
-
56
- p. And that's it! Now after every 'mysql-backup-s3', given you've provided the correct smtp configuration, you will be notified of each backup that has been created by email!
57
-
58
-
59
- h2. Backup goes independent with the release of version 2.3.0! Ruby on Rails is no longer "required"!
60
-
61
- *Before you read on, let me tell you that even though all this awesomeness has been added, Backup will still work as it did in the previous version with Ruby on Rails!*
62
-
63
- I am pleased to announce that Backup (version 2.3.0+) has been released and am very satisfied with this update. Backup can now make use of an executable bin file! Why is this so awesome? Because now Backup is Ruby on Rails independent! This means you can make use of Backup whether you use Rails or not, and with the same simplicity! *(pshh.. It's actually simpler to be honest!)*.
64
-
65
- Imagine you have one or more web applications written in another language on the same server, for example, a Python or PHP application. It'd be nice if you could also back up these databases in the same way you are used to, using Backup. Or what about having a MySQL Server running on a separate remote server? It'd be nice to be able to backup directly from that server instead of create a dump from there to the application's server and then push it to Amazon S3 or elsewhere. Previously this wasn't really possible. But now it is! Check this out.
66
-
67
- *Install Backup Gem version 2.3.0 or later!*
68
-
69
- bc. sudo gem install backup
70
-
71
- *Setup Backup*
72
-
73
- bc. sudo backup --setup
74
-
75
- *New folders and files are created in /opt/backup, these will look familiar if you've been using Backup.. Edit the config file!*
76
- The configuration file works *100% the same as the Ruby on Rails configuration file*, so no need to re-understand it!
77
-
78
- bc. sudo nano /opt/backup/config/backup.rb
79
-
80
- *And now just run it like so!*
81
-
82
- bc. sudo backup --run mytrigger
83
-
84
- *For a full list of commands:*
85
12
 
86
- bc. backup --help
87
-
88
-
89
- *Another handy command I added to this backup utility, is the ability to decrypt files that were encrypted by Backup.*
90
-
91
- bc. sudo backup --decrypt /path/to/encrypted/file
92
-
93
- h3. Get started with Backup in the Unix environment!
94
-
95
- "http://wiki.github.com/meskyanichi/backup/getting-started-unix":http://wiki.github.com/meskyanichi/backup/getting-started-unix
96
-
97
-
98
- h2. (Current) Backup's Capabilities
13
+ h2. Backup's Current Capabilities
99
14
 
100
15
  h3. Storage Methods
101
16
 
102
- * Amazon (S3)
103
- * Remote Server (SCP)
104
- * Remote Server (SFTP)
105
- * Remote Server (FTP)
17
+ * Amazon S3
18
+ * Remote Server (Available Protocols: SCP, SFTP, FTP)
19
+ * Local server (Example Locations: Another Hard Drive, Network path) *(coming in the next gem release)*
106
20
 
107
21
  h3. Adapters
108
22
 
109
23
  * MySQL
24
+ * SQLite *(in the next gem release)*
110
25
  * PostgreSQL
111
- * Archive (any files or folders)
112
- * Custom (any database format other than MySQL or PostgreSQL!)
26
+ * Archive (Any files and/or folders)
27
+ * Custom (Anything you can produce using the command line)
113
28
 
114
29
  h3. Archiving
115
30
 
116
- *Backup supports Archiving.*
117
- When you use the Archive adapter to backup a bunch of files and folders, backup will archive and compress these all together.
118
- Archiving also happens when using the *Custom* adapter. If you issue a few commands using it, to dump maybe 1-3 databases, Backup will
119
- handle the archiving, compression and encryption for you!
31
+ Handles archiving for the *Archive* and *Custom* adapters.
120
32
 
121
33
  h3. Encryption
122
34
 
123
- *Backup supports a simple form of encryption.*
124
- All adapters support encryption. This is very simple to enable. Just add the following method inside of the backup settings
125
- of which you wish to encrypt, and it will encrypt it with the specified password:
126
-
127
- bc. encrypt_with_password "mypassword"
128
-
129
- As of *Backup 2.3.0*, backup is executable through the command line. To decrypt an encrypted file, backup provides you with a handy utility to do this:
35
+ Handles encryption of *all* backups for *any* adapter.
36
+ To decrypt a "Backup encrypted file" you can use Backup's built-in utility command:
130
37
 
131
- bc. sudo backup --decrypt /path/to/encrypted/file
38
+ bc. sudo backup --decrypt /path/to/encrypted/file.enc
132
39
 
133
40
  h3. Backup Cleaning
134
41
 
135
- *Backup supports backup cleaning.*
136
- Backup Cleaning enables you to specify the amount of backups that may be stored on either Amazon S3 or a Remote Server. If you for example tell backup to limit the amount of backups at 20, then when the 21st backup gets pushed to the storage location, the oldest version will automatically be destroyed.
42
+ With Backup you can very easily specify how many backups you would like to have stored (per backup procedure!) on your Amazon S3, Remote or Local server. When the limit you specify gets exceeded, the oldest backup will automatically be cleaned up.
137
43
 
138
- The idea behind this is to not flood either your backup server, which might resort in possible lack of hard disk space. Another good reason to utilize this would be for Amazon. Although Amazon S3 is extremely cheap, when backing up 1-2GB of MySQL dumps twice a day, it can become quite expensive if you never remove old ones.
44
+ h3. Email Notifications
139
45
 
140
- To enable this you simply call the following method inside the desired "backup setting":
46
+ You will be able to specify whether you would like to be notified by email when a backup successfully been stored.
47
+ Simply fill in the email configuration block and set "notify" to true inside the backup procedure you would like to be notified of.
141
48
 
142
- bc. keep_backups 20
143
-
144
-
145
- h3. Quick Example of a Single Backup Setting inside the Backup Configuration File
146
-
147
- * In *Rails Environments* this file is located in *RAILS_ROOT/config/backup.rb*
148
- * In *Unix Environments* this file is located in */opt/backup/config/backup.rb*
49
+ h3. Quick Example of a Single Backup Setting/Procedure inside the Backup Configuration File
149
50
 
150
51
  bc. backup 'mysql-backup-s3' do
151
52
  adapter :mysql do
@@ -160,88 +61,53 @@ bc. backup 'mysql-backup-s3' do
160
61
  use_ssl true
161
62
  end
162
63
  keep_backups 25
163
- encrypt_with_password 'password'
164
- end
165
-
166
- The (backup 'mysql-backup-s3' do) is what I call a "backup setting". The first argument of the block is the so called "trigger".
167
-
168
- bc. backup 'mysql-backup-s3' do
169
- # Configuration Here
64
+ encrypt_with_password 'my_password'
65
+ notify true
170
66
  end
171
67
 
172
- This acts as an "identifier" for the "backup setting". The (above) "backup setting" is all pretty straightforward.
173
- So now that we've set up a "backup setting", we can run it using a rake task, like so:
174
-
175
- *If you're using this inside a Unix Environment, use the Backup utility:*
176
-
177
- bc. sudo backup --run mysql-backup-s3
68
+ Everything above should be pretty straightforward, so now, using the "trigger" we specified between
69
+ the *backup* and *do* you can execute this backup procedure like so:
178
70
 
179
- *If you're using this inside a Ruby on Rails Environment, use the Backup rake task:*
71
+ *Rails Environment*
180
72
 
181
- bc. rake backup:run trigger="mysql-backup-s3"
73
+ bc. rake backup:run trigger=mysql-backup-s3
182
74
 
183
- *That's it, the MySQL database has been "backed up" to Amazon S3. It has been dumped, compressed and encrypted with password.*
184
- Note: You can add as many "backup setting" blocks as you want inside the ("/opt/backup/config/backup.rb" for Unix) or ("RAILS_ROOT/config/backup.rb" for Ruby on Rails) configuration file and invoke each of them by their own "trigger". This means you can have as many backup setups as you want, which "don't" all run simultaneously when you initialize a backup.
75
+ *Unix Environment*
185
76
 
186
- *Depending on what environment you're running backup on, you will use different commands. Rails uses Rake Tasks, while Unix uses Backup's utility commands. See below!*
187
-
188
- *Runs the backup setting with the trigger "backup-logs"*
189
-
190
- bc. rake backup:run trigger="backup-logs"
191
- sudo backup --run backup-logs
192
-
193
- *Runs the backup setting with the trigger "backup-mysql"*
194
-
195
- bc. rake backup:run trigger="backup-mysql"
196
- sudo backup --run backup-mysql
197
-
198
- *Runs the backup setting with the trigger "backup-assets"*
199
-
200
- bc. rake backup:run trigger="backup-assets"
201
- sudo backup --run backup-assets
202
-
203
- h3. Additional Options for MySQL and PostgreSQL
204
-
205
- You can pass additional options/flags into the MySQL and PostgreSQL adapters via additional_options. For example:
77
+ bc. sudo backup --run mysql-backup-s3
206
78
 
207
- bc. backup 'mysql-backup-s3' do
208
- adapter :mysql do
209
- user 'user'
210
- password 'password'
211
- database 'database'
212
- additional_options '--single-transaction'
213
- end
214
- .
215
- .
216
- end
79
+ That's it. This was a simple example of how it works.
217
80
 
218
81
 
219
82
  h2. Interested in trying out Backup?
220
83
 
221
- h3. Check out the following Wiki pages to get up and running:
222
-
223
84
 
224
- h3. Getting started (Unix Environment)
85
+ h3. Getting started with Backup for the *Unix Environment*
225
86
 
226
87
  "http://wiki.github.com/meskyanichi/backup/getting-started-unix":http://wiki.github.com/meskyanichi/backup/getting-started-unix
227
88
 
228
89
 
229
- h3. Getting started (Rails Environment)
90
+ h3. Getting started with Backup for the *Rails Environment*
230
91
 
231
92
  "http://wiki.github.com/meskyanichi/backup/getting-started-ruby-on-rails":http://wiki.github.com/meskyanichi/backup/getting-started-ruby-on-rails
232
93
 
233
94
 
234
- h3. Production Mode (important)
95
+ h3. Production Mode *RAILS_ENV*
235
96
 
236
97
  "http://wiki.github.com/meskyanichi/backup/production-mode":http://wiki.github.com/meskyanichi/backup/production-mode
237
98
 
238
99
 
239
- h3. Backup Configuration File (All Adapters, Storage Methods and Options)
100
+ h3. Encrypting and Decrypting
101
+
102
+ "http://wiki.github.com/meskyanichi/backup/encrypting-and-decrypting":http://wiki.github.com/meskyanichi/backup/encrypting-and-decrypting
103
+
104
+
105
+ h3. Backup Configuration File (All Adapters, Storage Methods, Mail Settings and Options)
240
106
 
241
107
  "http://wiki.github.com/meskyanichi/backup/configuration-file":http://wiki.github.com/meskyanichi/backup/configuration-file
242
108
 
243
109
 
244
- h3. Utility Commands and Rake Tasks
110
+ h3. Unix Utility Commands and Rails Rake Tasks
245
111
 
246
112
  "http://wiki.github.com/meskyanichi/backup/utility-commands":http://wiki.github.com/meskyanichi/backup/utility-commands
247
113
 
@@ -285,12 +151,12 @@ h3. Resources
285
151
 
286
152
  h3. Requests
287
153
 
288
- If anyone has any requests, please send me a message!
154
+ If anyone has any requests, please send us a message or post it on the issues page!
289
155
 
290
156
 
291
157
  h3. Suggestions?
292
158
 
293
- Send me a message! Fork the project!
159
+ Send us a message! Fork the project!
294
160
 
295
161
 
296
162
  h3. Found a Bug?
@@ -305,6 +171,5 @@ List of people that forked and added stuff!
305
171
  * "dtrueman":http://github.com/dtrueman
306
172
 
307
173
 
308
- h3. Copyright
309
174
 
310
- Copyright (c) 2009 Michael van Rooijen | Final Creation. ("http://final-creation.com":http://final-creation.com) See LICENSE for details.
175
+ _Michael van Rooijen | Final Creation. ("http://final-creation.com":http://final-creation.com)_
data/bin/backup CHANGED
@@ -23,10 +23,11 @@ optparse = OptionParser.new do |opts|
23
23
  backup = Backup::Setup.new(trigger, @backup_procedures)
24
24
  records = Array.new
25
25
  case backup.procedure.storage_name.to_sym
26
- when :s3 then records = Backup::Record::S3.all :conditions => {:trigger => trigger}
27
- when :scp then records = Backup::Record::SCP.all :conditions => {:trigger => trigger}
28
- when :ftp then records = Backup::Record::FTP.all :conditions => {:trigger => trigger}
29
- when :sftp then records = Backup::Record::SFTP.all :conditions => {:trigger => trigger}
26
+ when :s3 then records = Backup::Record::S3.all :conditions => {:trigger => trigger}
27
+ when :scp then records = Backup::Record::SCP.all :conditions => {:trigger => trigger}
28
+ when :ftp then records = Backup::Record::FTP.all :conditions => {:trigger => trigger}
29
+ when :sftp then records = Backup::Record::SFTP.all :conditions => {:trigger => trigger}
30
+ when :local then records = Backup::Record::Local.all :conditions => {:trigger => trigger}
30
31
  end
31
32
 
32
33
  if options[:table]
@@ -40,10 +41,7 @@ optparse = OptionParser.new do |opts|
40
41
 
41
42
  opts.on('-t', '--truncate [trigger]', "Truncates backup records for specified trigger") do |trigger|
42
43
  puts "Truncating backup records with trigger: #{trigger}."
43
- Backup::Record::S3.destroy_all :trigger => trigger, :storage => 's3'
44
- Backup::Record::SCP.destroy_all :trigger => trigger, :storage => 'scp'
45
- Backup::Record::FTP.destroy_all :trigger => trigger, :storage => 'ftp'
46
- Backup::Record::SFTP.destroy_all :trigger => trigger, :storage => 'sftp'
44
+ Backup::Record::Base.destroy_all :trigger => trigger
47
45
  end
48
46
 
49
47
  opts.on('-d', '--destroy [trigger]', "Destroys backup records and files for specified trigger") do |trigger|
@@ -51,19 +49,17 @@ optparse = OptionParser.new do |opts|
51
49
  puts "Destroying backup records with trigger: #{trigger}."
52
50
  backup = Backup::Setup.new(trigger, @backup_procedures)
53
51
  case backup.procedure.storage_name.to_sym
54
- when :s3 then Backup::Record::S3.destroy_all_backups backup.procedure, trigger
55
- when :scp then Backup::Record::SCP.destroy_all_backups backup.procedure, trigger
56
- when :ftp then Backup::Record::FTP.destroy_all_backups backup.procedure, trigger
57
- when :sftp then Backup::Record::SFTP.destroy_all_backups backup.procedure, trigger
52
+ when :s3 then Backup::Record::S3.destroy_all_backups backup.procedure, trigger
53
+ when :scp then Backup::Record::SCP.destroy_all_backups backup.procedure, trigger
54
+ when :ftp then Backup::Record::FTP.destroy_all_backups backup.procedure, trigger
55
+ when :sftp then Backup::Record::SFTP.destroy_all_backups backup.procedure, trigger
56
+ when :local then Backup::Record::Local.destroy_all_backups backup.procedure, trigger
58
57
  end
59
58
  end
60
59
 
61
60
  opts.on('--truncate-all', "Truncates all backup records") do
62
61
  puts "Truncating all backup records."
63
- Backup::Record::S3.destroy_all
64
- Backup::Record::SCP.destroy_all
65
- Backup::Record::FTP.destroy_all
66
- Backup::Record::SFTP.destroy_all
62
+ Backup::Record::Base.destroy_all
67
63
  end
68
64
 
69
65
  opts.on('--destroy-all', "Destroys all backup records and files") do
@@ -76,6 +72,7 @@ optparse = OptionParser.new do |opts|
76
72
  when :scp then Backup::Record::SCP.destroy_all_backups backup_procedure, backup_procedure.trigger
77
73
  when :ftp then Backup::Record::FTP.destroy_all_backups backup_procedure, backup_procedure.trigger
78
74
  when :sftp then Backup::Record::SFTP.destroy_all_backups backup_procedure, backup_procedure.trigger
75
+ when :local then Backup::Record::Local.destroy_all_backups backup.procedure, backup_procedure.trigger
79
76
  end
80
77
  end
81
78
  end
@@ -124,4 +121,4 @@ rescue OptionParser::InvalidOption
124
121
  puts optparse
125
122
  puts "\n "
126
123
  exit
127
- end
124
+ end
@@ -1,4 +1,3 @@
1
-
2
1
  # Backup Configuration File
3
2
  #
4
3
  # Use the "backup" block to add backup settings to the configuration file.
@@ -17,18 +16,21 @@
17
16
  # ADAPTERS
18
17
  # - MySQL
19
18
  # - PostgreSQL
19
+ # - SQLite
20
20
  # - Archive
21
21
  # - Custom
22
22
  #
23
23
  # STORAGE METHODS
24
- # - S3 (Amazon)
25
- # - SCP (Remote Server)
26
- # - FTP (Remote Server)
27
- # - SFTP (Remote Server)
24
+ # - S3 (Amazon)
25
+ # - SCP (Remote Server)
26
+ # - FTP (Remote Server)
27
+ # - SFTP (Remote Server)
28
+ # - LOCAL (Local Server)
28
29
  #
29
30
  # GLOBAL OPTIONS
30
31
  # - Keep Backups (keep_backups)
31
32
  # - Encrypt With Pasword (encrypt_with_password)
33
+ # - Notify (notify)
32
34
  #
33
35
  # This is the "decrypt" command for all encrypted backups:
34
36
  # sudo backup --decrypt /path/to/encrypted/file
@@ -140,7 +142,6 @@ backup 'archive-backup-ftp' do
140
142
 
141
143
  adapter :archive do
142
144
  files ["#{RAILS_ROOT}/log", "#{RAILS_ROOT}/db"]
143
- # files "#{RAILS_ROOT}/log"
144
145
  end
145
146
 
146
147
  storage :ftp do
@@ -179,4 +180,23 @@ backup 'custom-backup-sftp' do
179
180
  encrypt_with_password 'password'
180
181
  notify false
181
182
 
183
+ end
184
+
185
+
186
+ # Initializ with:
187
+ # rake backup:run trigger='sqlite-backup-local'
188
+ backup 'sqlite-backup-local' do
189
+
190
+ adapter :sqlite do
191
+ database "#{RAILS_ROOT}/db/production.sqlite3"
192
+ end
193
+
194
+ storage :local do
195
+ path "/path/to/storage/location/"
196
+ end
197
+
198
+ keep_backups :all
199
+ encrypt_with_password false
200
+ notify false
201
+
182
202
  end