1
0
mirror of https://github.com/moparisthebest/SickRage synced 2024-11-17 23:05:11 -05:00

Merge branch 'develop' of https://github.com/SiCKRAGETV/SickRage into branch-tntvillage_provider

This commit is contained in:
Giovanni 2015-02-18 12:22:47 +01:00
commit eb300d5467
165 changed files with 4575 additions and 1940 deletions

5
.gitignore vendored
View File

@ -37,6 +37,10 @@ tests/failed.db
*.sw? *.sw?
Session.vim Session.vim
.ropeproject/* .ropeproject/*
*.iml
.idea
*.ipr
.settings/*
# OS generated files # # OS generated files #
###################### ######################
@ -48,7 +52,6 @@ ehthumbs.db
Thumbs.db Thumbs.db
.directory .directory
*~ *~
/.idea/
*.torrent *.torrent
# Unrar Executable # # Unrar Executable #

View File

@ -50,6 +50,10 @@ sys.path.insert(1, os.path.abspath(os.path.join(os.path.dirname(__file__), 'lib'
if sys.hexversion >= 0x020600F0: if sys.hexversion >= 0x020600F0:
from multiprocessing import freeze_support # @UnresolvedImport from multiprocessing import freeze_support # @UnresolvedImport
if sys.version_info >= (2, 7, 9):
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
import locale import locale
import datetime import datetime
import threading import threading

View File

@ -1,257 +1,257 @@
.country-flag { .country-flag {
width: 16px; width: 16px;
height: 11px; height: 11px;
background:url(images/country-flags.png) no-repeat background:url(../images/country-flags.png) no-repeat
} }
.country-flag.flag-ad {background-position: -16px 0} .country-flag.flag-ad {background-position: -16px 0}
.country-flag.flag-ae {background-position: -32px 0} .country-flag.flag-ae {background-position: -32px 0}
.country-flag.flag-af {background-position: -48px 0} .country-flag.flag-af {background-position: -48px 0}
.country-flag.flag-ag {background-position: -64px 0} .country-flag.flag-ag {background-position: -64px 0}
.country-flag.flag-ai {background-position: -80px 0} .country-flag.flag-ai {background-position: -80px 0}
.country-flag.flag-al {background-position: -96px 0} .country-flag.flag-al {background-position: -96px 0}
.country-flag.flag-am {background-position: -112px 0} .country-flag.flag-am {background-position: -112px 0}
.country-flag.flag-an {background-position: -128px 0} .country-flag.flag-an {background-position: -128px 0}
.country-flag.flag-ao {background-position: -144px 0} .country-flag.flag-ao {background-position: -144px 0}
.country-flag.flag-ar {background-position: -160px 0} .country-flag.flag-ar {background-position: -160px 0}
.country-flag.flag-as {background-position: -176px 0} .country-flag.flag-as {background-position: -176px 0}
.country-flag.flag-at {background-position: -192px 0} .country-flag.flag-at {background-position: -192px 0}
.country-flag.flag-au {background-position: -208px 0} .country-flag.flag-au {background-position: -208px 0}
.country-flag.flag-aw {background-position: -224px 0} .country-flag.flag-aw {background-position: -224px 0}
.country-flag.flag-az {background-position: -240px 0} .country-flag.flag-az {background-position: -240px 0}
.country-flag.flag-ba {background-position: 0 -11px} .country-flag.flag-ba {background-position: 0 -11px}
.country-flag.flag-bb {background-position: -16px -11px} .country-flag.flag-bb {background-position: -16px -11px}
.country-flag.flag-bd {background-position: -32px -11px} .country-flag.flag-bd {background-position: -32px -11px}
.country-flag.flag-be {background-position: -48px -11px} .country-flag.flag-be {background-position: -48px -11px}
.country-flag.flag-bf {background-position: -64px -11px} .country-flag.flag-bf {background-position: -64px -11px}
.country-flag.flag-bg {background-position: -80px -11px} .country-flag.flag-bg {background-position: -80px -11px}
.country-flag.flag-bh {background-position: -96px -11px} .country-flag.flag-bh {background-position: -96px -11px}
.country-flag.flag-bi {background-position: -112px -11px} .country-flag.flag-bi {background-position: -112px -11px}
.country-flag.flag-bj {background-position: -128px -11px} .country-flag.flag-bj {background-position: -128px -11px}
.country-flag.flag-bm {background-position: -144px -11px} .country-flag.flag-bm {background-position: -144px -11px}
.country-flag.flag-bn {background-position: -160px -11px} .country-flag.flag-bn {background-position: -160px -11px}
.country-flag.flag-bo {background-position: -176px -11px} .country-flag.flag-bo {background-position: -176px -11px}
.country-flag.flag-br {background-position: -192px -11px} .country-flag.flag-br {background-position: -192px -11px}
.country-flag.flag-bs {background-position: -208px -11px} .country-flag.flag-bs {background-position: -208px -11px}
.country-flag.flag-bt {background-position: -224px -11px} .country-flag.flag-bt {background-position: -224px -11px}
.country-flag.flag-bv {background-position: -240px -11px} .country-flag.flag-bv {background-position: -240px -11px}
.country-flag.flag-bw {background-position: 0 -22px} .country-flag.flag-bw {background-position: 0 -22px}
.country-flag.flag-by {background-position: -16px -22px} .country-flag.flag-by {background-position: -16px -22px}
.country-flag.flag-bz {background-position: -32px -22px} .country-flag.flag-bz {background-position: -32px -22px}
.country-flag.flag-ca {background-position: -48px -22px} .country-flag.flag-ca {background-position: -48px -22px}
.country-flag.flag-catalonia {background-position: -64px -22px} .country-flag.flag-catalonia {background-position: -64px -22px}
.country-flag.flag-cd {background-position: -80px -22px} .country-flag.flag-cd {background-position: -80px -22px}
.country-flag.flag-cf {background-position: -96px -22px} .country-flag.flag-cf {background-position: -96px -22px}
.country-flag.flag-cg {background-position: -112px -22px} .country-flag.flag-cg {background-position: -112px -22px}
.country-flag.flag-ch {background-position: -128px -22px} .country-flag.flag-ch {background-position: -128px -22px}
.country-flag.flag-ci {background-position: -144px -22px} .country-flag.flag-ci {background-position: -144px -22px}
.country-flag.flag-ck {background-position: -160px -22px} .country-flag.flag-ck {background-position: -160px -22px}
.country-flag.flag-cl {background-position: -176px -22px} .country-flag.flag-cl {background-position: -176px -22px}
.country-flag.flag-cm {background-position: -192px -22px} .country-flag.flag-cm {background-position: -192px -22px}
.country-flag.flag-cn {background-position: -208px -22px} .country-flag.flag-cn {background-position: -208px -22px}
.country-flag.flag-co {background-position: -224px -22px} .country-flag.flag-co {background-position: -224px -22px}
.country-flag.flag-cr {background-position: -240px -22px} .country-flag.flag-cr {background-position: -240px -22px}
.country-flag.flag-cu {background-position: 0 -33px} .country-flag.flag-cu {background-position: 0 -33px}
.country-flag.flag-cv {background-position: -16px -33px} .country-flag.flag-cv {background-position: -16px -33px}
.country-flag.flag-cw {background-position: -32px -33px} .country-flag.flag-cw {background-position: -32px -33px}
.country-flag.flag-cy {background-position: -48px -33px} .country-flag.flag-cy {background-position: -48px -33px}
.country-flag.flag-cz {background-position: -64px -33px} .country-flag.flag-cz {background-position: -64px -33px}
.country-flag.flag-de {background-position: -80px -33px} .country-flag.flag-de {background-position: -80px -33px}
.country-flag.flag-dj {background-position: -96px -33px} .country-flag.flag-dj {background-position: -96px -33px}
.country-flag.flag-dk {background-position: -112px -33px} .country-flag.flag-dk {background-position: -112px -33px}
.country-flag.flag-dm {background-position: -128px -33px} .country-flag.flag-dm {background-position: -128px -33px}
.country-flag.flag-do {background-position: -144px -33px} .country-flag.flag-do {background-position: -144px -33px}
.country-flag.flag-dz {background-position: -160px -33px} .country-flag.flag-dz {background-position: -160px -33px}
.country-flag.flag-ec {background-position: -176px -33px} .country-flag.flag-ec {background-position: -176px -33px}
.country-flag.flag-ee {background-position: -192px -33px} .country-flag.flag-ee {background-position: -192px -33px}
.country-flag.flag-eg {background-position: -208px -33px} .country-flag.flag-eg {background-position: -208px -33px}
.country-flag.flag-eh {background-position: -224px -33px} .country-flag.flag-eh {background-position: -224px -33px}
.country-flag.flag-england {background-position: -240px -33px} .country-flag.flag-england {background-position: -240px -33px}
.country-flag.flag-er {background-position: 0 -44px} .country-flag.flag-er {background-position: 0 -44px}
.country-flag.flag-es {background-position: -16px -44px} .country-flag.flag-es {background-position: -16px -44px}
.country-flag.flag-et {background-position: -32px -44px} .country-flag.flag-et {background-position: -32px -44px}
.country-flag.flag-eu {background-position: -48px -44px} .country-flag.flag-eu {background-position: -48px -44px}
.country-flag.flag-fi {background-position: -64px -44px} .country-flag.flag-fi {background-position: -64px -44px}
.country-flag.flag-fj {background-position: -80px -44px} .country-flag.flag-fj {background-position: -80px -44px}
.country-flag.flag-fk {background-position: -96px -44px} .country-flag.flag-fk {background-position: -96px -44px}
.country-flag.flag-fm {background-position: -112px -44px} .country-flag.flag-fm {background-position: -112px -44px}
.country-flag.flag-fo {background-position: -128px -44px} .country-flag.flag-fo {background-position: -128px -44px}
.country-flag.flag-fr {background-position: -144px -44px} .country-flag.flag-fr {background-position: -144px -44px}
.country-flag.flag-ga {background-position: -160px -44px} .country-flag.flag-ga {background-position: -160px -44px}
.country-flag.flag-gb {background-position: -176px -44px} .country-flag.flag-gb {background-position: -176px -44px}
.country-flag.flag-gd {background-position: -192px -44px} .country-flag.flag-gd {background-position: -192px -44px}
.country-flag.flag-ge {background-position: -208px -44px} .country-flag.flag-ge {background-position: -208px -44px}
.country-flag.flag-gf {background-position: -224px -44px} .country-flag.flag-gf {background-position: -224px -44px}
.country-flag.flag-gg {background-position: -240px -44px} .country-flag.flag-gg {background-position: -240px -44px}
.country-flag.flag-gh {background-position: 0 -55px} .country-flag.flag-gh {background-position: 0 -55px}
.country-flag.flag-gi {background-position: -16px -55px} .country-flag.flag-gi {background-position: -16px -55px}
.country-flag.flag-gl {background-position: -32px -55px} .country-flag.flag-gl {background-position: -32px -55px}
.country-flag.flag-gm {background-position: -48px -55px} .country-flag.flag-gm {background-position: -48px -55px}
.country-flag.flag-gn {background-position: -64px -55px} .country-flag.flag-gn {background-position: -64px -55px}
.country-flag.flag-gp {background-position: -80px -55px} .country-flag.flag-gp {background-position: -80px -55px}
.country-flag.flag-gq {background-position: -96px -55px} .country-flag.flag-gq {background-position: -96px -55px}
.country-flag.flag-gr {background-position: -112px -55px} .country-flag.flag-gr {background-position: -112px -55px}
.country-flag.flag-gs {background-position: -128px -55px} .country-flag.flag-gs {background-position: -128px -55px}
.country-flag.flag-gt {background-position: -144px -55px} .country-flag.flag-gt {background-position: -144px -55px}
.country-flag.flag-gu {background-position: -160px -55px} .country-flag.flag-gu {background-position: -160px -55px}
.country-flag.flag-gw {background-position: -176px -55px} .country-flag.flag-gw {background-position: -176px -55px}
.country-flag.flag-gy {background-position: -192px -55px} .country-flag.flag-gy {background-position: -192px -55px}
.country-flag.flag-hk {background-position: -208px -55px} .country-flag.flag-hk {background-position: -208px -55px}
.country-flag.flag-hm {background-position: -224px -55px} .country-flag.flag-hm {background-position: -224px -55px}
.country-flag.flag-hn {background-position: -240px -55px} .country-flag.flag-hn {background-position: -240px -55px}
.country-flag.flag-hr {background-position: 0 -66px} .country-flag.flag-hr {background-position: 0 -66px}
.country-flag.flag-ht {background-position: -16px -66px} .country-flag.flag-ht {background-position: -16px -66px}
.country-flag.flag-hu {background-position: -32px -66px} .country-flag.flag-hu {background-position: -32px -66px}
.country-flag.flag-ic {background-position: -48px -66px} .country-flag.flag-ic {background-position: -48px -66px}
.country-flag.flag-id {background-position: -64px -66px} .country-flag.flag-id {background-position: -64px -66px}
.country-flag.flag-ie {background-position: -80px -66px} .country-flag.flag-ie {background-position: -80px -66px}
.country-flag.flag-il {background-position: -96px -66px} .country-flag.flag-il {background-position: -96px -66px}
.country-flag.flag-im {background-position: -112px -66px} .country-flag.flag-im {background-position: -112px -66px}
.country-flag.flag-in {background-position: -128px -66px} .country-flag.flag-in {background-position: -128px -66px}
.country-flag.flag-io {background-position: -144px -66px} .country-flag.flag-io {background-position: -144px -66px}
.country-flag.flag-iq {background-position: -160px -66px} .country-flag.flag-iq {background-position: -160px -66px}
.country-flag.flag-ir {background-position: -176px -66px} .country-flag.flag-ir {background-position: -176px -66px}
.country-flag.flag-is {background-position: -192px -66px} .country-flag.flag-is {background-position: -192px -66px}
.country-flag.flag-it {background-position: -208px -66px} .country-flag.flag-it {background-position: -208px -66px}
.country-flag.flag-je {background-position: -224px -66px} .country-flag.flag-je {background-position: -224px -66px}
.country-flag.flag-jm {background-position: -240px -66px} .country-flag.flag-jm {background-position: -240px -66px}
.country-flag.flag-jo {background-position: 0 -77px} .country-flag.flag-jo {background-position: 0 -77px}
.country-flag.flag-jp {background-position: -16px -77px} .country-flag.flag-jp {background-position: -16px -77px}
.country-flag.flag-ke {background-position: -32px -77px} .country-flag.flag-ke {background-position: -32px -77px}
.country-flag.flag-kg {background-position: -48px -77px} .country-flag.flag-kg {background-position: -48px -77px}
.country-flag.flag-kh {background-position: -64px -77px} .country-flag.flag-kh {background-position: -64px -77px}
.country-flag.flag-ki {background-position: -80px -77px} .country-flag.flag-ki {background-position: -80px -77px}
.country-flag.flag-km {background-position: -96px -77px} .country-flag.flag-km {background-position: -96px -77px}
.country-flag.flag-kn {background-position: -112px -77px} .country-flag.flag-kn {background-position: -112px -77px}
.country-flag.flag-kp {background-position: -128px -77px} .country-flag.flag-kp {background-position: -128px -77px}
.country-flag.flag-kr {background-position: -144px -77px} .country-flag.flag-kr {background-position: -144px -77px}
.country-flag.flag-kurdistan {background-position: -160px -77px} .country-flag.flag-kurdistan {background-position: -160px -77px}
.country-flag.flag-kw {background-position: -176px -77px} .country-flag.flag-kw {background-position: -176px -77px}
.country-flag.flag-ky {background-position: -192px -77px} .country-flag.flag-ky {background-position: -192px -77px}
.country-flag.flag-kz {background-position: -208px -77px} .country-flag.flag-kz {background-position: -208px -77px}
.country-flag.flag-la {background-position: -224px -77px} .country-flag.flag-la {background-position: -224px -77px}
.country-flag.flag-lb {background-position: -240px -77px} .country-flag.flag-lb {background-position: -240px -77px}
.country-flag.flag-lc {background-position: 0 -88px} .country-flag.flag-lc {background-position: 0 -88px}
.country-flag.flag-li {background-position: -16px -88px} .country-flag.flag-li {background-position: -16px -88px}
.country-flag.flag-lk {background-position: -32px -88px} .country-flag.flag-lk {background-position: -32px -88px}
.country-flag.flag-lr {background-position: -48px -88px} .country-flag.flag-lr {background-position: -48px -88px}
.country-flag.flag-ls {background-position: -64px -88px} .country-flag.flag-ls {background-position: -64px -88px}
.country-flag.flag-lt {background-position: -80px -88px} .country-flag.flag-lt {background-position: -80px -88px}
.country-flag.flag-lu {background-position: -96px -88px} .country-flag.flag-lu {background-position: -96px -88px}
.country-flag.flag-lv {background-position: -112px -88px} .country-flag.flag-lv {background-position: -112px -88px}
.country-flag.flag-ly {background-position: -128px -88px} .country-flag.flag-ly {background-position: -128px -88px}
.country-flag.flag-ma {background-position: -144px -88px} .country-flag.flag-ma {background-position: -144px -88px}
.country-flag.flag-mc {background-position: -160px -88px} .country-flag.flag-mc {background-position: -160px -88px}
.country-flag.flag-md {background-position: -176px -88px} .country-flag.flag-md {background-position: -176px -88px}
.country-flag.flag-me {background-position: -192px -88px} .country-flag.flag-me {background-position: -192px -88px}
.country-flag.flag-mg {background-position: -208px -88px} .country-flag.flag-mg {background-position: -208px -88px}
.country-flag.flag-mh {background-position: -224px -88px} .country-flag.flag-mh {background-position: -224px -88px}
.country-flag.flag-mk {background-position: -240px -88px} .country-flag.flag-mk {background-position: -240px -88px}
.country-flag.flag-ml {background-position: 0 -99px} .country-flag.flag-ml {background-position: 0 -99px}
.country-flag.flag-mm {background-position: -16px -99px} .country-flag.flag-mm {background-position: -16px -99px}
.country-flag.flag-mn {background-position: -32px -99px} .country-flag.flag-mn {background-position: -32px -99px}
.country-flag.flag-mo {background-position: -48px -99px} .country-flag.flag-mo {background-position: -48px -99px}
.country-flag.flag-mp {background-position: -64px -99px} .country-flag.flag-mp {background-position: -64px -99px}
.country-flag.flag-mq {background-position: -80px -99px} .country-flag.flag-mq {background-position: -80px -99px}
.country-flag.flag-mr {background-position: -96px -99px} .country-flag.flag-mr {background-position: -96px -99px}
.country-flag.flag-ms {background-position: -112px -99px} .country-flag.flag-ms {background-position: -112px -99px}
.country-flag.flag-mt {background-position: -128px -99px} .country-flag.flag-mt {background-position: -128px -99px}
.country-flag.flag-mu {background-position: -144px -99px} .country-flag.flag-mu {background-position: -144px -99px}
.country-flag.flag-mv {background-position: -160px -99px} .country-flag.flag-mv {background-position: -160px -99px}
.country-flag.flag-mw {background-position: -176px -99px} .country-flag.flag-mw {background-position: -176px -99px}
.country-flag.flag-mx {background-position: -192px -99px} .country-flag.flag-mx {background-position: -192px -99px}
.country-flag.flag-my {background-position: -208px -99px} .country-flag.flag-my {background-position: -208px -99px}
.country-flag.flag-mz {background-position: -224px -99px} .country-flag.flag-mz {background-position: -224px -99px}
.country-flag.flag-na {background-position: -240px -99px} .country-flag.flag-na {background-position: -240px -99px}
.country-flag.flag-nc {background-position: 0 -110px} .country-flag.flag-nc {background-position: 0 -110px}
.country-flag.flag-ne {background-position: -16px -110px} .country-flag.flag-ne {background-position: -16px -110px}
.country-flag.flag-nf {background-position: -32px -110px} .country-flag.flag-nf {background-position: -32px -110px}
.country-flag.flag-ng {background-position: -48px -110px} .country-flag.flag-ng {background-position: -48px -110px}
.country-flag.flag-ni {background-position: -64px -110px} .country-flag.flag-ni {background-position: -64px -110px}
.country-flag.flag-nl {background-position: -80px -110px} .country-flag.flag-nl {background-position: -80px -110px}
.country-flag.flag-no {background-position: -96px -110px} .country-flag.flag-no {background-position: -96px -110px}
.country-flag.flag-np {background-position: -112px -110px} .country-flag.flag-np {background-position: -112px -110px}
.country-flag.flag-nr {background-position: -128px -110px} .country-flag.flag-nr {background-position: -128px -110px}
.country-flag.flag-nu {background-position: -144px -110px} .country-flag.flag-nu {background-position: -144px -110px}
.country-flag.flag-nz {background-position: -160px -110px} .country-flag.flag-nz {background-position: -160px -110px}
.country-flag.flag-om {background-position: -176px -110px} .country-flag.flag-om {background-position: -176px -110px}
.country-flag.flag-pa {background-position: -192px -110px} .country-flag.flag-pa {background-position: -192px -110px}
.country-flag.flag-pe {background-position: -208px -110px} .country-flag.flag-pe {background-position: -208px -110px}
.country-flag.flag-pf {background-position: -224px -110px} .country-flag.flag-pf {background-position: -224px -110px}
.country-flag.flag-pg {background-position: -240px -110px} .country-flag.flag-pg {background-position: -240px -110px}
.country-flag.flag-ph {background-position: 0 -121px} .country-flag.flag-ph {background-position: 0 -121px}
.country-flag.flag-pk {background-position: -16px -121px} .country-flag.flag-pk {background-position: -16px -121px}
.country-flag.flag-pl {background-position: -32px -121px} .country-flag.flag-pl {background-position: -32px -121px}
.country-flag.flag-pm {background-position: -48px -121px} .country-flag.flag-pm {background-position: -48px -121px}
.country-flag.flag-pn {background-position: -64px -121px} .country-flag.flag-pn {background-position: -64px -121px}
.country-flag.flag-pr {background-position: -80px -121px} .country-flag.flag-pr {background-position: -80px -121px}
.country-flag.flag-ps {background-position: -96px -121px} .country-flag.flag-ps {background-position: -96px -121px}
.country-flag.flag-pt {background-position: -112px -121px} .country-flag.flag-pt {background-position: -112px -121px}
.country-flag.flag-pw {background-position: -128px -121px} .country-flag.flag-pw {background-position: -128px -121px}
.country-flag.flag-py {background-position: -144px -121px} .country-flag.flag-py {background-position: -144px -121px}
.country-flag.flag-qa {background-position: -160px -121px} .country-flag.flag-qa {background-position: -160px -121px}
.country-flag.flag-re {background-position: -176px -121px} .country-flag.flag-re {background-position: -176px -121px}
.country-flag.flag-ro {background-position: -192px -121px} .country-flag.flag-ro {background-position: -192px -121px}
.country-flag.flag-rs {background-position: -208px -121px} .country-flag.flag-rs {background-position: -208px -121px}
.country-flag.flag-ru {background-position: -224px -121px} .country-flag.flag-ru {background-position: -224px -121px}
.country-flag.flag-rw {background-position: -240px -121px} .country-flag.flag-rw {background-position: -240px -121px}
.country-flag.flag-sa {background-position: 0 -132px} .country-flag.flag-sa {background-position: 0 -132px}
.country-flag.flag-sb {background-position: -16px -132px} .country-flag.flag-sb {background-position: -16px -132px}
.country-flag.flag-sc {background-position: -32px -132px} .country-flag.flag-sc {background-position: -32px -132px}
.country-flag.flag-scotland {background-position: -48px -132px} .country-flag.flag-scotland {background-position: -48px -132px}
.country-flag.flag-sd {background-position: -64px -132px} .country-flag.flag-sd {background-position: -64px -132px}
.country-flag.flag-se {background-position: -80px -132px} .country-flag.flag-se {background-position: -80px -132px}
.country-flag.flag-sg {background-position: -96px -132px} .country-flag.flag-sg {background-position: -96px -132px}
.country-flag.flag-sh {background-position: -112px -132px} .country-flag.flag-sh {background-position: -112px -132px}
.country-flag.flag-si {background-position: -128px -132px} .country-flag.flag-si {background-position: -128px -132px}
.country-flag.flag-sk {background-position: -144px -132px} .country-flag.flag-sk {background-position: -144px -132px}
.country-flag.flag-sl {background-position: -160px -132px} .country-flag.flag-sl {background-position: -160px -132px}
.country-flag.flag-sm {background-position: -176px -132px} .country-flag.flag-sm {background-position: -176px -132px}
.country-flag.flag-sn {background-position: -192px -132px} .country-flag.flag-sn {background-position: -192px -132px}
.country-flag.flag-so {background-position: -208px -132px} .country-flag.flag-so {background-position: -208px -132px}
.country-flag.flag-somaliland {background-position: -224px -132px} .country-flag.flag-somaliland {background-position: -224px -132px}
.country-flag.flag-sr {background-position: -240px -132px} .country-flag.flag-sr {background-position: -240px -132px}
.country-flag.flag-ss {background-position: 0 -143px} .country-flag.flag-ss {background-position: 0 -143px}
.country-flag.flag-st {background-position: -16px -143px} .country-flag.flag-st {background-position: -16px -143px}
.country-flag.flag-sv {background-position: -32px -143px} .country-flag.flag-sv {background-position: -32px -143px}
.country-flag.flag-sx {background-position: -48px -143px} .country-flag.flag-sx {background-position: -48px -143px}
.country-flag.flag-sy {background-position: -64px -143px} .country-flag.flag-sy {background-position: -64px -143px}
.country-flag.flag-sz {background-position: -80px -143px} .country-flag.flag-sz {background-position: -80px -143px}
.country-flag.flag-tc {background-position: -96px -143px} .country-flag.flag-tc {background-position: -96px -143px}
.country-flag.flag-td {background-position: -112px -143px} .country-flag.flag-td {background-position: -112px -143px}
.country-flag.flag-tf {background-position: -128px -143px} .country-flag.flag-tf {background-position: -128px -143px}
.country-flag.flag-tg {background-position: -144px -143px} .country-flag.flag-tg {background-position: -144px -143px}
.country-flag.flag-th {background-position: -160px -143px} .country-flag.flag-th {background-position: -160px -143px}
.country-flag.flag-tj {background-position: -176px -143px} .country-flag.flag-tj {background-position: -176px -143px}
.country-flag.flag-tk {background-position: -192px -143px} .country-flag.flag-tk {background-position: -192px -143px}
.country-flag.flag-tl {background-position: -208px -143px} .country-flag.flag-tl {background-position: -208px -143px}
.country-flag.flag-tm {background-position: -224px -143px} .country-flag.flag-tm {background-position: -224px -143px}
.country-flag.flag-tn {background-position: -240px -143px} .country-flag.flag-tn {background-position: -240px -143px}
.country-flag.flag-to {background-position: 0 -154px} .country-flag.flag-to {background-position: 0 -154px}
.country-flag.flag-tr {background-position: -16px -154px} .country-flag.flag-tr {background-position: -16px -154px}
.country-flag.flag-tt {background-position: -32px -154px} .country-flag.flag-tt {background-position: -32px -154px}
.country-flag.flag-tv {background-position: -48px -154px} .country-flag.flag-tv {background-position: -48px -154px}
.country-flag.flag-tw {background-position: -64px -154px} .country-flag.flag-tw {background-position: -64px -154px}
.country-flag.flag-tz {background-position: -80px -154px} .country-flag.flag-tz {background-position: -80px -154px}
.country-flag.flag-ua {background-position: -96px -154px} .country-flag.flag-ua {background-position: -96px -154px}
.country-flag.flag-ug {background-position: -112px -154px} .country-flag.flag-ug {background-position: -112px -154px}
.country-flag.flag-um {background-position: -128px -154px} .country-flag.flag-um {background-position: -128px -154px}
.country-flag.flag-us {background-position: -144px -154px} .country-flag.flag-us {background-position: -144px -154px}
.country-flag.flag-uy {background-position: -160px -154px} .country-flag.flag-uy {background-position: -160px -154px}
.country-flag.flag-uz {background-position: -176px -154px} .country-flag.flag-uz {background-position: -176px -154px}
.country-flag.flag-va {background-position: -192px -154px} .country-flag.flag-va {background-position: -192px -154px}
.country-flag.flag-vc {background-position: -208px -154px} .country-flag.flag-vc {background-position: -208px -154px}
.country-flag.flag-ve {background-position: -224px -154px} .country-flag.flag-ve {background-position: -224px -154px}
.country-flag.flag-vg {background-position: -240px -154px} .country-flag.flag-vg {background-position: -240px -154px}
.country-flag.flag-vi {background-position: 0 -165px} .country-flag.flag-vi {background-position: 0 -165px}
.country-flag.flag-vn {background-position: -16px -165px} .country-flag.flag-vn {background-position: -16px -165px}
.country-flag.flag-vu {background-position: -32px -165px} .country-flag.flag-vu {background-position: -32px -165px}
.country-flag.flag-wales {background-position: -48px -165px} .country-flag.flag-wales {background-position: -48px -165px}
.country-flag.flag-wf {background-position: -64px -165px} .country-flag.flag-wf {background-position: -64px -165px}
.country-flag.flag-ws {background-position: -80px -165px} .country-flag.flag-ws {background-position: -80px -165px}
.country-flag.flag-ye {background-position: -96px -165px} .country-flag.flag-ye {background-position: -96px -165px}
.country-flag.flag-yt {background-position: -112px -165px} .country-flag.flag-yt {background-position: -112px -165px}
.country-flag.flag-za {background-position: -128px -165px} .country-flag.flag-za {background-position: -128px -165px}
.country-flag.flag-zanzibar {background-position: -144px -165px} .country-flag.flag-zanzibar {background-position: -144px -165px}
.country-flag.flag-zm {background-position: -160px -165px} .country-flag.flag-zm {background-position: -160px -165px}
.country-flag.flag-zw {background-position: -176px -165px} .country-flag.flag-zw {background-position: -176px -165px}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 488 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 853 B

View File

@ -31,7 +31,7 @@
<div id="core-component-group1" class="tab-pane active component-group"> <div id="core-component-group1" class="tab-pane active component-group">
<div class="component-group-desc"> <div class="component-group-desc">
<img class="notifier-icon" src="$sbRoot/images/providers/anidb.gif" alt="AniDB" title="AniDB" width="24" height="24" /> <img class="notifier-icon" src="$sbRoot/images/anidb24.png" alt="AniDB" title="AniDB" width="24" height="24" />
<h3><a href="<%= anon_url('http://anidb.info') %>" onclick="window.open(this.href, '_blank'); return false;">AniDB</a></h3> <h3><a href="<%= anon_url('http://anidb.info') %>" onclick="window.open(this.href, '_blank'); return false;">AniDB</a></h3>
<p>AniDB is non-profit database of anime information that is freely open to the public</p> <p>AniDB is non-profit database of anime information that is freely open to the public</p>
</div> </div>

View File

@ -63,6 +63,16 @@
</label> </label>
</div> </div>
<div class="field-pair">
<label for="showupdate_hour">
<span class="component-title">When to update shows</span>
<span class="component-desc">
<input type="text" name="showupdate_hour" id="showupdate_hour" value="$sickbeard.SHOWUPDATE_HOUR" class="form-control input-sm input75" />
<p>with information such as next air dates, show ended, etc. Use 15 for 3pm, 4 for 4am etc. Anything over 23 or under 0 will be set to 0 (12am)</p>
</span>
</label>
</div>
<div class="field-pair"> <div class="field-pair">
<label for="update_shows_on_start"> <label for="update_shows_on_start">
<span class="component-title">Update shows on startup</span> <span class="component-title">Update shows on startup</span>

View File

@ -1375,30 +1375,39 @@
<span class="component-title">Trakt username</span> <span class="component-title">Trakt username</span>
<input type="text" name="trakt_username" id="trakt_username" value="$sickbeard.TRAKT_USERNAME" class="form-control input-sm input250" /> <input type="text" name="trakt_username" id="trakt_username" value="$sickbeard.TRAKT_USERNAME" class="form-control input-sm input250" />
</label> </label>
<label> <p>
<span class="component-title">&nbsp;</span>
<span class="component-desc">username of your Trakt account.</span> <span class="component-desc">username of your Trakt account.</span>
</label> </p>
</div> </div>
<div class="field-pair"> <div class="field-pair">
<label for="trakt_password"> <label for="trakt_password">
<span class="component-title">Trakt password</span> <span class="component-title">Trakt password</span>
<input type="password" name="trakt_password" id="trakt_password" value="$sickbeard.TRAKT_PASSWORD" class="form-control input-sm input250" /> <input type="password" name="trakt_password" id="trakt_password" value="$sickbeard.TRAKT_PASSWORD" class="form-control input-sm input250" />
</label> </label>
<label> <p>
<span class="component-title">&nbsp;</span>
<span class="component-desc">password of your Trakt account.</span> <span class="component-desc">password of your Trakt account.</span>
</label> </p>
</div> </div>
<div class="field-pair"> <div class="field-pair">
<label for="trakt_disable_ssl_verify"> <label for="trakt_disable_ssl_verify">
<span class="component-title">Disable SSL Verification:</span> <span class="component-title">Disable SSL Verification:</span>
<span class="component-desc"> <span class="component-desc">
<input type="checkbox" class="enabler" name="trakt_disable_ssl_verify" id="trakt_disable_ssl_verify" #if $sickbeard.TRAKT_DISABLE_SSL_VERIFY then "checked=\"checked\"" else ""# /> <input type="checkbox" class="enabler" name="trakt_disable_ssl_verify" id="trakt_disable_ssl_verify" #if $sickbeard.TRAKT_DISABLE_SSL_VERIFY then "checked=\"checked\"" else ""# />
<p>Disable SSL certificate verification on systems with broken SSL implementations, like the QNAP NAS.</p> <p>Disable SSL certificate verification for broken SSL installs (like QNAP NAS)</p>
</span> </span>
</label> </label>
</div> </div>
<div class="field-pair">
<label for="trakt_timeout">
<span class="component-title">API Timeout:</span>
<input type="text" name="trakt_timeout" id="trakt_timeout" value="$sickbeard.TRAKT_TIMEOUT" class="form-control input-sm input75" />
</label>
<p>
<span class="component-desc">
Seconds to wait for Trakt API to respond. (Use 0 to wait forever)
</span>
</p>
</div>
<div class="field-pair"> <div class="field-pair">
<label for="trakt_default_indexer"> <label for="trakt_default_indexer">
<span class="component-title">Default indexer:</span> <span class="component-title">Default indexer:</span>

View File

@ -449,7 +449,6 @@
<input type="text" name="torrent_host" id="torrent_host" value="$sickbeard.TORRENT_HOST" class="form-control input-sm input350" /> <input type="text" name="torrent_host" id="torrent_host" value="$sickbeard.TORRENT_HOST" class="form-control input-sm input350" />
<div class="clear-left"> <div class="clear-left">
<p id="host_desc_torrent">URL to your torrent client (e.g. http://localhost:8000/)</p> <p id="host_desc_torrent">URL to your torrent client (e.g. http://localhost:8000/)</p>
<p id="host_desc_rtorrent" style="display:none"><b>Note:</b> <i>rTorrent</i> client URLs use e.g. scgi://localhost:5000/</p>
</div> </div>
</span> </span>
</label> </label>
@ -467,12 +466,29 @@
</label> </label>
</div> </div>
<div class="field-pair" id="torrent_auth_type">
<label>
<span class="component-title">Http Authentication</span>
<span class="component-desc">
<select name="torrent_auth_type" id="torrent_auth_type" class="form-control input-sm">
#set $http_authtype = {'none': "None", 'basic': "Basic", 'digest': "Digest"}
#for $authvalue,$authname in $http_authtype.items():
#set $selected = $html_selected if $sickbeard.TORRENT_AUTH_TYPE == $authvalue else ''
<option value="$authvalue"$selected>$authname</option>
#end for
</select>
<p></p>
</span>
</label>
</div>
<div class="field-pair" id="torrent_verify_cert_option"> <div class="field-pair" id="torrent_verify_cert_option">
<label for="torrent_verify_cert"> <label for="torrent_verify_cert">
<span class="component-title">Verify certificate</span> <span class="component-title">Verify certificate</span>
<span class="component-desc"> <span class="component-desc">
<input type="checkbox" name="torrent_verify_cert" class="enabler" id="torrent_verify_cert" <%= html_checked if sickbeard.TORRENT_VERIFY_CERT == True else '' %>/> <input type="checkbox" name="torrent_verify_cert" class="enabler" id="torrent_verify_cert" <%= html_checked if sickbeard.TORRENT_VERIFY_CERT == True else '' %>/>
<p>disable if you get "Deluge: Authentication Error" in your log</p> <p id="torrent_verify_deluge">disable if you get "Deluge: Authentication Error" in your log</p>
<p id="torrent_verify_rtorrent">Verify SSL certificates for HTTPS requests</p>
</span> </span>
</label> </label>
</div> </div>

View File

@ -379,7 +379,7 @@
#if ($sickbeard.DISPLAY_FILESIZE == True): #if ($sickbeard.DISPLAY_FILESIZE == True):
style="min-width: 190px" style="min-width: 190px"
#end if #end if
>>Name</th> >Name</th>
#if ($sickbeard.DISPLAY_FILESIZE == True): #if ($sickbeard.DISPLAY_FILESIZE == True):
<th class="col-ep">Filesize</th> <th class="col-ep">Filesize</th>
#end if #end if
@ -507,13 +507,15 @@
#if $sickbeard.USE_SUBTITLES and $show.subtitles: #if $sickbeard.USE_SUBTITLES and $show.subtitles:
<td class="col-subtitles" align="center"> <td class="col-subtitles" align="center">
#if $epResult["subtitles"]: #if $epResult["subtitles"]:
#for $sub_lang in subliminal.language.language_list([x.strip() for x in $epResult["subtitles"].split(',')]): #for $sub_lang in subliminal.language.language_list([x.strip() for x in $epResult["subtitles"].split(',') if x != ""]):
#if sub_lang.alpha2 != "" #if sub_lang.alpha2 != ""
<img src="$sbRoot/images/flags/${sub_lang.alpha2}.png" width="16" height="11" alt="${sub_lang}" /> <img src="$sbRoot/images/flags/${sub_lang.alpha2}.png" width="16" height="11" alt="${sub_lang}" />
#end if #else
#end for <img src="$sbRoot/images/flags/unknown.png" width="16" height="11" alt="Unknown" />
#end if #end if
#end for
#end if
</td> </td>
#end if #end if

View File

@ -131,7 +131,11 @@
<td class="tvShow" width="35%"><a href="$sbRoot/home/displayShow?show=$hItem["showid"]#season-$hItem["season"]">$hItem["show_name"] - <%="S%02i" % int(hItem["season"])+"E%02i" % int(hItem["episode"]) %>#if "proper" in $hItem["resource"].lower() or "repack" in $hItem["resource"].lower() then ' <span class="quality Proper">Proper</span>' else ""#</a></td> <td class="tvShow" width="35%"><a href="$sbRoot/home/displayShow?show=$hItem["showid"]#season-$hItem["season"]">$hItem["show_name"] - <%="S%02i" % int(hItem["season"])+"E%02i" % int(hItem["episode"]) %>#if "proper" in $hItem["resource"].lower() or "repack" in $hItem["resource"].lower() then ' <span class="quality Proper">Proper</span>' else ""#</a></td>
<td align="center" #if $curStatus == SUBTITLED then 'class="subtitles_column"' else ''#> <td align="center" #if $curStatus == SUBTITLED then 'class="subtitles_column"' else ''#>
#if $curStatus == SUBTITLED: #if $curStatus == SUBTITLED:
<img width="16" height="11" style="vertical-align:middle;" src="$sbRoot/images/flags/<%= hItem["resource"][len(hItem["resource"])-6:len(hItem["resource"])-4]+'.png'%>"> #if $sickbeard.SUBTITLES_MULTI:
<img width="16" height="11" style="vertical-align:middle;" src="$sbRoot/images/flags/<%= hItem["resource"][len(hItem["resource"])-6:len(hItem["resource"])-4]+'.png'%>" onError="this.onerror=null;this.src='$sbRoot/images/flags/unknown.png';">
#else
<img width="16" height="11" style="vertical-align:middle;" src="$sbRoot/images/flags/unknown.png">
#end if
#end if #end if
<span style="cursor: help; vertical-align:middle;" title="$os.path.basename($hItem["resource"])">$statusStrings[$curStatus]</span> <span style="cursor: help; vertical-align:middle;" title="$os.path.basename($hItem["resource"])">$statusStrings[$curStatus]</span>
</td> </td>

View File

@ -104,7 +104,8 @@
filter_columnFilters: false, filter_columnFilters: false,
filter_reset: '.resetshows' filter_reset: '.resetshows'
}, },
sortStable: true sortStable: true,
sortAppend: [[1,0]]
}); });
\$("#showListTableAnime:has(tbody tr)").tablesorter({ \$("#showListTableAnime:has(tbody tr)").tablesorter({
@ -126,13 +127,16 @@
filter_columnFilters: false, filter_columnFilters: false,
filter_reset: '.resetanime' filter_reset: '.resetanime'
}, },
sortStable: true sortStable: true,
sortAppend: [[1,0]]
}); });
\$.tablesorter.filter.bindSearch( "#showListTableShows", \$('.search') ); if (\$("#showListTableShows").find("tbody").find("tr").size() > 0)
\$.tablesorter.filter.bindSearch( "#showListTableShows", \$('.search') );
#if $sickbeard.ANIME_SPLIT_HOME: #if $sickbeard.ANIME_SPLIT_HOME:
\$.tablesorter.filter.bindSearch( "#showListTableAnime", \$('.search') ); if (\$("#showListTableAnime").find("tbody").find("tr").size() > 0)
\$.tablesorter.filter.bindSearch( "#showListTableAnime", \$('.search') );
#end if #end if
#set $fuzzydate = 'airdate' #set $fuzzydate = 'airdate'
@ -403,7 +407,7 @@ $myShowList.sort(lambda x, y: cmp(x.name, y.name))
<td class="show-table"> <td class="show-table">
#if $layout != 'simple': #if $layout != 'simple':
#if $curShow.network: #if $curShow.network:
<img class="show-network-image" src="$sbRoot/images/network/${curShow.network.replace(u"\u00C9",'e').lower()}.png" alt="$curShow.network" title="$curShow.network" /> <img class="show-network-image" src="$sbRoot/images/network/${curShow.network.replace(u"\u00C9",'e').replace(u"\u00E9",'e').lower()}.png" alt="$curShow.network" title="$curShow.network" />
#else: #else:
<img class="show-network-image" src="$sbRoot/images/network/nonetwork.png" alt="No Network" title="No Network" /> <img class="show-network-image" src="$sbRoot/images/network/nonetwork.png" alt="No Network" title="No Network" />
#end if #end if
@ -561,7 +565,7 @@ $myShowList.sort(lambda x, y: cmp(x.name, y.name))
#if $layout != 'simple': #if $layout != 'simple':
<td align="center"> <td align="center">
#if $curShow.network: #if $curShow.network:
<img id="network" width="54" height="27" src="$sbRoot/images/network/${curShow.network.replace(u"\u00C9",'e').lower()}.png" alt="$curShow.network" title="$curShow.network" /> <img id="network" width="54" height="27" src="$sbRoot/images/network/${curShow.network.replace(u"\u00C9",'e').replace(u"\u00E9",'e').lower()}.png" alt="$curShow.network" title="$curShow.network" />
#else: #else:
<img id="network" width="54" height="27" src="$sbRoot/images/network/nonetwork.png" alt="No Network" title="No Network" /> <img id="network" width="54" height="27" src="$sbRoot/images/network/nonetwork.png" alt="No Network" title="No Network" />
#end if #end if

View File

@ -25,7 +25,3 @@
<input class="btn" type="button" id="defaultRootDir" value="Set as Default *" /> <input class="btn" type="button" id="defaultRootDir" value="Set as Default *" />
</div> </div>
<input type="text" style="display: none" id="rootDirText" /> <input type="text" style="display: none" id="rootDirText" />
<script type="text/javascript">
document.getElementById("rootDirs").selectedIndex = "0"
</script>

View File

@ -46,22 +46,25 @@
#end if #end if
#set $totalWanted = 0 #set $totalWanted = 0
#set $totalQual = 0 #set $totalQual = 0
#set $totalSnatched = 0
#for $curShow in $sickbeard.showList: #for $curShow in $sickbeard.showList:
#set $totalWanted = $totalWanted + $showCounts[$curShow.indexerid][$Overview.WANTED] #set $totalWanted = $totalWanted + $showCounts[$curShow.indexerid][$Overview.WANTED]
#set $totalQual = $totalQual + $showCounts[$curShow.indexerid][$Overview.QUAL] #set $totalQual = $totalQual + $showCounts[$curShow.indexerid][$Overview.QUAL]
#set $totalSnatched = $totalSnatched + $showCounts[$curShow.indexerid][$Overview.SNATCHED]
#end for #end for
<div class="h2footer pull-right"> <div class="h2footer pull-right">
<span class="listing-key wanted">Wanted: <b>$totalWanted</b></span> <span class="listing-key wanted">Wanted: <b>$totalWanted</b></span>
<span class="listing-key qual">Low Quality: <b>$totalQual</b></span> <span class="listing-key qual">Low Quality: <b>$totalQual</b></span>
<span class="listing-key snatched">Snatched: <b>$totalSnatched</b></span>
</div><br/> </div><br/>
<div class="float-left"> <div class="float-left">
Jump to Show Jump to Show
<select id="pickShow" class="form-control form-control-inline input-sm"> <select id="pickShow" class="form-control form-control-inline input-sm">
#for $curShow in sorted($sickbeard.showList, key = operator.attrgetter('name')): #for $curShow in sorted($sickbeard.showList, key = operator.attrgetter('name')):
#if $showCounts[$curShow.indexerid][$Overview.QUAL] + $showCounts[$curShow.indexerid][$Overview.WANTED] != 0: #if $showCounts[$curShow.indexerid][$Overview.QUAL] + $showCounts[$curShow.indexerid][$Overview.WANTED] + $showCounts[$curShow.indexerid][$Overview.SNATCHED] != 0:
<option value="$curShow.indexerid">$curShow.name</option> <option value="$curShow.indexerid">$curShow.name</option>
#end if #end if
#end for #end for
@ -72,7 +75,7 @@ Jump to Show
#for $curShow in sorted($sickbeard.showList, key = operator.attrgetter('name')): #for $curShow in sorted($sickbeard.showList, key = operator.attrgetter('name')):
#if $showCounts[$curShow.indexerid][$Overview.QUAL] + $showCounts[$curShow.indexerid][$Overview.WANTED] == 0: #if $showCounts[$curShow.indexerid][$Overview.QUAL] + $showCounts[$curShow.indexerid][$Overview.WANTED] + $showCounts[$curShow.indexerid][$Overview.SNATCHED] == 0:
#continue #continue
#end if #end if
@ -82,6 +85,7 @@ Jump to Show
<div class="pull-right"> <div class="pull-right">
<span class="listing-key wanted">Wanted: <b>$showCounts[$curShow.indexerid][$Overview.WANTED]</b></span> <span class="listing-key wanted">Wanted: <b>$showCounts[$curShow.indexerid][$Overview.WANTED]</b></span>
<span class="listing-key qual">Low Quality: <b>$showCounts[$curShow.indexerid][$Overview.QUAL]</b></span> <span class="listing-key qual">Low Quality: <b>$showCounts[$curShow.indexerid][$Overview.QUAL]</b></span>
<span class="listing-key snatched">Snatched: <b>$showCounts[$curShow.indexerid][$Overview.SNATCHED]</b></span>
<a class="btn btn-inline forceBacklog" href="$sbRoot/manage/backlogShow?indexer_id=$curShow.indexerid"><i class="icon-play-circle icon-white"></i> Force Backlog</a> <a class="btn btn-inline forceBacklog" href="$sbRoot/manage/backlogShow?indexer_id=$curShow.indexerid"><i class="icon-play-circle icon-white"></i> Force Backlog</a>
</div> </div>
</td> </td>
@ -97,7 +101,7 @@ Jump to Show
#continue #continue
#end try #end try
#if $overview not in ($Overview.QUAL, $Overview.WANTED): #if $overview not in ($Overview.QUAL, $Overview.WANTED, $Overview.SNATCHED):
#continue #continue
#end if #end if

View File

@ -14,9 +14,9 @@
$.each(subtitles,function(index, language){ $.each(subtitles,function(index, language){
if (language != "" && language != "und") { if (language != "" && language != "und") {
if (index != subtitles.length - 1) { if (index != subtitles.length - 1) {
subtitles_td.append($("<img/>").attr({"src": sbRoot+"/images/flags/"+language+".png", "alt": language, "width": 16, "height": 11}).css({'padding-right' : '6px','padding-bottom' : '4px'})); subtitles_td.append($("<img/>").attr({"src": sbRoot+"/images/flags/"+language+".png", "alt": language, "width": 16, "height": 11}));
} else { } else {
subtitles_td.append($("<img/>").attr({"src": sbRoot+"/images/flags/"+language+".png", "alt": language, "width": 16, "height": 11}).css({'padding-bottom' : '4px'})); subtitles_td.append($("<img/>").attr({"src": sbRoot+"/images/flags/"+language+".png", "alt": language, "width": 16, "height": 11}));
} }
} }
}); });

View File

@ -102,7 +102,7 @@ $(document).ready(function(){
$('#boxcar2_accesstoken').removeClass('warning'); $('#boxcar2_accesstoken').removeClass('warning');
$(this).prop('disabled', true); $(this).prop('disabled', true);
$('#testBoxcar2-result').html(loading); $('#testBoxcar2-result').html(loading);
$.get(sbRoot + '/home/testBoxcar2', {'accessToken': boxcar2_accesstoken}) $.get(sbRoot + '/home/testBoxcar2', {'accesstoken': boxcar2_accesstoken})
.done(function (data) { .done(function (data) {
$('#testBoxcar2-result').html(data); $('#testBoxcar2-result').html(data);
$('#testBoxcar2').prop('disabled', false); $('#testBoxcar2').prop('disabled', false);
@ -426,20 +426,25 @@ $(document).ready(function(){
return false; return false;
} }
var current_pushbullet_device = $("#pushbullet_device").val();
$.get(sbRoot + "/home/getPushbulletDevices", {'api': pushbullet_api}, $.get(sbRoot + "/home/getPushbulletDevices", {'api': pushbullet_api},
function (data) { function (data) {
var devices = jQuery.parseJSON(data).devices; var devices = jQuery.parseJSON(data).devices;
var current_pushbullet_device = $("#pushbullet_device").val();
$("#pushbullet_device_list").html(''); $("#pushbullet_device_list").html('');
for (var i = 0; i < devices.length; i++) { for (var i = 0; i < devices.length; i++) {
if(devices[i].active == true) { if(devices[i].active == true) {
if(current_pushbullet_device == devices[i].iden) { if(current_pushbullet_device == devices[i].iden) {
$("#pushbullet_device_list").append('<option value="'+devices[i].iden+'" selected>' + devices[i].nickname + '</option>') $("#pushbullet_device_list").append('<option value="'+devices[i].iden+'" selected>' + devices[i].nickname + '</option>');
} else { } else {
$("#pushbullet_device_list").append('<option value="'+devices[i].iden+'">' + devices[i].nickname + '</option>') $("#pushbullet_device_list").append('<option value="'+devices[i].iden+'">' + devices[i].nickname + '</option>');
} }
} }
} }
if (current_pushbullet_device == "") {
$("#pushbullet_device_list").prepend('<option value="" selected>All devices</option>');
} else {
$("#pushbullet_device_list").prepend('<option value="">All devices</option>');
}
if(msg) { if(msg) {
$('#testPushbullet-result').html(msg); $('#testPushbullet-result').html(msg);
} }

View File

@ -204,7 +204,7 @@ $(document).ready(function(){
$(this).getCategories(isDefault, data); $(this).getCategories(isDefault, data);
} }
else { else {
updateNewznabCaps( null, data ); $(this).updateNewznabCaps( null, data );
} }
} }
} }
@ -579,4 +579,4 @@ $(document).ready(function(){
$("#provider_order_list").disableSelection(); $("#provider_order_list").disableSelection();
}); });

View File

@ -69,6 +69,9 @@ $(document).ready(function(){
$(host_desc_rtorrent).hide(); $(host_desc_rtorrent).hide();
$(host_desc_torrent).show(); $(host_desc_torrent).show();
$(torrent_verify_cert_option).hide(); $(torrent_verify_cert_option).hide();
$(torrent_verify_deluge).hide();
$(torrent_verify_rtorrent).hide();
$(torrent_auth_type).hide();
$(torrent_path_option).show(); $(torrent_path_option).show();
$(torrent_path_option).find('.fileBrowser').show(); $(torrent_path_option).find('.fileBrowser').show();
$(torrent_seed_time_option).hide(); $(torrent_seed_time_option).hide();
@ -83,6 +86,7 @@ $(document).ready(function(){
client = 'uTorrent'; client = 'uTorrent';
$(torrent_path_option).hide(); $(torrent_path_option).hide();
$(torrent_seed_time_option).show(); $(torrent_seed_time_option).show();
$('#host_desc_torrent').text('URL to your uTorrent client (e.g. http://localhost:8000)');
} else if ('transmission' == selectedProvider){ } else if ('transmission' == selectedProvider){
client = 'Transmission'; client = 'Transmission';
$(torrent_seed_time_option).show(); $(torrent_seed_time_option).show();
@ -90,12 +94,16 @@ $(document).ready(function(){
$(torrent_label_option).hide(); $(torrent_label_option).hide();
$(torrent_label_anime_option).hide(); $(torrent_label_anime_option).hide();
$(torrent_rpcurl_option).show(); $(torrent_rpcurl_option).show();
$('#host_desc_torrent').text('URL to your Transmission client (e.g. http://localhost:9091)');
//$('#directory_title').text(client + directory); //$('#directory_title').text(client + directory);
} else if ('deluge' == selectedProvider){ } else if ('deluge' == selectedProvider){
client = 'Deluge'; client = 'Deluge';
$(torrent_verify_cert_option).show(); $(torrent_verify_cert_option).show();
$(torrent_verify_deluge).show();
$(torrent_verify_rtorrent).hide();
$(label_warning_deluge).show(); $(label_warning_deluge).show();
$(label_anime_warning_deluge).show(); $(label_anime_warning_deluge).show();
$('#host_desc_torrent').text('URL to your Deluge client (e.g. http://localhost:8112)');
//$('#directory_title').text(client + directory); //$('#directory_title').text(client + directory);
} else if ('download_station' == selectedProvider){ } else if ('download_station' == selectedProvider){
client = 'Synology DS'; client = 'Synology DS';
@ -103,13 +111,17 @@ $(document).ready(function(){
$(torrent_label_anime_option).hide(); $(torrent_label_anime_option).hide();
$('#torrent_paused_option').hide(); $('#torrent_paused_option').hide();
$(torrent_path_option).find('.fileBrowser').hide(); $(torrent_path_option).find('.fileBrowser').hide();
$('#host_desc_torrent').text('URL to your Synology DS client (e.g. http://localhost:5000)');
//$('#directory_title').text(client + directory); //$('#directory_title').text(client + directory);
$(path_synology).show(); $(path_synology).show();
} else if ('rtorrent' == selectedProvider){ } else if ('rtorrent' == selectedProvider){
client = 'rTorrent'; client = 'rTorrent';
$(host_desc_torrent).hide();
$(host_desc_rtorrent).show();
$(torrent_paused_option).hide(); $(torrent_paused_option).hide();
$('#host_desc_torrent').text('URL to your rTorrent client (e.g. scgi://localhost:5000 </br> or https://localhost/rutorrent/plugins/httprpc/action.php)');
$(torrent_verify_cert_option).show();
$(torrent_verify_deluge).hide();
$(torrent_verify_rtorrent).show();
$(torrent_auth_type).show();
//$('#directory_title').text(client + directory); //$('#directory_title').text(client + directory);
} }
$('#host_title').text(client + host); $('#host_title').text(client + host);

View File

@ -51,7 +51,7 @@ $(document).ready(function () {
}, },
success: function (data) { success: function (data) {
var firstResult = true; var firstResult = true;
var resultStr = '<fieldset>\n<legend>Search Results:</legend>\n'; var resultStr = '<fieldset>\n<legend class="legendStep">Search Results:</legend>\n';
var checked = ''; var checked = '';
if (data.results.length === 0) { if (data.results.length === 0) {
@ -68,7 +68,7 @@ $(document).ready(function () {
var whichSeries = obj.join('|'); var whichSeries = obj.join('|');
resultStr += '<input type="radio" id="whichSeries" name="whichSeries" value="' + whichSeries + '"' + checked + ' /> '; resultStr += '<input type="radio" id="whichSeries" name="whichSeries" value="' + whichSeries.replace(/"/g, "") + '"' + checked + ' /> ';
if (data.langid && data.langid != "") { if (data.langid && data.langid != "") {
resultStr += '<a href="' + anonURL + obj[2] + obj[3] + '&lid=' + data.langid + '" onclick=\"window.open(this.href, \'_blank\'); return false;\" ><b>' + obj[4] + '</b></a>'; resultStr += '<a href="' + anonURL + obj[2] + obj[3] + '&lid=' + data.langid + '" onclick=\"window.open(this.href, \'_blank\'); return false;\" ><b>' + obj[4] + '</b></a>';
} else { } else {

View File

@ -144,7 +144,7 @@ case "$1" in
stop_sickbeard stop_sickbeard
sleep 2 sleep 2
start_sickbeard start_sickbeard
return $? exit $?
;; ;;
status) status)
status_of_proc -p "$PID_FILE" "$DAEMON" "$DESC" status_of_proc -p "$PID_FILE" "$DAEMON" "$DESC"

View File

@ -58,7 +58,11 @@ class CacheControlAdapter(HTTPAdapter):
response = cached_response response = cached_response
else: else:
# try to cache the response # try to cache the response
self.controller.cache_response(request, response) try:
self.controller.cache_response(request, response)
except Exception as e:
# Failed to cache the results
pass
resp = super(CacheControlAdapter, self).build_response( resp = super(CacheControlAdapter, self).build_response(
request, response request, response

View File

@ -5,6 +5,7 @@ import os
from . import (LockBase, LockFailed, NotLocked, NotMyLock, LockTimeout, from . import (LockBase, LockFailed, NotLocked, NotMyLock, LockTimeout,
AlreadyLocked) AlreadyLocked)
import errno
class LinkLockFile(LockBase): class LinkLockFile(LockBase):
"""Lock access to a file using atomic property of link(2). """Lock access to a file using atomic property of link(2).
@ -28,7 +29,9 @@ class LinkLockFile(LockBase):
# Try and create a hard link to it. # Try and create a hard link to it.
try: try:
os.link(self.unique_name, self.lock_file) os.link(self.unique_name, self.lock_file)
except OSError: except OSError as e:
if e.errno == errno.ENOSYS:
raise LockFailed("%s" % e.strerror)
# Link creation failed. Maybe we've double-locked? # Link creation failed. Maybe we've double-locked?
nlinks = os.stat(self.unique_name).st_nlink nlinks = os.stat(self.unique_name).st_nlink
if nlinks == 2: if nlinks == 2:

View File

@ -13,7 +13,7 @@ Requests is an HTTP library, written in Python, for human beings. Basic GET
usage: usage:
>>> import requests >>> import requests
>>> r = requests.get('http://python.org') >>> r = requests.get('https://www.python.org')
>>> r.status_code >>> r.status_code
200 200
>>> 'Python is a programming language' in r.content >>> 'Python is a programming language' in r.content
@ -22,7 +22,7 @@ usage:
... or POST: ... or POST:
>>> payload = dict(key1='value1', key2='value2') >>> payload = dict(key1='value1', key2='value2')
>>> r = requests.post("http://httpbin.org/post", data=payload) >>> r = requests.post('http://httpbin.org/post', data=payload)
>>> print(r.text) >>> print(r.text)
{ {
... ...
@ -36,17 +36,17 @@ usage:
The other HTTP methods are supported - see `requests.api`. Full documentation The other HTTP methods are supported - see `requests.api`. Full documentation
is at <http://python-requests.org>. is at <http://python-requests.org>.
:copyright: (c) 2014 by Kenneth Reitz. :copyright: (c) 2015 by Kenneth Reitz.
:license: Apache 2.0, see LICENSE for more details. :license: Apache 2.0, see LICENSE for more details.
""" """
__title__ = 'requests' __title__ = 'requests'
__version__ = '2.3.0' __version__ = '2.5.1'
__build__ = 0x020300 __build__ = 0x020501
__author__ = 'Kenneth Reitz' __author__ = 'Kenneth Reitz'
__license__ = 'Apache 2.0' __license__ = 'Apache 2.0'
__copyright__ = 'Copyright 2014 Kenneth Reitz' __copyright__ = 'Copyright 2015 Kenneth Reitz'
# Attempt to enable urllib3's SNI support, if possible # Attempt to enable urllib3's SNI support, if possible
try: try:

View File

@ -9,23 +9,27 @@ and maintain connections.
""" """
import socket import socket
import copy
from .models import Response from .models import Response
from .packages.urllib3 import Retry
from .packages.urllib3.poolmanager import PoolManager, proxy_from_url from .packages.urllib3.poolmanager import PoolManager, proxy_from_url
from .packages.urllib3.response import HTTPResponse from .packages.urllib3.response import HTTPResponse
from .packages.urllib3.util import Timeout as TimeoutSauce from .packages.urllib3.util import Timeout as TimeoutSauce
from .compat import urlparse, basestring, urldefrag, unquote from .compat import urlparse, basestring
from .utils import (DEFAULT_CA_BUNDLE_PATH, get_encoding_from_headers, from .utils import (DEFAULT_CA_BUNDLE_PATH, get_encoding_from_headers,
except_on_missing_scheme, get_auth_from_url) prepend_scheme_if_needed, get_auth_from_url, urldefragauth)
from .structures import CaseInsensitiveDict from .structures import CaseInsensitiveDict
from .packages.urllib3.exceptions import MaxRetryError from .packages.urllib3.exceptions import ConnectTimeoutError
from .packages.urllib3.exceptions import TimeoutError
from .packages.urllib3.exceptions import SSLError as _SSLError
from .packages.urllib3.exceptions import HTTPError as _HTTPError from .packages.urllib3.exceptions import HTTPError as _HTTPError
from .packages.urllib3.exceptions import MaxRetryError
from .packages.urllib3.exceptions import ProxyError as _ProxyError from .packages.urllib3.exceptions import ProxyError as _ProxyError
from .packages.urllib3.exceptions import ProtocolError
from .packages.urllib3.exceptions import ReadTimeoutError
from .packages.urllib3.exceptions import SSLError as _SSLError
from .packages.urllib3.exceptions import ResponseError
from .cookies import extract_cookies_to_jar from .cookies import extract_cookies_to_jar
from .exceptions import ConnectionError, Timeout, SSLError, ProxyError from .exceptions import (ConnectionError, ConnectTimeout, ReadTimeout, SSLError,
ProxyError, RetryError)
from .auth import _basic_auth_str from .auth import _basic_auth_str
DEFAULT_POOLBLOCK = False DEFAULT_POOLBLOCK = False
@ -57,13 +61,17 @@ class HTTPAdapter(BaseAdapter):
:param pool_connections: The number of urllib3 connection pools to cache. :param pool_connections: The number of urllib3 connection pools to cache.
:param pool_maxsize: The maximum number of connections to save in the pool. :param pool_maxsize: The maximum number of connections to save in the pool.
:param int max_retries: The maximum number of retries each connection :param int max_retries: The maximum number of retries each connection
should attempt. Note, this applies only to failed connections and should attempt. Note, this applies only to failed DNS lookups, socket
timeouts, never to requests where the server returns a response. connections and connection timeouts, never to requests where data has
made it to the server. By default, Requests does not retry failed
connections. If you need granular control over the conditions under
which we retry a request, import urllib3's ``Retry`` class and pass
that instead.
:param pool_block: Whether the connection pool should block for connections. :param pool_block: Whether the connection pool should block for connections.
Usage:: Usage::
>>> import lib.requests >>> import requests
>>> s = requests.Session() >>> s = requests.Session()
>>> a = requests.adapters.HTTPAdapter(max_retries=3) >>> a = requests.adapters.HTTPAdapter(max_retries=3)
>>> s.mount('http://', a) >>> s.mount('http://', a)
@ -74,7 +82,10 @@ class HTTPAdapter(BaseAdapter):
def __init__(self, pool_connections=DEFAULT_POOLSIZE, def __init__(self, pool_connections=DEFAULT_POOLSIZE,
pool_maxsize=DEFAULT_POOLSIZE, max_retries=DEFAULT_RETRIES, pool_maxsize=DEFAULT_POOLSIZE, max_retries=DEFAULT_RETRIES,
pool_block=DEFAULT_POOLBLOCK): pool_block=DEFAULT_POOLBLOCK):
self.max_retries = max_retries if max_retries == DEFAULT_RETRIES:
self.max_retries = Retry(0, read=False)
else:
self.max_retries = Retry.from_int(max_retries)
self.config = {} self.config = {}
self.proxy_manager = {} self.proxy_manager = {}
@ -102,14 +113,17 @@ class HTTPAdapter(BaseAdapter):
self.init_poolmanager(self._pool_connections, self._pool_maxsize, self.init_poolmanager(self._pool_connections, self._pool_maxsize,
block=self._pool_block) block=self._pool_block)
def init_poolmanager(self, connections, maxsize, block=DEFAULT_POOLBLOCK): def init_poolmanager(self, connections, maxsize, block=DEFAULT_POOLBLOCK, **pool_kwargs):
"""Initializes a urllib3 PoolManager. This method should not be called """Initializes a urllib3 PoolManager.
from user code, and is only exposed for use when subclassing the
This method should not be called from user code, and is only
exposed for use when subclassing the
:class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
:param connections: The number of urllib3 connection pools to cache. :param connections: The number of urllib3 connection pools to cache.
:param maxsize: The maximum number of connections to save in the pool. :param maxsize: The maximum number of connections to save in the pool.
:param block: Block when no free connections are available. :param block: Block when no free connections are available.
:param pool_kwargs: Extra keyword arguments used to initialize the Pool Manager.
""" """
# save these values for pickling # save these values for pickling
self._pool_connections = connections self._pool_connections = connections
@ -117,7 +131,30 @@ class HTTPAdapter(BaseAdapter):
self._pool_block = block self._pool_block = block
self.poolmanager = PoolManager(num_pools=connections, maxsize=maxsize, self.poolmanager = PoolManager(num_pools=connections, maxsize=maxsize,
block=block) block=block, strict=True, **pool_kwargs)
def proxy_manager_for(self, proxy, **proxy_kwargs):
"""Return urllib3 ProxyManager for the given proxy.
This method should not be called from user code, and is only
exposed for use when subclassing the
:class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
:param proxy: The proxy to return a urllib3 ProxyManager for.
:param proxy_kwargs: Extra keyword arguments used to configure the Proxy Manager.
:returns: ProxyManager
"""
if not proxy in self.proxy_manager:
proxy_headers = self.proxy_headers(proxy)
self.proxy_manager[proxy] = proxy_from_url(
proxy,
proxy_headers=proxy_headers,
num_pools=self._pool_connections,
maxsize=self._pool_maxsize,
block=self._pool_block,
**proxy_kwargs)
return self.proxy_manager[proxy]
def cert_verify(self, conn, url, verify, cert): def cert_verify(self, conn, url, verify, cert):
"""Verify a SSL certificate. This method should not be called from user """Verify a SSL certificate. This method should not be called from user
@ -204,18 +241,9 @@ class HTTPAdapter(BaseAdapter):
proxy = proxies.get(urlparse(url.lower()).scheme) proxy = proxies.get(urlparse(url.lower()).scheme)
if proxy: if proxy:
except_on_missing_scheme(proxy) proxy = prepend_scheme_if_needed(proxy, 'http')
proxy_headers = self.proxy_headers(proxy) proxy_manager = self.proxy_manager_for(proxy)
conn = proxy_manager.connection_from_url(url)
if not proxy in self.proxy_manager:
self.proxy_manager[proxy] = proxy_from_url(
proxy,
proxy_headers=proxy_headers,
num_pools=self._pool_connections,
maxsize=self._pool_maxsize,
block=self._pool_block)
conn = self.proxy_manager[proxy].connection_from_url(url)
else: else:
# Only scheme should be lower case # Only scheme should be lower case
parsed = urlparse(url) parsed = urlparse(url)
@ -250,7 +278,7 @@ class HTTPAdapter(BaseAdapter):
proxy = proxies.get(scheme) proxy = proxies.get(scheme)
if proxy and scheme != 'https': if proxy and scheme != 'https':
url, _ = urldefrag(request.url) url = urldefragauth(request.url)
else: else:
url = request.path_url url = request.path_url
@ -297,7 +325,10 @@ class HTTPAdapter(BaseAdapter):
:param request: The :class:`PreparedRequest <PreparedRequest>` being sent. :param request: The :class:`PreparedRequest <PreparedRequest>` being sent.
:param stream: (optional) Whether to stream the request content. :param stream: (optional) Whether to stream the request content.
:param timeout: (optional) The timeout on the request. :param timeout: (optional) How long to wait for the server to send
data before giving up, as a float, or a (`connect timeout, read
timeout <user/advanced.html#timeouts>`_) tuple.
:type timeout: float or tuple
:param verify: (optional) Whether to verify SSL certificates. :param verify: (optional) Whether to verify SSL certificates.
:param cert: (optional) Any user-provided SSL certificate to be trusted. :param cert: (optional) Any user-provided SSL certificate to be trusted.
:param proxies: (optional) The proxies dictionary to apply to the request. :param proxies: (optional) The proxies dictionary to apply to the request.
@ -311,7 +342,18 @@ class HTTPAdapter(BaseAdapter):
chunked = not (request.body is None or 'Content-Length' in request.headers) chunked = not (request.body is None or 'Content-Length' in request.headers)
timeout = TimeoutSauce(connect=timeout, read=timeout) if isinstance(timeout, tuple):
try:
connect, read = timeout
timeout = TimeoutSauce(connect=connect, read=read)
except ValueError as e:
# this may raise a string formatting error.
err = ("Invalid timeout {0}. Pass a (connect, read) "
"timeout tuple, or a single float to set "
"both timeouts to the same value".format(timeout))
raise ValueError(err)
else:
timeout = TimeoutSauce(connect=timeout, read=timeout)
try: try:
if not chunked: if not chunked:
@ -369,10 +411,16 @@ class HTTPAdapter(BaseAdapter):
# All is well, return the connection to the pool. # All is well, return the connection to the pool.
conn._put_conn(low_conn) conn._put_conn(low_conn)
except socket.error as sockerr: except (ProtocolError, socket.error) as err:
raise ConnectionError(sockerr, request=request) raise ConnectionError(err, request=request)
except MaxRetryError as e: except MaxRetryError as e:
if isinstance(e.reason, ConnectTimeoutError):
raise ConnectTimeout(e, request=request)
if isinstance(e.reason, ResponseError):
raise RetryError(e, request=request)
raise ConnectionError(e, request=request) raise ConnectionError(e, request=request)
except _ProxyError as e: except _ProxyError as e:
@ -381,14 +429,9 @@ class HTTPAdapter(BaseAdapter):
except (_SSLError, _HTTPError) as e: except (_SSLError, _HTTPError) as e:
if isinstance(e, _SSLError): if isinstance(e, _SSLError):
raise SSLError(e, request=request) raise SSLError(e, request=request)
elif isinstance(e, TimeoutError): elif isinstance(e, ReadTimeoutError):
raise Timeout(e, request=request) raise ReadTimeout(e, request=request)
else: else:
raise raise
r = self.build_response(request, resp) return self.build_response(request, resp)
if not stream:
r.content
return r

View File

@ -22,12 +22,17 @@ def request(method, url, **kwargs):
:param url: URL for the new :class:`Request` object. :param url: URL for the new :class:`Request` object.
:param params: (optional) Dictionary or bytes to be sent in the query string for the :class:`Request`. :param params: (optional) Dictionary or bytes to be sent in the query string for the :class:`Request`.
:param data: (optional) Dictionary, bytes, or file-like object to send in the body of the :class:`Request`. :param data: (optional) Dictionary, bytes, or file-like object to send in the body of the :class:`Request`.
:param json: (optional) json data to send in the body of the :class:`Request`.
:param headers: (optional) Dictionary of HTTP Headers to send with the :class:`Request`. :param headers: (optional) Dictionary of HTTP Headers to send with the :class:`Request`.
:param cookies: (optional) Dict or CookieJar object to send with the :class:`Request`. :param cookies: (optional) Dict or CookieJar object to send with the :class:`Request`.
:param files: (optional) Dictionary of 'name': file-like-objects (or {'name': ('filename', fileobj)}) for multipart encoding upload. :param files: (optional) Dictionary of ``'name': file-like-objects`` (or ``{'name': ('filename', fileobj)}``) for multipart encoding upload.
:param auth: (optional) Auth tuple to enable Basic/Digest/Custom HTTP Auth. :param auth: (optional) Auth tuple to enable Basic/Digest/Custom HTTP Auth.
:param timeout: (optional) Float describing the timeout of the request in seconds. :param timeout: (optional) How long to wait for the server to send data
before giving up, as a float, or a (`connect timeout, read timeout
<user/advanced.html#timeouts>`_) tuple.
:type timeout: float or tuple
:param allow_redirects: (optional) Boolean. Set to True if POST/PUT/DELETE redirect following is allowed. :param allow_redirects: (optional) Boolean. Set to True if POST/PUT/DELETE redirect following is allowed.
:type allow_redirects: bool
:param proxies: (optional) Dictionary mapping protocol to the URL of the proxy. :param proxies: (optional) Dictionary mapping protocol to the URL of the proxy.
:param verify: (optional) if ``True``, the SSL cert will be verified. A CA_BUNDLE path can also be provided. :param verify: (optional) if ``True``, the SSL cert will be verified. A CA_BUNDLE path can also be provided.
:param stream: (optional) if ``False``, the response content will be immediately downloaded. :param stream: (optional) if ``False``, the response content will be immediately downloaded.
@ -41,7 +46,12 @@ def request(method, url, **kwargs):
""" """
session = sessions.Session() session = sessions.Session()
return session.request(method=method, url=url, **kwargs) response = session.request(method=method, url=url, **kwargs)
# By explicitly closing the session, we avoid leaving sockets open which
# can trigger a ResourceWarning in some cases, and look like a memory leak
# in others.
session.close()
return response
def get(url, **kwargs): def get(url, **kwargs):
@ -77,15 +87,16 @@ def head(url, **kwargs):
return request('head', url, **kwargs) return request('head', url, **kwargs)
def post(url, data=None, **kwargs): def post(url, data=None, json=None, **kwargs):
"""Sends a POST request. Returns :class:`Response` object. """Sends a POST request. Returns :class:`Response` object.
:param url: URL for the new :class:`Request` object. :param url: URL for the new :class:`Request` object.
:param data: (optional) Dictionary, bytes, or file-like object to send in the body of the :class:`Request`. :param data: (optional) Dictionary, bytes, or file-like object to send in the body of the :class:`Request`.
:param json: (optional) json data to send in the body of the :class:`Request`.
:param \*\*kwargs: Optional arguments that ``request`` takes. :param \*\*kwargs: Optional arguments that ``request`` takes.
""" """
return request('post', url, data=data, **kwargs) return request('post', url, data=data, json=json, **kwargs)
def put(url, data=None, **kwargs): def put(url, data=None, **kwargs):

View File

@ -16,7 +16,8 @@ from base64 import b64encode
from .compat import urlparse, str from .compat import urlparse, str
from .cookies import extract_cookies_to_jar from .cookies import extract_cookies_to_jar
from .utils import parse_dict_header from .utils import parse_dict_header, to_native_string
from .status_codes import codes
CONTENT_TYPE_FORM_URLENCODED = 'application/x-www-form-urlencoded' CONTENT_TYPE_FORM_URLENCODED = 'application/x-www-form-urlencoded'
CONTENT_TYPE_MULTI_PART = 'multipart/form-data' CONTENT_TYPE_MULTI_PART = 'multipart/form-data'
@ -25,7 +26,11 @@ CONTENT_TYPE_MULTI_PART = 'multipart/form-data'
def _basic_auth_str(username, password): def _basic_auth_str(username, password):
"""Returns a Basic Auth string.""" """Returns a Basic Auth string."""
return 'Basic ' + b64encode(('%s:%s' % (username, password)).encode('latin1')).strip().decode('latin1') authstr = 'Basic ' + to_native_string(
b64encode(('%s:%s' % (username, password)).encode('latin1')).strip()
)
return authstr
class AuthBase(object): class AuthBase(object):
@ -62,6 +67,7 @@ class HTTPDigestAuth(AuthBase):
self.nonce_count = 0 self.nonce_count = 0
self.chal = {} self.chal = {}
self.pos = None self.pos = None
self.num_401_calls = 1
def build_digest_header(self, method, url): def build_digest_header(self, method, url):
@ -146,6 +152,11 @@ class HTTPDigestAuth(AuthBase):
return 'Digest %s' % (base) return 'Digest %s' % (base)
def handle_redirect(self, r, **kwargs):
"""Reset num_401_calls counter on redirects."""
if r.is_redirect:
self.num_401_calls = 1
def handle_401(self, r, **kwargs): def handle_401(self, r, **kwargs):
"""Takes the given response and tries digest-auth, if needed.""" """Takes the given response and tries digest-auth, if needed."""
@ -158,7 +169,7 @@ class HTTPDigestAuth(AuthBase):
if 'digest' in s_auth.lower() and num_401_calls < 2: if 'digest' in s_auth.lower() and num_401_calls < 2:
setattr(self, 'num_401_calls', num_401_calls + 1) self.num_401_calls += 1
pat = re.compile(r'digest ', flags=re.IGNORECASE) pat = re.compile(r'digest ', flags=re.IGNORECASE)
self.chal = parse_dict_header(pat.sub('', s_auth, count=1)) self.chal = parse_dict_header(pat.sub('', s_auth, count=1))
@ -178,7 +189,7 @@ class HTTPDigestAuth(AuthBase):
return _r return _r
setattr(self, 'num_401_calls', 1) self.num_401_calls = 1
return r return r
def __call__(self, r): def __call__(self, r):
@ -188,6 +199,11 @@ class HTTPDigestAuth(AuthBase):
try: try:
self.pos = r.body.tell() self.pos = r.body.tell()
except AttributeError: except AttributeError:
pass # In the case of HTTPDigestAuth being reused and the body of
# the previous request was a file-like object, pos has the
# file position of the previous body. Ensure it's set to
# None.
self.pos = None
r.register_hook('response', self.handle_401) r.register_hook('response', self.handle_401)
r.register_hook('response', self.handle_redirect)
return r return r

View File

@ -11,14 +11,15 @@ If you are packaging Requests, e.g., for a Linux distribution or a managed
environment, you can change the definition of where() to return a separately environment, you can change the definition of where() to return a separately
packaged CA bundle. packaged CA bundle.
""" """
import os.path import os.path
try:
def where(): from certifi import where
"""Return the preferred certificate bundle.""" except ImportError:
# vendored bundle inside Requests def where():
return os.path.join(os.path.dirname(__file__), 'cacert.pem') """Return the preferred certificate bundle."""
# vendored bundle inside Requests
return os.path.join(os.path.dirname(__file__), 'cacert.pem')
if __name__ == '__main__': if __name__ == '__main__':
print(where()) print(where())

View File

@ -75,7 +75,9 @@ is_solaris = ('solar==' in str(sys.platform).lower()) # Complete guess.
try: try:
import simplejson as json import simplejson as json
except ImportError: except (ImportError, SyntaxError):
# simplejson does not support Python 3.2, it throws a SyntaxError
# because of u'...' Unicode literals.
import json import json
# --------- # ---------
@ -90,7 +92,6 @@ if is_py2:
from Cookie import Morsel from Cookie import Morsel
from StringIO import StringIO from StringIO import StringIO
from .packages.urllib3.packages.ordered_dict import OrderedDict from .packages.urllib3.packages.ordered_dict import OrderedDict
from httplib import IncompleteRead
builtin_str = str builtin_str = str
bytes = str bytes = str
@ -106,7 +107,6 @@ elif is_py3:
from http.cookies import Morsel from http.cookies import Morsel
from io import StringIO from io import StringIO
from collections import OrderedDict from collections import OrderedDict
from http.client import IncompleteRead
builtin_str = str builtin_str = str
str = str str = str

View File

@ -157,26 +157,28 @@ class CookieConflictError(RuntimeError):
class RequestsCookieJar(cookielib.CookieJar, collections.MutableMapping): class RequestsCookieJar(cookielib.CookieJar, collections.MutableMapping):
"""Compatibility class; is a cookielib.CookieJar, but exposes a dict interface. """Compatibility class; is a cookielib.CookieJar, but exposes a dict
interface.
This is the CookieJar we create by default for requests and sessions that This is the CookieJar we create by default for requests and sessions that
don't specify one, since some clients may expect response.cookies and don't specify one, since some clients may expect response.cookies and
session.cookies to support dict operations. session.cookies to support dict operations.
Don't use the dict interface internally; it's just for compatibility with Requests does not use the dict interface internally; it's just for
with external client code. All `requests` code should work out of the box compatibility with external client code. All requests code should work
with externally provided instances of CookieJar, e.g., LWPCookieJar and out of the box with externally provided instances of ``CookieJar``, e.g.
FileCookieJar. ``LWPCookieJar`` and ``FileCookieJar``.
Caution: dictionary operations that are normally O(1) may be O(n).
Unlike a regular CookieJar, this class is pickleable. Unlike a regular CookieJar, this class is pickleable.
"""
.. warning:: dictionary operations that are normally O(1) may be O(n).
"""
def get(self, name, default=None, domain=None, path=None): def get(self, name, default=None, domain=None, path=None):
"""Dict-like get() that also supports optional domain and path args in """Dict-like get() that also supports optional domain and path args in
order to resolve naming collisions from using one cookie jar over order to resolve naming collisions from using one cookie jar over
multiple domains. Caution: operation is O(n), not O(1).""" multiple domains.
.. warning:: operation is O(n), not O(1)."""
try: try:
return self._find_no_duplicates(name, domain, path) return self._find_no_duplicates(name, domain, path)
except KeyError: except KeyError:
@ -199,37 +201,38 @@ class RequestsCookieJar(cookielib.CookieJar, collections.MutableMapping):
return c return c
def iterkeys(self): def iterkeys(self):
"""Dict-like iterkeys() that returns an iterator of names of cookies from the jar. """Dict-like iterkeys() that returns an iterator of names of cookies
See itervalues() and iteritems().""" from the jar. See itervalues() and iteritems()."""
for cookie in iter(self): for cookie in iter(self):
yield cookie.name yield cookie.name
def keys(self): def keys(self):
"""Dict-like keys() that returns a list of names of cookies from the jar. """Dict-like keys() that returns a list of names of cookies from the
See values() and items().""" jar. See values() and items()."""
return list(self.iterkeys()) return list(self.iterkeys())
def itervalues(self): def itervalues(self):
"""Dict-like itervalues() that returns an iterator of values of cookies from the jar. """Dict-like itervalues() that returns an iterator of values of cookies
See iterkeys() and iteritems().""" from the jar. See iterkeys() and iteritems()."""
for cookie in iter(self): for cookie in iter(self):
yield cookie.value yield cookie.value
def values(self): def values(self):
"""Dict-like values() that returns a list of values of cookies from the jar. """Dict-like values() that returns a list of values of cookies from the
See keys() and items().""" jar. See keys() and items()."""
return list(self.itervalues()) return list(self.itervalues())
def iteritems(self): def iteritems(self):
"""Dict-like iteritems() that returns an iterator of name-value tuples from the jar. """Dict-like iteritems() that returns an iterator of name-value tuples
See iterkeys() and itervalues().""" from the jar. See iterkeys() and itervalues()."""
for cookie in iter(self): for cookie in iter(self):
yield cookie.name, cookie.value yield cookie.name, cookie.value
def items(self): def items(self):
"""Dict-like items() that returns a list of name-value tuples from the jar. """Dict-like items() that returns a list of name-value tuples from the
See keys() and values(). Allows client-code to call "dict(RequestsCookieJar) jar. See keys() and values(). Allows client-code to call
and get a vanilla python dict of key value pairs.""" ``dict(RequestsCookieJar)`` and get a vanilla python dict of key value
pairs."""
return list(self.iteritems()) return list(self.iteritems())
def list_domains(self): def list_domains(self):
@ -259,8 +262,9 @@ class RequestsCookieJar(cookielib.CookieJar, collections.MutableMapping):
return False # there is only one domain in jar return False # there is only one domain in jar
def get_dict(self, domain=None, path=None): def get_dict(self, domain=None, path=None):
"""Takes as an argument an optional domain and path and returns a plain old """Takes as an argument an optional domain and path and returns a plain
Python dict of name-value pairs of cookies that meet the requirements.""" old Python dict of name-value pairs of cookies that meet the
requirements."""
dictionary = {} dictionary = {}
for cookie in iter(self): for cookie in iter(self):
if (domain is None or cookie.domain == domain) and (path is None if (domain is None or cookie.domain == domain) and (path is None
@ -269,21 +273,24 @@ class RequestsCookieJar(cookielib.CookieJar, collections.MutableMapping):
return dictionary return dictionary
def __getitem__(self, name): def __getitem__(self, name):
"""Dict-like __getitem__() for compatibility with client code. Throws exception """Dict-like __getitem__() for compatibility with client code. Throws
if there are more than one cookie with name. In that case, use the more exception if there are more than one cookie with name. In that case,
explicit get() method instead. Caution: operation is O(n), not O(1).""" use the more explicit get() method instead.
.. warning:: operation is O(n), not O(1)."""
return self._find_no_duplicates(name) return self._find_no_duplicates(name)
def __setitem__(self, name, value): def __setitem__(self, name, value):
"""Dict-like __setitem__ for compatibility with client code. Throws exception """Dict-like __setitem__ for compatibility with client code. Throws
if there is already a cookie of that name in the jar. In that case, use the more exception if there is already a cookie of that name in the jar. In that
explicit set() method instead.""" case, use the more explicit set() method instead."""
self.set(name, value) self.set(name, value)
def __delitem__(self, name): def __delitem__(self, name):
"""Deletes a cookie given a name. Wraps cookielib.CookieJar's remove_cookie_by_name().""" """Deletes a cookie given a name. Wraps ``cookielib.CookieJar``'s
``remove_cookie_by_name()``."""
remove_cookie_by_name(self, name) remove_cookie_by_name(self, name)
def set_cookie(self, cookie, *args, **kwargs): def set_cookie(self, cookie, *args, **kwargs):
@ -300,10 +307,11 @@ class RequestsCookieJar(cookielib.CookieJar, collections.MutableMapping):
super(RequestsCookieJar, self).update(other) super(RequestsCookieJar, self).update(other)
def _find(self, name, domain=None, path=None): def _find(self, name, domain=None, path=None):
"""Requests uses this method internally to get cookie values. Takes as args name """Requests uses this method internally to get cookie values. Takes as
and optional domain and path. Returns a cookie.value. If there are conflicting cookies, args name and optional domain and path. Returns a cookie.value. If
_find arbitrarily chooses one. See _find_no_duplicates if you want an exception thrown there are conflicting cookies, _find arbitrarily chooses one. See
if there are conflicting cookies.""" _find_no_duplicates if you want an exception thrown if there are
conflicting cookies."""
for cookie in iter(self): for cookie in iter(self):
if cookie.name == name: if cookie.name == name:
if domain is None or cookie.domain == domain: if domain is None or cookie.domain == domain:
@ -313,10 +321,11 @@ class RequestsCookieJar(cookielib.CookieJar, collections.MutableMapping):
raise KeyError('name=%r, domain=%r, path=%r' % (name, domain, path)) raise KeyError('name=%r, domain=%r, path=%r' % (name, domain, path))
def _find_no_duplicates(self, name, domain=None, path=None): def _find_no_duplicates(self, name, domain=None, path=None):
"""__get_item__ and get call _find_no_duplicates -- never used in Requests internally. """Both ``__get_item__`` and ``get`` call this function: it's never
Takes as args name and optional domain and path. Returns a cookie.value. used elsewhere in Requests. Takes as args name and optional domain and
Throws KeyError if cookie is not found and CookieConflictError if there are path. Returns a cookie.value. Throws KeyError if cookie is not found
multiple cookies that match name and optionally domain and path.""" and CookieConflictError if there are multiple cookies that match name
and optionally domain and path."""
toReturn = None toReturn = None
for cookie in iter(self): for cookie in iter(self):
if cookie.name == name: if cookie.name == name:
@ -440,7 +449,7 @@ def merge_cookies(cookiejar, cookies):
""" """
if not isinstance(cookiejar, cookielib.CookieJar): if not isinstance(cookiejar, cookielib.CookieJar):
raise ValueError('You can only merge into CookieJar') raise ValueError('You can only merge into CookieJar')
if isinstance(cookies, dict): if isinstance(cookies, dict):
cookiejar = cookiejar_from_dict( cookiejar = cookiejar_from_dict(
cookies, cookiejar=cookiejar, overwrite=False) cookies, cookiejar=cookiejar, overwrite=False)

View File

@ -44,7 +44,23 @@ class SSLError(ConnectionError):
class Timeout(RequestException): class Timeout(RequestException):
"""The request timed out.""" """The request timed out.
Catching this error will catch both
:exc:`~requests.exceptions.ConnectTimeout` and
:exc:`~requests.exceptions.ReadTimeout` errors.
"""
class ConnectTimeout(ConnectionError, Timeout):
"""The request timed out while trying to connect to the remote server.
Requests that produced this error are safe to retry.
"""
class ReadTimeout(Timeout):
"""The server did not send any data in the allotted amount of time."""
class URLRequired(RequestException): class URLRequired(RequestException):
@ -73,3 +89,11 @@ class ChunkedEncodingError(RequestException):
class ContentDecodingError(RequestException, BaseHTTPError): class ContentDecodingError(RequestException, BaseHTTPError):
"""Failed to decode response content""" """Failed to decode response content"""
class StreamConsumedError(RequestException, TypeError):
"""The content for this response was already consumed"""
class RetryError(RequestException):
"""Custom retries logic failed"""

View File

@ -19,31 +19,35 @@ from .cookies import cookiejar_from_dict, get_cookie_header
from .packages.urllib3.fields import RequestField from .packages.urllib3.fields import RequestField
from .packages.urllib3.filepost import encode_multipart_formdata from .packages.urllib3.filepost import encode_multipart_formdata
from .packages.urllib3.util import parse_url from .packages.urllib3.util import parse_url
from .packages.urllib3.exceptions import DecodeError from .packages.urllib3.exceptions import (
DecodeError, ReadTimeoutError, ProtocolError, LocationParseError)
from .exceptions import ( from .exceptions import (
HTTPError, RequestException, MissingSchema, InvalidURL, HTTPError, MissingSchema, InvalidURL, ChunkedEncodingError,
ChunkedEncodingError, ContentDecodingError) ContentDecodingError, ConnectionError, StreamConsumedError)
from .utils import ( from .utils import (
guess_filename, get_auth_from_url, requote_uri, guess_filename, get_auth_from_url, requote_uri,
stream_decode_response_unicode, to_key_val_list, parse_header_links, stream_decode_response_unicode, to_key_val_list, parse_header_links,
iter_slices, guess_json_utf, super_len, to_native_string) iter_slices, guess_json_utf, super_len, to_native_string)
from .compat import ( from .compat import (
cookielib, urlunparse, urlsplit, urlencode, str, bytes, StringIO, cookielib, urlunparse, urlsplit, urlencode, str, bytes, StringIO,
is_py2, chardet, json, builtin_str, basestring, IncompleteRead) is_py2, chardet, json, builtin_str, basestring)
from .status_codes import codes from .status_codes import codes
#: The set of HTTP status codes that indicate an automatically #: The set of HTTP status codes that indicate an automatically
#: processable redirect. #: processable redirect.
REDIRECT_STATI = ( REDIRECT_STATI = (
codes.moved, # 301 codes.moved, # 301
codes.found, # 302 codes.found, # 302
codes.other, # 303 codes.other, # 303
codes.temporary_moved, # 307 codes.temporary_redirect, # 307
codes.permanent_redirect, # 308
) )
DEFAULT_REDIRECT_LIMIT = 30 DEFAULT_REDIRECT_LIMIT = 30
CONTENT_CHUNK_SIZE = 10 * 1024 CONTENT_CHUNK_SIZE = 10 * 1024
ITER_CHUNK_SIZE = 512 ITER_CHUNK_SIZE = 512
json_dumps = json.dumps
class RequestEncodingMixin(object): class RequestEncodingMixin(object):
@property @property
@ -187,7 +191,8 @@ class Request(RequestHooksMixin):
:param url: URL to send. :param url: URL to send.
:param headers: dictionary of headers to send. :param headers: dictionary of headers to send.
:param files: dictionary of {filename: fileobject} files to multipart upload. :param files: dictionary of {filename: fileobject} files to multipart upload.
:param data: the body to attach the request. If a dictionary is provided, form-encoding will take place. :param data: the body to attach to the request. If a dictionary is provided, form-encoding will take place.
:param json: json for the body to attach to the request (if data is not specified).
:param params: dictionary of URL parameters to append to the URL. :param params: dictionary of URL parameters to append to the URL.
:param auth: Auth handler or (user, pass) tuple. :param auth: Auth handler or (user, pass) tuple.
:param cookies: dictionary or CookieJar of cookies to attach to this request. :param cookies: dictionary or CookieJar of cookies to attach to this request.
@ -210,7 +215,8 @@ class Request(RequestHooksMixin):
params=None, params=None,
auth=None, auth=None,
cookies=None, cookies=None,
hooks=None): hooks=None,
json=None):
# Default empty dicts for dict params. # Default empty dicts for dict params.
data = [] if data is None else data data = [] if data is None else data
@ -228,6 +234,7 @@ class Request(RequestHooksMixin):
self.headers = headers self.headers = headers
self.files = files self.files = files
self.data = data self.data = data
self.json = json
self.params = params self.params = params
self.auth = auth self.auth = auth
self.cookies = cookies self.cookies = cookies
@ -244,6 +251,7 @@ class Request(RequestHooksMixin):
headers=self.headers, headers=self.headers,
files=self.files, files=self.files,
data=self.data, data=self.data,
json=self.json,
params=self.params, params=self.params,
auth=self.auth, auth=self.auth,
cookies=self.cookies, cookies=self.cookies,
@ -287,14 +295,15 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
self.hooks = default_hooks() self.hooks = default_hooks()
def prepare(self, method=None, url=None, headers=None, files=None, def prepare(self, method=None, url=None, headers=None, files=None,
data=None, params=None, auth=None, cookies=None, hooks=None): data=None, params=None, auth=None, cookies=None, hooks=None,
json=None):
"""Prepares the entire request with the given parameters.""" """Prepares the entire request with the given parameters."""
self.prepare_method(method) self.prepare_method(method)
self.prepare_url(url, params) self.prepare_url(url, params)
self.prepare_headers(headers) self.prepare_headers(headers)
self.prepare_cookies(cookies) self.prepare_cookies(cookies)
self.prepare_body(data, files) self.prepare_body(data, files, json)
self.prepare_auth(auth, url) self.prepare_auth(auth, url)
# Note that prepare_auth must be last to enable authentication schemes # Note that prepare_auth must be last to enable authentication schemes
# such as OAuth to work on a fully prepared request. # such as OAuth to work on a fully prepared request.
@ -309,8 +318,8 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
p = PreparedRequest() p = PreparedRequest()
p.method = self.method p.method = self.method
p.url = self.url p.url = self.url
p.headers = self.headers.copy() p.headers = self.headers.copy() if self.headers is not None else None
p._cookies = self._cookies.copy() p._cookies = self._cookies.copy() if self._cookies is not None else None
p.body = self.body p.body = self.body
p.hooks = self.hooks p.hooks = self.hooks
return p return p
@ -324,21 +333,27 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
def prepare_url(self, url, params): def prepare_url(self, url, params):
"""Prepares the given HTTP URL.""" """Prepares the given HTTP URL."""
#: Accept objects that have string representations. #: Accept objects that have string representations.
try: #: We're unable to blindy call unicode/str functions
url = unicode(url) #: as this will include the bytestring indicator (b'')
except NameError: #: on python 3.x.
# We're on Python 3. #: https://github.com/kennethreitz/requests/pull/2238
url = str(url) if isinstance(url, bytes):
except UnicodeDecodeError: url = url.decode('utf8')
pass else:
url = unicode(url) if is_py2 else str(url)
# Don't do any URL preparation for oddball schemes # Don't do any URL preparation for non-HTTP schemes like `mailto`,
# `data` etc to work around exceptions from `url_parse`, which
# handles RFC 3986 only.
if ':' in url and not url.lower().startswith('http'): if ':' in url and not url.lower().startswith('http'):
self.url = url self.url = url
return return
# Support for unicode domain names and paths. # Support for unicode domain names and paths.
scheme, auth, host, port, path, query, fragment = parse_url(url) try:
scheme, auth, host, port, path, query, fragment = parse_url(url)
except LocationParseError as e:
raise InvalidURL(*e.args)
if not scheme: if not scheme:
raise MissingSchema("Invalid URL {0!r}: No schema supplied. " raise MissingSchema("Invalid URL {0!r}: No schema supplied. "
@ -395,7 +410,7 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
else: else:
self.headers = CaseInsensitiveDict() self.headers = CaseInsensitiveDict()
def prepare_body(self, data, files): def prepare_body(self, data, files, json=None):
"""Prepares the given HTTP body data.""" """Prepares the given HTTP body data."""
# Check if file, fo, generator, iterator. # Check if file, fo, generator, iterator.
@ -406,11 +421,13 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
content_type = None content_type = None
length = None length = None
if json is not None:
content_type = 'application/json'
body = json_dumps(json)
is_stream = all([ is_stream = all([
hasattr(data, '__iter__'), hasattr(data, '__iter__'),
not isinstance(data, basestring), not isinstance(data, (basestring, list, tuple, dict))
not isinstance(data, list),
not isinstance(data, dict)
]) ])
try: try:
@ -433,9 +450,9 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
if files: if files:
(body, content_type) = self._encode_files(files, data) (body, content_type) = self._encode_files(files, data)
else: else:
if data: if data and json is None:
body = self._encode_params(data) body = self._encode_params(data)
if isinstance(data, str) or isinstance(data, builtin_str) or hasattr(data, 'read'): if isinstance(data, basestring) or hasattr(data, 'read'):
content_type = None content_type = None
else: else:
content_type = 'application/x-www-form-urlencoded' content_type = 'application/x-www-form-urlencoded'
@ -443,7 +460,7 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
self.prepare_content_length(body) self.prepare_content_length(body)
# Add content-type if it wasn't explicitly provided. # Add content-type if it wasn't explicitly provided.
if (content_type) and (not 'content-type' in self.headers): if content_type and ('content-type' not in self.headers):
self.headers['Content-Type'] = content_type self.headers['Content-Type'] = content_type
self.body = body self.body = body
@ -457,7 +474,7 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
l = super_len(body) l = super_len(body)
if l: if l:
self.headers['Content-Length'] = builtin_str(l) self.headers['Content-Length'] = builtin_str(l)
elif self.method not in ('GET', 'HEAD'): elif (self.method not in ('GET', 'HEAD')) and (self.headers.get('Content-Length') is None):
self.headers['Content-Length'] = '0' self.headers['Content-Length'] = '0'
def prepare_auth(self, auth, url=''): def prepare_auth(self, auth, url=''):
@ -558,6 +575,10 @@ class Response(object):
#: and the arrival of the response (as a timedelta) #: and the arrival of the response (as a timedelta)
self.elapsed = datetime.timedelta(0) self.elapsed = datetime.timedelta(0)
#: The :class:`PreparedRequest <PreparedRequest>` object to which this
#: is a response.
self.request = None
def __getstate__(self): def __getstate__(self):
# Consume everything; accessing the content attribute makes # Consume everything; accessing the content attribute makes
# sure the content has been fully read. # sure the content has been fully read.
@ -596,7 +617,7 @@ class Response(object):
def ok(self): def ok(self):
try: try:
self.raise_for_status() self.raise_for_status()
except RequestException: except HTTPError:
return False return False
return True return True
@ -607,6 +628,11 @@ class Response(object):
""" """
return ('location' in self.headers and self.status_code in REDIRECT_STATI) return ('location' in self.headers and self.status_code in REDIRECT_STATI)
@property
def is_permanent_redirect(self):
"""True if this Response one of the permanant versions of redirect"""
return ('location' in self.headers and self.status_code in (codes.moved_permanently, codes.permanent_redirect))
@property @property
def apparent_encoding(self): def apparent_encoding(self):
"""The apparent encoding, provided by the chardet library""" """The apparent encoding, provided by the chardet library"""
@ -618,21 +644,22 @@ class Response(object):
large responses. The chunk size is the number of bytes it should large responses. The chunk size is the number of bytes it should
read into memory. This is not necessarily the length of each item read into memory. This is not necessarily the length of each item
returned as decoding can take place. returned as decoding can take place.
"""
if self._content_consumed:
# simulate reading small chunks of the content
return iter_slices(self._content, chunk_size)
If decode_unicode is True, content will be decoded using the best
available encoding based on the response.
"""
def generate(): def generate():
try: try:
# Special case for urllib3. # Special case for urllib3.
try: try:
for chunk in self.raw.stream(chunk_size, decode_content=True): for chunk in self.raw.stream(chunk_size, decode_content=True):
yield chunk yield chunk
except IncompleteRead as e: except ProtocolError as e:
raise ChunkedEncodingError(e) raise ChunkedEncodingError(e)
except DecodeError as e: except DecodeError as e:
raise ContentDecodingError(e) raise ContentDecodingError(e)
except ReadTimeoutError as e:
raise ConnectionError(e)
except AttributeError: except AttributeError:
# Standard file-like object. # Standard file-like object.
while True: while True:
@ -643,14 +670,21 @@ class Response(object):
self._content_consumed = True self._content_consumed = True
gen = generate() if self._content_consumed and isinstance(self._content, bool):
raise StreamConsumedError()
# simulate reading small chunks of the content
reused_chunks = iter_slices(self._content, chunk_size)
stream_chunks = generate()
chunks = reused_chunks if self._content_consumed else stream_chunks
if decode_unicode: if decode_unicode:
gen = stream_decode_response_unicode(gen, self) chunks = stream_decode_response_unicode(chunks, self)
return gen return chunks
def iter_lines(self, chunk_size=ITER_CHUNK_SIZE, decode_unicode=None): def iter_lines(self, chunk_size=ITER_CHUNK_SIZE, decode_unicode=None, delimiter=None):
"""Iterates over the response data, one line at a time. When """Iterates over the response data, one line at a time. When
stream=True is set on the request, this avoids reading the stream=True is set on the request, this avoids reading the
content at once into memory for large responses. content at once into memory for large responses.
@ -662,7 +696,11 @@ class Response(object):
if pending is not None: if pending is not None:
chunk = pending + chunk chunk = pending + chunk
lines = chunk.splitlines()
if delimiter:
lines = chunk.split(delimiter)
else:
lines = chunk.splitlines()
if lines and lines[-1] and chunk and lines[-1][-1] == chunk[-1]: if lines and lines[-1] and chunk and lines[-1][-1] == chunk[-1]:
pending = lines.pop() pending = lines.pop()
@ -793,8 +831,8 @@ class Response(object):
raise HTTPError(http_error_msg, response=self) raise HTTPError(http_error_msg, response=self)
def close(self): def close(self):
"""Closes the underlying file descriptor and releases the connection """Releases the connection back to the pool. Once this method has been
back to the pool. called the underlying ``raw`` object must not be accessed again.
*Note: Should not normally need to be called explicitly.* *Note: Should not normally need to be called explicitly.*
""" """

View File

@ -1,3 +1,95 @@
"""
Copyright (c) Donald Stufft, pip, and individual contributors
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
"""
from __future__ import absolute_import from __future__ import absolute_import
from . import urllib3 import sys
class VendorAlias(object):
def __init__(self):
self._vendor_name = __name__
self._vendor_pkg = self._vendor_name + "."
def find_module(self, fullname, path=None):
if fullname.startswith(self._vendor_pkg):
return self
def load_module(self, name):
# Ensure that this only works for the vendored name
if not name.startswith(self._vendor_pkg):
raise ImportError(
"Cannot import %s, must be a subpackage of '%s'." % (
name, self._vendor_name,
)
)
# Check to see if we already have this item in sys.modules, if we do
# then simply return that.
if name in sys.modules:
return sys.modules[name]
# Check to see if we can import the vendor name
try:
# We do this dance here because we want to try and import this
# module without hitting a recursion error because of a bunch of
# VendorAlias instances on sys.meta_path
real_meta_path = sys.meta_path[:]
try:
sys.meta_path = [
m for m in sys.meta_path
if not isinstance(m, VendorAlias)
]
__import__(name)
module = sys.modules[name]
finally:
# Re-add any additions to sys.meta_path that were made while
# during the import we just did, otherwise things like
# requests.packages.urllib3.poolmanager will fail.
for m in sys.meta_path:
if m not in real_meta_path:
real_meta_path.append(m)
# Restore sys.meta_path with any new items.
sys.meta_path = real_meta_path
except ImportError:
# We can't import the vendor name, so we'll try to import the
# "real" name.
real_name = name[len(self._vendor_pkg):]
try:
__import__(real_name)
module = sys.modules[real_name]
except ImportError:
raise ImportError("No module named '%s'" % (name,))
# If we've gotten here we've found the module we're looking for, either
# as part of our vendored package, or as the real name, so we'll add
# it to sys.modules as the vendored name so that we don't have to do
# the lookup again.
sys.modules[name] = module
# Finally, return the loaded module
return module
sys.meta_path.append(VendorAlias())

View File

@ -15,7 +15,7 @@
# 02110-1301 USA # 02110-1301 USA
######################### END LICENSE BLOCK ######################### ######################### END LICENSE BLOCK #########################
__version__ = "2.2.1" __version__ = "2.3.0"
from sys import version_info from sys import version_info

66
lib/requests/packages/chardet/chardetect.py Normal file → Executable file
View File

@ -12,34 +12,68 @@ Example::
If no paths are provided, it takes its input from stdin. If no paths are provided, it takes its input from stdin.
""" """
from io import open
from sys import argv, stdin
from __future__ import absolute_import, print_function, unicode_literals
import argparse
import sys
from io import open
from chardet import __version__
from chardet.universaldetector import UniversalDetector from chardet.universaldetector import UniversalDetector
def description_of(file, name='stdin'): def description_of(lines, name='stdin'):
"""Return a string describing the probable encoding of a file.""" """
Return a string describing the probable encoding of a file or
list of strings.
:param lines: The lines to get the encoding of.
:type lines: Iterable of bytes
:param name: Name of file or collection of lines
:type name: str
"""
u = UniversalDetector() u = UniversalDetector()
for line in file: for line in lines:
u.feed(line) u.feed(line)
u.close() u.close()
result = u.result result = u.result
if result['encoding']: if result['encoding']:
return '%s: %s with confidence %s' % (name, return '{0}: {1} with confidence {2}'.format(name, result['encoding'],
result['encoding'], result['confidence'])
result['confidence'])
else: else:
return '%s: no result' % name return '{0}: no result'.format(name)
def main(): def main(argv=None):
if len(argv) <= 1: '''
print(description_of(stdin)) Handles command line arguments and gets things started.
else:
for path in argv[1:]: :param argv: List of arguments, as if specified on the command-line.
with open(path, 'rb') as f: If None, ``sys.argv[1:]`` is used instead.
print(description_of(f, path)) :type argv: list of str
'''
# Get command line arguments
parser = argparse.ArgumentParser(
description="Takes one or more file paths and reports their detected \
encodings",
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
conflict_handler='resolve')
parser.add_argument('input',
help='File whose encoding we would like to determine.',
type=argparse.FileType('rb'), nargs='*',
default=[sys.stdin])
parser.add_argument('--version', action='version',
version='%(prog)s {0}'.format(__version__))
args = parser.parse_args(argv)
for f in args.input:
if f.isatty():
print("You are running chardetect interactively. Press " +
"CTRL-D twice at the start of a blank line to signal the " +
"end of your input. If you want help, run chardetect " +
"--help\n", file=sys.stderr)
print(description_of(f, f.name))
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -177,6 +177,12 @@ class JapaneseContextAnalysis:
return -1, 1 return -1, 1
class SJISContextAnalysis(JapaneseContextAnalysis): class SJISContextAnalysis(JapaneseContextAnalysis):
def __init__(self):
self.charset_name = "SHIFT_JIS"
def get_charset_name(self):
return self.charset_name
def get_order(self, aBuf): def get_order(self, aBuf):
if not aBuf: if not aBuf:
return -1, 1 return -1, 1
@ -184,6 +190,8 @@ class SJISContextAnalysis(JapaneseContextAnalysis):
first_char = wrap_ord(aBuf[0]) first_char = wrap_ord(aBuf[0])
if ((0x81 <= first_char <= 0x9F) or (0xE0 <= first_char <= 0xFC)): if ((0x81 <= first_char <= 0x9F) or (0xE0 <= first_char <= 0xFC)):
charLen = 2 charLen = 2
if (first_char == 0x87) or (0xFA <= first_char <= 0xFC):
self.charset_name = "CP932"
else: else:
charLen = 1 charLen = 1

View File

@ -129,11 +129,11 @@ class Latin1Prober(CharSetProber):
if total < 0.01: if total < 0.01:
confidence = 0.0 confidence = 0.0
else: else:
confidence = ((self._mFreqCounter[3] / total) confidence = ((self._mFreqCounter[3] - self._mFreqCounter[1] * 20.0)
- (self._mFreqCounter[1] * 20.0 / total)) / total)
if confidence < 0.0: if confidence < 0.0:
confidence = 0.0 confidence = 0.0
# lower the confidence of latin1 so that other more accurate # lower the confidence of latin1 so that other more accurate
# detector can take priority. # detector can take priority.
confidence = confidence * 0.5 confidence = confidence * 0.73
return confidence return confidence

View File

@ -353,7 +353,7 @@ SJIS_cls = (
2,2,2,2,2,2,2,2, # 68 - 6f 2,2,2,2,2,2,2,2, # 68 - 6f
2,2,2,2,2,2,2,2, # 70 - 77 2,2,2,2,2,2,2,2, # 70 - 77
2,2,2,2,2,2,2,1, # 78 - 7f 2,2,2,2,2,2,2,1, # 78 - 7f
3,3,3,3,3,3,3,3, # 80 - 87 3,3,3,3,3,2,2,3, # 80 - 87
3,3,3,3,3,3,3,3, # 88 - 8f 3,3,3,3,3,3,3,3, # 88 - 8f
3,3,3,3,3,3,3,3, # 90 - 97 3,3,3,3,3,3,3,3, # 90 - 97
3,3,3,3,3,3,3,3, # 98 - 9f 3,3,3,3,3,3,3,3, # 98 - 9f
@ -369,9 +369,8 @@ SJIS_cls = (
2,2,2,2,2,2,2,2, # d8 - df 2,2,2,2,2,2,2,2, # d8 - df
3,3,3,3,3,3,3,3, # e0 - e7 3,3,3,3,3,3,3,3, # e0 - e7
3,3,3,3,3,4,4,4, # e8 - ef 3,3,3,3,3,4,4,4, # e8 - ef
4,4,4,4,4,4,4,4, # f0 - f7 3,3,3,3,3,3,3,3, # f0 - f7
4,4,4,4,4,0,0,0 # f8 - ff 3,3,3,3,3,0,0,0) # f8 - ff
)
SJIS_st = ( SJIS_st = (
@ -571,5 +570,3 @@ UTF8SMModel = {'classTable': UTF8_cls,
'stateTable': UTF8_st, 'stateTable': UTF8_st,
'charLenTable': UTF8CharLenTable, 'charLenTable': UTF8CharLenTable,
'name': 'UTF-8'} 'name': 'UTF-8'}
# flake8: noqa

View File

@ -47,7 +47,7 @@ class SJISProber(MultiByteCharSetProber):
self._mContextAnalyzer.reset() self._mContextAnalyzer.reset()
def get_charset_name(self): def get_charset_name(self):
return "SHIFT_JIS" return self._mContextAnalyzer.get_charset_name()
def feed(self, aBuf): def feed(self, aBuf):
aLen = len(aBuf) aLen = len(aBuf)

View File

@ -71,9 +71,9 @@ class UniversalDetector:
if not self._mGotData: if not self._mGotData:
# If the data starts with BOM, we know it is UTF # If the data starts with BOM, we know it is UTF
if aBuf[:3] == codecs.BOM: if aBuf[:3] == codecs.BOM_UTF8:
# EF BB BF UTF-8 with BOM # EF BB BF UTF-8 with BOM
self.result = {'encoding': "UTF-8", 'confidence': 1.0} self.result = {'encoding': "UTF-8-SIG", 'confidence': 1.0}
elif aBuf[:4] == codecs.BOM_UTF32_LE: elif aBuf[:4] == codecs.BOM_UTF32_LE:
# FF FE 00 00 UTF-32, little-endian BOM # FF FE 00 00 UTF-32, little-endian BOM
self.result = {'encoding': "UTF-32LE", 'confidence': 1.0} self.result = {'encoding': "UTF-32LE", 'confidence': 1.0}

Some files were not shown because too many files have changed in this diff Show More