github.com/bitcubate/cryptojournal@v1.2.5-0.20171102134152-f578b3d788ab/src/app/services.go (about)

     1  package app
     2  
     3  import (
     4  	"time"
     5  
     6  	"github.com/fragmenta/server/config"
     7  	"github.com/bitcubate/cryptojournal/src/lib/twitter"
     8  	"github.com/bitcubate/cryptojournal/src/stories/actions"
     9  )
    10  
    11  // SetupServices sets up external services from our config file
    12  func SetupServices() {
    13  
    14  	// Don't send if not on production server
    15  	if !config.Production() {
    16  		return
    17  	}
    18  
    19  	now := time.Now().UTC()
    20  
    21  	// Set up twitter if available, and schedule tweets
    22  	if config.Get("twitter_secret") != "" {
    23  		twitter.Setup(config.Get("twitter_key"), config.Get("twitter_secret"), config.Get("twitter_token"), config.Get("twitter_token_secret"))
    24  
    25  		tweetTime := time.Date(now.Year(), now.Month(), now.Day(), 6, 0, 0, 0, time.UTC)
    26  		tweetInterval := 51 * 3 * time.Minute
    27  
    28  		// For testing
    29  		//tweetTime = now.Add(time.Second * 5)
    30  
    31  		ScheduleAt(storyactions.TweetTopStory, tweetTime, tweetInterval)
    32  	}
    33  	/*
    34  		// Set up mail
    35  		if config.Get("mail_secret") != "" {
    36  			mail.Setup(config.Get("mail_secret"), config.Get("mail_from"))
    37  
    38  			// Schedule emails to go out at 09:00 every day, starting from the next occurance
    39  			emailTime := time.Date(now.Year(), now.Month(), now.Day(), 10, 10, 10, 10, time.UTC)
    40  			emailInterval := 7 * 24 * time.Hour // Send Emails weekly
    41  
    42  			// For testing send immediately on launch
    43  			//emailTime = now.Add(time.Second * 2)
    44  
    45  			schedule.At(useractions.DailyEmail, context, emailTime, emailInterval)
    46  		}
    47  	*/
    48  }
    49  
    50  // ScheduleAt schedules execution for a particular time and at intervals thereafter.
    51  // If interval is 0, the function will be called only once.
    52  // Callers should call close(task) before exiting the app or to stop repeating the action.
    53  func ScheduleAt(f func(), t time.Time, i time.Duration) chan struct{} {
    54  	task := make(chan struct{})
    55  	now := time.Now().UTC()
    56  
    57  	// Check that t is not in the past, if it is increment it by interval until it is not
    58  	for now.Sub(t) > 0 {
    59  		t = t.Add(i)
    60  	}
    61  
    62  	// We ignore the timer returned by AfterFunc - so no cancelling, perhaps rethink this
    63  	tillTime := t.Sub(now)
    64  	time.AfterFunc(tillTime, func() {
    65  		// Call f at least once at the time specified
    66  		go f()
    67  
    68  		// If we have an interval, call it again repeatedly after interval
    69  		// stopping if the caller calls stop(task) on returned channel
    70  		if i > 0 {
    71  			ticker := time.NewTicker(i)
    72  			go func() {
    73  				for {
    74  					select {
    75  					case <-ticker.C:
    76  						go f()
    77  					case <-task:
    78  						ticker.Stop()
    79  						return
    80  					}
    81  				}
    82  			}()
    83  		}
    84  	})
    85  
    86  	return task // call close(task) to stop executing the task for repeated tasks
    87  }