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 @@