Skip to content

Commit

Permalink
Merge commit '07735537f132976074a170d113154dfa055552ec' into drum-mas…
Browse files Browse the repository at this point in the history
…ter__tests_issue_28
  • Loading branch information
jnkwrych committed Nov 1, 2016
2 parents f71ecc6 + 0773553 commit c9aed96
Show file tree
Hide file tree
Showing 22 changed files with 133 additions and 94 deletions.
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/drum/links/static/* linguist-vendored=true
3 changes: 2 additions & 1 deletion AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@
* Vitaliy Kharin
* Alex Bendig
* Rafael Capdevielle
* Micah Yoder
* Micah Yoder
* Minwoo Park
18 changes: 12 additions & 6 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,12 @@ given title is broken up into keywords, and if those keywords already
exist as tags in the database, they're applied to the newly added link.

This means that for auto-tagging to work, the tags must already exist
in the database. You can either add them manually via the admin, or
if you have a large number of existing links, you can use the
``auto_tag`` management command Drum provides, which will analyse the
titles of all your existing links, and provide tags it extracts from
them. This makes use of the `topia.termextract`_ package which
you'll first need to install::
in the database. You can either add them manually via the admin (under
the "Keywords" section), or if you have a large number of existing
links, you can use the ``auto_tag`` management command Drum provides,
which will analyse the titles of all your existing links, and provide
tags it extracts from them. This makes use of the `topia.termextract`_
package which you'll first need to install::

python manage.py auto_tag --generate=100 --assign --remove

Expand All @@ -113,6 +113,12 @@ all tags in the database to all links in the database, as would occur
if they were newly created. The ``--remove`` option will cause all
existing tags to be removed.

You can also define your own tag extraction function, if splitting the
title on spaces doesn't suffice. To do so, define the setting
``AUTO_TAG_FUNCTION`` which should contain a string with the Python
dotted path to your custom tag function. The function will be given an
unsaved ``Link`` object, and should return a sequence of tags to add.


Contributing
============
Expand Down
2 changes: 1 addition & 1 deletion drum/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@

__version__ = "0.3.0"
__version__ = "0.4.0"
21 changes: 9 additions & 12 deletions drum/links/management/commands/auto_tag.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
from __future__ import unicode_literals

from optparse import make_option
from string import punctuation

from django.db import connection
from django.core.management.base import BaseCommand
from django.core.management.base import BaseCommand, CommandError
from mezzanine.generic.models import AssignedKeyword, Keyword
from mezzanine.utils.urls import slugify

Expand All @@ -13,15 +12,14 @@

class Command(BaseCommand):

option_list = BaseCommand.option_list + (
make_option("--generate", dest="generate", type=int),
make_option("--remove", dest="remove", action="store_true",
default=False),
make_option("--assign", dest="assign", action="store_true",
default=False),
)
def add_arguments(self, parser):
parser.add_argument("--generate", dest="generate", type=int)
parser.add_argument("--remove", dest="remove", action="store_true",
default=False)
parser.add_argument("--assign", dest="assign", action="store_true",
default=False)

def handle(self, *urls, **options):
def handle(self, **options):
cursor = connection.cursor()
if options["remove"]:
cursor.execute("DELETE FROM generic_assignedkeyword;")
Expand All @@ -40,8 +38,7 @@ def generate(self, size):
try:
from topia.termextract import extract
except ImportError:
print("topia.termextract library required")
return
raise CommandError("topia.termextract library required")

extractor = extract.TermExtractor()
extractor.filter = extract.permissiveFilter
Expand Down
30 changes: 15 additions & 15 deletions drum/links/management/commands/poll_rss.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from __future__ import unicode_literals
from __future__ import print_function, unicode_literals

from datetime import datetime
from optparse import make_option
from time import mktime

from django.contrib.auth.models import User
Expand All @@ -17,48 +16,49 @@

class Command(BaseCommand):

option_list = BaseCommand.option_list + (
make_option(
def add_arguments(self, parser):
parser.add_argument("urls", nargs="*")
parser.add_argument(
"--follow",
action="store_true",
dest="follow",
default=False,
help="Make a HTTP request for every link imported and follow "
"redirects, storing the final URL."
),
make_option(
)
parser.add_argument(
"--follow-old",
action="store_true",
dest="follow_old",
default=False,
help="Will go back and run --follow aginst previously added links"
),
)
)

def handle(self, *urls, **options):
def handle(self, **options):
if options["follow_old"]:
self.follow_old()
return
try:
user_id = User.objects.filter(is_superuser=1)[0].id
except IndexError:
return
for url in urls:
for url in options["urls"]:
for entry in parse(url).entries:
link = self.entry_to_link_dict(entry)
if options["follow"]:
try:
link["link"] = self.follow_redirects(link["link"])
except Exception as e:
print "%s - skipping %s" % (e, link["link"])
print("%s - skipping %s" % (e, link["link"]))
continue
link["user_id"] = user_id
try:
obj = Link.objects.get(link=link["link"])
except Link.DoesNotExist:
obj = Link.objects.create(**link)
obj.rating.add(Rating(value=1, user_id=user_id))
print "Added %s" % obj
obj.rating.add(Rating(value=1, user_id=user_id),
bulk=False)
print("Added %s" % obj)

def link_from_entry(self, entry):
"""
Expand Down Expand Up @@ -86,14 +86,14 @@ def entry_to_link_dict(self, entry):

def follow_redirects(self, link):
final = requests.get(link).url
print "followed %s to %s" % (link, final)
print("followed %s to %s" % (link, final))
return final

def follow_old(self):
for link in Link.objects.all():
try:
new_url = self.follow_redirects(link.link)
except Exception as e:
print "%s - skipping %s" % (e, link.link)
print("%s - skipping %s" % (e, link.link))
else:
Link.objects.filter(id=link.id).update(link=new_url)
15 changes: 7 additions & 8 deletions drum/links/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
from future import standard_library
from future.builtins import int

from re import sub, split
from time import time
from operator import ior
from functools import reduce
Expand All @@ -16,7 +15,7 @@
from django.core.urlresolvers import reverse
from django.db import models
from django.db.models import Q
from django.db.models.signals import post_save, post_delete
from django.db.models.signals import post_save, pre_delete
from django.dispatch import receiver
from django.utils.encoding import python_2_unicode_compatible

Expand All @@ -25,6 +24,7 @@
from mezzanine.core.request import current_request
from mezzanine.generic.models import Rating, Keyword, AssignedKeyword
from mezzanine.generic.fields import RatingField, CommentsField
from mezzanine.utils.importing import import_dotted_path
from mezzanine.utils.urls import slugify


Expand Down Expand Up @@ -54,15 +54,14 @@ def url(self):
def save(self, *args, **kwargs):
keywords = []
if not self.keywords_string and getattr(settings, "AUTO_TAG", False):
variations = lambda word: [word,
sub("^([^A-Za-z0-9])*|([^A-Za-z0-9]|s)*$", "", word),
sub("^([^A-Za-z0-9])*|([^A-Za-z0-9])*$", "", word)]
keywords = sum(map(variations, split("\s|/", self.title)), [])
func_name = getattr(settings, "AUTO_TAG_FUNCTION",
"drum.links.utils.auto_tag")
keywords = import_dotted_path(func_name)(self)
super(Link, self).save(*args, **kwargs)
if keywords:
lookup = reduce(ior, [Q(title__iexact=k) for k in keywords])
for keyword in Keyword.objects.filter(lookup):
self.keywords.add(AssignedKeyword(keyword=keyword))
self.keywords.add(AssignedKeyword(keyword=keyword), bulk=False)

@python_2_unicode_compatible
class Profile(models.Model):
Expand All @@ -77,7 +76,7 @@ def __str__(self):


@receiver(post_save, sender=Rating)
@receiver(post_delete, sender=Rating)
@receiver(pre_delete, sender=Rating)
def karma(sender, **kwargs):
"""
Each time a rating is saved, check its value and modify the
Expand Down
2 changes: 1 addition & 1 deletion drum/links/templates/accounts/account_profile.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{% extends "base.html" %}
{% load i18n future mezzanine_tags drum_tags %}
{% load i18n mezzanine_tags drum_tags %}

{% block meta_title %}{{ profile_user.username }}{% endblock %}
{% block title %}{{ profile_user|get_profile }}{% endblock %}
Expand Down
2 changes: 1 addition & 1 deletion drum/links/templates/accounts/includes/user_panel_nav.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{% load i18n future mezzanine_tags drum_tags %}
{% load i18n mezzanine_tags drum_tags %}

<ul class="nav pull-right"><li class="divider-vertical"></li></ul>

Expand Down
2 changes: 1 addition & 1 deletion drum/links/templates/admin/links/link/change_list.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
{% block extrahead %}
{{ block.super }}
<style>
.vTextField {width:300px !important; margin-top: 1px;}
.vTextField, .vURLField {width:auto !important; margin-top: 1px;}
.row1 td, .row2 td {max-width:310px; vertical-align: middle;}
.row1 a, .row2 a {display: block; margin-top: 10px;}
p.url * {display: none;}
Expand Down
2 changes: 1 addition & 1 deletion drum/links/templates/base.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<!doctype html>
<html lang="{{ LANGUAGE_CODE }}">
{% load mezzanine_tags i18n future staticfiles %}
{% load mezzanine_tags i18n staticfiles %}
<head>

<meta http-equiv="Content-type" content="text/html; charset=utf-8">
Expand Down
4 changes: 2 additions & 2 deletions drum/links/templates/generic/includes/comment.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{% load i18n mezzanine_tags comment_tags rating_tags drum_tags future %}
{% load i18n mezzanine_tags comment_tags rating_tags drum_tags %}

<ul class="unstyled comment-thread">
{% for comment in comments_for_thread %}
Expand All @@ -15,7 +15,7 @@
{% rating_for comment %}
<a href="{{ request.path }}#comment-{{ comment.id }}">link</a> |
<a href="#reply-{{ comment.id }}" class="reply no-pjax">reply</a>
<form class="reply-form" method="post" id="reply-{{ comment.id }}"
<form class="comment-reply-form" method="post" id="reply-{{ comment.id }}"
action="{{ comment_url }}#reply-{{ comment.id }}"
{% if replied_to != comment.id %}style="display:none;"{% endif %}>
{% if replied_to == comment.id %}
Expand Down
2 changes: 1 addition & 1 deletion drum/links/templates/generic/includes/rating.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{% load mezzanine_tags rating_tags i18n future %}
{% load mezzanine_tags rating_tags i18n %}

<div class="rating">

Expand Down
2 changes: 1 addition & 1 deletion drum/links/templates/generic/threadedcomment_list.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{% extends "base.html" %}

{% load mezzanine_tags rating_tags drum_tags future %}
{% load mezzanine_tags rating_tags drum_tags %}

{% block meta_title %}{{ title }}{% endblock %}
{% block title %}{{ title }}{% endblock %}
Expand Down
2 changes: 1 addition & 1 deletion drum/links/templates/includes/search_form.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{% load mezzanine_tags i18n future %}
{% load mezzanine_tags i18n %}
<form action="{% url "search" %}" class="navbar-search pull-right input-append">

<input class="search-query" placeholder="{% trans "Search" %}" type="text" name="q" value="{{ request.REQUEST.q }}">
Expand Down
2 changes: 1 addition & 1 deletion drum/links/templates/links/link_detail.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{% extends "base.html" %}

{% load mezzanine_tags rating_tags keyword_tags comment_tags drum_tags future %}
{% load mezzanine_tags rating_tags keyword_tags comment_tags drum_tags %}

{% block meta_description %}{% metablock %}{{ object.description }}{% endmetablock %}{% endblock %}
{% block meta_title %}{{ object.title }}{% endblock %}
Expand Down
2 changes: 1 addition & 1 deletion drum/links/templates/links/link_list.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{% extends "base.html" %}

{% load mezzanine_tags rating_tags keyword_tags drum_tags future %}
{% load mezzanine_tags rating_tags keyword_tags drum_tags %}

{% block meta_title %}{{ title|default:"Home" }}{% endblock %}
{% block title %}{{ title }}{% endblock %}
Expand Down
6 changes: 3 additions & 3 deletions drum/links/urls.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
from __future__ import unicode_literals

from django.conf.urls import patterns, url
from django.conf.urls import url
from django.contrib.auth.decorators import login_required

from drum.links.views import LinkList, LinkCreate, LinkDetail, CommentList, TagList


urlpatterns = patterns("",
urlpatterns = [
url("^$",
LinkList.as_view(),
name="home"),
Expand Down Expand Up @@ -37,4 +37,4 @@
url("^tags/(?P<tag>.*)/$",
LinkList.as_view(),
name="link_list_tag"),
)
]
16 changes: 14 additions & 2 deletions drum/links/utils.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from __future__ import division
from __future__ import unicode_literals
from __future__ import division, unicode_literals

from re import sub, split

from django.conf import settings
from django.utils.timezone import now
Expand Down Expand Up @@ -44,3 +45,14 @@ def order_by_score(queryset, score_fields, date_field, reverse=True):
score = score_fields_sum / pow(age, scale)
setattr(obj, "score", score)
return sorted(queryset, key=lambda obj: obj.score, reverse=reverse)


def auto_tag(link_obj):
"""
Split's the link object's title into words. Default function for the
``AUTO_TAG_FUNCTION`` setting.
"""
variations = lambda word: [word,
sub("^([^A-Za-z0-9])*|([^A-Za-z0-9]|s)*$", "", word),
sub("^([^A-Za-z0-9])*|([^A-Za-z0-9])*$", "", word)]
return sum(map(variations, split("\s|/", link_obj.title)), [])
Loading

0 comments on commit c9aed96

Please sign in to comment.