Beispiel #1
0
	def get(self):
		settings = Settings.get() #Force email address update...
		posts = Post.query().order(-Post.date).fetch(1)
		is_newest = True
		if posts:
			post = posts[0]
			is_oldest = post.date == Post.min_date()
		else:
			post = None
			is_oldest = True


		#See if this is the very first time we've been here. In that case
		#send an email immediately to get people started...
		first_time = False
		
		if not Slug.query().get() and not Post.query().get():
			first_time = True
			DailyMail().send(True)

		self.response.write(get_template('frontpage.html').render(
			{
				"page":"frontpage", 
				"post":post, 
				"is_oldest" : is_oldest,
				"is_newest" : is_newest,
				"first_time" : first_time,
				"email" : settings.email_address
			}))
Beispiel #2
0
    def get(self):
        settings = Settings.get()  #Force email address update...
        posts = Post.query().order(-Post.date).fetch(1)
        is_newest = True
        if posts:
            post = posts[0]
            is_oldest = post.date == Post.min_date()
        else:
            post = None
            is_oldest = True

        #See if this is the very first time we've been here. In that case
        #send an email immediately to get people started...
        first_time = False

        if not Slug.query().get() and not Post.query().get():
            first_time = True
            DailyMail().send(True)

        self.response.write(
            get_template('frontpage.html').render({
                "page":
                "frontpage",
                "post":
                post,
                "is_oldest":
                is_oldest,
                "is_newest":
                is_newest,
                "first_time":
                first_time,
                "email":
                settings.email_address
            }))
Beispiel #3
0
	def post(self):
		settings = Settings.get()

		settings.email_address = self.request.get('email-address')
		settings.timezone = self.request.get('timezone')
		settings.email_hour = int(self.request.get('email-hour'))
		settings.dropbox_access_token = self.request.get('dropbox-access-token')
		settings.include_old_post_in_entry = self.request.get('include-old-entry') == 'yes'
		settings.put()
		self._render(settings, True)
Beispiel #4
0
	def get(self):

		#Check whether the migration is done so we can see whether to show the Blobstore Migration
		#or not...
		settings = Settings.get()

		if not settings.blobstore_migration_done:
			migration_task_finished = bool(MigrateTask.query(MigrateTask.status == 'finished').get())
			if migration_task_finished:
				settings.blobstore_migration_done = True
				settings.put()
			else:
				#Try to figure out whether this is a new user that has nothing in the blobstore...
				if not UserImage.query().get():
					settings.blobstore_migration_done = True
					settings.put()

		self._render(settings)
Beispiel #5
0
def log_error(subject, message, *args):
	if args:
		try:
			message = message % args
		except:
			pass

	logging.error(subject + ' : ' + message)

	subject = 'MyLife Error: ' + subject
	app_id = app_identity.get_application_id()
	sender = "MyLife Errors <errors@%s.appspotmail.com>" % app_id
	try:
		to = Settings.get().email_address
		mail.check_email_valid(to, 'To')
		mail.send_mail(sender, to, subject, message)
	except:
		mail.send_mail_to_admins(sender, subject, message)
Beispiel #6
0
class Employee:
    """
    Employee class
    """
    def __init__(self):
        """
        Initialize Employee class
        """
        self.model = {
            "name":
            "employees",
            "id":
            "employee_id",
            "fields":
            ("employee_id", "salesrep", "fullname", "email", "country", "sas"),
            "types": ("INTEGER PRIMARY KEY NOT NULL", "TEXT", "TEXT", "TEXT",
                      "TEXT", "INTEGER DEFAULT 0")
        }
        self._employee = {}
        self.q = Query()
        if not self.q.exist_table(self.model["name"]):
            sql = self.q.build("create", self.model)
            self.q.execute(sql)
        self.s = Settings()
        if rules.check_settings(self.s.settings):
            self.load(self.s.settings["usermail"])

    @property
    def employee(self):
        """
        Return current and only employeeid
        """
        return self._employee

    def insert(self, values):
        """
        Insert employee in database
        Args:
            values:
        """
        sql = self.q.build("insert", self.model)
        self.q.execute(sql, values=values)

    def load(self, email):
        """
        Load the employee
        """
        filters = [("email", "=")]
        values = (email, )
        sql = self.q.build("select", self.model, filters=filters)
        success, data = self.q.execute(sql, values)
        # first check if employee is loaded
        # second check is in exception handling
        try:
            _ = data[0]
            self._employee = dict(zip(self.model["fields"], data[0]))
        except IndexError:
            if httpFn.inet_conn_check():
                # load from http
                self.load_from_http()
                success, data = self.q.execute(sql, values)
                try:
                    # second check after load_from_http
                    _ = data[0]
                    self._employee = dict(zip(self.model["fields"], data[0]))
                except IndexError:
                    self._employee = {}

    def load_from_http(self):
        """
        Load employee from http
        """
        self.s.get()
        data = httpFn.get_employee_data(self.s)
        if data:
            data = list(data)
            data[0:0] = [None]
            self.insert(tuple(data))

    def update(self):
        """
        Update employee in database
        """
        fields = list(self.model["fields"])[1:]
        filters = [(self.model["id"], "=")]
        values = self.q.values_to_update(self._employee.values())

        sql = self.q.build("update",
                           self.model,
                           update=fields,
                           filters=filters)

        self.q.execute(sql, values=values)
Beispiel #7
0
	def send(self, is_intro_email=False):

		try:
			now = datetime.datetime.now()
			settings = Settings.get()

			if is_intro_email:
				current_time = now
				logging.info('Sending intro email to %s' % settings.email_address)
			else:
				current_time, id, name, offset = self.get_time_in_timezone(settings)

				if current_time.hour != settings.email_hour:
					logging.info('Current time for %s is %s, not sending email now, will send at %02d:00' % (name, current_time, settings.email_hour))
					return


			today = current_time.date()
			
			if self.check_if_intro_email_sent_today(today):
				logging.info('Already sent the intro email today, skipping this email for now')	
				return	

			self.check_if_mail_already_sent(today)	


			slug_id = self.get_slug()

			slug = Slug(slug=slug_id, date=today)

			slug.put()

			subject = "It's %s, %s %s - How did your day go?" % (today.strftime('%A'), today.strftime("%b"), today.day)
			app_id = app_identity.get_application_id()

			sender = "MyLife <post+%s@%s.appspotmail.com>" % (slug.slug, app_id)

			message = mail.EmailMessage(sender=sender, subject=subject)

			message.to = settings.email_address
			if not settings.email_address:
				log_error('Missing To in daily email', 'There is no configured email address in your settings. Please visit your settings page to configure it so we can send you your daily email.')
				return

			message.body = """
Just reply to this email with your entry.

OLD_POST
You can see your past entries here:
https://APP_ID.appspot.com/past

	""".replace('APP_ID', app_id)

			message.html = """
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.=
w3.org/TR/html4/loose.dtd">
<html>
	<head>
		<title></title>
	</head>
	<body>
	Just reply to this email with your entry.
	<br>
	<br>
OLD_POST
	<a href="https://APP_ID.appspot.com/past">Past entries</a>
	</body>
</html>
""".replace('APP_ID', app_id)

			if is_intro_email:
				intro_msg = "Welcome to MyLife. We've sent you this email immediately so you can try the system out. In the future we will email you once a day and include an old post in each email. You can configure when you get your email and which email address we should use on the settings page."
				message.html = message.html.replace('OLD_POST', intro_msg + '<br><br>')
				message.body = message.body.replace('OLD_POST', intro_msg + '\r\n\r\n')
			else:
				#Lets try to put in an old post...
				old_post, old_type = self.get_old_post(today)

				if old_post and settings.include_old_post_in_entry:
					old_post_text = 'Remember this? One %s ago you wrote:\r\n\r\n' % old_type
					old_post_text += old_post.text.rstrip() + '\r\n\r\n'

					message.body = re.sub(r'OLD_POST\r?\n', old_post_text, message.body)

					old_post_text = re.sub(r'\r?\n', '<br>', old_post_text)
					message.html = re.sub(r'OLD_POST\r?\n', old_post_text, message.html)
				else:
					message.body = re.sub('OLD_POST\r?\n', '', message.body)
					message.html = re.sub('OLD_POST\r?\n', '', message.html)

			message.send()
			
			if is_intro_email:
				logging.info('Sent intro email')
			else:
				if old_post:
					logging.info('Sent daily email to %s, using old post from %s' % (message.to, old_post.date))
				else:
					logging.info('Sent daily email to %s, could not find old post' % message.to)

			return 'Email sent'
		except:
			log_error('Failed to send daily email', traceback.format_exc(6))
			return 'Failed sending email: %s' % traceback.format_exc(6)
Beispiel #8
0
    def get(self, year, month):
        Settings.get()  #Force email address update...

        now = datetime.datetime.now()
        if not year:
            last_post = Post.query().order(-Post.date).get()
            if last_post:
                year, month = last_post.date.year, last_post.date.month
            else:
                year, month = now.year, now.month
        else:
            year, month = int(year), int(month)

        from_date = datetime.date(year, month, 1)

        to_month = month + 1
        to_year = year
        if to_month == 13:
            to_month = 1
            to_year += 1

        to_date = datetime.date(to_year, to_month, 1)
        posts = [
            p for p in Post.query(
                ndb.AND(Post.date >= from_date, Post.date < to_date)).order(
                    -Post.date).fetch()
        ]
        month_name = from_date.strftime('%B %Y')

        #Get month list
        months = PostCounter.get().months[:]

        def cmp_months(a, b):
            if a.year != b.year:
                return cmp(a.year, b.year)
            else:
                return cmp(a.month, b.month)

        months.sort(cmp_months)

        archive = []

        next_link, prev_link = None, None

        for i, m in enumerate(months):
            date = datetime.date(m.year, m.month, 1)
            descr = '%s, %s posts' % (date.strftime('%B %Y'), m.count)
            value = date.strftime('%Y-%m')
            archive.append((value, descr, m.year == year and m.month == month))
            if m.year == year and m.month == month:
                if i != 0:
                    prev_link = '/past/%s' % datetime.date(
                        months[i - 1].year, months[i - 1].month,
                        1).strftime('%Y-%m')

                if i < len(months) - 1:
                    next_link = '/past/%s' % datetime.date(
                        months[i + 1].year, months[i + 1].month,
                        1).strftime('%Y-%m')

        if not archive:
            archive.append(('', '%s, 0 posts' % now.strftime('%B %Y'), False))

        data = {
            "page": "past",
            "posts": posts,
            "month": month_name,
            "archive": archive,
            "next": next_link,
            "prev": prev_link
        }
        self.response.write(get_template('past.html').render(data))
Beispiel #9
0
	def get(self):
		images_total = 0
		images_backed_up = 0
		try:
			self.response.headers['Content-Type'] = 'text/plain'
			settings = Settings.get()

			if not settings.dropbox_access_token:
				self.log('No access token available, no backup will be performed.')
				return


			posts = [p for p in Post.query().order(Post.date).fetch()]

			self.log('Backing up %s posts to Dropbox' % len(posts))
			post_text = StringIO()
			for p in posts:
				post_text.write(p.date.strftime('%Y-%m-%d'))
				post_text.write('\r\n\r\n')
				post_text.write(p.text.replace('\r\n', '\n').replace('\n', '\r\n').rstrip())
				post_text.write('\r\n\r\n')

			result = self.put_file(settings.dropbox_access_token, 'MyLife.txt', post_text.getvalue().encode('utf-8'))
			post_text.close()
			self.log('Backed up posts. Revision: %s' % result['rev'])

			self.log('Fetching Dropbox file list')
			
			files_in_dropbox = self.get_dropbox_filelist(settings.dropbox_access_token)
			
			self.log('Got %s files from Dropbox' % len(files_in_dropbox))

			self.log('Fetching images...')
			images = [i for i in UserImage.query().order(UserImage.date).fetch()]

			self.log('Total images in MyLife: %s' % len(images))

			not_backed_up = [i for i in images if not i.backed_up_in_dropbox]
			not_in_dropbox = [i for i in images if not i.filename in files_in_dropbox]

			self.log('\nFiles not backed up: \n\n' + '\n'.join([i.filename for i in not_backed_up]))
			self.log('\nFiles marked as backed up, but not in Dropbox: \n\n' + '\n'.join([i.filename for i in not_in_dropbox]))

			images = not_backed_up + not_in_dropbox

			images_total = len(images)
			self.log('Found %s images that need to be backed up in Dropbox' % images_total)
			for img in images:
				self.log('Backing up %s' % img.filename)
				bytes = filestore.read(img.original_size_key)
				result = self.put_file(settings.dropbox_access_token, img.filename, bytes)
				self.log('Backed up %s. Revision: %s' % (img.filename, result['rev']))
				img.backed_up_in_dropbox = True
				img.put()
				images_backed_up += 1


			settings.dropbox_last_backup = datetime.datetime.now()
			settings.put()
			self.log('Finished backup successfully')
		except apiproxy_errors.OverQuotaError, ex:
			self.log(ex)
			log_error('Error backing up to Dropbox, quota exceeded', 'The backup operation did not complete because it ran out of quota. ' +
				'The next time it runs it will continue backing up your posts and images.' +
				'%s images out of %s were backed up before failing' % (images_backed_up, images_total))
Beispiel #10
0
	def get(self, year, month):
		Settings.get() #Force email address update...

		now = datetime.datetime.now()
		if not year:
			last_post = Post.query().order(-Post.date).get()
			if last_post:
				year, month = last_post.date.year, last_post.date.month
			else:
				year, month = now.year, now.month
		else:
			year, month = int(year), int(month)

		from_date = datetime.date(year, month, 1)
		
		to_month = month + 1
		to_year = year
		if to_month == 13:
			to_month = 1
			to_year += 1

		to_date = datetime.date(to_year, to_month, 1)
		posts = [p for p in Post.query(ndb.AND(Post.date >= from_date, Post.date < to_date)).order(-Post.date).fetch()]
		month_name = from_date.strftime('%B %Y')
		
		#Get month list
		months = PostCounter.get().months[:]
		def cmp_months(a,b):
			if a.year != b.year:
				return cmp(a.year, b.year)
			else:
				return cmp(a.month, b.month)

		months.sort(cmp_months)

		archive = []

		next_link, prev_link = None, None

		for i, m in enumerate(months):
			date = datetime.date(m.year, m.month,1)
			descr = '%s, %s posts' % (date.strftime('%B %Y'), m.count)
			value = date.strftime('%Y-%m')
			archive.append((value,descr, m.year == year and m.month == month))
			if m.year == year and m.month == month:
				if i != 0:
					prev_link = '/past/%s' % datetime.date(months[i-1].year, months[i-1].month, 1).strftime('%Y-%m')

				if i < len(months)-1:
					next_link = '/past/%s' % datetime.date(months[i+1].year, months[i+1].month, 1).strftime('%Y-%m')

		if not archive:
			archive.append(('', '%s, 0 posts' % now.strftime('%B %Y'), False))

		data = {
			"page" : "past", 
			"posts" : posts, 
			"month" : month_name,
			"archive" : archive,
			"next" : next_link,
			"prev" : prev_link
		}
		self.response.write(get_template('past.html').render(data))
Beispiel #11
0
    def get(self):
        images_total = 0
        images_backed_up = 0
        try:
            self.response.headers['Content-Type'] = 'text/plain'
            settings = Settings.get()

            if not settings.dropbox_access_token:
                self.log(
                    'No access token available, no backup will be performed.')
                return

            posts = [p for p in Post.query().order(Post.date).fetch()]

            self.log('Backing up %s posts to Dropbox' % len(posts))
            post_text = StringIO()
            for p in posts:
                post_text.write(p.date.strftime('%Y-%m-%d'))
                post_text.write('\r\n\r\n')
                post_text.write(
                    p.text.replace('\r\n', '\n').replace('\n',
                                                         '\r\n').rstrip())
                post_text.write('\r\n\r\n')

            result = self.put_file(settings.dropbox_access_token, 'MyLife.txt',
                                   post_text.getvalue().encode('utf-8'))
            post_text.close()
            self.log('Backed up posts. Revision: %s' % result['rev'])

            self.log('Fetching Dropbox file list')

            files_in_dropbox = self.get_dropbox_filelist(
                settings.dropbox_access_token)

            self.log('Got %s files from Dropbox' % len(files_in_dropbox))

            self.log('Fetching images...')
            images = [
                i for i in UserImage.query().order(UserImage.date).fetch()
            ]

            self.log('Total images in MyLife: %s' % len(images))

            not_backed_up = [i for i in images if not i.backed_up_in_dropbox]
            not_in_dropbox = [
                i for i in images if not i.filename in files_in_dropbox
            ]

            self.log('\nFiles not backed up: \n\n' +
                     '\n'.join([i.filename for i in not_backed_up]))
            self.log('\nFiles marked as backed up, but not in Dropbox: \n\n' +
                     '\n'.join([i.filename for i in not_in_dropbox]))

            images = not_backed_up + not_in_dropbox

            images_total = len(images)
            self.log('Found %s images that need to be backed up in Dropbox' %
                     images_total)
            for img in images:
                self.log('Backing up %s' % img.filename)
                bytes = filestore.read(img.original_size_key)
                result = self.put_file(settings.dropbox_access_token,
                                       img.filename, bytes)
                self.log('Backed up %s. Revision: %s' %
                         (img.filename, result['rev']))
                img.backed_up_in_dropbox = True
                img.put()
                images_backed_up += 1

            settings.dropbox_last_backup = datetime.datetime.now()
            settings.put()
            self.log('Finished backup successfully')
        except apiproxy_errors.OverQuotaError, ex:
            self.log(ex)
            log_error(
                'Error backing up to Dropbox, quota exceeded',
                'The backup operation did not complete because it ran out of quota. '
                +
                'The next time it runs it will continue backing up your posts and images.'
                + '%s images out of %s were backed up before failing' %
                (images_backed_up, images_total))
Beispiel #12
0
	def send(self, is_intro_email=False, force_send=False, date=None):

		try:
			now = datetime.datetime.now()
			settings = Settings.get()

			if is_intro_email:
				current_time = now
				logging.info('Sending intro email to %s' % settings.email_address)
			else:
				current_time, id, name, offset = self.get_time_in_timezone(settings)

				if current_time.hour != settings.email_hour and not force_send:
					logging.info('Current time for %s is %s, not sending email now, will send at %02d:00' % (name, current_time, settings.email_hour))
					return


			if date and force_send:
				today = date #Allow overriding this stuff
			else:
				today = current_time.date()
			
			if self.check_if_intro_email_sent_today(today) and not force_send:
				logging.info('Already sent the intro email today, skipping this email for now')	
				return	


			#Check if we've already sent an email
			slug = Slug.query(Slug.date == today).get()

			if slug and not force_send:
				msg = 'Tried to send another email on %s, already sent %s' % (date, slug.slug)
				log_error('Tried to send email again', msg)
				raise Exception(msg)

			if not slug:
				slug_id = self.get_slug()

				slug = Slug(slug=slug_id, date=today)

				slug.put()

			subject = "It's %s, %s %s - How did your day go?" % (today.strftime('%A'), today.strftime("%b"), today.day)
			app_id = app_identity.get_application_id()

			sender = "MyLife <post+%s@%s.appspotmail.com>" % (slug.slug, app_id)

			message = mail.EmailMessage(sender=sender, subject=subject)

			message.to = settings.email_address
			if not settings.email_address:
				log_error('Missing To in daily email', 'There is no configured email address in your settings. Please visit your settings page to configure it so we can send you your daily email.')
				return

			message.body = """
Just reply to this email with your entry.

OLD_POST

	""".replace('APP_ID', app_id)

			message.html = """
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.=
w3.org/TR/html4/loose.dtd">
<html>
	<head>
		<title></title>
	</head>
	<body>
	Just reply to this email with your entry.
	<br>
	<br>
OLD_POST
	</body>
</html>
""".replace('APP_ID', app_id)

			if is_intro_email:
				intro_msg = "Welcome to MyLife. We've sent you this email immediately so you can try the system out. In the future we will email you once a day and include an old post in each email. You can configure when you get your email and which email address we should use on the settings page."
				message.html = message.html.replace('OLD_POST', intro_msg + '<br><br>')
				message.body = message.body.replace('OLD_POST', intro_msg + '\r\n\r\n')
			else:
				#Lets try to put in an old post...
				old_post, old_type = self.get_old_post(today)

				if old_post and settings.include_old_post_in_entry:
					logging.info('Going to use old post %s because %s' % (old_post, settings.include_old_post_in_entry))

					if (old_type == 'random'):
						old_post_text = 'Remember this? On <b>%s, %s %s, %s</b> you wrote:\r\n\r\n' % (old_post.date.strftime('%A'), old_post.date.strftime("%b"), old_post.date.day, old_post.date.strftime("%Y"))
					else:
						old_post_text = 'Remember this? One %s ago you wrote:\r\n\r\n' % old_type
					old_post_text += old_post.text.rstrip() + '\r\n\r\n'

					message.body = re.sub(r'OLD_POST\r?\n', old_post_text, message.body)

					old_post_text = re.sub(r'\r?\n', '<br>', old_post_text)
					message.html = re.sub(r'OLD_POST\r?\n', old_post_text, message.html)
				else:
					logging.info('Not using Old post %s because %s' % (old_post, settings.include_old_post_in_entry))
					message.body = re.sub('OLD_POST\r?\n', '', message.body)
					message.html = re.sub('OLD_POST\r?\n', '', message.html)

			message.send()
			
			if is_intro_email:
				logging.info('Sent intro email')
			else:
				if old_post:
					logging.info('Sent daily email to %s, using old post from %s' % (message.to, old_post.date))
				else:
					logging.info('Sent daily email to %s, could not find old post' % message.to)

			return 'Email sent'
		except:
			log_error('Failed to send daily email', traceback.format_exc(6))
			return 'Failed sending email: %s' % traceback.format_exc(6)