Results 1 to 5 of 5

Thread: Скрипт для скачивания подкастов Python + Google Reader

  1. #1

    Post Скрипт для скачивания подкастов Python + Google Reader

    Когда количество прослушиваемых подкастов перевалило за 3 стало достаточно сложно следить за ними всеми. Пользоваться агрегаторами монстрами типа iTunes нет желания, да и проблемы с ними тоже возникают: то в забуду тыкнуть кнопочку обновить/скачать, то времени не хватает дождаться скачивания. В общем проблема автоматической доставки подкаст-контента поближе ко мне видна на лицо. Решение проблемы принялся искать кардинально, но удобное. В итоге на был найден питоновский скрипт для автоматического скачивания подкастов из ленты Google Reader. Дело осталось за малым: запустить всё это на роутере.

    Список подкастерских лент храним Google Reader. Ленты помечены своим тегом, и аккуратно лежат в своей папке. В качестве основы скрипта взята библиотеку pyrfeed, в которой реализован полезный класс GoogleReader.

    1. Сначала ставим Python (на время написания статьи текущая версия в репозитории 2.5):
    Code:
    ipkg install python
    ipkg install py25-elementtree
    ipkg install py25-cheetah
    ipkg install py25-cherrypy
    2. Распаковываем pyrfeed-0.5.1.rar в /opt/lib/python2.5

    3. Содержимое PodcastDownloadTool.rar распаковываем в любое удобное вам место, например /opt/urs/bin/

    4. Настраиваем скрипт PodcastDownloadTool.py под себя:
    • downloadDir – каталог, куда будут скачиваться подкасты
    • logFile – название лог файла
    • tag – имя тега/папки в Google Reader, в которой будут просматриваться ленты
    • login и password – логин и пароль в Google Reader


    5. Проверяем работоспособность:
    Code:
    python /opt/usr/bin/PodcastDownloadTool.py
    В ответ мы должны получить как минимум "Login OK", если есть непрочитанные ленты подкастов, то начнётся их скачивание.

    6. Осталось заставить выполнять роутер запускать скрипт раз в час/день кому как удобно. Создаем в /opt/etc/cron.hourly (или /opt/etc/cron.daily) скрипт (например PodcastDownloadTool.sh) следующего содержания:
    Code:
    #!/bin/sh
    python /opt/usr/bin/PodcastDownloadTool.py >> /opt/var/log/PodcastDownloadTool.log 2>&1
    На этом собственно всё, осталось указать на маленькие недостатки:
    • Не поддерживается докачка. В случае сбоя RSS-запись не будет помечена как прочитанная. При следующем запуске скрипта файл будет выкачан заново.
    • Отсюда следующий момент – при следующем запуске скрипта, ошибочные записи (например, в записи нет ссылки на файл для скачивания) будут повторно обрабатываться. Можно бы их метить специальным тегом и пропускать в дальнейшем. Но меня устраивает последующий ручной просмотр ленты на предмет не прочитанных записей.
    • Хранение конфигурации – логин и пароль в открытом виде. Логин еще не так страшно, а вот пароль (если у кого-то паранойя, то можно ради этого завести пустого пользователя в GoogleReader)


    Мануал написан на основе статьи из блога Yustos.

  2. #2
    Здорово. Я как раз думал о том как организовать автоматическую загрузку программы телепередач. Спасибо за наводку.

  3. #3

    Unhappy Proxymin (на питоне) и fast mutexes :(

    Пробовал поднять proxymin на WL500gPV2 (на x86 работает на ура), но получил следующее:

    Code:
     --> -->
     
     
    DBInvalidArgError	Python 2.4.5: /opt/bin/python2.4
    Tue Jan 6 00:59:27 2009
    
    A problem occurred in a Python script. Here is the sequence of function calls leading up to the error, in the order they occurred.
     /opt/share/www/ctrl/proxymin.py
       91 # call appropriate page
       92 if(action == ACTION_SHOW_MAIN):
       93     gui_main.print_main_page(category, letter, group)
       94 elif(action == ACTION_DISPLAY_HELP):
       95     gui_help.print_help_page()
    gui_main = <module 'gui_main' from '/opt/share/www/ctrl/gui_main.py'>, gui_main.print_main_page = <function print_main_page>, category = 'groups', letter = None, group = None
     /opt/share/www/ctrl/gui_main.py in print_main_page(category='groups', letter=None, group=None)
       30     """display administration main page"""    
       31     gui_misc.print_html_head()       
       32     print_title_bar()
       33     print '<br><br>'
       34     print_tabs(category)
    global print_title_bar = <function print_title_bar>
     /opt/share/www/ctrl/gui_main.py in print_title_bar()
       51 def print_title_bar():
       52     # count all user/host/group objects
       53     iterator = objectiterator.ObjectIterator(CATEGORY_HOSTS)
       54     number_of_hosts = iterator.get_object_count()
       55     iterator.set_category(CATEGORY_USERS)
    iterator undefined, global objectiterator = <module 'objectiterator' from '/opt/share/www/ctrl/objectiterator.py'>, objectiterator.ObjectIterator = <class objectiterator.ObjectIterator>, global CATEGORY_HOSTS = 'hosts'
     /opt/share/www/ctrl/objectiterator.py in __init__(self=<objectiterator.ObjectIterator instance>, category='hosts')
       25     """uniform interface to access different object types - simplifies GUI programming"""
       26     def __init__(self, category):
       27         self.dba = dbaccess.DBAccess()
       28         self.set_category(category)
       29 
    self = <objectiterator.ObjectIterator instance>, self.dba undefined, global dbaccess = <module 'dbaccess' from '/opt/share/www/ctrl/dbaccess.py'>, dbaccess.DBAccess = <class dbaccess.DBAccess>
     /opt/share/www/ctrl/dbaccess.py in __init__(self=<dbaccess.DBAccess instance>)
       39     """persistence framework"""
       40     def __init__(self):
       41         self.users = shelve.open(userdb)
       42         self.hosts = shelve.open(hostdb)
       43         self.groups = shelve.open(groupdb)
    self = <dbaccess.DBAccess instance>, self.users undefined, global shelve = <module 'shelve' from '/opt/lib/python2.4/shelve.pyc'>, shelve.open = <function open>, global userdb = 'db//users'
     /opt/lib/python2.4/shelve.py in open(filename='db//users', flag='c', protocol=None, writeback=False, binary=None)
      230 
      231     See the module's __doc__ string for an overview of the interface.
      232     """
      233 
      234     return DbfilenameShelf(filename, flag, protocol, writeback, binary)
    global DbfilenameShelf = <class shelve.DbfilenameShelf>, filename = 'db//users', flag = 'c', protocol = None, writeback = False, binary = None
     /opt/lib/python2.4/shelve.py in __init__(self=<DbfilenameShelf instance>, filename='db//users', flag='c', protocol=None, writeback=False, binary=None)
      213     def __init__(self, filename, flag='c', protocol=None, writeback=False, binary=None):
      214         import anydbm
      215         Shelf.__init__(self, anydbm.open(filename, flag), protocol, writeback, binary)
      216 
      217 
    global Shelf = <class shelve.Shelf>, Shelf.__init__ = <unbound method Shelf.__init__>, self = <DbfilenameShelf instance>, anydbm = <module 'anydbm' from '/opt/lib/python2.4/anydbm.pyc'>, anydbm.open = <function open>, filename = 'db//users', flag = 'c', protocol = None, writeback = False, binary = None
     /opt/lib/python2.4/anydbm.py in open(file='db//users', flag='c', mode=438)
       79         # db type cannot be determined
       80         raise error, "db type could not be determined"
       81     else:
       82         mod = __import__(result)
       83     return mod.open(file, flag, mode)
    mod = <module 'dbhash' from '/opt/lib/python2.4/dbhash.pyc'>, mod.open = <function open>, file = 'db//users', flag = 'c', mode = 438
     /opt/lib/python2.4/dbhash.py in open(file='db//users', flag='c', mode=438)
       12 
       13 error = bsddb.error                     # Exported for anydbm
       14 
       15 def open(file, flag = 'r', mode=0666):
       16     return bsddb.hashopen(file, flag, mode)
    global bsddb = <module 'bsddb' from '/opt/lib/python2.4/bsddb/__init__.pyc'>, bsddb.hashopen = <function hashopen>, file = 'db//users', flag = 'c', mode = 438
     /opt/lib/python2.4/bsddb/__init__.py in hashopen(file='db//users', flag='c', mode=438, pgsize=None, ffactor=None, nelem=None, cachesize=None, lorder=None, hflags=0)
      289 
      290     flags = _checkflag(flag, file)
      291     e = _openDBEnv(cachesize)
      292     d = db.DB(e)
      293     d.set_flags(hflags)
    e undefined, global _openDBEnv = <function _openDBEnv>, cachesize = None
     /opt/lib/python2.4/bsddb/__init__.py in _openDBEnv(cachesize=None)
      345         else:
      346             raise error, "cachesize must be >= 20480"
      347     e.open('.', db.DB_PRIVATE | db.DB_CREATE | db.DB_THREAD | db.DB_INIT_LOCK | db.DB_INIT_MPOOL)
      348     return e
      349 
    e = <DBEnv object>, e.open = <built-in method open of DBEnv object>, global db = <module '_bsddb' from '/opt/lib/python2.4/lib-dynload/_bsddb.so'>, db.DB_PRIVATE = 1048576, db.DB_CREATE = 1, db.DB_THREAD = 64, db.DB_INIT_LOCK = 8192, db.DB_INIT_MPOOL = 32768
    
    DBInvalidArgError: (22, 'Invalid argument -- architecture lacks fast mutexes: applications cannot be threaded')
          args = (22, 'Invalid argument -- architecture lacks fast mutexes: applications cannot be threaded')
    Т.е. не поддерживаются какие то fast mutexes и поэтому proxymin не может открыть свою локальную базу данных.

    Кто-нибудь знает - лечится ли это как нибудь?

  4. #4
    Join Date
    Mar 2009
    Location
    Ukraine, Luts'k
    Posts
    11
    Автор, если не трудно, обновите ссылки для скачивания. Спасибо.

  5. #5

    Angry python HTTPServer Segmentation fault

    Всем привет.

    Роутер wl500g подключен непосредственно к провайдеру и имеет выделенный статический IP. thttpd сервер работает отлично как на LAN так и на WAN.

    Решил попробывать запустить на роутер простой HTTP сервер написанный на python. Вот его код:

    Code:
    from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler 
    
    import shutil
    try:
        from cStringIO import StringIO
    except ImportError:
        from StringIO import StringIO
    
    class MyHTTPRequestHandler(BaseHTTPRequestHandler):
    	def do_GET(self):
    
    		f = StringIO()
     		f.write('<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">')
     		f.write("<html>\n<title>Test Page</title>\n")
     		f.write("<body>\n<h2>Hi</h2>\n")
     		f.write("</body></html>\n")
    
     		length = f.tell()
     		self.send_response(200)
     		self.send_header("Content-type", "text/html")
     		self.send_header("Content-Length", str(length))
     		self.end_headers()
     		f.seek(0)
    
     		self.wfile.write(f.read(length))
    
    
    server_address = ('domain_name', 8666)
    server = HTTPServer(server_address, MyHTTPRequestHandler)
    
    while 1 == 1:
    	server.handle_request()
    iptables -I INPUT 7 -p tcp --dport 8666 -j ACCEPT
    прописано.

    Он запускается и работает отлично в LAN. Но стоит зайти на него с WAN, всё сразу падает с Segmentation fault:

    Code:
    [delirium@Delirium_Router disc0_1]$ python server.py 
    92.241.190.197 - - [18/Aug/2010 15:16:17] "GET / HTTP/1.1" 200 -
    92.241.190.197 - - [18/Aug/2010 15:16:20] "GET /favicon.ico HTTP/1.1" 200 -
    92.241.190.197 - - [18/Aug/2010 15:17:00] "GET / HTTP/1.1" 200 -
    92.241.190.197 - - [18/Aug/2010 15:17:03] "GET /favicon.ico HTTP/1.1" 200 -
    Segmentation fault
    (Первые два запроса из LAN, затем из WAN)

    Версия python:
    Python 2.5.5 (r255:77872, May 20 2010, 23:42:58)
    [GCC 4.1.1] on linux2

    Версия прошивки роутера: Olegs firmware 1.9.2.7-10

    С чем это может быть связано? Куда копать?

Similar Threads

  1. Replies: 559
    Last Post: 14-03-2012, 12:42

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •