import (outdated) daily reporting script version

This commit is contained in:
Thomas Renger 2023-12-28 22:27:47 +01:00
parent 6b83d69d87
commit 84de914c46
10 changed files with 264 additions and 481 deletions

View File

@ -1,170 +1,167 @@
BarbaraHoisl:
links:
- [0, barbara's blog, 'http://www.barbarahoisl.com/', 'http://www.barbarahoisl.com/feed/']
mail: barbara@barbarahoisl.com
name: Barbara Hoisl
start: 2012/10/08
ChemieEmma:
links:
- [dent, dent in the world (Englisch), 'http://dentintheworld.com/', 'http://dentintheworld.com/feed/atom/']
- [alpaka, the naked alpaca (Englisch), 'http://thenakedalpaca.com/', 'http://thenakedalpaca.com/feed/atom/']
mail: missp@dentintheworld.com
name: Paula Schramm
start: 2012/09/24
DVDtoday: DVDtoday:
links: links:
- [0, JKdigital, 'http://jkdigital.de/', 'http://jkdigital.de/feed/'] - [0, JKdigital, 'http://jkdigital.de/', 'http://jkdigital.de/feed/']
mail: jk@jkplus.de mail: jk@jkplus.de
name: "J\xFCrgen Kaiser" name: "J\xFCrgen Kaiser"
start: 2012/09/24 twitter: false
Der_Ideealist:
links:
- [0, Der Ideealist, 'http://der-ideealist.de/', 'http://der-ideealist.de/feed/']
mail: ideealist@steinhobelgruen.de
name: Jens Heim
EquilibriumBlog:
links:
- [0, Equilibrium, 'http://www.equilibriumblog.de', 'http://www.equilibriumblog.de/wordpress/feed/atom/']
name: Stefan Rybkowski
FlorianSchweer:
links:
- [0, blorts - wir bloggen sport!, 'http://www.blorts.de/', 'http://www.blorts.de/feed.xml']
mail: florian.schweer@blorts.de
name: Florian Schweer
twitter: false
Gedankenzirkus:
links:
- [0, Gedankenzirkus, 'http://www.gedankenzirkus.de/', 'http://www.gedankenzirkus.de/wordpress/feed/']
name: Oliver Koch
HeimBau:
links:
- [0, Teeren und Federn | HEIM Tiefbau Blog, 'http://blog.heim-tuttlingen.de/',
'http://blog.heim-tuttlingen.de/feed/']
mail: info@heim-tuttlingen.de
name: Jens Heim
HubertMayer: HubertMayer:
links: links:
- [0, Hubert Mayer, 'http://hubert-mayer.de/', 'http://hubert-mayer.de/feed/'] - [0, Hubert Mayer, 'http://hubert-mayer.de/', 'http://hubert-mayer.de/feed/']
- [testet, Hubert Testet, 'http://hubert-testet.de/', 'http://hubert-testet.de/feed/'] - [321blog, 321 Blog!, 'http://www.321blog.de/', 'http://www.321blog.de/author/dermayer/feed/']
mail: mayerwerbung@gmx.de mail: mayerwerbung@gmx.de
name: Hubert Mayer name: Hubert Mayer
start: 2012/09/24 SMCST:
TabTwo:
links: links:
- [0, Nerd Residenz, 'http://www.nerd-residenz.de/blog/', 'http://www.nerd-residenz.de/blog/index.atom'] - [0, Social Media Club Stuttgart, 'http://www.smcst.de/', 'http://www.smcst.de/feed/']
mail: rmayer@nerd-residenz.de name: Markus Besch
name: Ralph Mayer SocialMediaInst:
start: 2012/09/24
affiliteur:
links: links:
- [0, Affiliate auf Partytour, 'http://www.affiliteur.com/', 'http://www.affiliteur.com/feed/atom'] - [0, SocialMedia Institute, 'http://www.socialmedia-institute.com/', 'http://www.socialmedia-institute.com/feed/']
mail: info@affiliteur.com name: Markus Besch
name: Sascha Schilling _teecee:
start: 2012/09/24
cmsfunk:
links: links:
- [0, Stattmarketing, 'http://stattmarketing.wordpress.com/', 'http://stattmarketing.wordpress.com/feed/'] - [0, Thomas Christinck, 'http://christinck.de/', 'http://christinck.de/feed/']
mail: christoph.funk28@gmail.com mail: thomas@christinck.de
name: Christoph Funk name: Thomas Christinck
start: 2012/09/24
dentaku: dentaku:
links: links:
- [0, Dentaku, 'http://dentaku.wazong.de/', 'http://dentaku.wazong.de/category/blog/feed'] - [1, Dentaku Blog, 'http://dentaku.wazong.de/', 'http://dentaku.wazong.de/feed']
mail: dentaku@wazong.de mail: dentaku@wazong.de
name: Thomas Renger name: Thomas Renger
start: 2012/09/24 hensch:
dirkhaun:
links: links:
- [0, Dirks Hirnableiter, 'http://hirnableiter.tinycities.de/', 'http://hirnableiter.tinycities.de/feeds/hirnableiter.rss'] - [0, "Blog von Henning Sch\xFCrig", 'http://www.henningschuerig.de/blog/', 'http://www.henningschuerig.de/blog/feed/']
- [1, The Mobile Presenter (Englisch), 'http://www.themobilepresenter.com/', 'http://www.themobilepresenter.com/feeds/themobilepresenter.rss'] mail: info@henningschuerig.de
mail: dirk@haun-online.de name: "Henning Sch\xFCrig"
name: Dirk Haun
start: 2012/09/24
erikschimmel:
links:
- [0, Erik Schimmel, 'http://erikschimmel.de/', 'http://erikschimmel.de/feed/']
mail: mail@erikschimmel.de
name: Erik Schimmel
start: 2012/10/01
gordongeisler:
links:
- [0, (blog folgt), 'http://staging.wazong.de/', 'http://staging.wazong.de/feed/']
mail: gordon.geisler@freiarbeiter.com
name: Gordon Geisler
start: 2012/12/31
hirnrinde: hirnrinde:
links: links:
- [0, Hirnrinde, 'http://www.hirnrinde.de/', 'http://www.hirnrinde.de/hirnrinde.php'] - [0, Hirnrinde, 'http://www.hirnrinde.de/', 'http://www.hirnrinde.de/hirnrinde.php']
mail: stefan.evertz@gmail.com mail: stefan.evertz@gmail.com
name: Stefan Evertz name: Stefan Evertz
start: 2012/09/24 hubert_testet:
hoomygumb:
links: links:
- [0, it's a hoomygumb, 'http://hoomygumb.com/', 'http://hoomygumb.com/feed/'] - [testet, Hubert Testet, 'http://hubert-testet.de/', 'http://hubert-testet.de/feed/']
mail: hoomygumb@gmail.com mail: mayerwerbung@gmx.de
name: Jay F. Kay name: Hubert Mayer
start: 2012/09/24
idrottning:
links:
- [0, (blog folgt), 'http://staging.wazong.de/', 'http://staging.wazong.de/feed/']
mail: v.frankenberg@gmx.de
name: Viola Frankenberg
start: 2012/12/31
jantheofel: jantheofel:
links: links:
- [0, "Jans K\xFCchenleben", 'http://www.theofel.de/plog/', 'http://www.theofel.de/plog/index.xml'] - [0, "Jans K\xFCchenleben", 'http://www.theofel.de/plog/', 'http://www.theofel.de/plog/index.xml']
- [1, Jans Technik-Blog, 'http://www.theofel.de/weblog/', 'http://www.theofel.de/weblog/index.xml'] - [1, Jans Technik-Blog, 'http://www.theofel.de/weblog/', 'http://www.theofel.de/weblog/index.xml']
- [2, Schokolade geht immer, 'http://www.schokolade-geht-immer.de/', 'http://www.schokolade-geht-immer.de/feed/atom/']
- [3, Contao-Anleitungen.de, 'http://www.contao-anleitungen.de/', 'http://www.contao-anleitungen.de/blog.xml']
- [4, Brettspiel-Blog, 'http://www.brettspiel-blog.de/', 'http://www.brettspiel-blog.de/atom.xml']
mail: jan@theofel.de mail: jan@theofel.de
name: Jan Theofel name: Jan Theofel
start: 2012/09/24 kLAWtext:
lakritzplanet:
links: links:
- [0, Lakritzplanet, 'http://www.lakritzplanet.de/', 'http://www.lakritzplanet.de/feed/'] - [0, kLAWtext, 'http://klawtext.blogspot.de/', 'http://klawtext.blogspot.com/feeds/posts/default']
mail: mail@lakritzplanet.de name: Sebastian Dosch
name: Christian Kaufmann ma_y:
start: 2012/09/24
momstagebuch:
links: links:
- [0, Mom's Tagebuch, 'http://momstagebuch.blogspot.de', 'http://momstagebuch.blogspot.com/feeds/posts/default'] - [0, ma.y2, 'http://may2.wordpress.com/', 'http://may2.wordpress.com/feed/']
mail: hahn-elke@gmx.de mail: info@frauschuetze.de
name: Elke Hahn name: "Frau Sch\xFCtze"
start: 2012/10/08 mahrko:
musevg:
links: links:
- [0, Abenteuer im Musenland, 'http://www.outsourcer.de/', 'http://www.outsourcer.de/feed/'] - [0, blog.mahrko.de, 'http://blog.mahrko.de/', 'http://blog.mahrko.de/feed/']
- [b2s, Brain 2 Shirt, 'http://www.2shirt.org', 'http://www.2shirt.org/feed/atom/'] name: Marco Bereth
- [allesso, Alles so, 'http://www.alles.so/', 'http://www.alles.so/feed/'] micialmedia:
mail: iron@muse.vg
name: Michael Schommer
start: 2012/09/24
pNachhaltig:
links: links:
- [0, praktisch Nachhaltig, 'http://praktisch-nachhaltig.de/news-und-presse/praktisch-nachhaltig-blog', - [0, Micial Media, 'http://micialmedia.de/', 'http://micialmedia.de/feed/']
'http://staging.wazong.de/feed/'] mail: info@michael-roth.de
mail: info@madiko.com name: Michael M. Roth
name: "Franziska K\xF6ppe" miradlo:
start: 2012/12/31
poster4nature:
links: links:
- [0, poster4nature, 'http://www.poster4nature.com/category/blog/', 'http://www.poster4nature.com/category/blog/feed/'] - [0, miradlo bloggt, 'http://www.miradlo.net/bloggt/', 'http://www.miradlo.net/bloggt/feeds/atom.xml']
mail: partner@poster4nature.com - [1, uteles Blog, 'http://www.utele.eu/blog/', 'http://www.utele.eu/blog/feed']
name: Alexander Beck mail: miradlo@steinhobelgruen.de
start: 2012/09/24 name: Ute Hauth
reichepoet: nezzform:
links: links:
- [0, Der Reiche Poet, 'http://reichepoet.blogspot.de/', 'http://reichepoet.blogspot.com/feeds/posts/default'] - [0, blog.nezzform, 'http://nezzform.blogspot.de/', 'http://nezzform.blogspot.com/feeds/posts/default']
mail: ute.muendlein@10-o-clock.de - [1, Mama im Job, 'http://mamaimjob.blogspot.de/', 'http://mamaimjob.blogspot.com/feeds/posts/default']
name: "Ute M\xFCndlein" mail: jastel@gmx.de
start: 2012/09/24 name: Jana Akyildiz
oliverg:
links:
- [0, OGOK oliver gassner online-kommunikation, 'http://www.ogok.de/', 'http://www.ogok.de/feeds/posts/default']
- [321blog, 321 Blog!, 'http://www.321blog.de/', 'http://www.321blog.de/author/oliverg/feed/']
mail: oliver@steinhobelgruen.de
name: Oliver Gassner
publizist:
links:
- [0, Publizist - Eigensinn verpflichtet!, 'http://publizist.wordpress.com/', 'http://publizist.wordpress.com/feed/']
name: Immo Sennewald
quilthexle:
links:
- [0, Quilthexle, 'http://www.quilthexle.blogspot.de/', 'http://quilthexle.blogspot.com/feeds/posts/default']
mail: quilthexle@steinhobelgruen.de
name: Frauke Schramm
ralphjschiel:
links:
- [0, das naturblau-blog, 'http://blog.naturblau.de/', 'http://blog.naturblau.de/feed/']
mail: null
name: Ralph J. Schiel
twitter: false twitter: false
roadkill: roadkill:
links: links:
- [0, Hinten beim Bier, 'http://www.hintenbeimbier.de/', 'http://www.hintenbeimbier.de/feed/'] - [0, Hinten beim Bier, 'http://www.hintenbeimbier.de/', 'http://www.hintenbeimbier.de/feed/']
mail: st.sommer@gmail.com mail: st.sommer@gmail.com
name: Stefan Sommer name: Stefan Sommer
start: 2012/09/24
schiri: schiri:
links: links:
- [0, Patrick Schneider, 'http://www.patrickschneider.net', 'http://www.patrickschneider.net/feed/'] - [0, Patrick Schneider, 'http://www.patrickschneider.net', 'http://www.patrickschneider.net/feed/']
mail: info@patrickschneider.net mail: info@patrickschneider.net
name: Patrick Schneider name: Patrick Schneider
start: 2012/09/24 spaetzle_tweet:
spacedani:
links: links:
- [0, Danigee, 'http://www.danigee.de/', 'http://www.danigee.de/feed/'] - [0, "Sp\xE4tzle mit So\xDF", 'http://spaetzlemitsoss.de/', 'http://spaetzlemitsoss.de/feed']
mail: spacedani@gmail.com mail: info@spaetzlemitsoss.de
name: Danijela Grgic name: Christian Mehler
start: 2012/10/01 startupstgt:
sympatexter:
links: links:
- [0, Sympatexter, 'http://www.sympatexter.de/', 'http://www.sympatexter.de/feed'] - [0, Startup Stuttgart, 'http://startup-stuttgart.de/', 'http://startup-stuttgart.de/feed/']
mail: boehm.judith@gmail.com mail: burn@startup-stuttgart.de
name: "Judith B\xF6hm" name: Team Startup Stuttgart
start: 2012/09/24 tilohensel:
werkstatt:
links: links:
- [0, Wissenswerkstatt, 'http://www.wissenswerkstatt.net/', 'http://www.wissenswerkstatt.net/feed/'] - [0, Tilo Hensel Blog, 'http://www.tilo-hensel.de/', 'http://www.tilo-hensel.de/feed']
mail: marc.scheloske@gmail.com mail: tilohensel@steinhobelgruen.de
name: Marc Scheloske name: Tilo Hensel
start: 2012/09/24 travellerblog:
wunschgeburt:
links: links:
- [0, Wunschgeburt, 'http://www.wunschgeburt.de/weblog/', 'http://www.wunschgeburt.de/feed/'] - [0, Travellerblog, 'http://travellerblog.eu/', 'http://travellerblog.eu/feed/']
mail: frau.kienberger@web.de mail: mayerwerbung@gmx.de
name: Mika Kienberger name: Hubert Mayer
start: 2012/10/08 uliuli:
links:
- [0, dia-blog, 'http://www.dia-blog.de/', 'http://www.dia-blog.de/feed/']
- [1, Nichtsblog, 'http://www.nichtsblog.de/', 'http://www.nichtsblog.de/feed/atom/']
- [2, 'Wer ist dir lieber?', 'http://www.wer-ist-dir-lieber.de/', 'http://www.wer-ist-dir-lieber.de/feed/']
mail: uliuli@steinhobelgruen.de
name: Ulrich Eder

58
daily-update.py Executable file
View File

@ -0,0 +1,58 @@
#!/usr/bin/python
# This Python file uses the following encoding: utf-8
import render
import os
import sys
import xmlrpclib
import subprocess
import datetime
import yaml
import settings
config=settings.load_settings()
dry_run = False
send_mail = True
quick_view = False
args = sys.argv[1:]
if len(args)>0:
if args[0] == '-q':
dry_run = True
quick_view = True
send_mail = False
if args[0] == '-n':
dry_run = True
send_mail = False
START = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) - datetime.timedelta(days=1)
date = START.strftime("%Y-%m-%d")
email = render.render_template('templates/email.txt', date, start=START, mail=config['mail'])
if len(email)==0:
print("No posts.")
exit(0)
if not dry_run:
text = render.render_template('templates/week.tmpl', date, start=START)
lines = text.split("\n")
title = lines[0]
body = "\n".join(lines[1:])
page = dict(title = title, description = body)
x = xmlrpclib.ServerProxy(config['xmlrpc_endpoint'])
x.metaWeblog.newPost(config['blog_id'], config['username'], config['password'], page, True)
if quick_view:
print(render.render_template('templates/quick_view.tmpl',date,start=START))
if dry_run and not quick_view:
print email
if send_mail:
p = subprocess.Popen(['/usr/sbin/sendmail', '-oi', '-t'],
stdin=subprocess.PIPE)
p.communicate(email)

28
ledger
View File

@ -1,28 +0,0 @@
2012-10-01 Week 0
User:musevg $-5
Pool:Owed:musevg
2012-10-01 Week 0
User:poster4nature $-5
Pool:Owed:poster4nature
2012-10-08 Week 1, Blog 0
User:hirnrinde $-5
Pool:Owed:hirnrinde
2012-10-08 Week 1, Blog 0
User:jantheofel $-5
Pool:Owed:jantheofel
2012-10-08 Week 1, Blog 0
User:poster4nature $-5
Pool:Owed:poster4nature
2012-10-08 Week 1, Blog 0
User:werkstatt $-5
Pool:Owed:werkstatt
2012-10-15 Week 2, Blog b2s
User:musevg $-5
Pool:Owed:musevg
2012-10-15 Schulden bezahlt
Pool:Owed:poster4nature $-10
Pool:Paid

123
render.py
View File

@ -13,134 +13,23 @@ from mako.template import Template
config=settings.load_settings() config=settings.load_settings()
START = datetime.datetime.strptime(config['start_date'],"%Y/%m/%d")
HERE = os.path.dirname(__file__) HERE = os.path.dirname(__file__)
def get_balance(acct): def render_template(path, date, **kwargs):
p = subprocess.Popen(['ledger', '-f', os.path.join(HERE,'ledger'),
'-n', 'balance', acct],
stdout=subprocess.PIPE)
(out, _) = p.communicate()
try:
return int(out.split()[0][1:])
except:
return 0
def get_debts():
p = subprocess.Popen(['ledger', '-f', os.path.join(HERE, 'ledger'),
'-n', 'balance', 'Pool:Owed:'],
stdout=subprocess.PIPE)
(out, _) = p.communicate()
debts = []
for line in out.split("\n"):
if not line: continue
(val, acct) = line.split()
user = acct[len("Pool:Owed:"):]
val = int(val[len("$"):])
debts.append((user, val))
return debts
def to_week_num(date):
return (parse(date, default=START) - START).days / 7
def parse_skip(rec):
spec = rec.get('skip', [])
out = []
for s in spec:
if isinstance(s, list):
out.append(map(to_week_num, s))
else:
out.append(to_week_num(s))
return out
def should_skip(skips, week):
for e in skips:
if e == week:
return True
if isinstance(e, list) and e[0] <= week and e[1] > week:
return True
return False
def render_template(path, week=None, **kwargs):
with open('out/report.yml') as r: with open('out/report.yml') as r:
report = yaml.safe_load(r) report = yaml.safe_load(r)
with open('bloggers.yml') as f: with open('bloggers.yml') as f:
users = yaml.safe_load(f) users = yaml.safe_load(f)
if week:
week = parse(week, default=START)
else:
week = START
week = (week - START).days / 7 posts = report.setdefault(date, [])
week_start = START + (week * datetime.timedelta(7))
week_end = START + ((week + 1) * datetime.timedelta(7))
skip = [] if len(date)>0 and len(posts)==0:
skipped_users = [] return ""
userlist = []
punted = []
class User(object):
pass
for (un, rec) in users.items():
u = User()
u.username = un
u.name = rec['name']
u.mail = rec['mail']
u.links = rec['links']
u.twitter = rec.get('twitter')
u.start_de = datetime.datetime.strptime(rec['start'],"%Y/%m/%d").strftime("%d.%m.%Y")
u.start = rec['start']
u.end = rec.get('end')
u.stop = rec.get('stop')
u.skip = parse_skip(rec)
u.posts = report.get(un, {})
u.goodblogs = []
u.lameblogs = []
userlist.append(u)
# create a subset of punted users
if u.end:
u.end_de = datetime.datetime.strptime(rec.get('end'),"%Y/%m/%d").strftime("%d.%m.%Y")
punted.append(u)
def user_key(u):
return (u.start, u.username)
userlist.sort(key=user_key)
punted.sort(key=user_key)
for u in userlist:
user_start = parse(u.start, default=START)
if u.stop:
continue
if u.end and parse(u.end, default=START) <= week_start:
continue
if should_skip(u.skip, week):
skipped_users.append(u)
continue
elif user_start > week_start:
skip.append(u)
continue
for blog in u.links:
b=blog[0]
weeks=u.posts[b]
if len(weeks) <= week or not weeks[week]:
u.lameblogs.append(b)
else:
u.goodblogs.append(b)
debts = get_debts()
return Template(filename=path, output_encoding='utf-8').render( return Template(filename=path, output_encoding='utf-8').render(
week=week, week_start=week_start,week_end=week_end, users=users, posts=posts, date=date,
skip=skip, skipped_users=skipped_users, userlist=userlist, **kwargs)
pool=(get_balance('Pool')-get_balance('Event')), paid=get_balance('Pool:Paid'),
event=get_balance('Pool:Event'),
debts=debts, punted=punted, **kwargs)
if __name__ == '__main__': if __name__ == '__main__':
if len(sys.argv) < 2: if len(sys.argv) < 2:

View File

@ -3,6 +3,7 @@ import yaml
import feedparser import feedparser
import datetime import datetime
import sys import sys
import re
import os import os
from dateutil.parser import parse from dateutil.parser import parse
import dateutil.tz as tz import dateutil.tz as tz
@ -21,13 +22,14 @@ try:
except IOError: except IOError:
log = {} log = {}
START = datetime.datetime.strptime(config['start_date'],'%Y/%m/%d') START = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) - datetime.timedelta(days=7)
def parse_published(pub): def parse_published(pub):
try: try:
return parse(pub).astimezone(tz.tzlocal()).replace(tzinfo=None) return parse(pub).astimezone(tz.tzlocal()).replace(tzinfo=None)
except: except:
return parse(pub).replace(tzinfo=None) return parse(pub).replace(tzinfo=None)
def get_date(post): def get_date(post):
for k in ('published', 'created', 'updated'): for k in ('published', 'created', 'updated'):
if k in post: if k in post:
@ -36,10 +38,34 @@ def get_date(post):
def get_link(post): def get_link(post):
return post.link return post.link
def parse_feeds(weeks, uri): def remove_html_tags(txt):
feed = feedparser.parse(uri) p = re.compile(r'<[^<]*?/?>')
return p.sub('', txt)
print >>sys.stderr, "Parsing: %s" % uri def remove_extra_spaces(txt):
p = re.compile(r'\s+')
return p.sub(' ', txt)
def create_extract(txt):
stxt = remove_extra_spaces(remove_html_tags(txt))
if len(stxt) < 250:
return stxt
if stxt.rfind('. ',200,250)>0:
return stxt[:stxt.rfind('. ',200,250)+1]+" [...]"
if stxt.rfind('! ',200,250)>0:
return stxt[:stxt.rfind('! ',200,250)+1]+" [...]"
if stxt.rfind('? ',200,250)>0:
return stxt[:stxt.rfind('? ',200,250)+1]+" [...]"
if stxt.rfind(', ',200,250)>0:
return stxt[:stxt.rfind(', ',200,250)+1]+" [...]"
if stxt.rfind(' ',200,250)>0:
return stxt[:stxt.rfind(' ',200,250)]+" [...]"
return stxt[:250]+"[...]"
def parse_feeds(weeks, username, blog):
uri = blog[3]
# print >>sys.stderr, "Parsing ", uri
feed = feedparser.parse(uri)
if not feed.entries: if not feed.entries:
print >>sys.stderr, "WARN: no entries for ", uri print >>sys.stderr, "WARN: no entries for ", uri
@ -48,34 +74,31 @@ def parse_feeds(weeks, uri):
if date < START: if date < START:
continue continue
wn = (date - START).days / 7
key = date.strftime("%Y-%m-%d")
while len(weeks) <= wn: weeks.setdefault(key, [])
weeks.append([])
if post.has_key('title'): if post.has_key('title'):
post = dict(date=date, post = dict(date=date,
title=post.title, title=post.title,
url=get_link(post)) url=get_link(post),
username=username,
blogname=blog[0],
description=create_extract(post.description))
if not post.has_key('title'): if not post.has_key('title'):
post = dict(date=date, post = dict(date=date,
title="", title="",
url=get_link(post)) url=get_link(post),
if post['url'] not in [p['url'] for p in weeks[wn]]: username=username,
weeks[wn].append(post) blogname=blog[0],
description=create_extract(post.description))
if post['url'] not in [p['url'] for p in weeks[key]]:
weeks[key].append(post)
if len(sys.argv) > 1: for (username, u) in users.items():
for username in sys.argv[1:]: for l in u['links']:
blogs = log.setdefault(username, {}) parse_feeds(log, username, l)
for l in users[username]['links']:
weeks = blogs.setdefault(l[0], [])
parse_feeds(weeks, l[3])
else:
for (username, u) in users.items():
blogs = log.setdefault(username, {})
for l in u['links']:
weeks = blogs.setdefault(l[0], [])
parse_feeds(weeks, l[3])
with open('out/report.yml', 'w') as f: with open('out/report.yml', 'w') as f:
yaml.safe_dump(log, f) yaml.safe_dump(log, f)

View File

@ -6,7 +6,6 @@ def load_settings():
configfile.read('settings.cfg') configfile.read('settings.cfg')
config=dict() config=dict()
config['mail']=configfile.get("general","mail") config['mail']=configfile.get("general","mail")
config['start_date']=configfile.get("general","start_date")
config['username']=configfile.get("blogsettings","username") config['username']=configfile.get("blogsettings","username")
config['password']=configfile.get("blogsettings","password") config['password']=configfile.get("blogsettings","password")

View File

@ -1,56 +1,9 @@
## -*- coding: utf-8 -*- ## -*- coding: utf-8 -*-
From: ${mail} From: ${mail}
Content-Type: text/plain; charset=utf-8 Content-Type: text/plain; charset=utf-8
Subject: IRON BLOGGER results for the week beginning ${week_start.strftime("%F")} Subject: Blogging BW on ${start.strftime("%F")}
To: ${mail} To: ${mail}
SLACKERS: % for p in sorted(posts, key=lambda p:p['date']):
<% lame=0 %> - ${p['title'] or "[ohne Titel]"} -- ${p['url']}
% for u in sorted(userlist, key=lambda u:u.name[u.name.rfind(' '):].lower()):
% for b in u.lameblogs:
<% lame+=1 %> - ${u.name} in ${b}
% endfor
% endfor
% if punt:
PUNTED for balance ≥$30: ${", ".join(sorted(punt))}
% endif
People who posted:
% for u in sorted(userlist, key=lambda u:u.name[u.name.rfind(' '):].lower()):
% for b in u.goodblogs:
${u.name} in ${b} (${u.username}):
% for p in u.posts[b][week]:
- ${p['url']}
% endfor
% endfor
% endfor
% if skip:
People who have not yet started:
% for u in sorted(skip, key=lambda u:u.username):
${u.username}
% endfor
% endif
% if skipped_users:
People who are currently skipped:
% for u in sorted(skipped_users, key=lambda u:u.username):
${u.username}
% endfor
% endif
Beer pool:
This Week: € ${5 * lame}
Total: € ${pool}
Paid: € ${paid}
Events: € ${event}
Individual debts:
% for (u, v) in sorted(debts, key=lambda p:p[1], reverse=True):
${u"%20s %d \u20AC" % (u, v)}
% endfor
PREVIOUSLY PUNTED (pay € 30 balance to return):
% for (u) in sorted(punted, key=lambda p:p.username):
${"%20s (%s)" % (u.username, u.end)}
% endfor % endfor

View File

@ -1,39 +1,30 @@
<table id='participants'nowrap> <table id='participants' nowrap>
<tr> <tr>
<th>Name</th>
<th>Twitter</th>
<th>Blog</th> <th>Blog</th>
<th>Start</th> <th>Autor</th>
<th>nicht gewertet</th> <th>Twitter</th>
</tr> </tr>
% for u in sorted(userlist, key=lambda u:u.name[u.name.rfind(' '):].lower()): <%
blogs=[]
for username in users:
u=users[username]
for l in u['links']:
if u.get('twitter') != False:
blogs.append([l[2], l[1], u['name'], username])
else:
blogs.append([l[2], l[1], u['name']])
%>
% for b in sorted(blogs, key=lambda b:b[1].lower()):
<tr> <tr>
<td align="left" valign="top">${u.name}</td>
<td align="left" valign="top"> <td align="left" valign="top">
% if u.twitter != False: <a href="${b[0]}">${b[1]}</a>
@<a href="http://twitter.com/${u.username}">${u.username}</a> </td>
<td align="left" valign="top">${b[2]}</td>
<td align="left" valign="top">
% if len(b)==4:
@<a href="http://twitter.com/${b[3]}">${b[3]}</a>
% endif % endif
</td> </td>
<td align="left" valign="top">
% if u.links:
% for a in u.links:
<a href="${a[2]}">${a[1]}</a>
% endfor
% else:
fehlt noch
% endif
</td>
<td align="left" valign="top"> ${u.start_de} </td>
<td align="left" valign="top">
% if u.end:
Ausgeschieden<br>
% endif
% if u.skip:
${u.skip}
% endif
</td>
</tr> </tr>
% endfor % endfor
</table> </table>

View File

@ -1,117 +1,18 @@
Zusammenfassung der Woche ab ${week_start.strftime("%d.%m.%Y")} Blogging BW am ${start.strftime("%d.%m.%Y")}
<h3>Die Flei&szlig;igen:</h3>
<dl>
% for u in sorted(userlist, key=lambda u:u.name[u.name.rfind(' '):].lower()):
% for g in u.goodblogs:
% for b in u.links:
% if b[0] == g:
<dt><span class="user"><strong>${u.name} </strong> \
% if u.twitter != False:
(@<a href="http://twitter.com/${u.username}">${u.username}</a>) \
% endif
% if len(u.links) != 1:
in <a href="${b[2]}">${b[1]}</a> \
% endif
:</span></dt>
<dd>
<ul>
% for p in u.posts[g][week]:
<li><a href="${p['url']}">${p['title'] or "[ohne Titel]"}</a></li>
% endfor
</ul>
</dd>
% endif
% endfor
% endfor
% endfor
</dl>
<h3>Die Faulen:</h3> <% lame=0 %>
<ul> <ul>
% for u in sorted(userlist, key=lambda u:u.name[u.name.rfind(' '):].lower()): % for p in sorted(posts, key=lambda p:p['date']):
% for g in u.lameblogs: <%
% for b in u.links: u=users[p['username']]
% if b[0] == g: for l in u['links']:
<li class="user"><strong>${u.name} </strong> <% lame+=1 %> \ if l[0] == p['blogname']:
% if u.twitter != False: b = l
(@<a href="http://twitter.com/${u.username}">${u.username}</a>) \ %>
% endif <li>${p['date'].strftime("%H:%M")}: <span class="user"><strong><a href="${p['url']}">${p['title'] or "[ohne Titel]"}</a></strong></span><br/>
% if len(u.links) != 1: ${u['name']} \
in <a href="${b[2]}">${b[1]}</a> \ % if u.get('twitter') != False:
% endif (@<a href="http://twitter.com/${p['username']}">${p['username']}</a>) \
% endif
in <a href="${b[2]}">${b[1]}</a>:<blockquote>${p['description']}</blockquote>
</li> </li>
% endif
% endfor
% endfor
% endfor % endfor
</ul> </ul>
% if punt:
<h3>Ausgeschieden wegen zu hoher Schulden:</h3>
<ul>
% for u in sorted(punt):
<li class="user">${u}</li>
% endfor
</ul>
% endif
% if skip:
<h3>Noch nicht dabei:</h3>
<ul>
% for u in sorted(skip, key=lambda u:u.name[u.name.rfind(' '):].lower()):
<li class="user"><strong>${u.name} </strong> \
% if u.twitter != False:
(@<a href="http://twitter.com/${u.username}">${u.username}</a>) \
% endif
</li>
% endfor
</ul>
% endif
% if skipped_users:
<h3>Gerade im Urlaub:</h3>
<ul>
% for u in sorted(skipped_users, key=lambda u:u.name[u.name.rfind(' '):].lower()):
<li class="user"><strong>${u.name} </strong> \
% if u.twitter != False:
(@<a href="http://twitter.com/${u.username}">${u.username}</a>) \
% endif
</li>
% endfor
</ul>
% endif
<h3>Kasse:</h3>
<table style="border-left-style:none; border-right-style:none;">
<tr> <td> diese Woche: </td> <td> ${5 * lame}&nbsp;&euro; </td> </tr>
<tr> <td> insgesamt: </td> <td> ${pool}&nbsp;&euro;</td> </tr>
<tr> <td> beglichen: </td> <td> ${paid}&nbsp;&euro;</td> </tr>
<tr> <td> verfeiert: </td> <td> ${event}&nbsp;&euro;</td> </tr>
</table>
<h3>Schulden:</h3>
<% i = 0 %>
<table class="debts" style="border-left-style:none; border-right-style:none;">
% for (u, v) in sorted(debts, key=lambda p:p[1], reverse=True):
% if i % 3 == 0:
<tr>\
% endif
<% i += 1 %>\
<td class="user">${u}</td> <td class="money">${v}&nbsp;&euro;</td>\
% if i % 3 == 0:
</tr>
%endif
% endfor
% if i % 3 != 0:
</tr>
%endif
</table>
% if punted:
<h3>Zuvor ausgeschieden (m&uuml;ssen 30&nbsp;&euro; f&uuml;r den Wiedereinstieg bezahlen):</h3>
<ul>
% for (u) in sorted(punted, key=lambda p:p.name[p.name.rfind(' '):].lower()):
<li>${u.name} (seit ${u.end_de})</li>
% endfor
</ul>
% endif

View File

@ -12,7 +12,7 @@ config=settings.load_settings()
x = xmlrpclib.ServerProxy(config['xmlrpc_endpoint']) x = xmlrpclib.ServerProxy(config['xmlrpc_endpoint'])
page = x.wp.getPage(config['blog_id'], config['participants_page_id'], config['username'], config['password']) page = x.wp.getPage(config['blog_id'], config['participants_page_id'], config['username'], config['password'])
text = render.render_template('templates/users.tmpl') text = render.render_template('templates/users.tmpl', '')
page['description'] = text page['description'] = text
x.wp.editPage(config['blog_id'], config['participants_page_id'], config['username'], config['password'],page,True) x.wp.editPage(config['blog_id'], config['participants_page_id'], config['username'], config['password'],page,True)