GithubHelp home page GithubHelp logo

julie-ng / antwort-cli Goto Github PK

View Code? Open in Web Editor NEW
11.0 11.0 0.0 364 KB

CLI for Automated Email Development, incl. template generation and inlining CSS

Ruby 84.77% HTML 7.16% CSS 8.07%
cli dev-server email-template inline-css

antwort-cli's Introduction

antwort-cli's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

antwort-cli's Issues

Add outlook spacer helper

Add spacer helper for Outlook 2007/10/13

<!--[if mso]><div style="mso-line-height-rule:exactly;font-size:10px;line-height:10px;color:#ffffff">&nbsp;<br></div><![endif]-->

Use Case: margin below images

  • Outlook does not support margin or padding on <img>s.
  • Use padding to include Outlook.com support
  • Use spacer above for Outlook 2007/10/13 support

Why is bundle exec faster than binstub?

The bundle exec us so much faster

julieng@air in internations on dev/invites-design*
$ be antwort build invite-event-1a
    create  build/invite-event-1a-20150626134321/source/styles.css
    create  build/invite-event-1a-20150626134321/source/responsive.css
    create  build/invite-event-1a-20150626134321/source/invite-event-1a.html
    create  build/invite-event-1a-20150626134321/invite-event-1a.html

whereas binstub is really slow / never completes ?

julieng@air in internations on dev/invites-design*
$ antwort build invite-event-1a
^C/Users/julieng/.rbenv/versions/2.1.2/lib/ruby/2.1.0/rubygems/dependency.rb:165:in `type': Interrupt
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/2.1.0/rubygems/specification.rb:2148:in `block in runtime_dependencies'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/2.1.0/rubygems/specification.rb:2148:in `select'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/2.1.0/rubygems/specification.rb:2148:in `runtime_dependencies'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/2.1.0/rubygems/specification.rb:1479:in `block in conflicts'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/2.1.0/rubygems/specification.rb:1478:in `each'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/2.1.0/rubygems/specification.rb:1478:in `conflicts'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/2.1.0/rubygems/specification.rb:950:in `block (2 levels) in find_in_unresolved_tree'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/2.1.0/rubygems/specification.rb:2397:in `[]'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/2.1.0/rubygems/specification.rb:2397:in `block (2 levels) in traverse'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/2.1.0/rubygems/specification.rb:2396:in `each'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/2.1.0/rubygems/specification.rb:2396:in `block in traverse'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/2.1.0/rubygems/specification.rb:2395:in `each'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/2.1.0/rubygems/specification.rb:2395:in `traverse'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/2.1.0/rubygems/specification.rb:2398:in `block (2 levels) in traverse'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/2.1.0/rubygems/specification.rb:2396:in `each'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/2.1.0/rubygems/specification.rb:2396:in `block in traverse'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/2.1.0/rubygems/specification.rb:2395:in `each'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/2.1.0/rubygems/specification.rb:2395:in `traverse'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/2.1.0/rubygems/specification.rb:2398:in `block (2 levels) in traverse'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/2.1.0/rubygems/specification.rb:2396:in `each'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/2.1.0/rubygems/specification.rb:2396:in `block in traverse'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/2.1.0/rubygems/specification.rb:2395:in `each'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/2.1.0/rubygems/specification.rb:2395:in `traverse'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/2.1.0/rubygems/specification.rb:949:in `block in find_in_unresolved_tree'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/2.1.0/rubygems/specification.rb:947:in `reverse_each'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/2.1.0/rubygems/specification.rb:947:in `find_in_unresolved_tree'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:93:in `require'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/2.1.0/uri/ldap.rb:14:in `<top (required)>'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:126:in `require'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:126:in `require'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/2.1.0/uri.rb:109:in `<top (required)>'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:126:in `require'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:126:in `require'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/thor-0.19.1/lib/thor/actions.rb:2:in `<top (required)>'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/antwort-0.0.8/lib/antwort/cli/cli.rb:3:in `<class:CLI>'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/antwort-0.0.8/lib/antwort/cli/cli.rb:2:in `<module:Antwort>'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/antwort-0.0.8/lib/antwort/cli/cli.rb:1:in `<top (required)>'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:73:in `require'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:73:in `require'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/antwort-0.0.8/lib/antwort/cli.rb:5:in `<top (required)>'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:73:in `require'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:73:in `require'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/antwort-0.0.8/lib/antwort.rb:9:in `<top (required)>'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/antwort-0.0.8/bin/antwort:3:in `require_relative'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/antwort-0.0.8/bin/antwort:3:in `<top (required)>'
    from /Users/julieng/.rbenv/versions/2.1.2/bin/antwort:23:in `load'

Clue: what is the difference here?

julieng@air in internations on dev/invites-design*
$ which antwort
./bin/antwort

julieng@air in internations on dev/invites-design*
$ which bundle exec antwort
/Users/julieng/.rbenv/shims/bundle
./bin/antwort

Upload shared images

Currently we have to upload shared images by hand.
If we enter "shared" as email id, upload fails because email "shared" does not exist.

Server should ignore shared folder

When listing templates on main page, server should ignore shared folder and not list it. It's not a template, so there's nothing to show…

Fix CSS Inlining problems

PROBLEM some definitions are doubled, depending on how we write our SASS.

For example, if we have:

@mixin pad-me {
  padding-left: 10px;
  padding-right: 10px;
}

.foo {
  @include pad-me;
  padding-left: 20px;
  padding-right: 20px;
}

We get the following invalid markup:

<td class="foo" style="padding-top: 10px; padding-bottom: 10px; padding-top: 20px; padding-bottom: 20px;">

This is a contrived example, but can happen if we have a mixin for base fonts, default paddings, etc. which are adjusted for different responsive sizes.

Build duplicating HTML?

The server respects layout: false but builds do not.

Problem appears in all built emails, not just those with layout:false. The inlined CSS version has HTML twice.

Include initial demo email template on project init

Problem

Server immediately generates error on new project because

  • server path problem (should be fixed now)
  • no email exists for server to load.

Fix

  • add no emails found message
  • include test email on project init

Check build receives argument

Check that the build command receives an argument, otherwise return error. Right now we have:

$ a build
Error: Template '' not found.
/Users/julieng/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/antwort-0.0.11/lib/antwort/builder/email.rb:27:in `exist?': no implicit conversion of nil into String (TypeError)
    from /Users/julieng/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/antwort-0.0.11/lib/antwort/builder/email.rb:27:in `build'
    from /Users/julieng/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/antwort-0.0.11/lib/antwort/cli/cli.rb:143:in `block in build'
    from /Users/julieng/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/antwort-0.0.11/lib/antwort/cli/cli.rb:140:in `each'
    from /Users/julieng/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/antwort-0.0.11/lib/antwort/cli/cli.rb:140:in `build'
    from /Users/julieng/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/thor-0.19.1/lib/thor/command.rb:27:in `run'
    from /Users/julieng/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/thor-0.19.1/lib/thor/invocation.rb:126:in `invoke_command'
    from /Users/julieng/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/thor-0.19.1/lib/thor.rb:359:in `dispatch'
    from /Users/julieng/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/thor-0.19.1/lib/thor/base.rb:440:in `start'
    from /Users/julieng/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/antwort-0.0.11/bin/antwort:5:in `<top (required)>'
    from ./bin/antwort:16:in `load'
    from ./bin/antwort:16:in `<main>'

Sending Email fails since we changed build name

After changes made to inline partials, built emails also use the template name, e.g. announcement as the built html file, instead of inlined.html

Must adjust send function to account for that change.

Specs are broken

Running specs gives following error:

julieng@air in generator on master*
$ rake spec
/Users/julieng/.rbenv/versions/2.1.2/bin/ruby -I/Users/julieng/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-3.1.5/lib /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-3.1.5/exe/rspec --pattern spec/\*\*\{,/\*/\*\*\}/\*_spec.rb
Requiring lib/antwort.rb
/Users/julieng/Projects/antwort/generator/spec/cli/upload_spec.rb:3:in `<top (required)>': uninitialized constant Antwort::CLI::Upload (NameError)
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-3.1.5/lib/rspec/core/configuration.rb:1105:in `load'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-3.1.5/lib/rspec/core/configuration.rb:1105:in `block in load_spec_files'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-3.1.5/lib/rspec/core/configuration.rb:1105:in `each'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-3.1.5/lib/rspec/core/configuration.rb:1105:in `load_spec_files'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-3.1.5/lib/rspec/core/runner.rb:96:in `setup'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-3.1.5/lib/rspec/core/runner.rb:84:in `run'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-3.1.5/lib/rspec/core/runner.rb:69:in `run'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-3.1.5/lib/rspec/core/runner.rb:37:in `invoke'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-3.1.5/exe/rspec:4:in `<main>'
/Users/julieng/.rbenv/versions/2.1.2/bin/ruby -I/Users/julieng/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-3.1.5/lib /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rspec-core-3.1.5/exe/rspec --pattern spec/\*\*\{,/\*/\*\*\}/\*_spec.rb failed

gem sending wrong email

Note that past-event-notification-20151130125959 was built

but past-event-notification-photo-bundle-20151130124637 was sent

julieng@air in internations on dev/events-1*
$ a build past-event-notification
    create  build/past-event-notification-20151130125959/source/inline.css
    create  build/past-event-notification-20151130125959/source/include.css
    create  build/past-event-notification-20151130125959/source/past-event-notification.html
    create  build/past-event-notification-20151130125959/past-event-notification.html

julieng@air in internations on dev/events-1*
$ a send past-event-notification -s 'Past Event Notification (max, 30 Nov)'
#<Mail::Message:70363413040520, Multipart: true, Headers: <Date: Mon, 30 Nov 2015 13:00:19 +0100>, <From: [email protected]>, <To: [email protected]>, <Message-ID: <[email protected]>>, <Subject: Past Event Notification (max, 30 Nov)>, <Mime-Version: 1.0>, <Content-Type: multipart/alternative; boundary=--==_mimepart_565c3a535c9d6_3c983ffec2463bf0745d3>, <Content-Transfer-Encoding: 7bit>>
Sent past-event-notification-photo-bundle-20151130124637 at 30.11.2015 13:00

Build partials too

For a client project, we need to build and inline partials too (because they're be converted into another language, not ERB)

Note

  • if we build partials, we don't have the full DOM tree for traversal, meaning the selectors should not use nested forms, unless all selectors are also available in that single template.

Cleanup after gemification

  • move rake tasks to antwort executable?
  • remove old rake tasks
  • clean up .gitignore
  • clean up Sinatra server requirements, do we need all of contrib? Yes we do
  • Clean up new project templates

Add ability to convert main templates to twig versions too

  • currently only partials convert erb markup into twig
  • built emails are first compiled through server output, which loads all the data, hence loses our markup.

Will need to distinguish between actual builds and converting markup languages.

Use case where partial inliner doesn't work

<table width="600" border="0" cellpadding="0" cellspacing="0" align="center" class="container">
  <tr>
    <td align="left" valign="top">

      <!--[if mso]><table width="100%" border="0" cellpadding="0" cellspacing="0"><tr><td width="200"><![endif]-->

      <% @config.products.each_with_index do |product, i| %>

        <%= partial :'emails/newsletter/product', locals: {product: product, i: i} %>

        <% if i < @config.products.length - 1 %>
          <!--[if mso]></td><td width="200" valign="top"><![endif]-->
        <% end %>

      <% end %>

      <!--[if mso]></td></tr></table><![endif]-->

    </td>
  </tr>
</table>

becomes:


<table width="600" border="0" cellpadding="0" cellspacing="0" align="center" class="container" style="width:600px;max-width:600px;margin-left:auto;margin-right:auto">
  <tr>
    <td align="left" valign="top">

      <!--[if mso]><table width="100%" border="0" cellpadding="0" cellspacing="0"><tr><td width="200"><![endif]-->



        {{ partial :'emails/newsletter/product', locals: {product: product, i: i} }}

        {% if i </td>
<td width="200" valign="top">
        {% endif %}

      {% endfor %}

      <!--[if mso]></td></tr></table><![endif]-->

    </td>
  </tr>
</table>

The <% if i < @config.products.length - 1 %> gets lost

Image Upload Error

Can we rescue from this fog upload error?

julieng@air in email-tests on master*
$ a upload image-styling
Upload 10 images and overwrite 'image-styling' folder on assets server? (y/n) y
    create   https://email-tests-assets.s3.amazonaws.com/image-styling/check-mark.png
    create   https://email-tests-assets.s3.amazonaws.com/image-styling/email-icon-32.png
    create   https://email-tests-assets.s3.amazonaws.com/image-styling/email-icon.png
    create   https://email-tests-assets.s3.amazonaws.com/image-styling/github-no.png
    create   https://email-tests-assets.s3.amazonaws.com/image-styling/pin-2.png
    create   https://email-tests-assets.s3.amazonaws.com/image-styling/pin-with-bg.png
    create   https://email-tests-assets.s3.amazonaws.com/image-styling/pin.png
    create   https://email-tests-assets.s3.amazonaws.com/image-styling/twitter-no.png
    create   https://email-tests-assets.s3.amazonaws.com/image-styling/x-mark.png
/Users/julieng/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/excon-0.45.4/lib/excon/middlewares/expects.rb:6:in `response_call': Expected(200) <=> Actual(400 Bad Request) (Excon::Errors::BadRequest)
excon.error.response
  :body          => "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Error><Code>IncompleteBody</Code><Message>The request body terminated unexpectedly</Message><RequestId>1DB4049D17408C46</RequestId><HostId>rn66eUVxfeU28P3g62ARIS56ucsMI21atiwhZC6lCJC4UUJhqbVXcvOMGk/TGVz9fYYRJXbwnjo=</HostId></Error>"
  :headers       => {
    "Connection"       => "close"
    "Content-Type"     => "application/xml"
    "Date"             => "Thu, 28 Jan 2016 17:06:41 GMT"
    "Server"           => "AmazonS3"
    "x-amz-id-2"       => "rn66eUVxfeU28P3g62ARIS56ucsMI21atiwhZC6lCJC4UUJhqbVXcvOMGk/TGVz9fYYRJXbwnjo="
    "x-amz-request-id" => "1DB4049D17408C46"
  }
  :local_address => "192.168.178.108"
  :local_port    => 54978
  :reason_phrase => "Bad Request"
  :remote_ip     => "54.231.9.89"
  :status        => 400
  :status_line   => "HTTP/1.1 400 Bad Request\r\n"
    from /Users/julieng/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/excon-0.45.4/lib/excon/middlewares/response_parser.rb:8:in `response_call'
    from /Users/julieng/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/excon-0.45.4/lib/excon/connection.rb:372:in `response'
    from /Users/julieng/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/excon-0.45.4/lib/excon/connection.rb:236:in `request'
    from /Users/julieng/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/excon-0.45.4/lib/excon/middlewares/idempotent.rb:26:in `error_call'
    from /Users/julieng/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/excon-0.45.4/lib/excon/middlewares/base.rb:10:in `error_call'
    from /Users/julieng/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/excon-0.45.4/lib/excon/middlewares/base.rb:10:in `error_call'
    from /Users/julieng/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/excon-0.45.4/lib/excon/connection.rb:256:in `rescue in request'
    from /Users/julieng/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/excon-0.45.4/lib/excon/connection.rb:204:in `request'
    from /Users/julieng/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/excon-0.45.4/lib/excon/middlewares/idempotent.rb:26:in `error_call'
    from /Users/julieng/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/excon-0.45.4/lib/excon/middlewares/base.rb:10:in `error_call'
    from /Users/julieng/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/excon-0.45.4/lib/excon/middlewares/base.rb:10:in `error_call'
    from /Users/julieng/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/excon-0.45.4/lib/excon/connection.rb:256:in `rescue in request'
    from /Users/julieng/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/excon-0.45.4/lib/excon/connection.rb:204:in `request'
    from /Users/julieng/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/excon-0.45.4/lib/excon/middlewares/idempotent.rb:26:in `error_call'
    from /Users/julieng/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/excon-0.45.4/lib/excon/middlewares/base.rb:10:in `error_call'
    from /Users/julieng/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/excon-0.45.4/lib/excon/middlewares/base.rb:10:in `error_call'
    from /Users/julieng/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/excon-0.45.4/lib/excon/connection.rb:256:in `rescue in request'
    from /Users/julieng/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/excon-0.45.4/lib/excon/connection.rb:204:in `request'
    from /Users/julieng/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/fog-core-1.35.0/lib/fog/core/connection.rb:81:in `request'
    from /Users/julieng/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/fog-xml-0.1.2/lib/fog/xml/connection.rb:9:in `request'
    from /Users/julieng/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/fog-aws-0.7.6/lib/fog/aws/storage.rb:592:in `_request'
    from /Users/julieng/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/fog-aws-0.7.6/lib/fog/aws/storage.rb:587:in `request'
    from /Users/julieng/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/fog-aws-0.7.6/lib/fog/aws/requests/storage/put_object.rb:43:in `put_object'
    from /Users/julieng/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/fog-aws-0.7.6/lib/fog/aws/models/storage/file.rb:212:in `save'
    from /Users/julieng/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/fog-core-1.35.0/lib/fog/core/collection.rb:51:in `create'
    from /Users/julieng/Projects/antwort/generator/lib/antwort/cli/upload.rb:55:in `block in do_upload'
    from /Users/julieng/Projects/antwort/generator/lib/antwort/cli/upload.rb:53:in `foreach'
    from /Users/julieng/Projects/antwort/generator/lib/antwort/cli/upload.rb:53:in `do_upload'
    from /Users/julieng/Projects/antwort/generator/lib/antwort/cli/upload.rb:40:in `upload'
    from /Users/julieng/Projects/antwort/generator/lib/antwort/cli/cli.rb:69:in `upload'
    from /Users/julieng/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/thor-0.19.1/lib/thor/command.rb:27:in `run'
    from /Users/julieng/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/thor-0.19.1/lib/thor/invocation.rb:126:in `invoke_command'
    from /Users/julieng/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/thor-0.19.1/lib/thor.rb:359:in `dispatch'
    from /Users/julieng/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/thor-0.19.1/lib/thor/base.rb:440:in `start'
    from /Users/julieng/Projects/antwort/generator/bin/antwort:5:in `<top (required)>'
    from ./bin/antwort:16:in `load'
    from ./bin/antwort:16:in `<main>'

Nokogiri still messing up some inlined code

<table border="0" cellpadding="0" cellspacing="0" class="micro-user"<% if defined? align %> align="<%= align %>"<% end %><% if defined? width %> width="<%= width %>" style="min-width:<%= width/520.to_f*100 %>%;"<% else %> width="<%= size %>"<% end %>>

becomes

<table border="0" cellpadding="0" cellspacing="0" class="micro-user" if defined align end width style="min-width:{{ width/520.to_f*100 }}%;" else>

Sync Assets with S3

Idea: use the AWS CLI to sync assets, so we don't have to manually upload/update them.

Add task to remove email

Make it easy to remove emails (for example, demo).

Should be reverse of new commands. Removes appropriate files in css, images, data, and emails folders.

generator strips numbers from email ids

Use should be able to name email anything with alphanumeric characters.

currently antwort new android43 results in an email and corresponding folders named android missing 43…

email uploader working?

Hi @tmaier, dumb question: does the uploader work for you from the command line?

I get the following error message, even though I have the ENV variables defined in my .env file.

julieng@air in generator-demo on master*
$ bundle exec antwort upload demo
Are you sure? This will delete and replace all existing files in the demo directory y
/Users/julieng/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/fog-core-1.24.0/lib/fog/core/service.rb:237:in `validate_options': Missing required arguments: aws_access_key_id, aws_secret_access_key (ArgumentError)
  from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/fog-core-1.24.0/lib/fog/core/service.rb:261:in `handle_settings'
  from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/fog-core-1.24.0/lib/fog/core/service.rb:98:in `new'
  from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/fog-core-1.24.0/lib/fog/storage.rb:26:in `new'
  from /Users/julieng/Projects/antwort/generator/lib/antwort/cli/upload.rb:29:in `connection'
  from /Users/julieng/Projects/antwort/generator/lib/antwort/cli/upload.rb:41:in `directory'
  from /Users/julieng/Projects/antwort/generator/lib/antwort/cli/upload.rb:45:in `clean_directory!'
  from /Users/julieng/Projects/antwort/generator/lib/antwort/cli/upload.rb:14:in `upload'
  from /Users/julieng/Projects/antwort/generator/lib/antwort/cli.rb:69:in `upload_mail'
  from /Users/julieng/Projects/antwort/generator/lib/antwort/cli.rb:42:in `upload'
  from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/thor-0.19.1/lib/thor/command.rb:27:in `run'
  from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/thor-0.19.1/lib/thor/invocation.rb:126:in `invoke_command'
  from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/thor-0.19.1/lib/thor.rb:359:in `dispatch'
  from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/thor-0.19.1/lib/thor/base.rb:440:in `start'
  from /Users/julieng/Projects/antwort/generator/bin/antwort:5:in `<top (required)>'
  from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/bin/antwort:23:in `load'
  from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/bin/antwort:23:in `<main>'

How to test gem without generating package?

Problem

Today I wanted to fix some problems with the Sinatra server. I made some code changes, but running antwort server runs the currently installed version from /Users/julieng/.rbenv/…

How do I run the current working version in lib/antwort.rb?

My temporary solution

Run irb -Ilib to open irb and include local lib directory. Then inside irb console, type:

irb(main):001:0> require 'antwort'
=> true
irb(main):002:0> Antwort::Server.run!

@tmaier got a better idea?

Preserve `&nbsp;`

Currently, our inliner removes hard coded spaces &nbsp; if they're not inside a comment.

Send fails if no build

Problem

If you try to send an email that hasn't been built yet, you get an error:

$ be antwort send contact-confirmed -s 'Contact confirmed'
/Users/julieng/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/antwort-0.0.8/lib/antwort/cli/send.rb:29:in `template_name': undefined method `split' for nil:NilClass (NoMethodError)
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/antwort-0.0.8/lib/antwort/cli/send.rb:40:in `send'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/antwort-0.0.8/lib/antwort/cli/cli.rb:80:in `send'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/thor-0.19.1/lib/thor/command.rb:27:in `run'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/thor-0.19.1/lib/thor/invocation.rb:126:in `invoke_command'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/thor-0.19.1/lib/thor.rb:359:in `dispatch'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/thor-0.19.1/lib/thor/base.rb:440:in `start'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/antwort-0.0.8/bin/antwort:5:in `<top (required)>'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/bin/antwort:23:in `load'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/bin/antwort:23:in `<main>'

Solution

If Email does not exist, we should automatically run build command first, then send email.

Create template generator for new email templates

Problem (updated 4 Sept)
Right now we have to manually create/setup all the necessary directories and files for a new template.

The generator should be able to manage multiple emails, each of which has its own directories, for example:

source
|
+-- assets
|   +-- images
|   |   +-- newsletter
|   |       +-- image-1.png
|   |       +-- image-2.png
|   +-- css
|       +-- newsletter
|           +-- styles.css
|           +-- main.css
|           +-- responsive.css
+-- emails
    +-- newsletter
         +-- index.html.erb

Result: Create a newsletter folder in the following locations:

  • assets/images
  • assets/css
  • emails

Solution
Use a generator, for example like thor so we could have rake new:template or something similar

Rescue from errors to prevent long error messages

For example:

We already output file not found… or is this another bug?

julieng@air in project on dev/events-1
$ a send event-comment-attendees-host -s 'Event Comments (to host)'
   warning  No build found for 'event-activity-comment-attendees-host'. Building now...
/Users/julieng/Projects/antwort/generator/lib/antwort/builder/builder.rb:24:in `initialize': undefined method `to_sym' for nil:NilClass (NoMethodError)
    from /Users/julieng/Projects/antwort/generator/lib/antwort/cli/cli.rb:123:in `new'
    from /Users/julieng/Projects/antwort/generator/lib/antwort/cli/cli.rb:123:in `build'
    from /Users/julieng/Projects/antwort/generator/lib/antwort/cli/cli.rb:84:in `send'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/thor-0.19.1/lib/thor/command.rb:27:in `run'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/thor-0.19.1/lib/thor/invocation.rb:126:in `invoke_command'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/thor-0.19.1/lib/thor.rb:359:in `dispatch'
    from /Users/julieng/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/thor-0.19.1/lib/thor/base.rb:440:in `start'
    from /Users/julieng/Projects/antwort/generator/bin/antwort:5:in `<top (required)>'
    from ./bin/antwort:16:in `load'
    from ./bin/antwort:16:in `<main>'

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.