def setUpClass(cls): management.call_command('flush', verbosity=0, interactive=False) activate_language(settings.LANGUAGE_CODE) management.call_command('askbot_add_test_content', verbosity=0, interactive=False) super(PageLoadTestCase, cls).setUpClass()
def record_question_visit( language_code=None, question_post_id=None, update_view_count=False, user_id=None): """celery task which records question visit by a person updates view counter, if necessary, and awards the badges associated with the question visit """ activate_language(language_code) # 1) maybe update the view count try: question_post = Post.objects.get(id=question_post_id) except Post.DoesNotExist: logger.error("Unable to fetch post with id %s" % question_post_id) return if update_view_count and question_post.thread_id: question_post.thread.increase_view_count() # we do not track visits per anon user if user_id is None: return user = User.objects.get(id=user_id) # 2) question view count per user and clear response displays if user.is_authenticated(): # get response notifications user.visit_question(question_post) # 3) send award badges signal for any badges # that are awarded for question views award_badges_signal.send( None, event='view_question', actor=user, context_object=question_post)
def handle(self, **options): lang_code = options.get('language', settings.LANGUAGE_CODE.lower()) options['using'] = ['default_%s' % lang_code[:2],] activate_language(lang_code) klass = self._get_command_class('clear_index') klass.handle(*args, **options)
def __init__(self, app_labels, **kwargs): self.graphs = [] self.cli_options = kwargs.get('cli_options', None) self.disable_fields = kwargs.get('disable_fields', False) self.disable_abstract_fields = kwargs.get('disable_abstract_fields', False) self.include_models = parse_file_or_list( kwargs.get('include_models', "") ) self.all_applications = kwargs.get('all_applications', False) self.use_subgraph = kwargs.get('group_models', False) self.verbose_names = kwargs.get('verbose_names', False) self.inheritance = kwargs.get('inheritance', True) self.relations_as_fields = kwargs.get("relations_as_fields", True) self.sort_fields = kwargs.get("sort_fields", True) self.language = kwargs.get('language', None) if self.language is not None: activate_language(self.language) self.exclude_columns = parse_file_or_list( kwargs.get('exclude_columns', "") ) self.exclude_models = parse_file_or_list( kwargs.get('exclude_models', "") ) self.hide_edge_labels = kwargs.get('hide_edge_labels', False) self.arrow_shape = kwargs.get("arrow_shape") if self.all_applications: self.app_labels = [app.label for app in apps.get_app_configs()] else: self.app_labels = app_labels
def __init__(self, app_labels, **kwargs): self.graphs = [] self.cli_options = kwargs.get('cli_options', None) self.disable_fields = kwargs.get('disable_fields', False) self.include_models = parse_file_or_list( kwargs.get('include_models', "") ) self.all_applications = kwargs.get('all_applications', False) self.use_subgraph = kwargs.get('group_models', False) self.verbose_names = kwargs.get('verbose_names', False) self.inheritance = kwargs.get('inheritance', True) self.relations_as_fields = kwargs.get("relations_as_fields", True) self.sort_fields = kwargs.get("sort_fields", True) self.language = kwargs.get('language', None) if self.language is not None: activate_language(self.language) self.exclude_columns = parse_file_or_list( kwargs.get('exclude_columns', "") ) self.exclude_models = parse_file_or_list( kwargs.get('exclude_models', "") ) if self.all_applications: self.app_labels = [app.label for app in apps.get_app_configs()] else: self.app_labels = app_labels
def send_instant_notifications_about_activity_in_post(activity_id=None, post_id=None, recipients=None): if recipients is None: recipients = set() recipients = set(recipients) recipients.update(get_invited_moderators()) if len(recipients) == 0: return acceptable_types = const.RESPONSE_ACTIVITY_TYPES_FOR_INSTANT_NOTIFICATIONS try: update_activity = Activity.objects\ .filter(activity_type__in=acceptable_types)\ .get(id=activity_id) except Activity.DoesNotExist: logger.error("Unable to fetch activity with id %s" % post_id) return try: post = Post.objects.get(id=post_id) except Post.DoesNotExist: logger.error("Unable to fetch post with id %s" % post_id) return if not post.is_approved(): return if logger.getEffectiveLevel() <= logging.DEBUG: log_id = uuid.uuid1() message = 'email-alert %s, logId=%s' % (post.get_absolute_url(), log_id) logger.debug(message) else: log_id = None for user in recipients: if user.is_blocked(): continue activate_language(post.language_code) email = InstantEmailAlert({ 'to_user': user, 'from_user': update_activity.user, 'post': post, 'update_activity': update_activity }) try: email.send([user.email]) except askbot_exceptions.EmailNotSent as error: logger.debug('%s, error=%s, logId=%s' % (user.email, error, log_id)) else: logger.debug('success %s, logId=%s' % (user.email, log_id))
def notify_author_of_published_revision_celery_task(revision): #todo: move this to ``askbot.mail`` module #for answerable email only for now, because #we don't yet have the template for the read-only notification data = { 'site_name': askbot_settings.APP_SHORT_NAME, 'post': revision.post } headers = None if askbot_settings.REPLY_BY_EMAIL: #generate two reply codes (one for edit and one for addition) #to format an answerable email or not answerable email reply_options = { 'user': revision.author, 'post': revision.post, 'reply_action': 'append_content' } append_content_address = ReplyAddress.objects.create_new( **reply_options ).as_email_address() reply_options['reply_action'] = 'replace_content' replace_content_address = ReplyAddress.objects.create_new( **reply_options ).as_email_address() #populate template context variables reply_code = append_content_address + ',' + replace_content_address if revision.post.post_type == 'question': mailto_link_subject = revision.post.thread.title else: mailto_link_subject = _('make an edit by email') #todo: possibly add more mailto thread headers to organize messages prompt = _('To add to your post EDIT ABOVE THIS LINE') reply_separator_line = const.SIMPLE_REPLY_SEPARATOR_TEMPLATE % prompt data['reply_code'] = reply_code data['author_email_signature'] = revision.author.email_signature data['replace_content_address'] = replace_content_address data['reply_separator_line'] = reply_separator_line data['mailto_link_subject'] = mailto_link_subject headers = {'Reply-To': append_content_address} #load the template activate_language(revision.post.language_code) template = get_template('email/notify_author_about_approved_post.html') #todo: possibly add headers to organize messages in threads #send the message mail.send_mail( subject_line = _('Your post at %(site_name)s is now published') % data, body_text = template.render(Context(data)), recipient_list = [revision.author.email,], related_object = revision, activity_type = const.TYPE_ACTIVITY_EMAIL_UPDATE_SENT, headers = headers )
def handle(self, **options): lang_code = options.get('language', settings.LANGUAGE_CODE.lower()) options['using'] = [ 'default_%s' % lang_code[:2], ] activate_language(lang_code) klass = self._get_command_class('clear_index') klass.handle(*args, **options)
def send_instant_notifications_about_activity_in_post( activity_id=None, post_id=None, recipients=None): if recipients is None: recipients = set() recipients = set(recipients) recipients.update(get_invited_moderators()) if len(recipients) == 0: return acceptable_types = const.RESPONSE_ACTIVITY_TYPES_FOR_INSTANT_NOTIFICATIONS try: update_activity = Activity.objects\ .filter(activity_type__in=acceptable_types)\ .get(id=activity_id) except Activity.DoesNotExist: logger.error("Unable to fetch activity with id %s" % post_id) return try: post = Post.objects.get(id=post_id) except Post.DoesNotExist: logger.error("Unable to fetch post with id %s" % post_id) return if not post.is_approved(): return if logger.getEffectiveLevel() <= logging.DEBUG: log_id = uuid.uuid1() message = 'email-alert %s, logId=%s' % (post.get_absolute_url(), log_id) logger.debug(message) else: log_id = None for user in recipients: if user.is_blocked(): continue activate_language(post.language_code) email = InstantEmailAlert({ 'to_user': user, 'from_user': update_activity.user, 'post': post, 'update_activity': update_activity }) try: email.send([user.email]) except askbot_exceptions.EmailNotSent as error: logger.debug( '%s, error=%s, logId=%s' % (user.email, error, log_id) ) else: logger.debug('success %s, logId=%s' % (user.email, log_id))
def send_email_alerts(self, user): #does not change the database, only sends the email #todo: move this to template user.add_missing_askbot_subscriptions() #todo: q_list is a dictionary, not a list q_list = self.get_updated_questions_for_user(user) if len(q_list.keys()) == 0: return num_q = 0 for question, meta_data in q_list.items(): if meta_data['skip']: del q_list[question] else: num_q += 1 if num_q > 0: threads = Thread.objects.filter(id__in=[qq.thread_id for qq in q_list.keys()]) tag_summary = Thread.objects.get_tag_summary_from_threads(threads) question_count = len(q_list.keys()) items_added = 0 items_unreported = 0 questions_data = list() for q, meta_data in q_list.items(): act_list = [] if meta_data['skip']: continue if items_added >= askbot_settings.MAX_ALERTS_PER_EMAIL: items_unreported = num_q - items_added #may be inaccurate actually, but it's ok break else: items_added += 1 if meta_data['new_q']: act_list.append(_('new question')) format_action_count('%(num)d rev', meta_data['q_rev'], act_list) format_action_count('%(num)d ans', meta_data['new_ans'], act_list) format_action_count('%(num)d ans rev', meta_data['ans_rev'], act_list) questions_data.append({ 'url': site_url(q.get_absolute_url()), 'info': ', '.join(act_list), 'title': q.thread.title }) activate_language(user.get_primary_language()) email = BatchEmailAlert({ 'questions': questions_data, 'question_count': question_count, 'tag_summary': tag_summary, 'user': user }) if DEBUG_THIS_COMMAND == True: recipient_email = askbot_settings.ADMIN_EMAIL else: recipient_email = user.email email.send([recipient_email,])
def handle_noargs(self, **options): if askbot_settings.ENABLE_EMAIL_ALERTS: activate_language(django_settings.LANGUAGE_CODE) for user in User.objects.all(): try: self.send_email_alerts(user) except Exception: self.report_exception(user) connection.close()
def notify_author_of_published_revision_celery_task(revision_id): #todo: move this to ``askbot.mail`` module #for answerable email only for now, because #we don't yet have the template for the read-only notification try: revision = PostRevision.objects.get(pk=revision_id) except PostRevision.DoesNotExist: logger.error("Unable to fetch revision with id %s" % revision_id) return activate_language(revision.post.language_code) if askbot_settings.REPLY_BY_EMAIL == False: email = ApprovedPostNotification({ 'post': revision.post, 'recipient_user': revision.author }) email.send([ revision.author.email, ]) else: #generate two reply codes (one for edit and one for addition) #to format an answerable email or not answerable email reply_options = { 'user': revision.author, 'post': revision.post, 'reply_action': 'append_content' } append_content_address = ReplyAddress.objects.create_new( **reply_options).as_email_address() reply_options['reply_action'] = 'replace_content' replace_content_address = ReplyAddress.objects.create_new( **reply_options).as_email_address() if revision.post.post_type == 'question': mailto_link_subject = revision.post.thread.title else: mailto_link_subject = _('make an edit by email') email = ApprovedPostNotificationRespondable({ 'revision': revision, 'mailto_link_subject': mailto_link_subject, 'reply_code': append_content_address + ',' + replace_content_address, 'append_content_address': append_content_address, 'replace_content_address': replace_content_address }) email.send([ revision.author.email, ])
def notify_author_of_published_revision_celery_task(revision): #todo: move this to ``askbot.mail`` module #for answerable email only for now, because #we don't yet have the template for the read-only notification if askbot_settings.REPLY_BY_EMAIL: #generate two reply codes (one for edit and one for addition) #to format an answerable email or not answerable email reply_options = { 'user': revision.author, 'post': revision.post, 'reply_action': 'append_content' } append_content_address = ReplyAddress.objects.create_new( **reply_options).as_email_address() reply_options['reply_action'] = 'replace_content' replace_content_address = ReplyAddress.objects.create_new( **reply_options).as_email_address() #populate template context variables reply_code = append_content_address + ',' + replace_content_address if revision.post.post_type == 'question': mailto_link_subject = revision.post.thread.title else: mailto_link_subject = _('make an edit by email') #todo: possibly add more mailto thread headers to organize messages prompt = _('To add to your post EDIT ABOVE THIS LINE') reply_separator_line = const.SIMPLE_REPLY_SEPARATOR_TEMPLATE % prompt data = { 'site_name': askbot_settings.APP_SHORT_NAME, 'post': revision.post, 'author_email_signature': revision.author.email_signature, 'replace_content_address': replace_content_address, 'reply_separator_line': reply_separator_line, 'mailto_link_subject': mailto_link_subject, 'reply_code': reply_code } #load the template activate_language(revision.post.language_code) template = get_template('email/notify_author_about_approved_post.html') #todo: possibly add headers to organize messages in threads headers = {'Reply-To': append_content_address} #send the message mail.send_mail( subject_line=_('Your post at %(site_name)s is now published') % data, body_text=template.render(Context(data)), recipient_list=[ revision.author.email, ], related_object=revision, activity_type=const.TYPE_ACTIVITY_EMAIL_UPDATE_SENT, headers=headers)
def handle_noargs(self, **options): if askbot_settings.ENABLE_EMAIL_ALERTS: activate_language(django_settings.LANGUAGE_CODE) for user in User.objects.exclude(status='b').iterator(): try: if email_is_blacklisted(user.email) and askbot_settings.BLACKLISTED_EMAIL_PATTERNS_MODE == 'strict': continue self.send_email_alerts(user) except Exception: self.report_exception(user) connection.close()
def handle_noargs(self, **options): if askbot_settings.ENABLE_EMAIL_ALERTS: activate_language(django_settings.LANGUAGE_CODE) for user in User.objects.exclude(status='b').iterator(): try: if email_is_blacklisted(user.email) \ and askbot_settings.BLACKLISTED_EMAIL_PATTERNS_MODE == 'strict': continue self.send_email_alerts(user) except Exception: self.report_exception(user) connection.close()
def test_t_something_single(self): old_lang = get_language() self.item.save_d('names', {'ja': u'マリア', 'ru': u'Мария'}) activate_language('ja') self.assertEqual(self.item.t_name, u'マリア') activate_language('ru') self.assertEqual(self.item.t_name, u'Мария') activate_language('zh-hans') self.assertEqual(self.item.t_name, u'Maria') activate_language('en') self.assertEqual(self.item.t_name, u'Maria') activate_language(old_lang)
def get_default_editor_value(self, language_code): if self.use_default: if language_code and self.localized: current_lang = get_language() activate_language(language_code) localized_value = unicode(self.default) activate_language(current_lang) return localized_value elif self.use_default: return unicode(self.default) return ''
def get_default_editor_value(self, language_code): if self.use_default: if language_code and self.localized: current_lang = get_language() activate_language(language_code) localized_value = six.text_type(self.default) activate_language(current_lang) return localized_value elif self.use_default: return six.text_type(self.default) return ''
def handle(self, *args, **kwargs): activate_language(django_settings.LANGUAGE_CODE) #init the redirects file format table self.redirect_format = self.get_redirect_format(kwargs['redirect_format']) self.setup_run() self.read_xml_file(args[0]) self.remember_message_ids() self.handle_import() self.delete_new_messages()
def notify_author_of_published_revision_celery_task(revision_id): #todo: move this to ``askbot.mail`` module #for answerable email only for now, because #we don't yet have the template for the read-only notification try: revision = PostRevision.objects.get(pk=revision_id) except PostRevision.DoesNotExist: logger.error("Unable to fetch revision with id %s" % revision_id) return activate_language(revision.post.language_code) if askbot_settings.REPLY_BY_EMAIL == False: email = ApprovedPostNotification({ 'post': revision.post, 'recipient_user': revision.author }) email.send([revision.author.email,]) else: #generate two reply codes (one for edit and one for addition) #to format an answerable email or not answerable email reply_options = { 'user': revision.author, 'post': revision.post, 'reply_action': 'append_content' } append_content_address = ReplyAddress.objects.create_new( **reply_options ).as_email_address() reply_options['reply_action'] = 'replace_content' replace_content_address = ReplyAddress.objects.create_new( **reply_options ).as_email_address() if revision.post.post_type == 'question': mailto_link_subject = revision.post.thread.title else: mailto_link_subject = _('make an edit by email') email = ApprovedPostNotificationRespondable({ 'revision': revision, 'mailto_link_subject': mailto_link_subject, 'reply_code': append_content_address + ',' + replace_content_address, 'append_content_address': append_content_address, 'replace_content_address': replace_content_address }) email.send([revision.author.email,])
def handle(self, *args, **options): """Generates a Solr schema that reflects the indexes.""" using = options.get('using') language = options.get('language')[:2] activate_language(language) if language not in SUPPORTED_LANGUAGES: sys.stderr.write("\n\n") sys.stderr.write("WARNING: your language: '%s' is not supported in our " % language) sys.stderr.write("template it will default to English more information in http://wiki.apache.org/solr/LanguageAnalysis") sys.stderr.write("\n\n") schema_xml = self.build_template(using=using, language=language) if options.get('filename'): self.write_file(options.get('filename'), schema_xml) else: self.print_stdout(schema_xml)
def handle(self, *args, **kwargs): activate_language(django_settings.LANGUAGE_CODE) #init the redirects file format table format_table = { 'nginx': 'rewrite ^%s$ %s break;\n', 'apache': 'Redirect permanent %s %s\n', } format_table = defaultdict(lambda: '%s %s\n', format_table) self.redirect_format = format_table[kwargs['redirect_format']] self.setup_run() self.read_xml_file(args[0]) self.remember_message_ids() self.read_content_types() self.import_groups() self.import_users() #we don't import subscriptions if 'avatar' in django_settings.INSTALLED_APPS: self.import_avatars() #we need this to link old user ids to #new users' personal groups #self.record_personal_groups() self.import_user_logins() self.import_tags() self.import_marked_tags() self.import_threads() self.apply_groups_to_threads() #model="askbot.posttogroup"> self.import_posts('question', save_redirects=True) self.import_posts('answer') self.import_posts('comment') self.import_post_revisions() self.apply_groups_to_posts() self.apply_question_followers() self.import_votes() self.import_badges() self.import_badge_awards() self.delete_new_messages()
def test_has_translation_default_language(self): activate_language("en") self.assertTrue(self.model.has_translation()) activate_language("es") self.assertTrue(self.model.has_translation()) activate_language("it") self.assertFalse(self.model.has_translation())
def test_get_translation_default_language_fallback(self): activate_language('en') self.assertEquals(self.model.get_translation(), self.translation_en) activate_language('es') self.assertEquals(self.model.get_translation(), self.translation_es) activate_language('it') self.assertEquals(self.model.get_translation(), self.translation_en)
def test_has_translation_default_language(self): activate_language('en') self.assertTrue(self.model.has_translation()) activate_language('es') self.assertTrue(self.model.has_translation()) activate_language('it') self.assertFalse(self.model.has_translation())
def test_get_translation_given_language_fallback(self): activate_language("es") self.assertEquals(self.model.get_translation("en"), self.translation_en) activate_language("en") self.assertEquals(self.model.get_translation("es"), self.translation_es) activate_language("en") self.assertEquals(self.model.get_translation("it"), self.translation_en)
def test_get_translation_given_language_no_fallback(self): activate_language("es") self.assertEquals(self.model.get_translation("en", fallback=False), self.translation_en) activate_language("en") self.assertEquals(self.model.get_translation("es", fallback=False), self.translation_es) activate_language("en") with self.assertRaises(translatable.exceptions.MissingTranslation): self.model.get_translation("it", fallback=False)
def test_translated_given_language_fallback(self): activate_language("es") self.assertEquals(self.model.translated("field", language="en"), "Hello!") activate_language("en") self.assertEquals(self.model.translated("field", language="es"), "Hola!") activate_language("es") self.assertEquals(self.model.translated("field", language="it"), "Hello!") self.assertEquals(self.model.translated("field", "default", language="it"), "Hello!")
def test_translated_default_language_no_fallback(self): activate_language("en") self.assertEquals(self.model.translated("field", fallback=False), "Hello!") activate_language("es") self.assertEquals(self.model.translated("field", fallback=False), "Hola!") activate_language("it") self.assertIsNone(self.model.translated("field", fallback=False)) self.assertEquals(self.model.translated("field", "default", fallback=False), "default")
def test_translated_default_language_fallback(self): activate_language('en') self.assertEquals(self.model.translated('field'), "Hello!") activate_language('es') self.assertEquals(self.model.translated('field'), "Hola!") activate_language('it') self.assertEquals(self.model.translated('field'), "Hello!") self.assertEquals(self.model.translated('field', "default"), "Hello!")
def test_get_translation_given_language_no_fallback(self): activate_language('es') self.assertEquals(self.model.get_translation('en', fallback=False), self.translation_en) activate_language('en') self.assertEquals(self.model.get_translation('es', fallback=False), self.translation_es) activate_language('en') with self.assertRaises(translatable.exceptions.MissingTranslation): self.model.get_translation('it', fallback=False)
def test_translated_given_language_no_fallback(self): activate_language('es') self.assertEquals( self.model.translated('field', language='en', fallback=False), "Hello!") activate_language('en') self.assertEquals( self.model.translated('field', language='es', fallback=False), "Hola!") activate_language('en') self.assertIsNone( self.model.translated('field', language='it', fallback=False)) self.assertEquals( self.model.translated('field', "default", language='it', fallback=False), "default")
def send_email_alerts(self): #does not change the database, only sends the email #todo: move this to template activate_language(django_settings.LANGUAGE_CODE) template = get_template('email/delayed_email_alert.html') for user in User.objects.all(): user.add_missing_askbot_subscriptions() #todo: q_list is a dictionary, not a list q_list = self.get_updated_questions_for_user(user) if len(q_list.keys()) == 0: continue num_q = 0 for question, meta_data in q_list.items(): if meta_data['skip']: del q_list[question] else: num_q += 1 if num_q > 0: threads = Thread.objects.filter( id__in=[qq.thread_id for qq in q_list.keys()]) tag_summary = Thread.objects.get_tag_summary_from_threads( threads) question_count = len(q_list.keys()) if tag_summary: subject_line = ungettext( '%(question_count)d update about %(topics)s', '%(question_count)d updates about %(topics)s', question_count) % { 'question_count': question_count, 'topics': tag_summary } else: subject_line = ungettext( '%(question_count)d update', '%(question_count)d updates', question_count) % { 'question_count': question_count, } items_added = 0 items_unreported = 0 questions_data = list() for q, meta_data in q_list.items(): act_list = [] if meta_data['skip']: continue if items_added >= askbot_settings.MAX_ALERTS_PER_EMAIL: items_unreported = num_q - items_added #may be inaccurate actually, but it's ok break else: items_added += 1 if meta_data['new_q']: act_list.append(_('new question')) format_action_count('%(num)d rev', meta_data['q_rev'], act_list) format_action_count('%(num)d ans', meta_data['new_ans'], act_list) format_action_count('%(num)d ans rev', meta_data['ans_rev'], act_list) questions_data.append({ 'url': site_url(q.get_absolute_url()), 'info': ', '.join(act_list), 'title': q.thread.title }) activate_language(user.get_primary_language()) text = template.render({ 'recipient_user': user, 'questions': questions_data, 'name': user.username, 'admin_email': askbot_settings.ADMIN_EMAIL, 'site_name': askbot_settings.APP_SHORT_NAME, 'is_multilingual': getattr(django_settings, 'ASKBOT_MULTILINGUAL', False) }) if DEBUG_THIS_COMMAND == True: recipient_email = askbot_settings.ADMIN_EMAIL else: recipient_email = user.email mail.send_mail(subject_line=subject_line, body_text=text, recipient_list=[recipient_email])
def generate_dot(app_labels, **kwargs): disable_fields = kwargs.get('disable_fields', False) include_models = parse_file_or_list(kwargs.get('include_models', "")) all_applications = kwargs.get('all_applications', False) use_subgraph = kwargs.get('group_models', False) verbose_names = kwargs.get('verbose_names', False) language = kwargs.get('language', None) if language is not None: activate_language(language) exclude_columns = parse_file_or_list(kwargs.get('exclude_columns', "")) exclude_models = parse_file_or_list(kwargs.get('exclude_models', "")) def skip_field(field): if exclude_columns: if verbose_names and field.verbose_name: if field.verbose_name in exclude_columns: return True if field.name in exclude_columns: return True return False t = loader.get_template('django_extensions/graph_models/head.html') c = Context({}) dot = t.render(c) apps = [] if all_applications: apps = models.get_apps() for app_label in app_labels: app = models.get_app(app_label) if not app in apps: apps.append(app) graphs = [] for app in apps: graph = Context({ 'name': '"%s"' % app.__name__, 'app_name': "%s" % '.'.join(app.__name__.split('.')[:-1]), 'cluster_app_name': "cluster_%s" % app.__name__.replace(".", "_"), 'disable_fields': disable_fields, 'use_subgraph': use_subgraph, 'models': [] }) for appmodel in get_models(app): abstracts = [e.__name__ for e in appmodel.__bases__ if hasattr(e, '_meta') and e._meta.abstract] # collect all attribs of abstract superclasses def getBasesAbstractFields(c): _abstract_fields = [] for e in c.__bases__: if hasattr(e, '_meta') and e._meta.abstract: _abstract_fields.extend(e._meta.fields) _abstract_fields.extend(getBasesAbstractFields(e)) return _abstract_fields abstract_fields = getBasesAbstractFields(appmodel) model = { 'app_name': appmodel.__module__.replace(".", "_"), 'name': appmodel.__name__, 'abstracts': abstracts, 'fields': [], 'relations': [] } # consider given model name ? def consider(model_name): if exclude_models and model_name in exclude_models: return False return not include_models or model_name in include_models if not consider(appmodel._meta.object_name): continue if verbose_names and appmodel._meta.verbose_name: model['label'] = appmodel._meta.verbose_name else: model['label'] = model['name'] # model attributes def add_attributes(field): if verbose_names and field.verbose_name: label = field.verbose_name else: label = field.name model['fields'].append({ 'name': field.name, 'label': label, 'type': type(field).__name__, 'blank': field.blank, 'abstract': field in abstract_fields, }) for field in appmodel._meta.fields: if skip_field(field): continue add_attributes(field) if appmodel._meta.many_to_many: for field in appmodel._meta.many_to_many: if skip_field(field): continue add_attributes(field) # relations def add_relation(field, extras=""): if verbose_names and field.verbose_name: label = field.verbose_name else: label = field.name _rel = { 'target_app': field.rel.to.__module__.replace('.', '_'), 'target': field.rel.to.__name__, 'type': type(field).__name__, 'name': field.name, 'label': label, 'arrows': extras, 'needs_node': True } if _rel not in model['relations'] and consider(_rel['target']): model['relations'].append(_rel) for field in appmodel._meta.fields: if skip_field(field): continue if isinstance(field, OneToOneField): add_relation(field, '[arrowhead=none arrowtail=none]') elif isinstance(field, ForeignKey): add_relation(field) if appmodel._meta.many_to_many: for field in appmodel._meta.many_to_many: if skip_field(field): continue if isinstance(field, ManyToManyField): if (getattr(field, 'creates_table', False) or # django 1.1. (field.rel.through and field.rel.through._meta.auto_created)): # django 1.2 add_relation(field, '[arrowhead=normal arrowtail=normal]') elif isinstance(field, GenericRelation): add_relation(field, mark_safe('[style="dotted"] [arrowhead=normal arrowtail=normal]')) graph['models'].append(model) graphs.append(graph) nodes = [] for graph in graphs: nodes.extend([e['name'] for e in graph['models']]) for graph in graphs: # don't draw duplication nodes because of relations for model in graph['models']: for relation in model['relations']: if relation['target'] in nodes: relation['needs_node'] = False # render templates t = loader.get_template('django_extensions/graph_models/body.html') dot += '\n' + t.render(graph) for graph in graphs: t = loader.get_template('django_extensions/graph_models/rel.html') dot += '\n' + t.render(graph) t = loader.get_template('django_extensions/graph_models/tail.html') c = Context({}) dot += '\n' + t.render(c) return dot
def setUpClass(cls): super(PageLoadTestCase, cls).setUpClass() management.call_command("flush", verbosity=0, interactive=False) activate_language(settings.LANGUAGE_CODE) management.call_command("askbot_add_test_content", verbosity=0, interactive=False)
def activate_en(): activate_language('en') yield deactivate_language()
def send_email_alerts(self): #does not change the database, only sends the email #todo: move this to template activate_language(django_settings.LANGUAGE_CODE) template = get_template('email/delayed_email_alert.html') for user in User.objects.all(): user.add_missing_askbot_subscriptions() #todo: q_list is a dictionary, not a list q_list = self.get_updated_questions_for_user(user) if len(q_list.keys()) == 0: continue num_q = 0 for question, meta_data in q_list.items(): if meta_data['skip']: del q_list[question] else: num_q += 1 if num_q > 0: threads = Thread.objects.filter(id__in=[qq.thread_id for qq in q_list.keys()]) tag_summary = Thread.objects.get_tag_summary_from_threads(threads) question_count = len(q_list.keys()) subject_line = ungettext( '%(question_count)d updated question about %(topics)s', '%(question_count)d updated questions about %(topics)s', question_count ) % { 'question_count': question_count, 'topics': tag_summary } #todo: send this to special log print 'have %d updated questions for %s' % (num_q, user.username) if DEBUG_THIS_COMMAND == True: continue text = ungettext( '<p>Dear %(name)s,</p><p>The following question has been updated ' '%(sitename)s</p>', '<p>Dear %(name)s,</p><p>The following %(num)d questions have been ' 'updated on %(sitename)s:</p>', num_q ) % { 'num':num_q, 'name':user.username, 'sitename': askbot_settings.APP_SHORT_NAME } text += '<ul>' items_added = 0 items_unreported = 0 questions_data = list() for q, meta_data in q_list.items(): act_list = [] if meta_data['skip']: continue if items_added >= askbot_settings.MAX_ALERTS_PER_EMAIL: items_unreported = num_q - items_added #may be inaccurate actually, but it's ok break else: items_added += 1 if meta_data['new_q']: act_list.append(_('new question')) format_action_count('%(num)d rev', meta_data['q_rev'], act_list) format_action_count('%(num)d ans', meta_data['new_ans'], act_list) format_action_count('%(num)d ans rev', meta_data['ans_rev'], act_list) questions_data.append({ 'url': site_url(q.get_absolute_url()), 'info': ', '.join(act_list), 'title': q.thread.title }) activate_language(user.get_primary_language()) text = template.render({ 'recipient_user': user, 'questions': questions_data, 'name': user.username, 'admin_email': askbot_settings.ADMIN_EMAIL, 'site_name': askbot_settings.APP_SHORT_NAME, 'is_multilingual': django_settings.ASKBOT_MULTILINGUAL }) if DEBUG_THIS_COMMAND == True: recipient_email = askbot_settings.ADMIN_EMAIL else: recipient_email = user.email mail.send_mail( subject_line = subject_line, body_text = text, recipient_list = [recipient_email] )
def get_text_kn(self, obj): activate_language("kn") return _(obj.text)
def generate_dot(app_labels, **kwargs): disable_fields = kwargs.get('disable_fields', False) include_models = parse_file_or_list(kwargs.get('include_models', "")) all_applications = kwargs.get('all_applications', False) use_subgraph = kwargs.get('group_models', False) verbose_names = kwargs.get('verbose_names', False) language = kwargs.get('language', None) if language is not None: activate_language(language) exclude_columns = parse_file_or_list(kwargs.get('exclude_columns', "")) exclude_models = parse_file_or_list(kwargs.get('exclude_models', "")) def skip_field(field): if exclude_columns: if verbose_names and field.verbose_name: if field.verbose_name in exclude_columns: return True if field.name in exclude_columns: return True return False t = loader.get_template('django_extensions/graph_models/head.html') c = Context({}) dot = t.render(c) apps = [] if all_applications: apps = models.get_apps() for app_label in app_labels: app = models.get_app(app_label) if not app in apps: apps.append(app) graphs = [] for app in apps: graph = Context({ 'name': '"%s"' % app.__name__, 'app_name': "%s" % '.'.join(app.__name__.split('.')[:-1]), 'cluster_app_name': "cluster_%s" % app.__name__.replace(".", "_"), 'disable_fields': disable_fields, 'use_subgraph': use_subgraph, 'models': [] }) for appmodel in get_models(app): abstracts = [ e.__name__ for e in appmodel.__bases__ if hasattr(e, '_meta') and e._meta.abstract ] # collect all attribs of abstract superclasses def getBasesAbstractFields(c): _abstract_fields = [] for e in c.__bases__: if hasattr(e, '_meta') and e._meta.abstract: _abstract_fields.extend(e._meta.fields) _abstract_fields.extend(getBasesAbstractFields(e)) return _abstract_fields abstract_fields = getBasesAbstractFields(appmodel) model = { 'app_name': appmodel.__module__.replace(".", "_"), 'name': appmodel.__name__, 'abstracts': abstracts, 'fields': [], 'relations': [] } # consider given model name ? def consider(model_name): if exclude_models and model_name in exclude_models: return False return not include_models or model_name in include_models if not consider(appmodel._meta.object_name): continue if verbose_names and appmodel._meta.verbose_name: model['label'] = appmodel._meta.verbose_name else: model['label'] = model['name'] # model attributes def add_attributes(field): if verbose_names and field.verbose_name: label = field.verbose_name else: label = field.name model['fields'].append({ 'name': field.name, 'label': label, 'type': type(field).__name__, 'blank': field.blank, 'abstract': field in abstract_fields, }) for field in appmodel._meta.fields: if skip_field(field): continue add_attributes(field) if appmodel._meta.many_to_many: for field in appmodel._meta.many_to_many: if skip_field(field): continue add_attributes(field) # relations def add_relation(field, extras=""): if verbose_names and field.verbose_name: label = field.verbose_name else: label = field.name _rel = { 'target_app': field.rel.to.__module__.replace('.', '_'), 'target': field.rel.to.__name__, 'type': type(field).__name__, 'name': field.name, 'label': label, 'arrows': extras, 'needs_node': True } if _rel not in model['relations'] and consider(_rel['target']): model['relations'].append(_rel) for field in appmodel._meta.fields: if skip_field(field): continue if isinstance(field, OneToOneField): add_relation(field, '[arrowhead=none arrowtail=none]') elif isinstance(field, ForeignKey): add_relation(field) if appmodel._meta.many_to_many: for field in appmodel._meta.many_to_many: if skip_field(field): continue if isinstance(field, ManyToManyField): if (getattr(field, 'creates_table', False) or # django 1.1. (field.rel.through and field.rel.through._meta.auto_created) ): # django 1.2 add_relation( field, '[arrowhead=normal arrowtail=normal]') elif isinstance(field, GenericRelation): add_relation( field, mark_safe( '[style="dotted"] [arrowhead=normal arrowtail=normal]' )) graph['models'].append(model) graphs.append(graph) nodes = [] for graph in graphs: nodes.extend([e['name'] for e in graph['models']]) for graph in graphs: # don't draw duplication nodes because of relations for model in graph['models']: for relation in model['relations']: if relation['target'] in nodes: relation['needs_node'] = False # render templates t = loader.get_template('django_extensions/graph_models/body.html') dot += '\n' + t.render(graph) for graph in graphs: t = loader.get_template('django_extensions/graph_models/rel.html') dot += '\n' + t.render(graph) t = loader.get_template('django_extensions/graph_models/tail.html') c = Context({}) dot += '\n' + t.render(c) return dot
def send_instant_notifications_about_activity_in_post( activity_id=None, post_id=None, recipients=None, ): if recipients is None: return acceptable_types = const.RESPONSE_ACTIVITY_TYPES_FOR_INSTANT_NOTIFICATIONS try: update_activity = Activity.objects.filter( activity_type__in=acceptable_types).get(id=activity_id) except Activity.DoesNotExist: logger.error("Unable to fetch activity with id %s" % post_id) return try: post = Post.objects.get(id=post_id) except Post.DoesNotExist: logger.error("Unable to fetch post with id %s" % post_id) return if post.is_approved() is False: return #calculate some variables used in the loop below update_type_map = const.RESPONSE_ACTIVITY_TYPE_MAP_FOR_TEMPLATES update_type = update_type_map[update_activity.activity_type] origin_post = post.get_origin_post() headers = mail.thread_headers(post, origin_post, update_activity.activity_type) if logger.getEffectiveLevel() <= logging.DEBUG: log_id = uuid.uuid1() message = 'email-alert %s, logId=%s' % (post.get_absolute_url(), log_id) logger.debug(message) else: log_id = None for user in recipients: if user.is_blocked(): continue reply_address, alt_reply_address = get_reply_to_addresses(user, post) activate_language(post.language_code) subject_line, body_text = format_instant_notification_email( to_user=user, from_user=update_activity.user, post=post, reply_address=reply_address, alt_reply_address=alt_reply_address, update_type=update_type, template=get_template('email/instant_notification.html')) headers['Reply-To'] = reply_address try: mail.send_mail(subject_line=subject_line, body_text=body_text, recipient_list=[user.email], related_object=origin_post, activity_type=const.TYPE_ACTIVITY_EMAIL_UPDATE_SENT, headers=headers, raise_on_failure=True) except askbot_exceptions.EmailNotSent, error: logger.debug('%s, error=%s, logId=%s' % (user.email, error, log_id)) else: logger.debug('success %s, logId=%s' % (user.email, log_id))
def generate_graph_data(app_labels, **kwargs): cli_options = kwargs.get('cli_options', None) disable_fields = kwargs.get('disable_fields', False) include_models = parse_file_or_list(kwargs.get('include_models', "")) all_applications = kwargs.get('all_applications', False) use_subgraph = kwargs.get('group_models', False) verbose_names = kwargs.get('verbose_names', False) inheritance = kwargs.get('inheritance', True) relations_as_fields = kwargs.get("relations_as_fields", True) sort_fields = kwargs.get("sort_fields", True) language = kwargs.get('language', None) if language is not None: activate_language(language) exclude_columns = parse_file_or_list(kwargs.get('exclude_columns', "")) exclude_models = parse_file_or_list(kwargs.get('exclude_models', "")) def skip_field(field): if exclude_columns: if verbose_names and field.verbose_name: if field.verbose_name in exclude_columns: return True if field.name in exclude_columns: return True return False if all_applications: app_labels = list_app_labels() graphs = [] for app_label in app_labels: app = get_app(app_label) if not app: continue graph = Context({ 'name': '"%s"' % app.__name__, 'app_name': "%s" % '.'.join(app.__name__.split('.')[:-1]), 'cluster_app_name': "cluster_%s" % app.__name__.replace(".", "_"), 'models': [] }) appmodels = list(get_models_compat(app_label)) abstract_models = [] for appmodel in appmodels: abstract_models = abstract_models + [abstract_model for abstract_model in appmodel.__bases__ if hasattr(abstract_model, '_meta') and abstract_model._meta.abstract] abstract_models = list(set(abstract_models)) # remove duplicates appmodels = abstract_models + appmodels for appmodel in appmodels: appmodel_abstracts = [abstract_model.__name__ for abstract_model in appmodel.__bases__ if hasattr(abstract_model, '_meta') and abstract_model._meta.abstract] # collect all attribs of abstract superclasses def getBasesAbstractFields(c): _abstract_fields = [] for e in c.__bases__: if hasattr(e, '_meta') and e._meta.abstract: _abstract_fields.extend(e._meta.fields) _abstract_fields.extend(getBasesAbstractFields(e)) return _abstract_fields abstract_fields = getBasesAbstractFields(appmodel) model = { 'app_name': appmodel.__module__.replace(".", "_"), 'name': appmodel.__name__, 'abstracts': appmodel_abstracts, 'fields': [], 'relations': [] } if not use_model( appmodel._meta.object_name, include_models, exclude_models ): continue if verbose_names and appmodel._meta.verbose_name: model['label'] = force_bytes(appmodel._meta.verbose_name) else: model['label'] = model['name'] # model attributes def add_attributes(field): if verbose_names and field.verbose_name: label = force_bytes(field.verbose_name) if label.islower(): label = label.capitalize() else: label = field.name t = type(field).__name__ if isinstance(field, (OneToOneField, ForeignKey)): t += " ({0})".format(field.rel.field_name) # TODO: ManyToManyField, GenericRelation model['fields'].append({ 'name': field.name, 'label': label, 'type': t, 'blank': field.blank, 'abstract': field in abstract_fields, 'relation': isinstance(field, RelatedField), 'primary_key': field.primary_key, }) attributes = [field for field in appmodel._meta.local_fields] if not relations_as_fields: # Find all the 'real' attributes. Relations are depicted as graph edges instead of attributes attributes = [field for field in attributes if not isinstance(field, RelatedField)] # find primary key and print it first, ignoring implicit id if other pk exists pk = appmodel._meta.pk if pk and not appmodel._meta.abstract and pk in attributes: add_attributes(pk) for field in attributes: if skip_field(field): continue if pk and field == pk: continue add_attributes(field) if sort_fields: model['fields'] = sorted(model['fields'], key=lambda field: (not field['primary_key'], not field['relation'], field['label'])) # FIXME: actually many_to_many fields aren't saved in this model's db table, so why should we add an attribute-line for them in the resulting graph? # if appmodel._meta.many_to_many: # for field in appmodel._meta.many_to_many: # if skip_field(field): # continue # add_attributes(field) # relations def add_relation(field, extras=""): if verbose_names and field.verbose_name: label = force_bytes(field.verbose_name) if label.islower(): label = label.capitalize() else: label = field.name # show related field name if hasattr(field, 'related_query_name'): related_query_name = field.related_query_name() if verbose_names and related_query_name.islower(): related_query_name = related_query_name.replace('_', ' ').capitalize() label = '{} ({})'.format(label, force_bytes(related_query_name)) # handle self-relationships and lazy-relationships if isinstance(field.rel.to, six.string_types): if field.rel.to == 'self': target_model = field.model else: target_model = get_model(field.rel.to) else: target_model = field.rel.to _rel = { 'target_app': target_model.__module__.replace('.', '_'), 'target': target_model.__name__, 'type': type(field).__name__, 'name': field.name, 'label': label, 'arrows': extras, 'needs_node': True } if _rel not in model['relations'] and use_model( _rel['target'], include_models, exclude_models ): model['relations'].append(_rel) for field in appmodel._meta.local_fields: if field.attname.endswith('_ptr_id'): # excluding field redundant with inheritance relation continue if field in abstract_fields: # excluding fields inherited from abstract classes. they too show as local_fields continue if skip_field(field): continue if isinstance(field, OneToOneField): add_relation(field, '[arrowhead=none, arrowtail=none, dir=both]') elif isinstance(field, ForeignKey): add_relation(field, '[arrowhead=none, arrowtail=dot, dir=both]') for field in appmodel._meta.local_many_to_many: if skip_field(field): continue if isinstance(field, ManyToManyField): if (getattr(field, 'creates_table', False) or # django 1.1. (hasattr(field.rel.through, '_meta') and field.rel.through._meta.auto_created)): # django 1.2 add_relation(field, '[arrowhead=dot arrowtail=dot, dir=both]') elif isinstance(field, GenericRelation): add_relation(field, mark_safe('[style="dotted", arrowhead=normal, arrowtail=normal, dir=both]')) if inheritance: # add inheritance arrows for parent in appmodel.__bases__: if hasattr(parent, "_meta"): # parent is a model l = "multi-table" if parent._meta.abstract: l = "abstract" if appmodel._meta.proxy: l = "proxy" l += r"\ninheritance" _rel = { 'target_app': parent.__module__.replace(".", "_"), 'target': parent.__name__, 'type': "inheritance", 'name': "inheritance", 'label': l, 'arrows': '[arrowhead=empty, arrowtail=none, dir=both]', 'needs_node': True, } # TODO: seems as if abstract models aren't part of models.getModels, which is why they are printed by this without any attributes. if _rel not in model['relations'] and use_model( _rel['target'], include_models, exclude_columns ): model['relations'].append(_rel) graph['models'].append(model) if graph['models']: graphs.append(graph) nodes = [] for graph in graphs: nodes.extend([e['name'] for e in graph['models']]) for graph in graphs: for model in graph['models']: for relation in model['relations']: if relation['target'] in nodes: relation['needs_node'] = False now = datetime.datetime.now() graph_data = { 'created_at': now.strftime("%Y-%m-%d %H:%M"), 'cli_options': cli_options, 'disable_fields': disable_fields, 'use_subgraph': use_subgraph, 'graphs': graphs, } return graph_data
def langpage(request, lang, page): translation.activate_language(lang) return page(request, page)
def generate_dot(app_labels, **kwargs): disable_fields = kwargs.get('disable_fields', False) include_models = parse_file_or_list(kwargs.get('include_models', "")) all_applications = kwargs.get('all_applications', False) use_subgraph = kwargs.get('group_models', False) verbose_names = kwargs.get('verbose_names', False) inheritance = kwargs.get('inheritance', False) language = kwargs.get('language', None) if language is not None: activate_language(language) exclude_columns = parse_file_or_list(kwargs.get('exclude_columns', "")) exclude_models = parse_file_or_list(kwargs.get('exclude_models', "")) def skip_field(field): if exclude_columns: if verbose_names and field.verbose_name: if field.verbose_name in exclude_columns: return True if field.name in exclude_columns: return True return False t = loader.get_template_from_string(""" digraph name { fontname = "Helvetica" fontsize = 8 node [ fontname = "Helvetica" fontsize = 8 shape = "plaintext" ] edge [ fontname = "Helvetica" fontsize = 8 ] """) c = Context({}) dot = t.render(c) apps = [] if all_applications: apps = models.get_apps() for app_label in app_labels: app = models.get_app(app_label) if not app in apps: apps.append(app) graphs = [] for app in apps: graph = Context({ 'name': '"%s"' % app.__name__, 'app_name': "%s" % '.'.join(app.__name__.split('.')[:-1]), 'cluster_app_name': "cluster_%s" % app.__name__.replace(".", "_"), 'disable_fields': disable_fields, 'use_subgraph': use_subgraph, 'models': [] }) appmodels = get_models(app) abstract_models = [] for appmodel in appmodels: abstract_models = abstract_models + [ abstract_model for abstract_model in appmodel.__bases__ if hasattr( abstract_model, '_meta') and abstract_model._meta.abstract ] abstract_models = list(set(abstract_models)) # remove duplicates appmodels = abstract_models + appmodels for appmodel in appmodels: appmodel_abstracts = [ abstract_model.__name__ for abstract_model in appmodel.__bases__ if hasattr(abstract_model, '_meta') and abstract_model._meta.abstract ] # collect all attribs of abstract superclasses def getBasesAbstractFields(c): _abstract_fields = [] for e in c.__bases__: if hasattr(e, '_meta') and e._meta.abstract: _abstract_fields.extend(e._meta.fields) _abstract_fields.extend(getBasesAbstractFields(e)) return _abstract_fields abstract_fields = getBasesAbstractFields(appmodel) model = { 'app_name': appmodel.__module__.replace(".", "_"), 'name': appmodel.__name__, 'abstracts': appmodel_abstracts, 'fields': [], 'relations': [] } # consider given model name ? def consider(model_name): if exclude_models and model_name in exclude_models: return False return not include_models or model_name in include_models if not consider(appmodel._meta.object_name): continue if verbose_names and appmodel._meta.verbose_name: model['label'] = appmodel._meta.verbose_name else: model['label'] = model['name'] # model attributes def add_attributes(field): if verbose_names and field.verbose_name: label = field.verbose_name else: label = field.name t = type(field).__name__ if isinstance(field, (OneToOneField, ForeignKey)): t += " ({0})".format(field.rel.field_name) # TODO: ManyToManyField, GenericRelation model['fields'].append({ 'name': field.name, 'label': label, 'type': t, 'blank': field.blank, 'abstract': field in abstract_fields, }) # Find all the real attributes. Relations are depicted as graph edges instead of attributes attributes = [ field for field in appmodel._meta.local_fields if not isinstance(field, RelatedField) ] # find primary key and print it first, ignoring implicit id if other pk exists pk = appmodel._meta.pk if not appmodel._meta.abstract and pk in attributes: add_attributes(pk) for field in attributes: if skip_field(field): continue if not field.primary_key: add_attributes(field) # FIXME: actually many_to_many fields aren't saved in this model's db table, so why should we add an attribute-line for them in the resulting graph? #if appmodel._meta.many_to_many: # for field in appmodel._meta.many_to_many: # if skip_field(field): # continue # add_attributes(field) # relations def add_relation(field, extras=""): if verbose_names and field.verbose_name: label = field.verbose_name else: label = field.name # show related field name if hasattr(field, 'related_query_name'): label += ' (%s)' % field.related_query_name() # handle self-relationships if field.rel.to == 'self': target_model = field.model else: target_model = field.rel.to _rel = { 'target_app': target_model.__module__.replace('.', '_'), 'target': target_model.__name__, 'type': type(field).__name__, 'name': field.name, 'label': label, 'arrows': extras, 'needs_node': True } if _rel not in model['relations'] and consider(_rel['target']): model['relations'].append(_rel) for field in appmodel._meta.local_fields: if field.attname.endswith( '_ptr_id' ): # excluding field redundant with inheritance relation continue if field in abstract_fields: # excluding fields inherited from abstract classes. they too show as local_fields continue if skip_field(field): continue if isinstance(field, OneToOneField): add_relation(field, '[arrowhead=none, arrowtail=none]') elif isinstance(field, ForeignKey): add_relation(field, '[arrowhead=none, arrowtail=dot]') for field in appmodel._meta.local_many_to_many: if skip_field(field): continue if isinstance(field, ManyToManyField): if (getattr(field, 'creates_table', False) or # django 1.1. (hasattr(field.rel.through, '_meta') and field.rel.through._meta.auto_created)): # django 1.2 add_relation( field, '[arrowhead=dot arrowtail=dot, dir=both]') elif isinstance(field, GenericRelation): add_relation( field, mark_safe( '[style="dotted", arrowhead=normal, arrowtail=normal, dir=both]' )) if inheritance: # add inheritance arrows for parent in appmodel.__bases__: if hasattr(parent, "_meta"): # parent is a model l = "multi-table" if parent._meta.abstract: l = "abstract" if appmodel._meta.proxy: l = "proxy" l += r"\ninheritance" _rel = { 'target_app': parent.__module__.replace(".", "_"), 'target': parent.__name__, 'type': "inheritance", 'name': "inheritance", 'label': l, 'arrows': '[arrowhead=empty, arrowtail=none]', 'needs_node': True } # TODO: seems as if abstract models aren't part of models.getModels, which is why they are printed by this without any attributes. if _rel not in model['relations'] and consider( _rel['target']): model['relations'].append(_rel) graph['models'].append(model) graphs.append(graph) nodes = [] for graph in graphs: nodes.extend([e['name'] for e in graph['models']]) for graph in graphs: # don't draw duplication nodes because of relations for model in graph['models']: for relation in model['relations']: if relation['target'] in nodes: relation['needs_node'] = False # render templates t = loader.get_template_from_string("""{% if use_subgraph %} subgraph {{ cluster_app_name }} { label=< <TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0"> <TR><TD COLSPAN="2" CELLPADDING="4" ALIGN="CENTER" ><FONT FACE="Helvetica Bold" COLOR="Black" POINT-SIZE="12" >{{ app_name }}</FONT></TD></TR> </TABLE> > color=olivedrab4 style="rounded" {% endif %} {% for model in models %} {{ model.app_name }}_{{ model.name }} [label=< <TABLE BGCOLOR="palegoldenrod" BORDER="0" CELLBORDER="0" CELLSPACING="0"> <TR><TD COLSPAN="2" CELLPADDING="4" ALIGN="CENTER" BGCOLOR="olivedrab4" ><FONT FACE="Helvetica Bold" COLOR="white" >{{ model.label }}{% if model.abstracts %}<BR/><<FONT FACE="Helvetica Italic">{{ model.abstracts|join:"," }}</FONT>>{% endif %}</FONT></TD></TR> {% if not disable_fields %} {% for field in model.fields %} <TR><TD ALIGN="LEFT" BORDER="0" ><FONT {% if field.blank %}COLOR="#7B7B7B" {% endif %}FACE="Helvetica {% if field.abstract %}Italic{% else %}Bold{% endif %}">{{ field.label }}</FONT ></TD> <TD ALIGN="LEFT" ><FONT {% if field.blank %}COLOR="#7B7B7B" {% endif %}FACE="Helvetica {% if field.abstract %}Italic{% else %}Bold{% endif %}">{{ field.type }}</FONT ></TD></TR> {% endfor %} {% endif %} </TABLE> >] {% endfor %} {% if use_subgraph %} } {% endif %}""") dot += '\n' + t.render(graph) for graph in graphs: t = loader.get_template_from_string("""{% for model in models %} {% for relation in model.relations %} {% if relation.needs_node %} {{ relation.target_app }}_{{ relation.target }} [label=< <TABLE BGCOLOR="palegoldenrod" BORDER="0" CELLBORDER="0" CELLSPACING="0"> <TR><TD COLSPAN="2" CELLPADDING="4" ALIGN="CENTER" BGCOLOR="olivedrab4" ><FONT FACE="Helvetica Bold" COLOR="white" >{{ relation.target }}</FONT></TD></TR> </TABLE> >] {% endif %} {{ model.app_name }}_{{ model.name }} -> {{ relation.target_app }}_{{ relation.target }} [label="{{ relation.label }}"] {{ relation.arrows }}; {% endfor %} {% endfor %}""") dot += '\n' + t.render(graph) t = loader.get_template_from_string("}") c = Context({}) dot += '\n' + t.render(c) return dot
def send_email_alerts(self, user): #does not change the database, only sends the email #todo: move this to template user.add_missing_askbot_subscriptions() #todo: q_list is a dictionary, not a list q_list = self.get_updated_questions_for_user(user) if len(q_list.keys()) == 0: return num_q = 0 for question, meta_data in q_list.items(): if meta_data['skip']: del q_list[question] else: num_q += 1 if num_q > 0: threads = Thread.objects.filter( id__in=[qq.thread_id for qq in q_list.keys()]) tag_summary = Thread.objects.get_tag_summary_from_threads(threads) question_count = len(q_list.keys()) items_added = 0 items_unreported = 0 questions_data = list() for q, meta_data in q_list.items(): act_list = [] if meta_data['skip']: continue if items_added >= askbot_settings.MAX_ALERTS_PER_EMAIL: items_unreported = num_q - items_added #may be inaccurate actually, but it's ok break else: items_added += 1 if meta_data['new_q']: act_list.append(_('new question')) format_action_count('%(num)d rev', meta_data['q_rev'], act_list) format_action_count('%(num)d ans', meta_data['new_ans'], act_list) format_action_count('%(num)d ans rev', meta_data['ans_rev'], act_list) questions_data.append({ 'url': site_url(q.get_absolute_url()), 'info': ', '.join(act_list), 'title': q.thread.title }) activate_language(user.get_primary_language()) email = BatchEmailAlert({ 'questions': questions_data, 'question_count': question_count, 'tag_summary': tag_summary, 'user': user }) if DEBUG_THIS_COMMAND == True: recipient_email = askbot_settings.ADMIN_EMAIL else: recipient_email = user.email if recipient_email: email.send([recipient_email])
def generate_dot(app_labels, **kwargs): disable_fields = kwargs.get("disable_fields", False) include_models = parse_file_or_list(kwargs.get("include_models", "")) all_applications = kwargs.get("all_applications", False) use_subgraph = kwargs.get("group_models", False) verbose_names = kwargs.get("verbose_names", False) inheritance = kwargs.get("inheritance", False) language = kwargs.get("language", None) if language is not None: activate_language(language) exclude_columns = parse_file_or_list(kwargs.get("exclude_columns", "")) exclude_models = parse_file_or_list(kwargs.get("exclude_models", "")) def skip_field(field): if exclude_columns: if verbose_names and field.verbose_name: if field.verbose_name in exclude_columns: return True if field.name in exclude_columns: return True return False t = loader.get_template("django_extensions/graph_models/head.html") c = Context({}) dot = t.render(c) apps = [] if all_applications: apps = models.get_apps() for app_label in app_labels: app = models.get_app(app_label) if not app in apps: apps.append(app) graphs = [] for app in apps: graph = Context( { "name": '"%s"' % app.__name__, "app_name": "%s" % ".".join(app.__name__.split(".")[:-1]), "cluster_app_name": "cluster_%s" % app.__name__.replace(".", "_"), "disable_fields": disable_fields, "use_subgraph": use_subgraph, "models": [], } ) appmodels = get_models(app) abstract_models = [] for appmodel in appmodels: abstract_models = abstract_models + [ abstract_model for abstract_model in appmodel.__bases__ if hasattr(abstract_model, "_meta") and abstract_model._meta.abstract ] abstract_models = list(set(abstract_models)) # remove duplicates appmodels = abstract_models + appmodels for appmodel in appmodels: appmodel_abstracts = [ abstract_model.__name__ for abstract_model in appmodel.__bases__ if hasattr(abstract_model, "_meta") and abstract_model._meta.abstract ] # collect all attribs of abstract superclasses def getBasesAbstractFields(c): _abstract_fields = [] for e in c.__bases__: if hasattr(e, "_meta") and e._meta.abstract: _abstract_fields.extend(e._meta.fields) _abstract_fields.extend(getBasesAbstractFields(e)) return _abstract_fields abstract_fields = getBasesAbstractFields(appmodel) model = { "app_name": appmodel.__module__.replace(".", "_"), "name": appmodel.__name__, "abstracts": appmodel_abstracts, "fields": [], "relations": [], } # consider given model name ? def consider(model_name): if exclude_models and model_name in exclude_models: return False return not include_models or model_name in include_models if not consider(appmodel._meta.object_name): continue if verbose_names and appmodel._meta.verbose_name: model["label"] = appmodel._meta.verbose_name else: model["label"] = model["name"] # model attributes def add_attributes(field): if verbose_names and field.verbose_name: label = field.verbose_name else: label = field.name t = type(field).__name__ if isinstance(field, (OneToOneField, ForeignKey)): t += " ({0})".format(field.rel.field_name) # TODO: ManyToManyField, GenericRelation model["fields"].append( { "name": field.name, "label": label, "type": t, "blank": field.blank, "abstract": field in abstract_fields, } ) # Find all the real attributes. Relations are depicted as graph edges instead of attributes attributes = [field for field in appmodel._meta.local_fields if not isinstance(field, RelatedField)] # find primary key and print it first, ignoring implicit id if other pk exists pk = appmodel._meta.pk if not appmodel._meta.abstract and pk in attributes: add_attributes(pk) for field in attributes: if skip_field(field): continue if not field.primary_key: add_attributes(field) # FIXME: actually many_to_many fields aren't saved in this model's db table, so why should we add an attribute-line for them in the resulting graph? # if appmodel._meta.many_to_many: # for field in appmodel._meta.many_to_many: # if skip_field(field): # continue # add_attributes(field) # relations def add_relation(field, extras=""): if verbose_names and field.verbose_name: label = field.verbose_name else: label = field.name # show related field name if hasattr(field, "related_query_name"): label += " (%s)" % field.related_query_name() _rel = { "target_app": field.rel.to.__module__.replace(".", "_"), "target": field.rel.to.__name__, "type": type(field).__name__, "name": field.name, "label": label, "arrows": extras, "needs_node": True, } if _rel not in model["relations"] and consider(_rel["target"]): model["relations"].append(_rel) for field in appmodel._meta.local_fields: if field.attname.endswith("_ptr_id"): # excluding field redundant with inheritance relation continue if ( field in abstract_fields ): # excluding fields inherited from abstract classes. they too show as local_fields continue if skip_field(field): continue if isinstance(field, OneToOneField): add_relation(field, "[arrowhead=none, arrowtail=none]") elif isinstance(field, ForeignKey): add_relation(field, "[arrowhead=none, arrowtail=dot]") for field in appmodel._meta.local_many_to_many: if skip_field(field): continue if isinstance(field, ManyToManyField): if getattr(field, "creates_table", False) or ( # django 1.1. hasattr(field.rel.through, "_meta") and field.rel.through._meta.auto_created ): # django 1.2 add_relation(field, "[arrowhead=dot arrowtail=dot, dir=both]") elif isinstance(field, GenericRelation): add_relation(field, mark_safe('[style="dotted", arrowhead=normal, arrowtail=normal, dir=both]')) if inheritance: # add inheritance arrows for parent in appmodel.__bases__: if hasattr(parent, "_meta"): # parent is a model l = "multi-table" if parent._meta.abstract: l = "abstract" if appmodel._meta.proxy: l = "proxy" l += r"\ninheritance" _rel = { "target_app": parent.__module__.replace(".", "_"), "target": parent.__name__, "type": "inheritance", "name": "inheritance", "label": l, "arrows": "[arrowhead=empty, arrowtail=none]", "needs_node": True, } # TODO: seems as if abstract models aren't part of models.getModels, which is why they are printed by this without any attributes. if _rel not in model["relations"] and consider(_rel["target"]): model["relations"].append(_rel) graph["models"].append(model) graphs.append(graph) nodes = [] for graph in graphs: nodes.extend([e["name"] for e in graph["models"]]) for graph in graphs: # don't draw duplication nodes because of relations for model in graph["models"]: for relation in model["relations"]: if relation["target"] in nodes: relation["needs_node"] = False # render templates t = loader.get_template("django_extensions/graph_models/body.html") dot += "\n" + t.render(graph) for graph in graphs: t = loader.get_template("django_extensions/graph_models/rel.html") dot += "\n" + t.render(graph) t = loader.get_template("django_extensions/graph_models/tail.html") c = Context({}) dot += "\n" + t.render(c) return dot
def generate_dot(app_labels, **kwargs): disable_fields = kwargs.get('disable_fields', False) include_models = parse_file_or_list(kwargs.get('include_models', "")) all_applications = kwargs.get('all_applications', False) use_subgraph = kwargs.get('group_models', False) verbose_names = kwargs.get('verbose_names', False) inheritance = kwargs.get('inheritance', False) language = kwargs.get('language', None) if language is not None: activate_language(language) exclude_columns = parse_file_or_list(kwargs.get('exclude_columns', "")) exclude_models = parse_file_or_list(kwargs.get('exclude_models', "")) def skip_field(field): if exclude_columns: if verbose_names and field.verbose_name: if field.verbose_name in exclude_columns: return True if field.name in exclude_columns: return True return False t = loader.get_template_from_string(""" digraph name { fontname = "Helvetica" fontsize = 8 node [ fontname = "Helvetica" fontsize = 8 shape = "plaintext" ] edge [ fontname = "Helvetica" fontsize = 8 ] """) c = Context({}) dot = t.render(c) apps = [] if all_applications: apps = models.get_apps() for app_label in app_labels: app = models.get_app(app_label) if not app in apps: apps.append(app) graphs = [] for app in apps: graph = Context({ 'name': '"%s"' % app.__name__, 'app_name': "%s" % '.'.join(app.__name__.split('.')[:-1]), 'cluster_app_name': "cluster_%s" % app.__name__.replace(".", "_"), 'disable_fields': disable_fields, 'use_subgraph': use_subgraph, 'models': [] }) appmodels = get_models(app) abstract_models = [] for appmodel in appmodels: abstract_models = abstract_models + [abstract_model for abstract_model in appmodel.__bases__ if hasattr(abstract_model, '_meta') and abstract_model._meta.abstract] abstract_models = list(set(abstract_models)) # remove duplicates appmodels = abstract_models + appmodels for appmodel in appmodels: appmodel_abstracts = [abstract_model.__name__ for abstract_model in appmodel.__bases__ if hasattr(abstract_model, '_meta') and abstract_model._meta.abstract] # collect all attribs of abstract superclasses def getBasesAbstractFields(c): _abstract_fields = [] for e in c.__bases__: if hasattr(e, '_meta') and e._meta.abstract: _abstract_fields.extend(e._meta.fields) _abstract_fields.extend(getBasesAbstractFields(e)) return _abstract_fields abstract_fields = getBasesAbstractFields(appmodel) model = { 'app_name': appmodel.__module__.replace(".", "_"), 'name': appmodel.__name__, 'abstracts': appmodel_abstracts, 'fields': [], 'relations': [] } # consider given model name ? def consider(model_name): if exclude_models and model_name in exclude_models: return False return not include_models or model_name in include_models if not consider(appmodel._meta.object_name): continue if verbose_names and appmodel._meta.verbose_name: model['label'] = appmodel._meta.verbose_name else: model['label'] = model['name'] # model attributes def add_attributes(field): if verbose_names and field.verbose_name: label = field.verbose_name else: label = field.name t = type(field).__name__ if isinstance(field, (OneToOneField, ForeignKey)): t += " ({0})".format(field.rel.field_name) # TODO: ManyToManyField, GenericRelation model['fields'].append({ 'name': field.name, 'label': label, 'type': t, 'blank': field.blank, 'abstract': field in abstract_fields, }) # Find all the real attributes. Relations are depicted as graph edges instead of attributes attributes = [field for field in appmodel._meta.local_fields if not isinstance(field, RelatedField)] # find primary key and print it first, ignoring implicit id if other pk exists pk = appmodel._meta.pk if not appmodel._meta.abstract and pk in attributes: add_attributes(pk) for field in attributes: if skip_field(field): continue if not field.primary_key: add_attributes(field) # FIXME: actually many_to_many fields aren't saved in this model's db table, so why should we add an attribute-line for them in the resulting graph? #if appmodel._meta.many_to_many: # for field in appmodel._meta.many_to_many: # if skip_field(field): # continue # add_attributes(field) # relations def add_relation(field, extras=""): if verbose_names and field.verbose_name: label = field.verbose_name else: label = field.name # show related field name if hasattr(field, 'related_query_name'): label += ' (%s)' % field.related_query_name() # handle self-relationships if field.rel.to == 'self': target_model = field.model else: target_model = field.rel.to _rel = { 'target_app': target_model.__module__.replace('.', '_'), 'target': target_model.__name__, 'type': type(field).__name__, 'name': field.name, 'label': label, 'arrows': extras, 'needs_node': True } if _rel not in model['relations'] and consider(_rel['target']): model['relations'].append(_rel) for field in appmodel._meta.local_fields: if field.attname.endswith('_ptr_id'): # excluding field redundant with inheritance relation continue if field in abstract_fields: # excluding fields inherited from abstract classes. they too show as local_fields continue if skip_field(field): continue if isinstance(field, OneToOneField): add_relation(field, '[arrowhead=none, arrowtail=none]') elif isinstance(field, ForeignKey): add_relation(field, '[arrowhead=none, arrowtail=dot]') for field in appmodel._meta.local_many_to_many: if skip_field(field): continue if isinstance(field, ManyToManyField): if (getattr(field, 'creates_table', False) or # django 1.1. (hasattr(field.rel.through, '_meta') and field.rel.through._meta.auto_created)): # django 1.2 add_relation(field, '[arrowhead=dot arrowtail=dot, dir=both]') elif isinstance(field, GenericRelation): add_relation(field, mark_safe('[style="dotted", arrowhead=normal, arrowtail=normal, dir=both]')) if inheritance: # add inheritance arrows for parent in appmodel.__bases__: if hasattr(parent, "_meta"): # parent is a model l = "multi-table" if parent._meta.abstract: l = "abstract" if appmodel._meta.proxy: l = "proxy" l += r"\ninheritance" _rel = { 'target_app': parent.__module__.replace(".", "_"), 'target': parent.__name__, 'type': "inheritance", 'name': "inheritance", 'label': l, 'arrows': '[arrowhead=empty, arrowtail=none]', 'needs_node': True } # TODO: seems as if abstract models aren't part of models.getModels, which is why they are printed by this without any attributes. if _rel not in model['relations'] and consider(_rel['target']): model['relations'].append(_rel) graph['models'].append(model) graphs.append(graph) nodes = [] for graph in graphs: nodes.extend([e['name'] for e in graph['models']]) for graph in graphs: # don't draw duplication nodes because of relations for model in graph['models']: for relation in model['relations']: if relation['target'] in nodes: relation['needs_node'] = False # render templates t = loader.get_template_from_string("""{% if use_subgraph %} subgraph {{ cluster_app_name }} { label=< <TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0"> <TR><TD COLSPAN="2" CELLPADDING="4" ALIGN="CENTER" ><FONT FACE="Helvetica Bold" COLOR="Black" POINT-SIZE="12" >{{ app_name }}</FONT></TD></TR> </TABLE> > color=olivedrab4 style="rounded" {% endif %} {% for model in models %} {{ model.app_name }}_{{ model.name }} [label=< <TABLE BGCOLOR="palegoldenrod" BORDER="0" CELLBORDER="0" CELLSPACING="0"> <TR><TD COLSPAN="2" CELLPADDING="4" ALIGN="CENTER" BGCOLOR="olivedrab4" ><FONT FACE="Helvetica Bold" COLOR="white" >{{ model.label }}{% if model.abstracts %}<BR/><<FONT FACE="Helvetica Italic">{{ model.abstracts|join:"," }}</FONT>>{% endif %}</FONT></TD></TR> {% if not disable_fields %} {% for field in model.fields %} <TR><TD ALIGN="LEFT" BORDER="0" ><FONT {% if field.blank %}COLOR="#7B7B7B" {% endif %}FACE="Helvetica {% if field.abstract %}Italic{% else %}Bold{% endif %}">{{ field.label }}</FONT ></TD> <TD ALIGN="LEFT" ><FONT {% if field.blank %}COLOR="#7B7B7B" {% endif %}FACE="Helvetica {% if field.abstract %}Italic{% else %}Bold{% endif %}">{{ field.type }}</FONT ></TD></TR> {% endfor %} {% endif %} </TABLE> >] {% endfor %} {% if use_subgraph %} } {% endif %}""") dot += '\n' + t.render(graph) for graph in graphs: t = loader.get_template_from_string("""{% for model in models %} {% for relation in model.relations %} {% if relation.needs_node %} {{ relation.target_app }}_{{ relation.target }} [label=< <TABLE BGCOLOR="palegoldenrod" BORDER="0" CELLBORDER="0" CELLSPACING="0"> <TR><TD COLSPAN="2" CELLPADDING="4" ALIGN="CENTER" BGCOLOR="olivedrab4" ><FONT FACE="Helvetica Bold" COLOR="white" >{{ relation.target }}</FONT></TD></TR> </TABLE> >] {% endif %} {{ model.app_name }}_{{ model.name }} -> {{ relation.target_app }}_{{ relation.target }} [label="{{ relation.label }}"] {{ relation.arrows }}; {% endfor %} {% endfor %}""") dot += '\n' + t.render(graph) t = loader.get_template_from_string("}") c = Context({}) dot += '\n' + t.render(c) return dot
def send_instant_notifications_about_activity_in_post( update_activity = None, post = None, recipients = None, ): #reload object from the database post = Post.objects.get(id=post.id) if post.is_approved() is False: return if recipients is None: return acceptable_types = const.RESPONSE_ACTIVITY_TYPES_FOR_INSTANT_NOTIFICATIONS if update_activity.activity_type not in acceptable_types: return #calculate some variables used in the loop below update_type_map = const.RESPONSE_ACTIVITY_TYPE_MAP_FOR_TEMPLATES update_type = update_type_map[update_activity.activity_type] origin_post = post.get_origin_post() headers = mail.thread_headers( post, origin_post, update_activity.activity_type ) logger = logging.getLogger() if logger.getEffectiveLevel() <= logging.DEBUG: log_id = uuid.uuid1() message = 'email-alert %s, logId=%s' % (post.get_absolute_url(), log_id) logger.debug(message) else: log_id = None for user in recipients: if user.is_blocked(): continue reply_address, alt_reply_address = get_reply_to_addresses(user, post) activate_language(post.language_code) subject_line, body_text = format_instant_notification_email( to_user = user, from_user = update_activity.user, post = post, reply_address = reply_address, alt_reply_address = alt_reply_address, update_type = update_type, template = get_template('email/instant_notification.html') ) headers['Reply-To'] = reply_address try: mail.send_mail( subject_line=subject_line, body_text=body_text, recipient_list=[user.email], related_object=origin_post, activity_type=const.TYPE_ACTIVITY_EMAIL_UPDATE_SENT, headers=headers, raise_on_failure=True ) except askbot_exceptions.EmailNotSent, error: logger.debug( '%s, error=%s, logId=%s' % (user.email, error, log_id) ) else: logger.debug('success %s, logId=%s' % (user.email, log_id))
def generate_dot(app_labels, **kwargs): disable_fields = kwargs.get('disable_fields', False) include_models = parse_file_or_list(kwargs.get('include_models', "")) all_applications = kwargs.get('all_applications', False) use_subgraph = kwargs.get('group_models', False) verbose_names = kwargs.get('verbose_names', False) inheritance = kwargs.get('inheritance', False) language = kwargs.get('language', None) if language is not None: activate_language(language) exclude_columns = parse_file_or_list(kwargs.get('exclude_columns', "")) exclude_models = parse_file_or_list(kwargs.get('exclude_models', "")) def skip_field(field): if exclude_columns: if verbose_names and field.verbose_name: if field.verbose_name in exclude_columns: return True if field.name in exclude_columns: return True return False t = loader.get_template('django_extensions/graph_models/head.html') c = Context({}) dot = t.render(c) apps = [] if all_applications: apps = models.get_apps() for app_label in app_labels: app = models.get_app(app_label) if app not in apps: apps.append(app) graphs = [] for app in apps: graph = Context({ 'name': '"%s"' % app.__name__, 'app_name': "%s" % '.'.join(app.__name__.split('.')[:-1]), 'cluster_app_name': "cluster_%s" % app.__name__.replace(".", "_"), 'disable_fields': disable_fields, 'use_subgraph': use_subgraph, 'models': [] }) appmodels = get_models(app) abstract_models = [] for appmodel in appmodels: abstract_models = abstract_models + [ abstract_model for abstract_model in appmodel.__bases__ if hasattr( abstract_model, '_meta') and abstract_model._meta.abstract] abstract_models = list(set(abstract_models)) # remove duplicates appmodels = abstract_models + appmodels for appmodel in appmodels: appmodel_abstracts = [ abstract_model.__name__ for abstract_model in appmodel.__bases__ if hasattr( abstract_model, '_meta') and abstract_model._meta.abstract] # collect all attribs of abstract superclasses def getBasesAbstractFields(c): _abstract_fields = [] for e in c.__bases__: if hasattr(e, '_meta') and e._meta.abstract: _abstract_fields.extend(e._meta.fields) _abstract_fields.extend(getBasesAbstractFields(e)) return _abstract_fields abstract_fields = getBasesAbstractFields(appmodel) model = { 'app_name': appmodel.__module__.replace(".", "_"), 'name': appmodel.__name__, 'abstracts': appmodel_abstracts, 'fields': [], 'relations': [] } # consider given model name ? def consider(model_name): if exclude_models and model_name in exclude_models: return False return not include_models or model_name in include_models if not consider(appmodel._meta.object_name): continue if verbose_names and appmodel._meta.verbose_name: model['label'] = appmodel._meta.verbose_name else: model['label'] = model['name'] # model attributes def add_attributes(field): if verbose_names and field.verbose_name: label = field.verbose_name else: label = field.name t = type(field).__name__ if isinstance(field, (OneToOneField, ForeignKey)): t += " ({0})".format(field.rel.field_name) # TODO: ManyToManyField, GenericRelation model['fields'].append({ 'name': field.name, 'label': label, 'type': t, 'blank': field.blank, 'abstract': field in abstract_fields, }) # Find all the real attributes. Relations are depicted as graph # edges instead of attributes attributes = [ field for field in appmodel._meta.local_fields if not isinstance( field, RelatedField)] # find primary key and print it first, ignoring implicit id if # other pk exists pk = appmodel._meta.pk if not appmodel._meta.abstract and pk in attributes: add_attributes(pk) for field in attributes: if skip_field(field): continue if not field.primary_key: add_attributes(field) # FIXME: actually many_to_many fields aren't saved in this model's db table, so why should we add an attribute-line for them in the resulting graph? # if appmodel._meta.many_to_many: # for field in appmodel._meta.many_to_many: # if skip_field(field): # continue # add_attributes(field) # relations def add_relation(field, extras=""): if verbose_names and field.verbose_name: label = field.verbose_name else: label = field.name # show related field name if hasattr(field, 'related_query_name'): label += ' (%s)' % field.related_query_name() # handle self-relationships if field.rel.to == 'self': target_model = field.model else: target_model = field.rel.to _rel = { 'target_app': target_model.__module__.replace('.', '_'), 'target': target_model.__name__, 'type': type(field).__name__, 'name': field.name, 'label': label, 'arrows': extras, 'needs_node': True } if _rel not in model['relations'] and consider(_rel['target']): model['relations'].append(_rel) for field in appmodel._meta.local_fields: if field.attname.endswith( '_ptr_id'): # excluding field redundant with inheritance relation continue if field in abstract_fields: # excluding fields inherited from abstract classes. they too show as local_fields continue if skip_field(field): continue if isinstance(field, OneToOneField): add_relation(field, '[arrowhead=none, arrowtail=none]') elif isinstance(field, ForeignKey): add_relation(field, '[arrowhead=none, arrowtail=dot]') for field in appmodel._meta.local_many_to_many: if skip_field(field): continue if isinstance(field, ManyToManyField): if (getattr(field, 'creates_table', False) or # django 1.1. (hasattr(field.rel.through, '_meta') and field.rel.through._meta.auto_created)): # django 1.2 add_relation( field, '[arrowhead=dot arrowtail=dot, dir=both]') elif isinstance(field, GenericRelation): add_relation(field, mark_safe( '[style="dotted", arrowhead=normal, arrowtail=normal, dir=both]')) if inheritance: # add inheritance arrows for parent in appmodel.__bases__: if hasattr(parent, "_meta"): # parent is a model l = "multi-table" if parent._meta.abstract: l = "abstract" if appmodel._meta.proxy: l = "proxy" l += r"\ninheritance" _rel = { 'target_app': parent.__module__.replace(".", "_"), 'target': parent.__name__, 'type': "inheritance", 'name': "inheritance", 'label': l, 'arrows': '[arrowhead=empty, arrowtail=none]', 'needs_node': True } # TODO: seems as if abstract models aren't part of # models.getModels, which is why they are printed by # this without any attributes. if _rel not in model[ 'relations'] and consider(_rel['target']): model['relations'].append(_rel) graph['models'].append(model) graphs.append(graph) nodes = [] for graph in graphs: nodes.extend([e['name'] for e in graph['models']]) for graph in graphs: # don't draw duplication nodes because of relations for model in graph['models']: for relation in model['relations']: if relation['target'] in nodes: relation['needs_node'] = False # render templates t = loader.get_template('django_extensions/graph_models/body.html') dot += '\n' + t.render(graph) for graph in graphs: t = loader.get_template('django_extensions/graph_models/rel.html') dot += '\n' + t.render(graph) t = loader.get_template('django_extensions/graph_models/tail.html') c = Context({}) dot += '\n' + t.render(c) return dot
def send_email_alerts(self, user, template): #does not change the database, only sends the email #todo: move this to template user.add_missing_askbot_subscriptions() #todo: q_list is a dictionary, not a list q_list = self.get_updated_questions_for_user(user) if len(q_list.keys()) == 0: return num_q = 0 for question, meta_data in q_list.items(): if meta_data['skip']: del q_list[question] else: num_q += 1 if num_q > 0: threads = Thread.objects.filter(id__in=[qq.thread_id for qq in q_list.keys()]) tag_summary = Thread.objects.get_tag_summary_from_threads(threads) question_count = len(q_list.keys()) if tag_summary: subject_line = ungettext( '%(question_count)d update about %(topics)s', '%(question_count)d updates about %(topics)s', question_count ) % { 'question_count': question_count, 'topics': tag_summary } else: subject_line = ungettext( '%(question_count)d update', '%(question_count)d updates', question_count ) % { 'question_count': question_count, } items_added = 0 items_unreported = 0 questions_data = list() for q, meta_data in q_list.items(): act_list = [] if meta_data['skip']: continue if items_added >= askbot_settings.MAX_ALERTS_PER_EMAIL: items_unreported = num_q - items_added #may be inaccurate actually, but it's ok break else: items_added += 1 if meta_data['new_q']: act_list.append(_('new question')) format_action_count('%(num)d rev', meta_data['q_rev'], act_list) format_action_count('%(num)d ans', meta_data['new_ans'], act_list) format_action_count('%(num)d ans rev', meta_data['ans_rev'], act_list) questions_data.append({ 'url': site_url(q.get_absolute_url()), 'info': ', '.join(act_list), 'title': q.thread.title }) activate_language(user.get_primary_language()) text = template.render({ 'recipient_user': user, 'questions': questions_data, 'name': user.username, 'admin_email': askbot_settings.ADMIN_EMAIL, 'site_name': askbot_settings.APP_SHORT_NAME, 'is_multilingual': getattr(django_settings, 'ASKBOT_MULTILINGUAL', False) }) if DEBUG_THIS_COMMAND == True: recipient_email = askbot_settings.ADMIN_EMAIL else: recipient_email = user.email mail.send_mail( subject_line = subject_line, body_text = text, recipient_list = [recipient_email] )
def generate_dot(app_labels, **kwargs): disable_fields = kwargs.get('disable_fields', False) include_models = parse_file_or_list(kwargs.get('include_models', "")) all_applications = kwargs.get('all_applications', False) use_subgraph = kwargs.get('group_models', False) verbose_names = kwargs.get('verbose_names', False) inheritance = kwargs.get('inheritance', False) language = kwargs.get('language', None) if language is not None: activate_language(language) exclude_columns = parse_file_or_list(kwargs.get('exclude_columns', "")) exclude_models = parse_file_or_list(kwargs.get('exclude_models', "")) def skip_field(field): if exclude_columns: if verbose_names and field.verbose_name: if field.verbose_name in exclude_columns: return True if field.name in exclude_columns: return True return False t = loader.get_template('django_extensions/graph_models/head.html') c = Context({}) dot = t.render(c) apps = [] if all_applications: apps = models.get_apps() for app_label in app_labels: app = models.get_app(app_label) if not app in apps: apps.append(app) graphs = [] for app in apps: graph = Context({ 'name': '"%s"' % app.__name__, 'app_name': "%s" % '.'.join(app.__name__.split('.')[:-1]), 'cluster_app_name': "cluster_%s" % app.__name__.replace(".", "_"), 'disable_fields': disable_fields, 'use_subgraph': use_subgraph, 'models': [] }) appmodels = get_models(app) abstract_models = [] for appmodel in appmodels: abstract_models = abstract_models + [ abstract_model for abstract_model in appmodel.__bases__ if hasattr( abstract_model, '_meta') and abstract_model._meta.abstract ] abstract_models = list(set(abstract_models)) # remove duplicates appmodels = abstract_models + appmodels for appmodel in appmodels: appmodel_abstracts = [ abstract_model.__name__ for abstract_model in appmodel.__bases__ if hasattr(abstract_model, '_meta') and abstract_model._meta.abstract ] # collect all attribs of abstract superclasses def getBasesAbstractFields(c): _abstract_fields = [] for e in c.__bases__: if hasattr(e, '_meta') and e._meta.abstract: _abstract_fields.extend(e._meta.fields) _abstract_fields.extend(getBasesAbstractFields(e)) return _abstract_fields abstract_fields = getBasesAbstractFields(appmodel) model = { 'app_name': appmodel.__module__.replace(".", "_"), 'name': appmodel.__name__, 'abstracts': appmodel_abstracts, 'fields': [], 'relations': [] } # consider given model name ? def consider(model_name): if exclude_models and model_name in exclude_models: return False return not include_models or model_name in include_models if not consider(appmodel._meta.object_name): continue if verbose_names and appmodel._meta.verbose_name: model['label'] = appmodel._meta.verbose_name else: model['label'] = model['name'] # model attributes def add_attributes(field): if verbose_names and field.verbose_name: label = field.verbose_name else: label = field.name t = type(field).__name__ if isinstance(field, (OneToOneField, ForeignKey)): t += " ({0})".format(field.rel.field_name) # TODO: ManyToManyField, GenericRelation model['fields'].append({ 'name': field.name, 'label': label, 'type': t, 'blank': field.blank, 'abstract': field in abstract_fields, }) # Find all the real attributes. Relations are depicted as graph edges instead of attributes attributes = [ field for field in appmodel._meta.local_fields if not isinstance(field, RelatedField) ] # find primary key and print it first, ignoring implicit id if other pk exists pk = appmodel._meta.pk if not appmodel._meta.abstract and pk in attributes: add_attributes(pk) for field in attributes: if skip_field(field): continue if not field.primary_key: add_attributes(field) # FIXME: actually many_to_many fields aren't saved in this model's db table, so why should we add an attribute-line for them in the resulting graph? #if appmodel._meta.many_to_many: # for field in appmodel._meta.many_to_many: # if skip_field(field): # continue # add_attributes(field) # relations def add_relation(field, extras=""): if verbose_names and field.verbose_name: label = field.verbose_name else: label = field.name # show related field name if hasattr(field, 'related_query_name'): label += ' (%s)' % field.related_query_name() _rel = { 'target_app': field.rel.to.__module__.replace('.', '_'), 'target': field.rel.to.__name__, 'type': type(field).__name__, 'name': field.name, 'label': label, 'arrows': extras, 'needs_node': True } if _rel not in model['relations'] and consider(_rel['target']): model['relations'].append(_rel) for field in appmodel._meta.local_fields: if field.attname.endswith( '_ptr_id' ): # excluding field redundant with inheritance relation continue if field in abstract_fields: # excluding fields inherited from abstract classes. they too show as local_fields continue if skip_field(field): continue if isinstance(field, OneToOneField): add_relation(field, '[arrowhead=none, arrowtail=none]') elif isinstance(field, ForeignKey): add_relation(field, '[arrowhead=none, arrowtail=dot]') for field in appmodel._meta.local_many_to_many: if skip_field(field): continue if isinstance(field, ManyToManyField): if (getattr(field, 'creates_table', False) or # django 1.1. (hasattr(field.rel.through, '_meta') and field.rel.through._meta.auto_created)): # django 1.2 add_relation( field, '[arrowhead=dot arrowtail=dot, dir=both]') elif isinstance(field, GenericRelation): add_relation( field, mark_safe( '[style="dotted", arrowhead=normal, arrowtail=normal, dir=both]' )) if inheritance: # add inheritance arrows for parent in appmodel.__bases__: if hasattr(parent, "_meta"): # parent is a model l = "multi-table" if parent._meta.abstract: l = "abstract" if appmodel._meta.proxy: l = "proxy" l += r"\ninheritance" _rel = { 'target_app': parent.__module__.replace(".", "_"), 'target': parent.__name__, 'type': "inheritance", 'name': "inheritance", 'label': l, 'arrows': '[arrowhead=empty, arrowtail=none]', 'needs_node': True } # TODO: seems as if abstract models aren't part of models.getModels, which is why they are printed by this without any attributes. if _rel not in model['relations'] and consider( _rel['target']): model['relations'].append(_rel) graph['models'].append(model) graphs.append(graph) nodes = [] for graph in graphs: nodes.extend([e['name'] for e in graph['models']]) for graph in graphs: # don't draw duplication nodes because of relations for model in graph['models']: for relation in model['relations']: if relation['target'] in nodes: relation['needs_node'] = False # render templates t = loader.get_template('django_extensions/graph_models/body.html') dot += '\n' + t.render(graph) for graph in graphs: t = loader.get_template('django_extensions/graph_models/rel.html') dot += '\n' + t.render(graph) t = loader.get_template('django_extensions/graph_models/tail.html') c = Context({}) dot += '\n' + t.render(c) return dot
def generate_dot(app_labels, **kwargs): cli_options = kwargs.get('cli_options', None) disable_fields = kwargs.get('disable_fields', False) include_models = parse_file_or_list(kwargs.get('include_models', "")) all_applications = kwargs.get('all_applications', False) use_subgraph = kwargs.get('group_models', False) verbose_names = kwargs.get('verbose_names', False) inheritance = kwargs.get('inheritance', True) relations_as_fields = kwargs.get("relations_as_fields", True) sort_fields = kwargs.get("sort_fields", True) language = kwargs.get('language', None) if language is not None: activate_language(language) exclude_columns = parse_file_or_list(kwargs.get('exclude_columns', "")) exclude_models = parse_file_or_list(kwargs.get('exclude_models', "")) def skip_field(field): if exclude_columns: if verbose_names and field.verbose_name: if field.verbose_name in exclude_columns: return True if field.name in exclude_columns: return True return False apps = [] if all_applications: apps = models.get_apps() for app_label in app_labels: app = models.get_app(app_label) if not app in apps: apps.append(app) graphs = [] for app in apps: graph = Context({ 'name': '"%s"' % app.__name__, 'app_name': "%s" % '.'.join(app.__name__.split('.')[:-1]), 'cluster_app_name': "cluster_%s" % app.__name__.replace(".", "_"), 'models': [] }) appmodels = get_models(app) abstract_models = [] for appmodel in appmodels: abstract_models = abstract_models + [ abstract_model for abstract_model in appmodel.__bases__ if hasattr( abstract_model, '_meta') and abstract_model._meta.abstract ] abstract_models = list(set(abstract_models)) # remove duplicates appmodels = abstract_models + appmodels for appmodel in appmodels: appmodel_abstracts = [ abstract_model.__name__ for abstract_model in appmodel.__bases__ if hasattr(abstract_model, '_meta') and abstract_model._meta.abstract ] # collect all attribs of abstract superclasses def getBasesAbstractFields(c): _abstract_fields = [] for e in c.__bases__: if hasattr(e, '_meta') and e._meta.abstract: _abstract_fields.extend(e._meta.fields) _abstract_fields.extend(getBasesAbstractFields(e)) return _abstract_fields abstract_fields = getBasesAbstractFields(appmodel) model = { 'app_name': appmodel.__module__.replace(".", "_"), 'name': appmodel.__name__, 'abstracts': appmodel_abstracts, 'fields': [], 'relations': [] } # consider given model name ? def consider(model_name): if exclude_models and model_name in exclude_models: return False return not include_models or model_name in include_models if not consider(appmodel._meta.object_name): continue if verbose_names and appmodel._meta.verbose_name: model['label'] = appmodel._meta.verbose_name.decode("utf8") else: model['label'] = model['name'] # model attributes def add_attributes(field): if verbose_names and field.verbose_name: label = field.verbose_name.decode("utf8") if label.islower(): label = label.capitalize() else: label = field.name t = type(field).__name__ if isinstance(field, (OneToOneField, ForeignKey)): t += " ({0})".format(field.rel.field_name) # TODO: ManyToManyField, GenericRelation model['fields'].append({ 'name': field.name, 'label': label, 'type': t, 'blank': field.blank, 'abstract': field in abstract_fields, 'relation': isinstance(field, RelatedField), 'primary_key': field.primary_key, }) attributes = [field for field in appmodel._meta.local_fields] if not relations_as_fields: # Find all the 'real' attributes. Relations are depicted as graph edges instead of attributes attributes = [ field for field in attributes if not isinstance(field, RelatedField) ] # find primary key and print it first, ignoring implicit id if other pk exists pk = appmodel._meta.pk if pk and not appmodel._meta.abstract and pk in attributes: add_attributes(pk) for field in attributes: if skip_field(field): continue if pk and field == pk: continue add_attributes(field) if sort_fields: model['fields'] = sorted(model['fields'], key=lambda field: (not field['primary_key'], not field[ 'relation'], field['label'])) # FIXME: actually many_to_many fields aren't saved in this model's db table, so why should we add an attribute-line for them in the resulting graph? #if appmodel._meta.many_to_many: # for field in appmodel._meta.many_to_many: # if skip_field(field): # continue # add_attributes(field) # relations def add_relation(field, extras=""): if verbose_names and field.verbose_name: label = field.verbose_name.decode("utf8") if label.islower(): label = label.capitalize() else: label = field.name # show related field name if hasattr(field, 'related_query_name'): related_query_name = field.related_query_name() if verbose_names and related_query_name.islower(): related_query_name = related_query_name.replace( '_', ' ').capitalize() label += ' (%s)' % related_query_name # handle self-relationships if field.rel.to == 'self': target_model = field.model else: target_model = field.rel.to _rel = { 'target_app': target_model.__module__.replace('.', '_'), 'target': target_model.__name__, 'type': type(field).__name__, 'name': field.name, 'label': label, 'arrows': extras, 'needs_node': True } if _rel not in model['relations'] and consider(_rel['target']): model['relations'].append(_rel) for field in appmodel._meta.local_fields: if field.attname.endswith( '_ptr_id' ): # excluding field redundant with inheritance relation continue if field in abstract_fields: # excluding fields inherited from abstract classes. they too show as local_fields continue if skip_field(field): continue if isinstance(field, OneToOneField): add_relation(field, '[arrowhead=none, arrowtail=none, dir=both]') elif isinstance(field, ForeignKey): add_relation(field, '[arrowhead=none, arrowtail=dot, dir=both]') for field in appmodel._meta.local_many_to_many: if skip_field(field): continue if isinstance(field, ManyToManyField): if (getattr(field, 'creates_table', False) or # django 1.1. (hasattr(field.rel.through, '_meta') and field.rel.through._meta.auto_created)): # django 1.2 add_relation( field, '[arrowhead=dot arrowtail=dot, dir=both]') elif isinstance(field, GenericRelation): add_relation( field, mark_safe( '[style="dotted", arrowhead=normal, arrowtail=normal, dir=both]' )) if inheritance: # add inheritance arrows for parent in appmodel.__bases__: if hasattr(parent, "_meta"): # parent is a model l = "multi-table" if parent._meta.abstract: l = "abstract" if appmodel._meta.proxy: l = "proxy" l += r"\ninheritance" _rel = { 'target_app': parent.__module__.replace(".", "_"), 'target': parent.__name__, 'type': "inheritance", 'name': "inheritance", 'label': l, 'arrows': '[arrowhead=empty, arrowtail=none, dir=both]', 'needs_node': True, } # TODO: seems as if abstract models aren't part of models.getModels, which is why they are printed by this without any attributes. if _rel not in model['relations'] and consider( _rel['target']): model['relations'].append(_rel) graph['models'].append(model) if graph['models']: graphs.append(graph) nodes = [] for graph in graphs: nodes.extend([e['name'] for e in graph['models']]) for graph in graphs: for model in graph['models']: for relation in model['relations']: if relation['target'] in nodes: relation['needs_node'] = False now = datetime.datetime.now() t = loader.get_template('django_extensions/graph_models/digraph.dot') if not isinstance(t, Template): raise Exception("Default Django template loader isn't used. " "This can lead to the incorrect template rendering. " "Please, check the settings.") c = Context({ 'created_at': now.strftime("%Y-%m-%d %H:%M"), 'cli_options': cli_options, 'disable_fields': disable_fields, 'use_subgraph': use_subgraph, 'graphs': graphs, }) dot = t.render(c) return dot
def setUpClass(cls): management.call_command('flush', verbosity=0, interactive=False) activate_language(settings.LANGUAGE_CODE) management.call_command('askbot_add_test_content', verbosity=0, interactive=False)