Example #1
0
func baseFind(o Option) r.Term {
	q := r.Table(resourceName)

	// slicing
	if o.Slice != "" {
		slice := strings.Split(o.Slice, ",")
		start, _ := strconv.Atoi(slice[0])
		end, _ := strconv.Atoi(slice[1])
		q = q.Slice(start, end)
	}

	// ordering
	if o.Order != "" {
		order := strings.Split(strings.ToLower(o.Order), ",")
		if len(order) == 2 && order[1] == "desc" {
			q = q.OrderBy(r.Desc(order[0]))
		} else {
			q = q.OrderBy(order[0])
		}
	}

	// filtering
	q = q.Filter(o.Filter)

	return q
}
Example #2
0
func addOptions(q rdb.Term, value string, index string, opts *t.BrowseOpt) rdb.Term {
	var limit uint = 1024 // TODO(gene): pass into adapter as a config param
	var lower, upper interface{}

	if opts != nil {
		if opts.Since > 0 {
			lower = opts.Since
		} else {
			lower = rdb.MinVal
		}

		if opts.Before > 0 {
			upper = opts.Before
		} else {
			upper = rdb.MaxVal
		}

		if value != "" {
			lower = []interface{}{value, lower}
			upper = []interface{}{value, upper}
		}

		if opts.Limit > 0 && opts.Limit < limit {
			limit = opts.Limit
		}
	} else {
		lower = []interface{}{value, rdb.MinVal}
		upper = []interface{}{value, rdb.MaxVal}
	}

	return q.Between(lower, upper, rdb.BetweenOpts{Index: index}).
		OrderBy(rdb.OrderByOpts{Index: rdb.Desc(index)}).Limit(limit)
}
func loadLatestSales(websocketConnection *websocket.Conn) {
	results, err := r.Table("analytics").Filter(M{
		"type": "sale",
	}).OrderBy(
		r.Desc(r.Row.Field("data").Field("date")),
	).Limit(10).Map(func(row r.Term) interface{} {
		return row.Field("data")
	}).Run(rethinkSession)
	if err != nil {
		log.Printf("error loadLatestSales: %q", err)
	}
	defer results.Close()

	var latestSales []interface{}
	err = results.All(&latestSales)
	if err != nil {
		log.Println(err)
		return
	}

	log.Printf("sending latest %d sales\n", len(latestSales))

	socketOutgoingMessage := &SocketOutgoingMessage{
		Function: "loadLatestSales",
		Data: M{
			"type": "sale",
			"data": latestSales,
		},
	}

	err = websocketConnection.WriteJSON(socketOutgoingMessage)
	if err != nil {
		log.Println(err)
	}
}
Example #4
0
func Slot(r Repository) (*db.Cursor, error) {
	return db.Table(r.Table()).
		Filter(db.Row.Field("slot").Gt(0)).
		OrderBy(db.Desc("slot")).
		Pluck("id", "name", "slot").
		Run(r.Session())
}
Example #5
0
func (r *repo) GetAllArticlesInBlog(blog *blogalert.Blog) ([]*blogalert.Article, error) {
	if blog == nil {
		return nil, nil
	}

	cursor, err := gorethink.DB(Database).Table(ArticleTable).
		OrderBy(gorethink.Desc("ts")).
		Filter(gorethink.Row.Field("blog").Eq(blog.URL.String())).
		Limit(100).
		Run(r.session)

	if err != nil {
		return nil, err
	}

	a := []*article{}

	err = cursor.All(&a)
	if err != nil {
		return nil, err
	}

	articles := make([]*blogalert.Article, 0, len(a))

	for _, v := range a {
		if article, err := v.ToArticle(blog); err == nil {
			articles = append(articles, article)
			r.cache.SetArticle(article)
		}
	}

	return articles, nil
}
Example #6
0
func (r *repo) GetUserArticlesRead(UID string, blog *blogalert.Blog) ([]*blogalert.Article, error) {
	if blog == nil {
		return nil, nil
	}

	cursor, err := gorethink.DB(Database).Table(ArticleReadTable).
		OrderBy(gorethink.Desc("ts")).
		Filter(gorethink.Row.Field("uid").Eq(UID)).
		Filter(gorethink.Row.Field("blog").Eq(blog.URL.String())).
		Limit(100).
		Run(r.session)
	if err != nil {
		return nil, err
	}

	a := []*articleRead{}

	err = cursor.All(&a)
	if err != nil {
		return nil, err
	}

	articles := make([]*blogalert.Article, 0, len(a))

	for _, v := range a {
		if article, err := r.GetArticle(v.ArticleURL); err == nil {
			articles = append(articles, article)
		}
	}

	return articles, nil
}
Example #7
0
func List(r Repository, nameField string, offset int, limit int) (*db.Cursor, error) {
	return db.Table(r.Table()).
		OrderBy(db.OrderByOpts{Index: db.Desc("id")}).
		Slice(offset, limit).
		Pluck("id", nameField).
		Run(r.Session())
}
Example #8
0
func subscribeChannelMessage(client *Client, data interface{}) {
	go func() {
		eventData := data.(map[string]interface{})
		val, ok := eventData["channelId"]
		if !ok {
			return
		}
		channelId, ok := val.(string)
		if !ok {
			return
		}
		stop := client.NewStopChannel(MessageStop)
		cursor, err := r.Table("message").
			OrderBy(r.OrderByOpts{Index: r.Desc("createdAt")}).
			Filter(r.Row.Field("channelId").Eq(channelId)).
			Changes(r.ChangesOpts{IncludeInitial: true}).
			Run(client.session)

		if err != nil {
			client.send <- Message{"error", err.Error()}
			return
		}
		changeFeedHelper(cursor, "message", client.send, stop)
	}()
}
Example #9
0
func (m *Manager) Events(limit int) ([]*shipyard.Event, error) {
	res, err := r.Table(tblNameEvents).OrderBy(r.Desc("Time")).Limit(limit).Run(m.session)
	if err != nil {
		return nil, err
	}
	var events []*shipyard.Event
	if err := res.All(&events); err != nil {
		return nil, err
	}
	return events, nil
}
Example #10
0
func main() {
	log.Println("VERSION: ", VERSION)
	e := echo.New()
	e.Use(middleware.Logger())
	e.Use(middleware.Recover())
	e.Use(cors.Default().Handler)
	e.Index("public/index.html")
	e.Static("/", "public")

	if len(os.Args) < 2 {
		fmt.Println("\nPlease input callback url.\n  Usage: app.exe [callback_url]")
		os.Exit(0)
	}
	callback_url = os.Args[1]
	//e.Favicon("public/favicon.ico")

	server, err := socketio.NewServer(nil)
	if err != nil {
		log.Fatal(err)
	}
	e.Get("/publish/photo", CallbackHandler)
	e.Post("/publish/photo", ReceiveHandler)
	e.Get("/socket.io/", server)

	server.On("connection", func(so socketio.Socket) {
		log.Println("====================== on connection ======================")
		result := make([]interface{}, 12)
		cur, err := r.Table("instacat").OrderBy(r.OrderByOpts{
			Index: r.Desc("time"),
		}).Limit(12).Run(session)
		if err != nil {
			log.Println(err.Error())
		}
		cur.All(&result)
		fmt.Println("Get result over. ")
		err = so.Emit("recent", result)
		if err != nil {
			log.Println(err.Error())
		}
		so.On("disconnect", func() {
			log.Println("on disconnect")
		})

		RealtimeChangefeed(so)
	})

	//go SubscribeTag()
	go sub()
	port := ":3000"
	log.Printf("Starting HTTP service on %s ...", port)
	e.Run(port)

}
Example #11
0
func (m DefaultManager) Events(limit int) ([]*shipyard.Event, error) {
	t := r.Table(tblNameEvents).OrderBy(r.Desc("Time"))
	if limit > -1 {
		t.Limit(limit)
	}
	res, err := t.Run(m.session)
	if err != nil {
		return nil, err
	}
	events := []*shipyard.Event{}
	if err := res.All(&events); err != nil {
		return nil, err
	}
	return events, nil
}
Example #12
0
func (s *Storage) GetLatestQuote() Quote {

	rows, err := r.Table("quotes").OrderBy(r.Desc("timestamp")).Run(s.Session)
	if err != nil {
		fmt.Println(err)
	}
	defer rows.Close()

	var quote Quote
	err2 := rows.One(&quote)
	if err2 != nil {
		fmt.Println(err2)
	}

	fmt.Printf("Fetch one record %#v\n", quote)

	return quote
}
Example #13
0
func (c *rethinkClient) GetPipelineRunStatusLatest(id string) (*pps.PipelineRunStatus, error) {
	cursor, err := c.statuses.
		GetAllByIndex("pipeline_run_id", id).
		OrderBy(gorethink.Desc("timestamp")).
		Nth(0).
		ToJSON().
		Run(c.session)
	if err != nil {
		return nil, err
	}
	data := ""
	if !cursor.Next(&data) {
		return nil, cursor.Err()
	}
	var pipelineRunStatus pps.PipelineRunStatus
	if err := jsonpb.UnmarshalString(data, &pipelineRunStatus); err != nil {
		return nil, err
	}
	return &pipelineRunStatus, nil
}
func (a *rethinkAPIServer) ListPipelineInfos(ctx context.Context, request *google_protobuf.Empty) (response *persist.PipelineInfos, err error) {
	defer func(start time.Time) { a.Log(request, response, err, time.Since(start)) }(time.Now())
	pipelineInfoObjs, err := a.getAllMessages(
		pipelineInfosTable,
		func() proto.Message { return &persist.PipelineInfo{} },
		func(term gorethink.Term) gorethink.Term {
			return term.OrderBy(gorethink.Desc("created_at"))
		},
	)
	if err != nil {
		return nil, err
	}
	pipelineInfos := make([]*persist.PipelineInfo, len(pipelineInfoObjs))
	for i, pipelineInfoObj := range pipelineInfoObjs {
		pipelineInfos[i] = pipelineInfoObj.(*persist.PipelineInfo)
	}
	return &persist.PipelineInfos{
		PipelineInfo: pipelineInfos,
	}, nil
}
Example #15
0
func (c *Connection) GetBookmarks(userID string, page int64) ([]Bookmark, error) {
	var bookmarks []Bookmark

	cursor, err := r.DB("magnet").
		Table("bookmarks").
		OrderBy(r.OrderByOpts{r.Desc("Created")}).
		Filter(r.Row.Field("User").Eq(userID)).
		Skip(50 * page).
		Limit(50).
		Run(c.session)

	if err != nil {
		log.Print(err)
		return bookmarks, err
	}

	cursor.All(&bookmarks)
	cursor.Close()
	return bookmarks, err
}
Example #16
0
func (c *rethinkClient) GetAllPipelineRunStatuses(pipelineRunID string) ([]*pps.PipelineRunStatus, error) {
	cursor, err := c.pipelineRunStatuses.
		GetAllByIndex("pipeline_run_id", pipelineRunID).
		OrderBy(gorethink.Desc("timestamp")).
		Without("id").
		Map(rethinkToJSON).
		Run(c.session)
	if err != nil {
		return nil, err
	}
	var pipelineRunStatuses []*pps.PipelineRunStatus
	data := ""
	for cursor.Next(&data) {
		var pipelineRunStatus pps.PipelineRunStatus
		if err := jsonpb.UnmarshalString(data, &pipelineRunStatus); err != nil {
			return nil, err
		}
		pipelineRunStatuses = append(pipelineRunStatuses, &pipelineRunStatus)
	}
	return pipelineRunStatuses, cursor.Err()
}
Example #17
0
func orders(w http.ResponseWriter, q *http.Request) {
	ctx, err := NewContext(q)
	if err != nil {
		log.Println(err)
	}

	rows, err := r.Db("goShop").Table("orders").OrderBy(r.Desc("Date")).Run(ctx.Db)

	if err != nil {
		log.Println(err)
	}
	var t []Order
	err = rows.All(&t)
	if err != nil {
		log.Println(err)
	}

	newmap := map[string]interface{}{"Orders": t}

	templatesA.ExecuteTemplate(w, "orders", newmap)

}
func (a *rethinkAPIServer) GetJobInfosByPipeline(ctx context.Context, request *pps.Pipeline) (response *persist.JobInfos, err error) {
	defer func(start time.Time) { a.Log(request, response, err, time.Since(start)) }(time.Now())
	jobInfoObjs, err := a.getMessagesByIndex(
		jobInfosTable,
		pipelineNameIndex,
		request.Name,
		func() proto.Message { return &persist.JobInfo{} },
		func(term gorethink.Term) gorethink.Term {
			return term.OrderBy(gorethink.Desc("created_at"))
		},
	)
	if err != nil {
		return nil, err
	}
	jobInfos := make([]*persist.JobInfo, len(jobInfoObjs))
	for i, jobInfoObj := range jobInfoObjs {
		jobInfos[i] = jobInfoObj.(*persist.JobInfo)
	}
	return &persist.JobInfos{
		JobInfo: jobInfos,
	}, nil
}
// ordered by time, latest to earliest
func (a *rethinkAPIServer) GetJobLogs(ctx context.Context, request *pps.Job) (response *persist.JobLogs, err error) {
	defer func(start time.Time) { a.Log(request, response, err, time.Since(start)) }(time.Now())
	jobLogObjs, err := a.getMessagesByIndex(
		jobLogsTable,
		jobIDIndex,
		request.Id,
		func() proto.Message { return &persist.JobLog{} },
		func(term gorethink.Term) gorethink.Term {
			return term.OrderBy(gorethink.Desc("timestamp"))
		},
	)
	if err != nil {
		return nil, err
	}
	jobLogs := make([]*persist.JobLog, len(jobLogObjs))
	for i, jobLogObj := range jobLogObjs {
		jobLogs[i] = jobLogObj.(*persist.JobLog)
	}
	return &persist.JobLogs{
		JobLog: jobLogs,
	}, nil
}
Example #20
0
func (c *Connection) Search(userID string, params martini.Params, query string) ([]interface{}, error) {
	var response []interface{}
	page, _ := strconv.ParseInt(params["page"], 10, 16)

	cursor, err := r.DB("magnet").
		Table("bookmarks").
		OrderBy(r.OrderByOpts{r.Desc("Created")}).
		Filter(r.Row.Field("Title").Match("(?i)" + query).
			And(r.Row.Field("User").Eq(userID))).
		Skip(50 * page).
		Limit(50).
		Run(c.session)

	if err != nil {
		log.Print(err)
		return nil, err
	}

	cursor.All(&response)
	cursor.Close()
	return response, err
}
Example #21
0
func Get(session *gorethink.Session, w http.ResponseWriter, r *http.Request, render render.Render) {
	humidityPage := HumidityPage{}
	var offset int
	{
		strPage := r.URL.Query().Get("page")
		offset, _ = strconv.Atoi(strPage)
		if offset <= 0 {
			offset = 0
		}
	}
	limit := 10
	humidityPage.CurrentPage = offset * limit
	res, err := gorethink.Table("humidity").OrderBy(gorethink.Desc("date_created")).Skip(humidityPage.CurrentPage).Limit(limit).Run(session)
	if err != nil {
		render.HTML(404, "current_humidity", nil)
		return
	}

	humidityPage.Humidities = make([]*models.HumidityRecord, limit)
	for i := 0; i < limit; i++ {
		humidityPage.Humidities[i] = models.NewCleanRecord()
	}
	err = res.All(&humidityPage.Humidities)
	humidityPage.HasNext = false
	if len(humidityPage.Humidities) == limit {
		humidityPage.HasNext = true
	}

	if err != nil {
		render.HTML(404, "current_humidity", nil)
		return
	}

	humidityPage.NextPage = humidityPage.CurrentPage + 1
	humidityPage.PreviousPage = humidityPage.CurrentPage - 1

	render.HTML(200, "current_humidity", humidityPage)
}
func (a *rethinkAPIServer) ListJobInfos(ctx context.Context, request *pps.ListJobRequest) (response *persist.JobInfos, err error) {
	defer func(start time.Time) { a.Log(request, response, err, time.Since(start)) }(time.Now())
	query := a.getTerm(jobInfosTable)
	if request.Pipeline != nil && request.Input != nil {
		query = query.GetAllByIndex(
			pipelineNameAndInputIndex,
			gorethink.Expr([]string{request.Pipeline.Name, request.Input.Repo.Name, request.Input.Id}),
		)
	} else if request.Pipeline != nil {
		query = query.GetAllByIndex(
			pipelineNameIndex,
			request.Pipeline.Name,
		)
	} else if request.Input != nil {
		query = query.GetAllByIndex(
			inputIndex,
			gorethink.Expr([]string{request.Input.Repo.Name, request.Input.Id}),
		)
	}
	jobInfoObjs, err := a.getAllMessages(
		jobInfosTable,
		func() proto.Message { return &persist.JobInfo{} },
		func(term gorethink.Term) gorethink.Term {
			return term.OrderBy(gorethink.Desc("created_at"))
		},
	)
	if err != nil {
		return nil, err
	}
	jobInfos := make([]*persist.JobInfo, len(jobInfoObjs))
	for i, jobInfoObj := range jobInfoObjs {
		jobInfos[i] = jobInfoObj.(*persist.JobInfo)
	}
	return &persist.JobInfos{
		JobInfo: jobInfos,
	}, nil
}
Example #23
0
func (e *EmailsTable) List(
	owner string,
	sort []string,
	offset int,
	limit int,
	thread string,
) ([]*models.Email, error) {

	filter := map[string]interface{}{}

	if owner != "" {
		filter["owner"] = owner
	}

	if thread != "" {
		filter["thread"] = thread
	}

	term := e.GetTable().Filter(filter).Filter(gorethink.Not(gorethink.Row.Field("status").Eq(gorethink.Expr("queued"))))

	// If sort array has contents, parse them and add to the term
	if sort != nil && len(sort) > 0 {
		var conds []interface{}
		for _, cond := range sort {
			if cond[0] == '-' {
				conds = append(conds, gorethink.Desc(cond[1:]))
			} else if cond[0] == '+' || cond[0] == ' ' {
				conds = append(conds, gorethink.Asc(cond[1:]))
			} else {
				conds = append(conds, gorethink.Asc(cond))
			}
		}

		term = term.OrderBy(conds...)
	}

	// Slice the result in 3 cases
	if offset != 0 && limit == 0 {
		term = term.Skip(offset)
	}

	if offset == 0 && limit != 0 {
		term = term.Limit(limit)
	}

	if offset != 0 && limit != 0 {
		term = term.Slice(offset, offset+limit)
	}

	// Run the query
	cursor, err := term.Run(e.GetSession())
	if err != nil {
		return nil, err
	}
	defer cursor.Close()

	// Fetch the cursor
	var resp []*models.Email
	err = cursor.All(&resp)
	if err != nil {
		return nil, err
	}

	return resp, nil
}
Example #24
0
func StartQueue(config *shared.Flags) {
	// Initialize a new logger
	log := logrus.New()
	if config.LogFormatterType == "text" {
		log.Formatter = &logrus.TextFormatter{
			ForceColors: config.ForceColors,
		}
	} else if config.LogFormatterType == "json" {
		log.Formatter = &logrus.JSONFormatter{}
	}

	log.Level = logrus.DebugLevel

	// Create a new header encoder
	he := quotedprintable.Q.NewHeaderEncoder("utf-8")

	// Initialize the database connection
	session, err := gorethink.Connect(gorethink.ConnectOpts{
		Address: config.RethinkAddress,
		AuthKey: config.RethinkKey,
		MaxIdle: 10,
		Timeout: time.Second * 10,
	})
	if err != nil {
		log.WithFields(logrus.Fields{
			"error": err.Error(),
		}).Fatal("Unable to connect to RethinkDB")
	}

	// Create a new producer
	consumer, err := nsq.NewConsumer("send_email", "receive", nsq.NewConfig())
	if err != nil {
		log.WithFields(logrus.Fields{
			"error": err.Error(),
		}).Fatal("Unable to create a consumer")
	}

	// Connect to NSQ
	producer, err := nsq.NewProducer(config.NSQDAddress, nsq.NewConfig())
	if err != nil {
		log.WithFields(logrus.Fields{
			"error": err.Error(),
		}).Fatal("Unable to connect to NSQd")
	}

	// Load a DKIM signer
	var dkimSigner map[string]*dkim.DKIM
	if config.DKIMKey != "" {
		dkimSigner = map[string]*dkim.DKIM{}

		key, err := ioutil.ReadFile(config.DKIMKey)
		if err != nil {
			log.WithFields(logrus.Fields{
				"error": err.Error(),
			}).Fatal("Unable to read DKIM private key")
		}

		for domain, _ := range domains {
			dkimConf, err := dkim.NewConf(domain, config.DKIMSelector)
			if err != nil {
				log.WithFields(logrus.Fields{
					"error": err.Error(),
				}).Fatal("Unable to create a new DKIM conf object")
			}

			dk, err := dkim.New(dkimConf, key)
			if err != nil {
				log.WithFields(logrus.Fields{
					"error": err.Error(),
				}).Fatal("Unable to create a new DKIM signer")
			}

			dkimSigner[domain] = dk
		}
	}

	consumer.AddConcurrentHandlers(nsq.HandlerFunc(func(msg *nsq.Message) error {
		var id string
		if err := json.Unmarshal(msg.Body, &id); err != nil {
			return err
		}

		// Get the email from the database
		cursor, err := gorethink.Db(config.RethinkDatabase).Table("emails").Get(id).Run(session)
		if err != nil {
			return err
		}
		defer cursor.Close()
		var email *models.Email
		if err := cursor.One(&email); err != nil {
			return err
		}

		// Get the thread
		cursor, err = gorethink.Db(config.RethinkDatabase).Table("threads").Get(email.Thread).Run(session)
		if err != nil {
			return err
		}
		defer cursor.Close()
		var thread *models.Thread
		if err := cursor.One(&thread); err != nil {
			return err
		}

		// Get the proper In-Reply-To
		hasInReplyTo := false
		inReplyTo := ""

		// Fetch received emails in the thread
		cursor, err = gorethink.Db(config.RethinkDatabase).Table("emails").GetAllByIndex("threadStatus", []interface{}{
			thread.ID,
			"received",
		}).Pluck("date_created", "message_id", "from").OrderBy(gorethink.Desc(gorethink.Row.Field("date_created"))).
			Filter(func(row gorethink.Term) gorethink.Term {
				return gorethink.Expr(email.To).Contains(row.Field("from"))
			}).Limit(1).Run(session)
		if err != nil {
			return err
		}
		defer cursor.Close()
		var emid []*models.Email
		if err := cursor.All(&emid); err != nil {
			return err
		}

		if len(emid) == 1 {
			hasInReplyTo = true
			inReplyTo = emid[0].MessageID
		}

		// Fetch the files
		var files []*models.File
		if email.Files != nil && len(email.Files) > 0 {
			filesList := []interface{}{}
			for _, v := range email.Files {
				filesList = append(filesList, v)
			}
			cursor, err = gorethink.Db(config.RethinkDatabase).Table("files").GetAll(filesList...).Run(session)
			if err != nil {
				return err
			}
			defer cursor.Close()
			if err := cursor.All(&files); err != nil {
				return err
			}
		} else {
			files = []*models.File{}
		}

		// Fetch the owner
		cursor, err = gorethink.Db(config.RethinkDatabase).Table("accounts").Get(email.Owner).Run(session)
		if err != nil {
			return err
		}
		defer cursor.Close()
		var account *models.Account
		if err := cursor.One(&account); err != nil {
			return err
		}

		// Declare a contents variable
		contents := ""

		ctxFrom := email.From

		// Check if charset is set
		if !strings.Contains(email.ContentType, "; charset=") {
			email.ContentType += "; charset=utf-8"
		}

		if email.Kind == "raw" {
			// Encode the email
			if files == nil || len(files) == 0 {
				buffer := &bytes.Buffer{}

				context := &rawSingleContext{
					From:         ctxFrom,
					CombinedTo:   strings.Join(email.To, ", "),
					MessageID:    email.MessageID,
					HasInReplyTo: hasInReplyTo,
					InReplyTo:    inReplyTo,
					Subject:      he.Encode(email.Name),
					ContentType:  email.ContentType,
					Body:         quotedprintable.EncodeToString([]byte(email.Body)),
					Date:         email.DateCreated.Format(time.RubyDate),
				}

				if email.CC != nil && len(email.CC) > 0 {
					context.HasCC = true
					context.CombinedCC = strings.Join(email.CC, ", ")
				}

				if email.ReplyTo != "" {
					context.HasReplyTo = true
					context.ReplyTo = email.ReplyTo
				}

				if err := rawSingleTemplate.Execute(buffer, context); err != nil {
					return err
				}

				contents = buffer.String()
			} else {
				buffer := &bytes.Buffer{}

				emailFiles := []*emailFile{}
				for _, file := range files {
					emailFiles = append(emailFiles, &emailFile{
						Encoding: file.Encoding,
						Name:     file.Name,
						Body:     base64.StdEncoding.EncodeToString([]byte(file.Data)),
					})
				}

				context := &rawMultiContext{
					From:         ctxFrom,
					CombinedTo:   strings.Join(email.To, ", "),
					MessageID:    email.MessageID,
					HasInReplyTo: hasInReplyTo,
					InReplyTo:    inReplyTo,
					Boundary1:    uniuri.NewLen(20),
					Subject:      he.Encode(email.Name),
					ContentType:  email.ContentType,
					Body:         quotedprintable.EncodeToString([]byte(email.Body)),
					Files:        emailFiles,
					Date:         email.DateCreated.Format(time.RubyDate),
				}

				if email.CC != nil && len(email.CC) > 0 {
					context.HasCC = true
					context.CombinedCC = strings.Join(email.CC, ", ")
				}

				if email.ReplyTo != "" {
					context.HasReplyTo = true
					context.ReplyTo = email.ReplyTo
				}

				if err := rawMultiTemplate.Execute(buffer, context); err != nil {
					return err
				}

				contents = buffer.String()
			}

			// Fetch owner's account
			cursor, err = gorethink.Db(config.RethinkDatabase).Table("accounts").Get(email.Owner).Run(session)
			if err != nil {
				return err
			}
			defer cursor.Close()
			var account *models.Account
			if err := cursor.One(&account); err != nil {
				return err
			}

			// Get owner's key
			var key *models.Key
			if account.PublicKey != "" {
				cursor, err = gorethink.Db(config.RethinkDatabase).Table("keys").Get(account.PublicKey).Run(session)
				if err != nil {
					return err
				}
				defer cursor.Close()
				if err := cursor.One(&key); err != nil {
					return err
				}
			} else {
				cursor, err = gorethink.Db(config.RethinkDatabase).Table("keys").GetAllByIndex("owner", account.ID).Run(session)
				if err != nil {
					return err
				}
				defer cursor.Close()
				var keys []*models.Key
				if err := cursor.All(&keys); err != nil {
					return err
				}

				key = keys[0]
			}

			// Parse the key
			keyring, err := openpgp.ReadArmoredKeyRing(strings.NewReader(key.Key))
			if err != nil {
				return err
			}

			// From, to and cc parsing
			fromAddr, err := mail.ParseAddress(email.From)
			if err != nil {
				fromAddr = &mail.Address{
					Address: email.From,
				}
			}
			toAddr, err := mail.ParseAddressList(strings.Join(email.To, ", "))
			if err != nil {
				toAddr = []*mail.Address{}
				for _, addr := range email.To {
					toAddr = append(toAddr, &mail.Address{
						Address: addr,
					})
				}
			}

			// Prepare a new manifest
			manifest := &man.Manifest{
				Version: semver.Version{
					Major: 1,
				},
				From:    fromAddr,
				To:      toAddr,
				Subject: he.Encode(email.Name),
				Parts:   []*man.Part{},
			}

			if email.CC != nil && len(email.CC) > 0 {
				ccAddr, nil := mail.ParseAddressList(strings.Join(email.CC, ", "))
				if err != nil {
					ccAddr = []*mail.Address{}
					for _, addr := range email.CC {
						ccAddr = append(ccAddr, &mail.Address{
							Address: addr,
						})
					}
				}

				manifest.CC = ccAddr
			}

			// Encrypt and hash the body
			encryptedBody, err := shared.EncryptAndArmor([]byte(email.Body), keyring)
			if err != nil {
				return err
			}
			hash := sha256.Sum256([]byte(email.Body))

			// Append body to the parts
			manifest.Parts = append(manifest.Parts, &man.Part{
				ID:          "body",
				Hash:        hex.EncodeToString(hash[:]),
				ContentType: email.ContentType,
				Size:        len(email.Body),
			})

			// Encrypt the attachments
			for _, file := range files {
				// Encrypt the attachment
				cipher, err := shared.EncryptAndArmor([]byte(file.Data), keyring)
				if err != nil {
					return err
				}

				// Hash it
				hash := sha256.Sum256([]byte(file.Data))

				// Generate a random ID
				id := uniuri.NewLen(20)

				// Push the attachment into the manifest
				manifest.Parts = append(manifest.Parts, &man.Part{
					ID:          id,
					Hash:        hex.EncodeToString(hash[:]),
					Filename:    file.Name,
					ContentType: file.Encoding,
					Size:        len(file.Data),
				})

				// Replace the file in database
				err = gorethink.Db(config.RethinkDatabase).Table("files").Get(file.ID).Replace(&models.File{
					Resource: models.Resource{
						ID:           file.ID,
						DateCreated:  file.DateCreated,
						DateModified: time.Now(),
						Name:         id + ".pgp",
						Owner:        account.ID,
					},
					Encrypted: models.Encrypted{
						Encoding: "application/pgp-encrypted",
						Data:     string(cipher),
					},
				}).Exec(session)
				if err != nil {
					return err
				}
			}

			// Encrypt the manifest
			strManifest, err := man.Write(manifest)
			if err != nil {
				return err
			}
			encryptedManifest, err := shared.EncryptAndArmor(strManifest, keyring)
			if err != nil {
				return err
			}

			err = gorethink.Db(config.RethinkDatabase).Table("emails").Get(email.ID).Replace(&models.Email{
				Resource: models.Resource{
					ID:           email.ID,
					DateCreated:  email.DateCreated,
					DateModified: time.Now(),
					Name:         "Encrypted message (" + email.ID + ")",
					Owner:        account.ID,
				},
				Kind:      "manifest",
				From:      email.From,
				To:        email.To,
				CC:        email.CC,
				BCC:       email.BCC,
				Files:     email.Files,
				Manifest:  string(encryptedManifest),
				Body:      string(encryptedBody),
				Thread:    email.Thread,
				MessageID: email.MessageID,
			}).Exec(session)
			if err != nil {
				return err
			}
		} else if email.Kind == "pgpmime" {
			buffer := &bytes.Buffer{}

			context := &pgpContext{
				From:         ctxFrom,
				CombinedTo:   strings.Join(email.To, ", "),
				MessageID:    email.MessageID,
				HasInReplyTo: hasInReplyTo,
				InReplyTo:    inReplyTo,
				Subject:      email.Name,
				ContentType:  email.ContentType,
				Body:         email.Body,
				Date:         email.DateCreated.Format(time.RubyDate),
			}

			if email.CC != nil && len(email.CC) > 0 {
				context.HasCC = true
				context.CombinedCC = strings.Join(email.CC, ", ")
			}

			if email.ReplyTo != "" {
				context.HasReplyTo = true
				context.ReplyTo = email.ReplyTo
			}

			if err := pgpTemplate.Execute(buffer, context); err != nil {
				return err
			}

			contents = buffer.String()
		} else if email.Kind == "manifest" {
			if files == nil || len(files) == 0 {
				buffer := &bytes.Buffer{}

				context := &manifestSingleContext{
					From:         ctxFrom,
					CombinedTo:   strings.Join(email.To, ", "),
					MessageID:    email.MessageID,
					HasInReplyTo: hasInReplyTo,
					InReplyTo:    inReplyTo,
					Subject:      he.Encode(email.Name),
					Boundary1:    uniuri.NewLen(20),
					Boundary2:    uniuri.NewLen(20),
					ID:           email.ID,
					Body:         email.Body,
					Manifest:     email.Manifest,
					SubjectHash:  thread.SubjectHash,
					Date:         email.DateCreated.Format(time.RubyDate),
				}

				if email.CC != nil && len(email.CC) > 0 {
					context.HasCC = true
					context.CombinedCC = strings.Join(email.CC, ", ")
				}

				if email.ReplyTo != "" {
					context.HasReplyTo = true
					context.ReplyTo = email.ReplyTo
				}

				if err := manifestSingleTemplate.Execute(buffer, context); err != nil {
					return err
				}

				contents = buffer.String()
			} else {
				buffer := &bytes.Buffer{}

				emailFiles := []*emailFile{}
				for _, file := range files {
					emailFiles = append(emailFiles, &emailFile{
						Encoding: file.Encoding,
						Name:     file.Name,
						Body:     file.Data,
					})
				}

				context := &manifestMultiContext{
					From:         ctxFrom,
					CombinedTo:   strings.Join(email.To, ", "),
					MessageID:    email.MessageID,
					HasInReplyTo: hasInReplyTo,
					InReplyTo:    inReplyTo,
					Subject:      he.Encode(email.Name),
					Boundary1:    uniuri.NewLen(20),
					Boundary2:    uniuri.NewLen(20),
					ID:           email.ID,
					Body:         email.Body,
					Manifest:     email.Manifest,
					SubjectHash:  thread.SubjectHash,
					Files:        emailFiles,
					Date:         email.DateCreated.Format(time.RubyDate),
				}

				if email.CC != nil && len(email.CC) > 0 {
					context.HasCC = true
					context.CombinedCC = strings.Join(email.CC, ", ")
				}

				if email.ReplyTo != "" {
					context.HasReplyTo = true
					context.ReplyTo = email.ReplyTo
				}

				if err := manifestMultiTemplate.Execute(buffer, context); err != nil {
					return err
				}

				contents = buffer.String()
			}
		}

		recipients := email.To
		if email.CC != nil {
			recipients = append(recipients, email.CC...)
		}

		nsqmsg, _ := json.Marshal(map[string]interface{}{
			"id":    email.ID,
			"owner": email.Owner,
		})

		// Sign the email
		if dkimSigner != nil {
			parts := strings.Split(email.From, "@")
			if len(parts) == 2 {
				if _, ok := dkimSigner[parts[1]]; ok {
					// Replace newlines with \r\n
					contents = strings.Replace(contents, "\n", "\r\n", -1)

					// Sign it
					data, err := dkimSigner[parts[1]].Sign([]byte(contents))
					if err != nil {
						log.Print(err)
						return err
					}

					// Replace contents with signed
					contents = strings.Replace(string(data), "\r\n", "\n", -1)
				}
			}
		}

		if err := smtp.SendMail(config.SMTPAddress, nil, email.From, recipients, []byte(contents)); err != nil {
			err := producer.Publish("email_bounced", nsqmsg)
			if err != nil {
				log.WithFields(logrus.Fields{
					"error": err,
				}).Error("Unable to publish a bounce msg")
			}
		} else {
			err := producer.Publish("email_delivery", nsqmsg)
			if err != nil {
				log.WithFields(logrus.Fields{
					"error": err,
				}).Error("Unable to publish a bounce msg")
			}
		}
		err = gorethink.Db(config.RethinkDatabase).Table("emails").Get(email.ID).Update(map[string]interface{}{
			"status": "sent",
		}).Exec(session)
		if err != nil {
			log.WithFields(logrus.Fields{
				"error": err,
			}).Error("Unable to mark an email as sent")
		}

		msg.Finish()

		return nil
	}), 10)

	if err := consumer.ConnectToNSQLookupd(config.LookupdAddress); err != nil {
		log.WithFields(logrus.Fields{
			"error": err,
		}).Fatal("Unable to connect to nsqlookupd")
	}

	log.Info("Connected to NSQ and awaiting data")
}
Example #25
0
func (c *AccountTransactions) ReadMany(ctx context.Context) (err error) {

	var transactions []models.Transaction
	accountId := ctx.PathValue("account_id")

	rows, err := r.Table("transactions").Filter(r.Row.Field("accountId").Eq(accountId)).OrderBy(r.Desc("createdAt")).Run(c.DbSession)

	for rows.Next() {
		var transaction models.Transaction

		err = rows.Scan(&transaction)
		if err != nil {
			return
		}

		transactions = append(transactions, transaction)
	}

	if err != nil {
		log.Fatal(err)
		return goweb.Respond.WithStatus(ctx, http.StatusNotFound)
	}
	return goweb.API.RespondWithData(ctx, transactions)
}
Example #26
0
func (t *ThreadsTable) List(
	owner string,
	sort []string,
	offset int,
	limit int,
	labels []string,
) ([]*models.Thread, error) {

	term := t.GetTable()

	if owner != "" {
		term = t.GetTable().GetAllByIndex("owner", owner)
	}

	// If sort array has contents, parse them and add to the term
	if sort != nil && len(sort) > 0 {
		var conds []interface{}
		for _, cond := range sort {
			if cond[0] == '-' {
				conds = append(conds, gorethink.Desc(cond[1:]))
			} else if cond[0] == '+' || cond[0] == ' ' {
				conds = append(conds, gorethink.Asc(cond[1:]))
			} else {
				conds = append(conds, gorethink.Asc(cond))
			}
		}

		term = term.OrderBy(conds...)
	}

	// Parse labels
	hasLabels := []string{}
	excLabels := []string{}
	for _, label := range labels {
		if label[0] == '-' {
			excLabels = append(excLabels, label[1:])
		} else {
			hasLabels = append(hasLabels, label)
		}
	}

	// Transform that into a term
	if len(hasLabels) > 0 || len(excLabels) > 0 {
		var hasTerm gorethink.Term
		if len(hasLabels) == 1 {
			hasTerm = gorethink.Row.Field("labels").Contains(hasLabels[0])
		} else if len(hasLabels) > 0 {
			for i, label := range hasLabels {
				if i == 0 {
					hasTerm = gorethink.Row.Field("labels").Contains(label)
				} else {
					hasTerm = hasTerm.And(gorethink.Row.Field("labels").Contains(label))
				}
			}
		}

		var excTerm gorethink.Term
		if len(excLabels) == 1 {
			excTerm = gorethink.Not(gorethink.Row.Field("labels").Contains(excLabels[0]))
		} else {
			for i, label := range excLabels {
				if i == 0 {
					excTerm = gorethink.Not(gorethink.Row.Field("labels").Contains(label))
				} else {
					excTerm = excTerm.And(gorethink.Not(gorethink.Row.Field("labels").Contains(label)))
				}
			}
		}

		// Append them into the term
		if len(hasLabels) > 0 && len(excLabels) > 0 {
			term = term.Filter(hasTerm.And(excTerm))
		} else if len(hasLabels) > 0 && len(excLabels) == 0 {
			term = term.Filter(hasTerm)
		} else if len(hasLabels) == 0 && len(excLabels) > 0 {
			term = term.Filter(excTerm)
		}
	}

	// Slice the result
	if offset != 0 || limit != 0 {
		term = term.Slice(offset, offset+limit)
	}

	// Add manifests
	term = term.Map(func(thread gorethink.Term) gorethink.Term {
		return thread.Merge(gorethink.Db(t.GetDBName()).Table("emails").Between([]interface{}{
			thread.Field("id"),
			time.Date(1990, time.January, 1, 23, 0, 0, 0, time.UTC),
		}, []interface{}{
			thread.Field("id"),
			time.Date(2090, time.January, 1, 23, 0, 0, 0, time.UTC),
		}, gorethink.BetweenOpts{
			Index: "threadAndDate",
		}).OrderBy(gorethink.OrderByOpts{Index: "threadAndDate"}).
			Nth(0).Pluck("manifest"))
	})

	// Run the query
	cursor, err := term.Run(t.GetSession())
	if err != nil {
		return nil, err
	}
	defer cursor.Close()

	// Fetch the cursor
	var resp []*models.Thread
	err = cursor.All(&resp)
	if err != nil {
		return nil, err
	}

	return resp, nil
}
Example #27
0
func All(r Repository, offset int, limit int) (*db.Cursor, error) {
	return db.Table(r.Table()).
		OrderBy(db.OrderByOpts{Index: db.Desc("id")}).
		Slice(offset, limit).
		Run(r.Session())
}