-
Notifications
You must be signed in to change notification settings - Fork 5
new upload #43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
new upload #43
Changes from all commits
6b17a3f
c1ff9ee
b969b37
ca1f80e
303df27
db702c6
23486ff
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,48 +17,96 @@ | |
| # Python imports | ||
| from __future__ import unicode_literals | ||
| import re | ||
|
|
||
| import six | ||
| # Django imports | ||
| #from django.contrib.sitemaps import ping_google | ||
| from django.utils.encoding import python_2_unicode_compatible | ||
|
|
||
| from django.core.urlresolvers import reverse | ||
| from django.db import models | ||
| from django.utils import timezone | ||
| from django.conf import settings | ||
|
|
||
|
|
||
| # 3d party imports | ||
| from model_utils import Choices | ||
| import markdown | ||
| import textile # to do: add oembed for textile markup | ||
| from pyembed.markdown import PyEmbedMarkdown | ||
| from pyembed.core import PyEmbed | ||
| from bs4 import BeautifulSoup | ||
|
|
||
| # App imports | ||
| from .managers import PostQuerySet, ChannelQuerySet, TagQuerySet | ||
| from .managers import PostQuerySet, ChannelQuerySet, TagQuerySet, MediaQuerySet | ||
|
|
||
| # URL_REGEX = r"""(?i)\b((?:https?:(?:/{1,3}|[a-z0-9%])|[a-z0-9.\-]+[.](?:com|net|org|edu|gov|mil|aero|asia|biz|cat|coop|info|int|jobs|mobi|museum|name|post|pro|tel|travel|xxx|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cs|cu|cv|cx|cy|cz|dd|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|Ja|sk|sl|sm|sn|so|sr|ss|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zw)/)(?:[^\s()<>{}\[\]]+|\([^\s()]*?\([^\s()]+\)[^\s()]*?\)|\([^\s]+?\))+(?:\([^\s()]*?\([^\s()]+\)[^\s()]*?\)|\([^\s]+?\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’])|(?:(?<!@)[a-z0-9]+(?:[.\-][a-z0-9]+)*[.](?:com|net|org|edu|gov|mil|aero|asia|biz|cat|coop|info|int|jobs|mobi|museum|name|post|pro|tel|travel|xxx|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cs|cu|cv|cx|cy|cz|dd|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|Ja|sk|sl|sm|sn|so|sr|ss|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zw)\b/?(?!@)))""" | ||
| URL_REGEX = r"""http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+""" | ||
|
|
||
| # def get_match_and_replace(text): | ||
|
|
||
| # # for each in re.findall(URL_REGEX, text): | ||
| # # text = text.replace(each, '<a href="%s">%s</a>' % (each,each), 1) | ||
| # # return text # text but with anchors inserted | ||
|
|
||
| oembed_regex = re.compile(r'^(?P<spacing>\s*)(?P<url>http://.+)', re.MULTILINE) | ||
|
|
||
| @python_2_unicode_compatible | ||
| class _Abstract(models.Model): #microblog compatible. | ||
| slug = models.SlugField(unique=True) | ||
| title = models.CharField(max_length=140, unique=True) | ||
| text = models.TextField(default='') | ||
| rendered_text = models.TextField(default='', blank=True) | ||
| TEXT_TYPE = Choices( | ||
| (0, 'SIMPLE', 'Simple',), | ||
| (1, 'MARKDOWN', 'Markdown',), | ||
| (2, 'TEXTILE', 'Textile'), | ||
| ) | ||
|
|
||
| def get_oembed_markup(self, matchobj): | ||
| gd = matchobj.groupdict('') | ||
| return '%(spacing)s<a href="%(url)s">%(url)s</a>' % gd | ||
| text_type = models.IntegerField(max_length=1, default=TEXT_TYPE.SIMPLE, choices=TEXT_TYPE) | ||
|
|
||
| def render(self): | ||
| #TODO: strip out dangerous HTML attributes, only allow basic formatting tags | ||
| self.rendered_text = oembed_regex.sub(self.get_oembed_markup, self.text) | ||
| def render(self, *args, **kwargs): | ||
|
|
||
| self.rendered_text = markdown.markdown(self.text) | ||
|
|
||
| if self.text_type == self.TEXT_TYPE.SIMPLE: | ||
| self.rendered_text = self.text | ||
|
|
||
| elif self.text_type == self.TEXT_TYPE.TEXTILE: | ||
| self.rendered_text = textile.textile(self.text) | ||
|
|
||
|
|
||
| soup = BeautifulSoup(self.rendered_text) | ||
|
|
||
| matching_text_nodes = soup.find_all(text = re.compile(URL_REGEX)) | ||
|
|
||
| pyembed = PyEmbed() | ||
|
|
||
|
|
||
| for matching_text_node in matching_text_nodes: | ||
|
|
||
| plain_text = six.text_type(matching_text_node) | ||
|
|
||
| for each in re.findall(URL_REGEX, plain_text): | ||
| plain_text = plain_text.replace(each, '<a href="%s">%s</a>' % (each,each), 1) | ||
|
|
||
| if matching_text_node.parent.text == each: # if url on one line, each == url == matching_text_node | ||
| try: | ||
| oembed = pyembed.embed(matching_text_node) | ||
| except: | ||
| matching_text_node.replace_with(plain_text) | ||
| else: | ||
| matching_text_node.replace_with(oembed) | ||
| else: | ||
| matching_text_node.replace_with(plain_text) | ||
|
|
||
| soup = BeautifulSoup(soup.encode(formatter=None)) | ||
|
|
||
| self.rendered_text = soup.encode(formatter=None).decode() | ||
|
|
||
| def save(self, *args, **kwargs): | ||
| if self.rendered_text == '': | ||
| self.render() | ||
|
|
||
| super(_Abstract, self).save(*args, **kwargs) | ||
| # try: | ||
| # ping_google() | ||
| # except Exception: | ||
| # # Bare 'except' because we could get a variety of HTTP-related exceptions. | ||
| # pass | ||
|
|
||
| def __str__(self): | ||
| return self.title | ||
|
|
@@ -134,3 +182,58 @@ def get_absolute_url(self): | |
|
|
||
| class Meta: | ||
| ordering = ['published'] | ||
|
|
||
| class MockYoutube(models.Model): | ||
| ysc = models.IntegerField(max_length=3) | ||
| yu = models.CharField(max_length=140, unique=True) | ||
| yc = models.CharField(max_length=140, unique=True) | ||
| yt = models.TextField(default='') | ||
| yh = models.CharField(max_length=140, unique=True) | ||
|
|
||
| yosc = models.IntegerField(max_length=3) | ||
| you = models.CharField(max_length=140, unique=True) | ||
| yoh = models.CharField(max_length=140, unique=True) | ||
| yot = models.TextField(default='') | ||
| yoj = models.TextField(default='') | ||
|
|
||
| class Media(_Abstract): | ||
|
|
||
| MEDIA_TYPES = Choices( | ||
| (0, 'NONE', 'none',), | ||
| (1, 'IMAGE', 'image',), | ||
| (2, 'VIDEO', 'video',), | ||
| ) | ||
|
|
||
| channel = models.ForeignKey(Channel) | ||
| objects = MediaQuerySet.as_manager() | ||
|
|
||
| upload_file = models.FileField(upload_to='uploads/%Y/%m/%d') | ||
|
|
||
| media_type = models.IntegerField(max_length=1, default=MEDIA_TYPES.NONE, choices=MEDIA_TYPES) | ||
|
|
||
| oembed_html = models.TextField(default='', blank=True) | ||
|
|
||
| media_height = models.SmallIntegerField(null=True) | ||
| media_width = models.SmallIntegerField(null=True) | ||
|
|
||
| thumbnail_height = models.SmallIntegerField(default=120) | ||
| thumbnail_width = models.SmallIntegerField(default=200) | ||
|
|
||
| @property | ||
| def file_url(self): | ||
| return self.upload_file.url | ||
|
|
||
| def render(self): | ||
|
|
||
| embed = '<a href="%s"> %s </a>' % (self.file_url, self.file_url) | ||
|
||
|
|
||
| if self.media_type == Media.MEDIA_TYPES.IMAGE: | ||
| embed = '<img src="%s" alt="%s" style="width:%d%%; height:%d%%;">' % (self.file_url, self.title, self.media_width, self.media_height) | ||
|
||
|
|
||
| elif self.media_type == Media.MEDIA_TYPES.VIDEO: | ||
| embed = '<video width="%d" height="%d" controls> <source src="%s" type="video/mp4"> Your browser does not support the video tag. </video>' % (self.media_width, self.media_height, self.file_url) | ||
|
|
||
| self.oembed_html = embed | ||
|
|
||
| def get_absolute_url(self): | ||
| return reverse('mesh_media_view', kwargs={'slug': self.slug,}) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1 @@ | ||
| {% extends "base.html" %} | ||
| {% extends "base.html" %} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| {% extends "django_mesh/base.html" %} | ||
|
|
||
| {% block content %} | ||
|
|
||
| <div class="media_list"> | ||
| {% if media_list %} | ||
|
|
||
| {% for media in media_list %} | ||
| <div> | ||
| <a href="{% url 'mesh_media_view' slug=media.slug %}">{{ media.title|safe }}</a> | ||
| <div class="container2"> | ||
|
|
||
| <p> <embed src="{{ media.file_url }}" autoplay="false" height="{{ media.thumbnail_height }}" width="{{ media.thumbnail_width }}"> | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the embed tag is non-standard and doesn't work in all browsers. Typically is placed inside an tag. Does work for non-videos? Was the intent to have the actual file in the index or just a thumbnail image? |
||
| </p> | ||
| </div></div> | ||
| {% endfor %} | ||
|
|
||
| {% else %} | ||
| There are no files to display. | ||
| {% endif %} | ||
| </div> | ||
|
|
||
| {% endblock content %} | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| {% extends "django_mesh/base.html" %} | ||
|
|
||
| {% block extra_head %} | ||
| <link rel="alternate" type="application/json" href="{% url 'mesh_oembed' slug=media.slug %}" title="{{ media.title }}"></link> | ||
| {% endblock %} | ||
|
|
||
| {% block content %} | ||
|
|
||
| <div class="media_list"> | ||
| {% if Media.MEDIA_TYPES.IMAGE %} | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Need to add "media.media_type == " |
||
|
|
||
| <a href="{{ media.file_url }}"> {{ media.oembed_html|safe }} </a> | ||
| {% else %} | ||
| {{ media.oembed_html | safe}} | ||
| {% endif %} | ||
|
|
||
| {% endblock content %} | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,7 +8,7 @@ | |
|
|
||
| <h2>{{ post.title }}</h2> | ||
|
|
||
| {{ post.rendered_text }} | ||
| {{ post.rendered_text|safe }} | ||
| </div> | ||
| </div> | ||
| </div> | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you take this out?