diff --git a/models/campaign.go b/models/campaign.go index 7e8f35b1..81ec8c21 100644 --- a/models/campaign.go +++ b/models/campaign.go @@ -36,6 +36,17 @@ func (c *Campaign) Validate() (string, bool) { return "", true } +func (c *Campaign) UpdateStatus(s string) error { + // This could be made simpler, but I think there's a bug in gorm + return db.Table("campaigns").Where("id=?", c.Id).Update("status", s).Error +} + +func (c *Campaign) AddEvent (e Event) error { + e.CampaignId = c.Id + e.Time = time.Now() + return db.Debug().Save(&e).Error +} + type Result struct { Id int64 `json:"-"` CampaignId int64 `json:"-"` @@ -43,12 +54,16 @@ type Result struct { Status string `json:"status" sql:"not null"` } +func (r *Result) UpdateStatus(s string) error { + return db.Debug().Table("results").Where("id=?", r.Id).Update("status", s).Error +} + type Event struct { Id int64 `json:"-"` CampaignId int64 `json:"-"` Email string `json:"email"` Time time.Time `json:"time"` - Message time.Time `json:"message"` + Message string `json:"message"` } // GetCampaigns returns the campaigns owned by the given user. @@ -81,10 +96,10 @@ func GetCampaign(id int64, uid int64) (Campaign, error) { // PostCampaign inserts a campaign and all associated records into the database. func PostCampaign(c *Campaign, uid int64) error { // Fill in the details + c.UserId = uid c.CreatedDate = time.Now() c.CompletedDate = time.Time{} c.Status = QUEUED - c.Events = append(c.Events) // Check to make sure all the groups already exist for i, g := range c.Groups { c.Groups[i], err = GetGroupByName(g.Name, uid) @@ -113,27 +128,26 @@ func PostCampaign(c *Campaign, uid int64) error { Logger.Println(err) return err } + err = c.AddEvent(Event{Message:"Campaign Created"}) + if err != nil { + Logger.Println(err) + } // Insert all the results for _, g := range c.Groups { // Insert a result for each target in the group for _, t := range g.Targets { r := Result{Email: t.Email, Status: "Unknown", CampaignId: c.Id} - c.Results = append(c.Results, r) err := db.Save(&r).Error if err != nil { Logger.Printf("Error adding result record for target %s\n", t.Email) Logger.Println(err) } + c.Results = append(c.Results, r) } } return nil } -func UpdateCampaignStatus(c *Campaign, s string) error { - // This could be made simpler, but I think there's a bug in gorm - return db.Table("campaigns").Where("id=?", c.Id).Update("status", s).Error -} - //DeleteCampaign deletes the specified campaign func DeleteCampaign(id int64) error { // Delete all the campaign results diff --git a/models/models.go b/models/models.go index 9c5b0bcc..8f5248a3 100644 --- a/models/models.go +++ b/models/models.go @@ -57,6 +57,7 @@ func Setup() error { db.CreateTable(GroupTarget{}) db.CreateTable(Template{}) db.CreateTable(SMTP{}) + db.CreateTable(Event{}) db.CreateTable(Campaign{}) //Create the default user init_user := User{ diff --git a/static/css/main.css b/static/css/main.css index 75334181..37b7a85b 100644 --- a/static/css/main.css +++ b/static/css/main.css @@ -127,4 +127,24 @@ .dropdown-menu > li > a { cursor:pointer; +} + +.btn-file { + position: relative; + overflow: hidden; +} +.btn-file input[type=file] { + position: absolute; + top: 0; + right: 0; + min-width: 100%; + min-height: 100%; + font-size: 999px; + text-align: right; + filter: alpha(opacity=0); + opacity: 0; + outline: none; + background: white; + cursor: inherit; + display: block; } \ No newline at end of file diff --git a/static/js/app/app.js b/static/js/app/app.js index 86d382fc..1b03eaeb 100644 --- a/static/js/app/app.js +++ b/static/js/app/app.js @@ -35,6 +35,19 @@ app.config(function($routeProvider) { }) }); +app.filter('cut', function() { + return function(value, max, tail) { + if (!value) return ''; + max = parseInt(max, 10); + truncd = [] + for(var i=0; i < Math.min(value.length,max); i++) { + if (i == max-1) truncd.push("...") + else truncd.push(value[i].email); + } + return truncd; + }; +}); + // Example provided by http://docs.angularjs.org/api/ng/type/ngModel.NgModelController app.directive('contenteditable', function() { return { @@ -59,11 +72,11 @@ app.directive('contenteditable', function() { var html = element.html(); // When we clear the content editable the browser leaves a
behind // If strip-br attribute is provided then we strip this out - if (attrs.stripBr && html == '
') { - html = ''; - } + //if (attrs.stripBr && html == '
') { + // html = ''; + //} ngModel.$setViewValue(html); } } }; -}); \ No newline at end of file +}); diff --git a/static/js/app/controllers.js b/static/js/app/controllers.js index 50e112ae..48ef07a5 100644 --- a/static/js/app/controllers.js +++ b/static/js/app/controllers.js @@ -124,6 +124,10 @@ var CampaignModalCtrl = function($scope, $modalInstance) { $scope.cancel = function() { $modalInstance.dismiss('cancel'); }; + $scope.ok = function(campaign) { + $modalInstance.dismiss("") + $scope.saveCampaign(campaign) + } }; app.controller('CampaignResultsCtrl', function($scope, CampaignService, GroupService, ngTableParams, $http, $window) { @@ -333,7 +337,6 @@ var GroupModalCtrl = function($scope, $modalInstance, $upload) { }).progress(function(evt) { console.log('percent: ' + parseInt(100.0 * evt.loaded / evt.total)); }).success(function(data, status, headers, config) { - // file is uploaded successfully angular.forEach(data, function(record, key) { $scope.group.targets.push({ email: record.email @@ -451,6 +454,10 @@ var TemplateModalCtrl = function($scope, $modalInstance) { $scope.cancel = function() { $modalInstance.dismiss('cancel'); }; + $scope.ok = function(template) { + $modalInstance.dismiss('') + $scope.saveTemplate(template) + }; }; app.controller('SettingsCtrl', function($scope, $http, $window) { diff --git a/static/js/app/partials/modals/templateModal.html b/static/js/app/partials/modals/templateModal.html index c4dfdc75..b3ae1cd8 100644 --- a/static/js/app/partials/modals/templateModal.html +++ b/static/js/app/partials/modals/templateModal.html @@ -39,5 +39,5 @@ diff --git a/static/js/app/partials/modals/userModal.html b/static/js/app/partials/modals/userModal.html index 27756e01..6ebd01a0 100644 --- a/static/js/app/partials/modals/userModal.html +++ b/static/js/app/partials/modals/userModal.html @@ -10,12 +10,11 @@
- -
-
- -
-
+
+ Bulk Import Users + + +
diff --git a/static/js/app/partials/users.html b/static/js/app/partials/users.html index dfd16c3b..7f02db02 100644 --- a/static/js/app/partials/users.html +++ b/static/js/app/partials/users.html @@ -37,8 +37,8 @@ {{group.name}} - - {{target.email}}{{$last ? '' : ', '}} + + {{target}}{{$last ? '' : ', '}}
diff --git a/worker/worker.go b/worker/worker.go index e6d5de39..5fed33a0 100644 --- a/worker/worker.go +++ b/worker/worker.go @@ -33,7 +33,7 @@ func (w *Worker) Start() { func processCampaign(c *models.Campaign) { Logger.Printf("Worker received: %s", c.Name) - err := models.UpdateCampaignStatus(c, models.IN_PROGRESS) + err := c.UpdateStatus(models.IN_PROGRESS) if err != nil { Logger.Println(err) } @@ -58,7 +58,17 @@ func processCampaign(c *models.Campaign) { err := e.Send(c.SMTP.Host, auth) if err != nil { Logger.Println(err) + err = t.UpdateStatus("Error") + if err != nil { + Logger.Println(err) + } + } else { + err = t.UpdateStatus("Email Sent") + if err != nil { + Logger.Println(err) + } } + Logger.Printf("Sending Email to %s\n", t.Email) } }