Permalink
Browse files

Initial commit.

  • Loading branch information...
0 parents commit aa1719b5cbdefbcff5ca134830dd3732b3e15741 @alexksikes committed Jun 29, 2009
@@ -0,0 +1,53 @@
+1) Download the latest tar ball: http://github.com/alexksikes/mailer/tarball/master.
+
+2) tar xvzf "the tar ball"
+
+3) Download install webpy, follow instructions here: http://webpy.org/install
+
+4) Setup lighttpd, here is a part your config file:
+
+ ...
+
+ name = "mailer"
+ script = "path to ./application.py"
+
+ server.document-root = "path to ./public/"
+
+ # password protect access to this site
+ $HTTP["url"] !~ "" {
+ auth.require = ( "" =>
+ (
+ "method" => "digest",
+ "realm" => "Authorized users only",
+ "require" => "valid-user",
+ ))
+ }
+
+ url.rewrite += (
+ # Commented for development
+ "^/img/(.*)$" => "/img/$1",
+ "^/css/(.*)$" => "/css/$1",
+ "^/js/(.*)$" => "/js/$1",
+
+ "^/(.*)$" => script + "/$1",
+ )
+
+ fastcgi.server += ( script =>
+ ((
+ "socket" => "/tmp/" + name + var.PID + ".socket",
+ "bin-path" => script,
+ "check-local" => "disable",
+ "max-procs" => 1,
+ "bin-environment" => (
+ "REAL_SCRIPT_NAME" => ""
+ ),
+ ))
+ )
+
+ ...
+
+5) Setup your database: mysql -p mailer < ./schema.sql
+
+6) Go over your iste settings: go over config_example.py and rename it config.py
+
+7) Restart lighttpd and you're done!
@@ -0,0 +1,165 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+ This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+ 0. Additional Definitions.
+
+ As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+ "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+ An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+ A "Combined Work" is a work produced by combining or linking an
+Application with the Library. The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+ The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+ The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+ You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+ If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+ a) under this License, provided that you make a good faith effort to
+ ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+
+ b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+ The object code form of an Application may incorporate material from
+a header file that is part of the Library. You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+ a) Give prominent notice with each copy of the object code that the
+ Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the object code with a copy of the GNU GPL and this license
+ document.
+
+ 4. Combined Works.
+
+ You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+ a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
+ document.
+
+ c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among
+ these notices, as well as a reference directing the user to the
+ copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+ 0) Convey the Minimal Corresponding Source under the terms of this
+ License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+
+ 1) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (a) uses at run time
+ a copy of the Library already present on the user's computer
+ system, and (b) will operate properly with a modified version
+ of the Library that is interface-compatible with the Linked
+ Version.
+
+ e) Provide Installation Information, but only if you would otherwise
+ be required to provide such information under section 6 of the
+ GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the
+ Combined Work produced by recombining or relinking the
+ Application with a modified version of the Linked Version. (If
+ you use option 4d0, the Installation Information must accompany
+ the Minimal Corresponding Source and Corresponding Application
+ Code. If you use option 4d1, you must provide the Installation
+ Information in the manner specified by section 6 of the GNU GPL
+ for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+ You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+ a) Accompany the combined library with a copy of the same work based
+ on the Library, uncombined with any other library facilities,
+ conveyed under the terms of this License.
+
+ b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+ The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+ If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
@@ -0,0 +1,3 @@
+A very simple but flexible mass mailer.
+
+Try a demo: http://mailer.ksikes.net.
@@ -0,0 +1,14 @@
+IMPLEMENT:
+
+- keep a list of message / email address in order to avoid resending to the same email (unless force is checked)
+- send a copy to ...
+
+MORE IDEAS:
+
+- have recipient lists which are SQL queries.
+>> recipients creation should be part of another panel (more advanced one).
+>> templates are connected to recipients (variables being used) so it might not be a good idea to disociate the two.
+
+- have an export data as CSV option.
+- need to be able to save templates.
+- need to keep rack of exactly which email was sent and to whom.
No changes.
No changes.
No changes.
@@ -0,0 +1,47 @@
+# Author: Alex Ksikes
+
+import web
+import config
+
+from config import view
+from web import form
+
+from app.models import templates
+from app.helpers import utils
+
+sendmail_form = \
+ utils.Form(
+ form.Textbox('reply_to',
+ description='Reply to: '),
+ form.Textbox('to',
+ form.notnull,
+ description='To: ',
+ pre='<label class="help" for="to">Use the template variable email e.g. $email specified by the SQL query.</label>'),
+ form.Textbox('subject',
+ form.notnull,
+ description='Subject: ',
+ pre='<label class="help" for="to">Use any template variable e.g. $variable_name specified by the SQL query.</label>'),
+ form.Textarea('message',
+ form.notnull,
+ description='Message: ',
+ pre='<label class="help" for="to">Use any template variable e.g. $variable_name specified by the SQL query.</label>'),
+ form.Checkbox('send_copy',
+ description='',
+ post='<span>Send a copy to:</span> <span>%s</span>' % web.htmlquote(config.mail_bcc)),
+ form.Checkbox('force_resend',
+ description='',
+ post='<span>Force resend to previously emailed recipients.</span>'))
+
+class index:
+ def GET(self):
+ return view.base(view.index(view.sendmail_form(sendmail_form())))
+
+class send:
+ def POST(self):
+ f = sendmail_form()
+
+ count = 0
+ if f.validates():
+ d = f.d; d.sql_query = web.input().sql_query
+ count = templates.send(d.to, d.subject, d.message, d.sql_query, d.reply_to)
+ return view.sendmail_form(f, success=f.valid, count=count)
@@ -0,0 +1,24 @@
+# Author: Alex Ksikes
+
+import web
+import config
+
+from config import view
+
+from app.helpers import paging
+from app.models import recipients
+
+import re
+
+results_per_page = 15
+
+class browse:
+ def GET(self):
+ i = web.input(start=0, sql_query='')
+ start = int(i.start)
+
+ results, count, columns = recipients.get(i.sql_query, offset=start, limit=results_per_page)
+ pager = web.storage(paging.get_paging(start, count,
+ results_per_page=results_per_page, window_size=1))
+
+ return view.recipients_preview(results, columns, pager, i)
@@ -0,0 +1,17 @@
+# Author: Alex Ksikes
+
+import web
+import mimetypes
+
+class public:
+ def GET(self):
+ public_dir = 'public'
+ try:
+ file_name = web.ctx.path.split('/')[-1]
+ web.header('Content-type', mime_type(file_name))
+ return open(public_dir + web.ctx.path, 'rb').read()
+ except IOError:
+ raise web.notfound()
+
+def mime_type(filename):
+ return mimetypes.guess_type(filename)[0] or 'application/octet-stream'
No changes.
@@ -0,0 +1,64 @@
+# Author: Alex Ksikes
+
+import web
+import config
+
+import re, urlparse, datetime, urllib, utils, string
+
+def format_date(d, f):
+ return d.strftime(f)
+
+def url_quote(url):
+ return web.urlquote(url)
+
+def html_quote(html):
+ return web.htmlquote(url)
+
+def url_encode(query, clean=True, doseq=True, **kw):
+ query = web.dictadd(query, kw)
+ if clean is True:
+ for q, v in query.items():
+ if not v:
+ del query[q]
+ return urllib.urlencode(query, doseq)
+
+def cut_length(s, max=40):
+ if len(s) > max:
+ s = s[0:max] + '...'
+ return s
+
+def get_nice_url(url):
+ host, path = urlparse.urlparse(url)[1:3]
+ if path == '/':
+ path = ''
+ return cut_length(host+path)
+
+def capitalize_first(str):
+ if not str:
+ str = ''
+ return ' '.join(map(string.capitalize, str.lower().split()))
+
+def text2html(s):
+ s = replace_breaks(s)
+ s = replace_indents(s)
+ return replace_links(s)
+
+def replace_breaks(s):
+ return re.sub('\n', '<br />', s)
+
+def replace_indents(s):
+ s = re.sub('\t', 4*' ', s)
+ return re.sub('\s{2}', '&nbsp;'*2, s)
+
+def replace_links(s):
+ return re.sub('(http://[^\s]+)', r'<a rel="nofollow" href="\1">' + get_nice_url(r'\1') + '</a>', s, re.I)
+
+# we may need to get months ago as well
+def how_long(d):
+ return web.datestr(d, datetime.datetime.now())
+
+def split(pattern, str):
+ return re.split(pattern, str)
+
+def get_site_config(attr):
+ return getattr(config, attr)
Oops, something went wrong.

0 comments on commit aa1719b

Please sign in to comment.