Check-in [7911337325]
Overview
| Comment: | more Python3 syntax fixes, introduce compat2and3 module |
|---|---|
| Downloads: | Tarball | ZIP archive | SQL archive |
| Timelines: | family | ancestors | descendants | both | py3 |
| Files: | files | file ages | folders |
| SHA1: |
7911337325807d54a047947842f1b57a |
| User & Date: | mario on 2014-04-08 21:50:21 |
| Other Links: | branch diff | manifest | tags |
Context
|
2014-04-08
| ||
| 21:53 | fix dict + dict back into list join check-in: d09e020ecf user: mario tags: py3 | |
| 21:50 | more Python3 syntax fixes, introduce compat2and3 module check-in: 7911337325 user: mario tags: py3 | |
| 21:16 | rename http to ahttp to avoid conflict with Python3 modules, change .iteritems and xrange, remove same remaining plain print statements check-in: d3b1418bc6 user: mario tags: py3 | |
Changes
Modified ahttp.py from [2dbe950381] to [11eca44aed].
1 2 3 4 5 6 | # # encoding: UTF-8 # api: streamtuner2 # type: functions # title: http download / methods # description: http utility | | < < < < < < < < < < < < < < < < < | < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | # # encoding: UTF-8 # api: streamtuner2 # type: functions # title: http download / methods # description: http utility # version: 1.4 # # Provides a http GET method with gtk.statusbar() callback. # And a function to add trailings slashes on http URLs. # # from compat2and3 import urllib2, urlencode, urlparse, cookielib, StringIO, xrange from gzip import GzipFile from config import conf, __print__, dbg #-- url download --------------------------------------------- |
| ︙ | ︙ |
Modified channels/_generic.py from [5d7f7dc2ae] to [a20153b668].
| ︙ | ︙ | |||
179 180 181 182 183 184 185 |
# switch stream category,
# load data,
# update treeview content
def load(self, category, force=False):
# get data from cache or download
| | | 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 |
# switch stream category,
# load data,
# update treeview content
def load(self, category, force=False):
# get data from cache or download
if (force or not category in self.streams):
new_streams = self.update_streams(category)
if new_streams:
# modify
[self.postprocess(row) for row in new_streams]
|
| ︙ | ︙ | |||
233 234 235 236 237 238 239 |
# finds differences in new/old streamlist, marks deleted with flag
def deleted_streams(self, new, old):
diff = []
new = [row.get("url","http://example.com/") for row in new]
for row in old:
| | | 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 |
# finds differences in new/old streamlist, marks deleted with flag
def deleted_streams(self, new, old):
diff = []
new = [row.get("url","http://example.com/") for row in new]
for row in old:
if (url in row and (row.get("url") not in new)):
row["deleted"] = 1
diff.append(row)
return diff
# prepare data for display
def prepare(self, streams):
|
| ︙ | ︙ |
Modified channels/links.py from [692f83efe7] to [e2e193464a].
| ︙ | ︙ | |||
54 55 56 57 58 59 60 |
bookmarks = parent.bookmarks
if not bookmarks.streams.get(self.module):
bookmarks.streams[self.module] = []
bookmarks.add_category(self.module)
# collect links from channel plugins
| | | | 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
bookmarks = parent.bookmarks
if not bookmarks.streams.get(self.module):
bookmarks.streams[self.module] = []
bookmarks.add_category(self.module)
# collect links from channel plugins
for name,channel in parent.channels.items():
try:
self.streams.append({
"favourite": 1,
"title": channel.title,
"homepage": channel.homepage,
})
except: pass
for title,homepage in self.default.items():
self.streams.append({
"title": title,
"homepage": homepage,
})
# add to bookmarks
bookmarks.streams[self.module] = self.streams
|
Modified channels/myoggradio.py from [37210dae1e] to [6c4dac0144].
| ︙ | ︙ | |||
22 23 24 25 26 27 28 | from channels import * from config import conf from action import action import re import json | | | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | from channels import * from config import conf from action import action import re import json from compat2and3 import StringIO import copy # open source radio sharing stie class myoggradio(ChannelPlugin): |
| ︙ | ︙ |
Modified channels/shoutcast.py from [0c3da6eedb] to [dd8d75b19e].
| ︙ | ︙ | |||
62 63 64 65 66 67 68 |
# sub-categories are queried per 'AJAX'
def update_categories(self):
html = http.get(self.base_url)
self.categories = []
__print__( dbg.DATA, html )
# <h2>Radio Genres</h2>
| | | | 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# sub-categories are queried per 'AJAX'
def update_categories(self):
html = http.get(self.base_url)
self.categories = []
__print__( dbg.DATA, html )
# <h2>Radio Genres</h2>
rx = re.compile(r'<li((?:\s+id="\d+"\s+class="files")?)><a href="\?action=sub&cat=([\w\s]+)#(\d+)">[\w\s]+</a>', re.S)
sub = []
for uu in rx.findall(html):
__print__( dbg.DATA, uu )
(main,name,id) = uu
name = urllib.unquote(name)
# main category
if main:
if sub:
self.categories.append(sub)
sub = []
|
| ︙ | ︙ |
Modified channels/timer.py from [c50adafaed] to [73a61c99cb].
| ︙ | ︙ | |||
16 17 18 19 20 21 22 23 24 25 26 27 28 29 | # # Programmed events are visible in "timer" under the "bookmarks" channel. Times # are stored in the description field, and can thus be edited. However, after editing # times manually, streamtuner2 must be restarted for the changes to take effect. # from channels import * import kronos from mygtk import mygtk from action import action import copy | > | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | # # Programmed events are visible in "timer" under the "bookmarks" channel. Times # are stored in the description field, and can thus be edited. However, after editing # times manually, streamtuner2 must be restarted for the changes to take effect. # from config import __print__, dbg from channels import * import kronos from mygtk import mygtk from action import action import copy |
| ︙ | ︙ | |||
72 73 74 75 76 77 78 |
"timer_cancel": lambda w,*a: self.parent.timer_dialog.hide() or 1,
})
# prepare spool
self.sched = kronos.ThreadedScheduler()
for row in self.streams:
try: self.queue(row)
| | | 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
"timer_cancel": lambda w,*a: self.parent.timer_dialog.hide() or 1,
})
# prepare spool
self.sched = kronos.ThreadedScheduler()
for row in self.streams:
try: self.queue(row)
except Exception as e: __print__(dbg.ERR, "queuing error", e)
self.sched.start()
# display GUI for setting timespec
def edit_timer(self, *w):
self.parent.timer_dialog.show()
self.parent.timer_value.set_text("Fri,Sat 20:00-21:00 play")
|
| ︙ | ︙ |
Added compat2and3.py version [022ad69c97].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
#
# encoding: UTF-8
# api: python
# type: functions
# title: Python2 and Python3 compatibility
# version: 0.1
#
# Renames some Python3 modules into their Py2 equivalent.
# Slim local alternative to `six` module.
#
import sys
# Python 2
if sys.version_info < (3,0):
# version tags
PY2 = 1
PY3 = 0
# basic functions
xrange = xrange
range = xrange
# urllib modules
import urllib
import urllib2
from urllib import urlencode
import urlparse
import cookielib
# filesys
from StringIO import StringIO
# Python 3
else:
# version tags
PY2 = 0
PY3 = 1
# basic functions
xrange = range
# urllib modules
import urllib.request as urllib
import urllib.request as urllib2
from urllib.parse import urlencode
import urllib.parse as urlparse
from http import cookiejar as cookielib
# filesys
from io import StringIO
|
Modified favicon.py from [997ecd51ce] to [983556d34c].
| ︙ | ︙ | |||
24 25 26 27 28 29 30 | always_google = 1 # use favicon service for speed only_google = 1 # if that fails, try our other/slower methods? delete_google_stub = 1 # don't keep placeholder images google_placeholder_filesizes = (726,896) import os, os.path | | | 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | always_google = 1 # use favicon service for speed only_google = 1 # if that fails, try our other/slower methods? delete_google_stub = 1 # don't keep placeholder images google_placeholder_filesizes = (726,896) import os, os.path from compat2and3 import xrange, urllib import re from config import conf try: from processing import Process as Thread except: from threading import Thread import ahttp |
| ︙ | ︙ |
Modified kronos.py from [6ae12b7565] to [24a87e43ef].
| ︙ | ︙ | |||
270 271 272 273 274 275 276 |
self.sched.queue[:] = []
def _run(self):
# Low-level run method to do the actual scheduling loop.
while self.running:
try:
self.sched.run()
| | | 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 |
self.sched.queue[:] = []
def _run(self):
# Low-level run method to do the actual scheduling loop.
while self.running:
try:
self.sched.run()
except Exception as x:
print >>sys.stderr, "ERROR DURING SCHEDULER EXECUTION",x
print >>sys.stderr, "".join(
traceback.format_exception(*sys.exc_info()))
print >>sys.stderr, "-" * 20
# queue is empty; sleep a short while before checking again
if self.running:
time.sleep(5)
|
| ︙ | ︙ | |||
294 295 296 297 298 299 300 |
self.args=args
self.kw=kw
def __call__(self, schedulerref):
"""Execute the task action in the scheduler's thread."""
try:
self.execute()
| | | 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 |
self.args=args
self.kw=kw
def __call__(self, schedulerref):
"""Execute the task action in the scheduler's thread."""
try:
self.execute()
except Exception as x:
self.handle_exception(x)
self.reschedule(schedulerref())
def reschedule(self, scheduler):
"""This method should be defined in one of the sub classes!"""
raise NotImplementedError("You're using the abstract base class 'Task',"
" use a concrete class instead")
|
| ︙ | ︙ | |||
462 463 464 465 466 467 468 |
self.reschedule(schedulerref())
def threadedcall(self):
# This method is run within its own thread, so we have to
# do the execute() call and exception handling here.
try:
self.execute()
| | | 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 |
self.reschedule(schedulerref())
def threadedcall(self):
# This method is run within its own thread, so we have to
# do the execute() call and exception handling here.
try:
self.execute()
except Exception as x:
self.handle_exception(x)
class ThreadedIntervalTask(ThreadedTaskMixin, IntervalTask):
"""Interval Task that executes in its own thread."""
pass
class ThreadedSingleTask(ThreadedTaskMixin, SingleTask):
|
| ︙ | ︙ | |||
529 530 531 532 533 534 535 |
def __call__(self, schedulerref):
"""Execute the task action in its own process."""
pid = os.fork()
if pid == 0:
# we are the child
try:
self.execute()
| | | 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 |
def __call__(self, schedulerref):
"""Execute the task action in its own process."""
pid = os.fork()
if pid == 0:
# we are the child
try:
self.execute()
except Exception as x:
self.handle_exception(x)
os._exit(0)
else:
# we are the parent
self.reschedule(schedulerref())
|
| ︙ | ︙ |
Modified pq.py from [774d8a07cf] to [9ad9a3d426].
| ︙ | ︙ | |||
15 16 17 18 19 20 21 |
try:
from pyquery import PyQuery as pq
# pq.each_pq = lambda self,func: self.each( lambda i,html: func( pq(html, parser="html") ) )
| | | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
try:
from pyquery import PyQuery as pq
# pq.each_pq = lambda self,func: self.each( lambda i,html: func( pq(html, parser="html") ) )
except Exception as e:
# disable use
pq = None
config.conf.pyquery = False
# error hint
print("LXML is missing\n", e)
|
| ︙ | ︙ |
Modified st2.py from [1b132a9fda] to [9090947823].
| ︙ | ︙ | |||
216 217 218 219 220 221 222 |
"search_google": search.google,
"search_cancel": search.cancel,
"true": lambda w,*args: True,
"streamedit_open": streamedit.open,
"streamedit_save": streamedit.save,
"streamedit_new": streamedit.new,
"streamedit_cancel": streamedit.cancel,
| | | 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 |
"search_google": search.google,
"search_cancel": search.cancel,
"true": lambda w,*args: True,
"streamedit_open": streamedit.open,
"streamedit_save": streamedit.save,
"streamedit_new": streamedit.new,
"streamedit_cancel": streamedit.cancel,
}.items() | self.add_signals.items() ))
# actually display main window
gui_startup(99/100.0)
self.win_streamtuner2.show()
# WHY DON'T YOU WANT TO WORK?!
#self.shoutcast.gtk_list.set_enable_search(True)
|
| ︙ | ︙ | |||
521 522 523 524 525 526 527 |
gtk.rc_parse(f)
pass
# end application and gtk+ main loop
def gtk_main_quit(self, widget, *x):
if conf.auto_save_appstate:
| | | 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 |
gtk.rc_parse(f)
pass
# end application and gtk+ main loop
def gtk_main_quit(self, widget, *x):
if conf.auto_save_appstate:
try: # doesn't work with gtk3 yet (probably just hooking at the wrong time)
self.app_state(widget)
except:
None
gtk.main_quit()
|
| ︙ | ︙ |