Merge remote-tracking branch 'upstream/develop' into develop
5
.gitignore
vendored
@ -37,6 +37,10 @@ tests/failed.db
|
||||
*.sw?
|
||||
Session.vim
|
||||
.ropeproject/*
|
||||
*.iml
|
||||
.idea
|
||||
*.ipr
|
||||
.settings/*
|
||||
|
||||
# OS generated files #
|
||||
######################
|
||||
@ -48,7 +52,6 @@ ehthumbs.db
|
||||
Thumbs.db
|
||||
.directory
|
||||
*~
|
||||
/.idea/
|
||||
*.torrent
|
||||
|
||||
# Unrar Executable #
|
||||
|
36
SickBeard.py
@ -50,6 +50,10 @@ sys.path.insert(1, os.path.abspath(os.path.join(os.path.dirname(__file__), 'lib'
|
||||
if sys.hexversion >= 0x020600F0:
|
||||
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 datetime
|
||||
import threading
|
||||
@ -258,12 +262,15 @@ class SickRage(object):
|
||||
os.chdir(sickbeard.DATA_DIR)
|
||||
|
||||
# Check if we need to perform a restore first
|
||||
restoreDir = os.path.join(sickbeard.DATA_DIR, 'restore')
|
||||
if self.consoleLogging and os.path.exists(restoreDir):
|
||||
if self.restore(restoreDir, sickbeard.DATA_DIR):
|
||||
sys.stdout.write("Restore successful...\n")
|
||||
else:
|
||||
sys.stdout.write("Restore FAILED!\n")
|
||||
try:
|
||||
restoreDir = os.path.join(sickbeard.DATA_DIR, 'restore')
|
||||
if self.consoleLogging and os.path.exists(restoreDir):
|
||||
if self.restoreDB(restoreDir, sickbeard.DATA_DIR):
|
||||
sys.stdout.write("Restore: restoring DB and config.ini successful...\n")
|
||||
else:
|
||||
sys.stdout.write("Restore: restoring DB and config.ini FAILED!\n")
|
||||
except Exception as e:
|
||||
sys.stdout.write("Restore: restoring DB and config.ini FAILED!\n")
|
||||
|
||||
# Load the config and publish it to the sickbeard package
|
||||
if self.consoleLogging and not os.path.isfile(sickbeard.CONFIG_FILE):
|
||||
@ -443,16 +450,17 @@ class SickRage(object):
|
||||
logger.ERROR)
|
||||
logger.log(traceback.format_exc(), logger.DEBUG)
|
||||
|
||||
def restore(self, srcDir, dstDir):
|
||||
def restoreDB(self, srcDir, dstDir):
|
||||
try:
|
||||
for file in os.listdir(srcDir):
|
||||
srcFile = os.path.join(srcDir, file)
|
||||
dstFile = os.path.join(dstDir, file)
|
||||
bakFile = os.path.join(dstDir, file + '.bak')
|
||||
shutil.move(dstFile, bakFile)
|
||||
shutil.move(srcFile, dstFile)
|
||||
filesList = ['sickbeard.db', 'config.ini', 'failed.db', 'cache.db']
|
||||
|
||||
os.rmdir(srcDir)
|
||||
for filename in filesList:
|
||||
srcFile = os.path.join(srcDir, filename)
|
||||
dstFile = os.path.join(dstDir, filename)
|
||||
bakFile = os.path.join(dstDir, '{0}.bak-{1}'.format(filename, datetime.datetime.strftime(datetime.datetime.now(), '%Y%m%d_%H%M%S')))
|
||||
if os.path.isfile(dstFile):
|
||||
shutil.move(dstFile, bakFile)
|
||||
shutil.move(srcFile, dstFile)
|
||||
return True
|
||||
except:
|
||||
return False
|
||||
|
@ -1,257 +1,257 @@
|
||||
.country-flag {
|
||||
width: 16px;
|
||||
height: 11px;
|
||||
background:url(images/country-flags.png) no-repeat
|
||||
}
|
||||
|
||||
.country-flag.flag-ad {background-position: -16px 0}
|
||||
.country-flag.flag-ae {background-position: -32px 0}
|
||||
.country-flag.flag-af {background-position: -48px 0}
|
||||
.country-flag.flag-ag {background-position: -64px 0}
|
||||
.country-flag.flag-ai {background-position: -80px 0}
|
||||
.country-flag.flag-al {background-position: -96px 0}
|
||||
.country-flag.flag-am {background-position: -112px 0}
|
||||
.country-flag.flag-an {background-position: -128px 0}
|
||||
.country-flag.flag-ao {background-position: -144px 0}
|
||||
.country-flag.flag-ar {background-position: -160px 0}
|
||||
.country-flag.flag-as {background-position: -176px 0}
|
||||
.country-flag.flag-at {background-position: -192px 0}
|
||||
.country-flag.flag-au {background-position: -208px 0}
|
||||
.country-flag.flag-aw {background-position: -224px 0}
|
||||
.country-flag.flag-az {background-position: -240px 0}
|
||||
.country-flag.flag-ba {background-position: 0 -11px}
|
||||
.country-flag.flag-bb {background-position: -16px -11px}
|
||||
.country-flag.flag-bd {background-position: -32px -11px}
|
||||
.country-flag.flag-be {background-position: -48px -11px}
|
||||
.country-flag.flag-bf {background-position: -64px -11px}
|
||||
.country-flag.flag-bg {background-position: -80px -11px}
|
||||
.country-flag.flag-bh {background-position: -96px -11px}
|
||||
.country-flag.flag-bi {background-position: -112px -11px}
|
||||
.country-flag.flag-bj {background-position: -128px -11px}
|
||||
.country-flag.flag-bm {background-position: -144px -11px}
|
||||
.country-flag.flag-bn {background-position: -160px -11px}
|
||||
.country-flag.flag-bo {background-position: -176px -11px}
|
||||
.country-flag.flag-br {background-position: -192px -11px}
|
||||
.country-flag.flag-bs {background-position: -208px -11px}
|
||||
.country-flag.flag-bt {background-position: -224px -11px}
|
||||
.country-flag.flag-bv {background-position: -240px -11px}
|
||||
.country-flag.flag-bw {background-position: 0 -22px}
|
||||
.country-flag.flag-by {background-position: -16px -22px}
|
||||
.country-flag.flag-bz {background-position: -32px -22px}
|
||||
.country-flag.flag-ca {background-position: -48px -22px}
|
||||
.country-flag.flag-catalonia {background-position: -64px -22px}
|
||||
.country-flag.flag-cd {background-position: -80px -22px}
|
||||
.country-flag.flag-cf {background-position: -96px -22px}
|
||||
.country-flag.flag-cg {background-position: -112px -22px}
|
||||
.country-flag.flag-ch {background-position: -128px -22px}
|
||||
.country-flag.flag-ci {background-position: -144px -22px}
|
||||
.country-flag.flag-ck {background-position: -160px -22px}
|
||||
.country-flag.flag-cl {background-position: -176px -22px}
|
||||
.country-flag.flag-cm {background-position: -192px -22px}
|
||||
.country-flag.flag-cn {background-position: -208px -22px}
|
||||
.country-flag.flag-co {background-position: -224px -22px}
|
||||
.country-flag.flag-cr {background-position: -240px -22px}
|
||||
.country-flag.flag-cu {background-position: 0 -33px}
|
||||
.country-flag.flag-cv {background-position: -16px -33px}
|
||||
.country-flag.flag-cw {background-position: -32px -33px}
|
||||
.country-flag.flag-cy {background-position: -48px -33px}
|
||||
.country-flag.flag-cz {background-position: -64px -33px}
|
||||
.country-flag.flag-de {background-position: -80px -33px}
|
||||
.country-flag.flag-dj {background-position: -96px -33px}
|
||||
.country-flag.flag-dk {background-position: -112px -33px}
|
||||
.country-flag.flag-dm {background-position: -128px -33px}
|
||||
.country-flag.flag-do {background-position: -144px -33px}
|
||||
.country-flag.flag-dz {background-position: -160px -33px}
|
||||
.country-flag.flag-ec {background-position: -176px -33px}
|
||||
.country-flag.flag-ee {background-position: -192px -33px}
|
||||
.country-flag.flag-eg {background-position: -208px -33px}
|
||||
.country-flag.flag-eh {background-position: -224px -33px}
|
||||
.country-flag.flag-england {background-position: -240px -33px}
|
||||
.country-flag.flag-er {background-position: 0 -44px}
|
||||
.country-flag.flag-es {background-position: -16px -44px}
|
||||
.country-flag.flag-et {background-position: -32px -44px}
|
||||
.country-flag.flag-eu {background-position: -48px -44px}
|
||||
.country-flag.flag-fi {background-position: -64px -44px}
|
||||
.country-flag.flag-fj {background-position: -80px -44px}
|
||||
.country-flag.flag-fk {background-position: -96px -44px}
|
||||
.country-flag.flag-fm {background-position: -112px -44px}
|
||||
.country-flag.flag-fo {background-position: -128px -44px}
|
||||
.country-flag.flag-fr {background-position: -144px -44px}
|
||||
.country-flag.flag-ga {background-position: -160px -44px}
|
||||
.country-flag.flag-gb {background-position: -176px -44px}
|
||||
.country-flag.flag-gd {background-position: -192px -44px}
|
||||
.country-flag.flag-ge {background-position: -208px -44px}
|
||||
.country-flag.flag-gf {background-position: -224px -44px}
|
||||
.country-flag.flag-gg {background-position: -240px -44px}
|
||||
.country-flag.flag-gh {background-position: 0 -55px}
|
||||
.country-flag.flag-gi {background-position: -16px -55px}
|
||||
.country-flag.flag-gl {background-position: -32px -55px}
|
||||
.country-flag.flag-gm {background-position: -48px -55px}
|
||||
.country-flag.flag-gn {background-position: -64px -55px}
|
||||
.country-flag.flag-gp {background-position: -80px -55px}
|
||||
.country-flag.flag-gq {background-position: -96px -55px}
|
||||
.country-flag.flag-gr {background-position: -112px -55px}
|
||||
.country-flag.flag-gs {background-position: -128px -55px}
|
||||
.country-flag.flag-gt {background-position: -144px -55px}
|
||||
.country-flag.flag-gu {background-position: -160px -55px}
|
||||
.country-flag.flag-gw {background-position: -176px -55px}
|
||||
.country-flag.flag-gy {background-position: -192px -55px}
|
||||
.country-flag.flag-hk {background-position: -208px -55px}
|
||||
.country-flag.flag-hm {background-position: -224px -55px}
|
||||
.country-flag.flag-hn {background-position: -240px -55px}
|
||||
.country-flag.flag-hr {background-position: 0 -66px}
|
||||
.country-flag.flag-ht {background-position: -16px -66px}
|
||||
.country-flag.flag-hu {background-position: -32px -66px}
|
||||
.country-flag.flag-ic {background-position: -48px -66px}
|
||||
.country-flag.flag-id {background-position: -64px -66px}
|
||||
.country-flag.flag-ie {background-position: -80px -66px}
|
||||
.country-flag.flag-il {background-position: -96px -66px}
|
||||
.country-flag.flag-im {background-position: -112px -66px}
|
||||
.country-flag.flag-in {background-position: -128px -66px}
|
||||
.country-flag.flag-io {background-position: -144px -66px}
|
||||
.country-flag.flag-iq {background-position: -160px -66px}
|
||||
.country-flag.flag-ir {background-position: -176px -66px}
|
||||
.country-flag.flag-is {background-position: -192px -66px}
|
||||
.country-flag.flag-it {background-position: -208px -66px}
|
||||
.country-flag.flag-je {background-position: -224px -66px}
|
||||
.country-flag.flag-jm {background-position: -240px -66px}
|
||||
.country-flag.flag-jo {background-position: 0 -77px}
|
||||
.country-flag.flag-jp {background-position: -16px -77px}
|
||||
.country-flag.flag-ke {background-position: -32px -77px}
|
||||
.country-flag.flag-kg {background-position: -48px -77px}
|
||||
.country-flag.flag-kh {background-position: -64px -77px}
|
||||
.country-flag.flag-ki {background-position: -80px -77px}
|
||||
.country-flag.flag-km {background-position: -96px -77px}
|
||||
.country-flag.flag-kn {background-position: -112px -77px}
|
||||
.country-flag.flag-kp {background-position: -128px -77px}
|
||||
.country-flag.flag-kr {background-position: -144px -77px}
|
||||
.country-flag.flag-kurdistan {background-position: -160px -77px}
|
||||
.country-flag.flag-kw {background-position: -176px -77px}
|
||||
.country-flag.flag-ky {background-position: -192px -77px}
|
||||
.country-flag.flag-kz {background-position: -208px -77px}
|
||||
.country-flag.flag-la {background-position: -224px -77px}
|
||||
.country-flag.flag-lb {background-position: -240px -77px}
|
||||
.country-flag.flag-lc {background-position: 0 -88px}
|
||||
.country-flag.flag-li {background-position: -16px -88px}
|
||||
.country-flag.flag-lk {background-position: -32px -88px}
|
||||
.country-flag.flag-lr {background-position: -48px -88px}
|
||||
.country-flag.flag-ls {background-position: -64px -88px}
|
||||
.country-flag.flag-lt {background-position: -80px -88px}
|
||||
.country-flag.flag-lu {background-position: -96px -88px}
|
||||
.country-flag.flag-lv {background-position: -112px -88px}
|
||||
.country-flag.flag-ly {background-position: -128px -88px}
|
||||
.country-flag.flag-ma {background-position: -144px -88px}
|
||||
.country-flag.flag-mc {background-position: -160px -88px}
|
||||
.country-flag.flag-md {background-position: -176px -88px}
|
||||
.country-flag.flag-me {background-position: -192px -88px}
|
||||
.country-flag.flag-mg {background-position: -208px -88px}
|
||||
.country-flag.flag-mh {background-position: -224px -88px}
|
||||
.country-flag.flag-mk {background-position: -240px -88px}
|
||||
.country-flag.flag-ml {background-position: 0 -99px}
|
||||
.country-flag.flag-mm {background-position: -16px -99px}
|
||||
.country-flag.flag-mn {background-position: -32px -99px}
|
||||
.country-flag.flag-mo {background-position: -48px -99px}
|
||||
.country-flag.flag-mp {background-position: -64px -99px}
|
||||
.country-flag.flag-mq {background-position: -80px -99px}
|
||||
.country-flag.flag-mr {background-position: -96px -99px}
|
||||
.country-flag.flag-ms {background-position: -112px -99px}
|
||||
.country-flag.flag-mt {background-position: -128px -99px}
|
||||
.country-flag.flag-mu {background-position: -144px -99px}
|
||||
.country-flag.flag-mv {background-position: -160px -99px}
|
||||
.country-flag.flag-mw {background-position: -176px -99px}
|
||||
.country-flag.flag-mx {background-position: -192px -99px}
|
||||
.country-flag.flag-my {background-position: -208px -99px}
|
||||
.country-flag.flag-mz {background-position: -224px -99px}
|
||||
.country-flag.flag-na {background-position: -240px -99px}
|
||||
.country-flag.flag-nc {background-position: 0 -110px}
|
||||
.country-flag.flag-ne {background-position: -16px -110px}
|
||||
.country-flag.flag-nf {background-position: -32px -110px}
|
||||
.country-flag.flag-ng {background-position: -48px -110px}
|
||||
.country-flag.flag-ni {background-position: -64px -110px}
|
||||
.country-flag.flag-nl {background-position: -80px -110px}
|
||||
.country-flag.flag-no {background-position: -96px -110px}
|
||||
.country-flag.flag-np {background-position: -112px -110px}
|
||||
.country-flag.flag-nr {background-position: -128px -110px}
|
||||
.country-flag.flag-nu {background-position: -144px -110px}
|
||||
.country-flag.flag-nz {background-position: -160px -110px}
|
||||
.country-flag.flag-om {background-position: -176px -110px}
|
||||
.country-flag.flag-pa {background-position: -192px -110px}
|
||||
.country-flag.flag-pe {background-position: -208px -110px}
|
||||
.country-flag.flag-pf {background-position: -224px -110px}
|
||||
.country-flag.flag-pg {background-position: -240px -110px}
|
||||
.country-flag.flag-ph {background-position: 0 -121px}
|
||||
.country-flag.flag-pk {background-position: -16px -121px}
|
||||
.country-flag.flag-pl {background-position: -32px -121px}
|
||||
.country-flag.flag-pm {background-position: -48px -121px}
|
||||
.country-flag.flag-pn {background-position: -64px -121px}
|
||||
.country-flag.flag-pr {background-position: -80px -121px}
|
||||
.country-flag.flag-ps {background-position: -96px -121px}
|
||||
.country-flag.flag-pt {background-position: -112px -121px}
|
||||
.country-flag.flag-pw {background-position: -128px -121px}
|
||||
.country-flag.flag-py {background-position: -144px -121px}
|
||||
.country-flag.flag-qa {background-position: -160px -121px}
|
||||
.country-flag.flag-re {background-position: -176px -121px}
|
||||
.country-flag.flag-ro {background-position: -192px -121px}
|
||||
.country-flag.flag-rs {background-position: -208px -121px}
|
||||
.country-flag.flag-ru {background-position: -224px -121px}
|
||||
.country-flag.flag-rw {background-position: -240px -121px}
|
||||
.country-flag.flag-sa {background-position: 0 -132px}
|
||||
.country-flag.flag-sb {background-position: -16px -132px}
|
||||
.country-flag.flag-sc {background-position: -32px -132px}
|
||||
.country-flag.flag-scotland {background-position: -48px -132px}
|
||||
.country-flag.flag-sd {background-position: -64px -132px}
|
||||
.country-flag.flag-se {background-position: -80px -132px}
|
||||
.country-flag.flag-sg {background-position: -96px -132px}
|
||||
.country-flag.flag-sh {background-position: -112px -132px}
|
||||
.country-flag.flag-si {background-position: -128px -132px}
|
||||
.country-flag.flag-sk {background-position: -144px -132px}
|
||||
.country-flag.flag-sl {background-position: -160px -132px}
|
||||
.country-flag.flag-sm {background-position: -176px -132px}
|
||||
.country-flag.flag-sn {background-position: -192px -132px}
|
||||
.country-flag.flag-so {background-position: -208px -132px}
|
||||
.country-flag.flag-somaliland {background-position: -224px -132px}
|
||||
.country-flag.flag-sr {background-position: -240px -132px}
|
||||
.country-flag.flag-ss {background-position: 0 -143px}
|
||||
.country-flag.flag-st {background-position: -16px -143px}
|
||||
.country-flag.flag-sv {background-position: -32px -143px}
|
||||
.country-flag.flag-sx {background-position: -48px -143px}
|
||||
.country-flag.flag-sy {background-position: -64px -143px}
|
||||
.country-flag.flag-sz {background-position: -80px -143px}
|
||||
.country-flag.flag-tc {background-position: -96px -143px}
|
||||
.country-flag.flag-td {background-position: -112px -143px}
|
||||
.country-flag.flag-tf {background-position: -128px -143px}
|
||||
.country-flag.flag-tg {background-position: -144px -143px}
|
||||
.country-flag.flag-th {background-position: -160px -143px}
|
||||
.country-flag.flag-tj {background-position: -176px -143px}
|
||||
.country-flag.flag-tk {background-position: -192px -143px}
|
||||
.country-flag.flag-tl {background-position: -208px -143px}
|
||||
.country-flag.flag-tm {background-position: -224px -143px}
|
||||
.country-flag.flag-tn {background-position: -240px -143px}
|
||||
.country-flag.flag-to {background-position: 0 -154px}
|
||||
.country-flag.flag-tr {background-position: -16px -154px}
|
||||
.country-flag.flag-tt {background-position: -32px -154px}
|
||||
.country-flag.flag-tv {background-position: -48px -154px}
|
||||
.country-flag.flag-tw {background-position: -64px -154px}
|
||||
.country-flag.flag-tz {background-position: -80px -154px}
|
||||
.country-flag.flag-ua {background-position: -96px -154px}
|
||||
.country-flag.flag-ug {background-position: -112px -154px}
|
||||
.country-flag.flag-um {background-position: -128px -154px}
|
||||
.country-flag.flag-us {background-position: -144px -154px}
|
||||
.country-flag.flag-uy {background-position: -160px -154px}
|
||||
.country-flag.flag-uz {background-position: -176px -154px}
|
||||
.country-flag.flag-va {background-position: -192px -154px}
|
||||
.country-flag.flag-vc {background-position: -208px -154px}
|
||||
.country-flag.flag-ve {background-position: -224px -154px}
|
||||
.country-flag.flag-vg {background-position: -240px -154px}
|
||||
.country-flag.flag-vi {background-position: 0 -165px}
|
||||
.country-flag.flag-vn {background-position: -16px -165px}
|
||||
.country-flag.flag-vu {background-position: -32px -165px}
|
||||
.country-flag.flag-wales {background-position: -48px -165px}
|
||||
.country-flag.flag-wf {background-position: -64px -165px}
|
||||
.country-flag.flag-ws {background-position: -80px -165px}
|
||||
.country-flag.flag-ye {background-position: -96px -165px}
|
||||
.country-flag.flag-yt {background-position: -112px -165px}
|
||||
.country-flag.flag-za {background-position: -128px -165px}
|
||||
.country-flag.flag-zanzibar {background-position: -144px -165px}
|
||||
.country-flag.flag-zm {background-position: -160px -165px}
|
||||
.country-flag.flag-zw {background-position: -176px -165px}
|
||||
.country-flag {
|
||||
width: 16px;
|
||||
height: 11px;
|
||||
background:url(../images/country-flags.png) no-repeat
|
||||
}
|
||||
|
||||
.country-flag.flag-ad {background-position: -16px 0}
|
||||
.country-flag.flag-ae {background-position: -32px 0}
|
||||
.country-flag.flag-af {background-position: -48px 0}
|
||||
.country-flag.flag-ag {background-position: -64px 0}
|
||||
.country-flag.flag-ai {background-position: -80px 0}
|
||||
.country-flag.flag-al {background-position: -96px 0}
|
||||
.country-flag.flag-am {background-position: -112px 0}
|
||||
.country-flag.flag-an {background-position: -128px 0}
|
||||
.country-flag.flag-ao {background-position: -144px 0}
|
||||
.country-flag.flag-ar {background-position: -160px 0}
|
||||
.country-flag.flag-as {background-position: -176px 0}
|
||||
.country-flag.flag-at {background-position: -192px 0}
|
||||
.country-flag.flag-au {background-position: -208px 0}
|
||||
.country-flag.flag-aw {background-position: -224px 0}
|
||||
.country-flag.flag-az {background-position: -240px 0}
|
||||
.country-flag.flag-ba {background-position: 0 -11px}
|
||||
.country-flag.flag-bb {background-position: -16px -11px}
|
||||
.country-flag.flag-bd {background-position: -32px -11px}
|
||||
.country-flag.flag-be {background-position: -48px -11px}
|
||||
.country-flag.flag-bf {background-position: -64px -11px}
|
||||
.country-flag.flag-bg {background-position: -80px -11px}
|
||||
.country-flag.flag-bh {background-position: -96px -11px}
|
||||
.country-flag.flag-bi {background-position: -112px -11px}
|
||||
.country-flag.flag-bj {background-position: -128px -11px}
|
||||
.country-flag.flag-bm {background-position: -144px -11px}
|
||||
.country-flag.flag-bn {background-position: -160px -11px}
|
||||
.country-flag.flag-bo {background-position: -176px -11px}
|
||||
.country-flag.flag-br {background-position: -192px -11px}
|
||||
.country-flag.flag-bs {background-position: -208px -11px}
|
||||
.country-flag.flag-bt {background-position: -224px -11px}
|
||||
.country-flag.flag-bv {background-position: -240px -11px}
|
||||
.country-flag.flag-bw {background-position: 0 -22px}
|
||||
.country-flag.flag-by {background-position: -16px -22px}
|
||||
.country-flag.flag-bz {background-position: -32px -22px}
|
||||
.country-flag.flag-ca {background-position: -48px -22px}
|
||||
.country-flag.flag-catalonia {background-position: -64px -22px}
|
||||
.country-flag.flag-cd {background-position: -80px -22px}
|
||||
.country-flag.flag-cf {background-position: -96px -22px}
|
||||
.country-flag.flag-cg {background-position: -112px -22px}
|
||||
.country-flag.flag-ch {background-position: -128px -22px}
|
||||
.country-flag.flag-ci {background-position: -144px -22px}
|
||||
.country-flag.flag-ck {background-position: -160px -22px}
|
||||
.country-flag.flag-cl {background-position: -176px -22px}
|
||||
.country-flag.flag-cm {background-position: -192px -22px}
|
||||
.country-flag.flag-cn {background-position: -208px -22px}
|
||||
.country-flag.flag-co {background-position: -224px -22px}
|
||||
.country-flag.flag-cr {background-position: -240px -22px}
|
||||
.country-flag.flag-cu {background-position: 0 -33px}
|
||||
.country-flag.flag-cv {background-position: -16px -33px}
|
||||
.country-flag.flag-cw {background-position: -32px -33px}
|
||||
.country-flag.flag-cy {background-position: -48px -33px}
|
||||
.country-flag.flag-cz {background-position: -64px -33px}
|
||||
.country-flag.flag-de {background-position: -80px -33px}
|
||||
.country-flag.flag-dj {background-position: -96px -33px}
|
||||
.country-flag.flag-dk {background-position: -112px -33px}
|
||||
.country-flag.flag-dm {background-position: -128px -33px}
|
||||
.country-flag.flag-do {background-position: -144px -33px}
|
||||
.country-flag.flag-dz {background-position: -160px -33px}
|
||||
.country-flag.flag-ec {background-position: -176px -33px}
|
||||
.country-flag.flag-ee {background-position: -192px -33px}
|
||||
.country-flag.flag-eg {background-position: -208px -33px}
|
||||
.country-flag.flag-eh {background-position: -224px -33px}
|
||||
.country-flag.flag-england {background-position: -240px -33px}
|
||||
.country-flag.flag-er {background-position: 0 -44px}
|
||||
.country-flag.flag-es {background-position: -16px -44px}
|
||||
.country-flag.flag-et {background-position: -32px -44px}
|
||||
.country-flag.flag-eu {background-position: -48px -44px}
|
||||
.country-flag.flag-fi {background-position: -64px -44px}
|
||||
.country-flag.flag-fj {background-position: -80px -44px}
|
||||
.country-flag.flag-fk {background-position: -96px -44px}
|
||||
.country-flag.flag-fm {background-position: -112px -44px}
|
||||
.country-flag.flag-fo {background-position: -128px -44px}
|
||||
.country-flag.flag-fr {background-position: -144px -44px}
|
||||
.country-flag.flag-ga {background-position: -160px -44px}
|
||||
.country-flag.flag-gb {background-position: -176px -44px}
|
||||
.country-flag.flag-gd {background-position: -192px -44px}
|
||||
.country-flag.flag-ge {background-position: -208px -44px}
|
||||
.country-flag.flag-gf {background-position: -224px -44px}
|
||||
.country-flag.flag-gg {background-position: -240px -44px}
|
||||
.country-flag.flag-gh {background-position: 0 -55px}
|
||||
.country-flag.flag-gi {background-position: -16px -55px}
|
||||
.country-flag.flag-gl {background-position: -32px -55px}
|
||||
.country-flag.flag-gm {background-position: -48px -55px}
|
||||
.country-flag.flag-gn {background-position: -64px -55px}
|
||||
.country-flag.flag-gp {background-position: -80px -55px}
|
||||
.country-flag.flag-gq {background-position: -96px -55px}
|
||||
.country-flag.flag-gr {background-position: -112px -55px}
|
||||
.country-flag.flag-gs {background-position: -128px -55px}
|
||||
.country-flag.flag-gt {background-position: -144px -55px}
|
||||
.country-flag.flag-gu {background-position: -160px -55px}
|
||||
.country-flag.flag-gw {background-position: -176px -55px}
|
||||
.country-flag.flag-gy {background-position: -192px -55px}
|
||||
.country-flag.flag-hk {background-position: -208px -55px}
|
||||
.country-flag.flag-hm {background-position: -224px -55px}
|
||||
.country-flag.flag-hn {background-position: -240px -55px}
|
||||
.country-flag.flag-hr {background-position: 0 -66px}
|
||||
.country-flag.flag-ht {background-position: -16px -66px}
|
||||
.country-flag.flag-hu {background-position: -32px -66px}
|
||||
.country-flag.flag-ic {background-position: -48px -66px}
|
||||
.country-flag.flag-id {background-position: -64px -66px}
|
||||
.country-flag.flag-ie {background-position: -80px -66px}
|
||||
.country-flag.flag-il {background-position: -96px -66px}
|
||||
.country-flag.flag-im {background-position: -112px -66px}
|
||||
.country-flag.flag-in {background-position: -128px -66px}
|
||||
.country-flag.flag-io {background-position: -144px -66px}
|
||||
.country-flag.flag-iq {background-position: -160px -66px}
|
||||
.country-flag.flag-ir {background-position: -176px -66px}
|
||||
.country-flag.flag-is {background-position: -192px -66px}
|
||||
.country-flag.flag-it {background-position: -208px -66px}
|
||||
.country-flag.flag-je {background-position: -224px -66px}
|
||||
.country-flag.flag-jm {background-position: -240px -66px}
|
||||
.country-flag.flag-jo {background-position: 0 -77px}
|
||||
.country-flag.flag-jp {background-position: -16px -77px}
|
||||
.country-flag.flag-ke {background-position: -32px -77px}
|
||||
.country-flag.flag-kg {background-position: -48px -77px}
|
||||
.country-flag.flag-kh {background-position: -64px -77px}
|
||||
.country-flag.flag-ki {background-position: -80px -77px}
|
||||
.country-flag.flag-km {background-position: -96px -77px}
|
||||
.country-flag.flag-kn {background-position: -112px -77px}
|
||||
.country-flag.flag-kp {background-position: -128px -77px}
|
||||
.country-flag.flag-kr {background-position: -144px -77px}
|
||||
.country-flag.flag-kurdistan {background-position: -160px -77px}
|
||||
.country-flag.flag-kw {background-position: -176px -77px}
|
||||
.country-flag.flag-ky {background-position: -192px -77px}
|
||||
.country-flag.flag-kz {background-position: -208px -77px}
|
||||
.country-flag.flag-la {background-position: -224px -77px}
|
||||
.country-flag.flag-lb {background-position: -240px -77px}
|
||||
.country-flag.flag-lc {background-position: 0 -88px}
|
||||
.country-flag.flag-li {background-position: -16px -88px}
|
||||
.country-flag.flag-lk {background-position: -32px -88px}
|
||||
.country-flag.flag-lr {background-position: -48px -88px}
|
||||
.country-flag.flag-ls {background-position: -64px -88px}
|
||||
.country-flag.flag-lt {background-position: -80px -88px}
|
||||
.country-flag.flag-lu {background-position: -96px -88px}
|
||||
.country-flag.flag-lv {background-position: -112px -88px}
|
||||
.country-flag.flag-ly {background-position: -128px -88px}
|
||||
.country-flag.flag-ma {background-position: -144px -88px}
|
||||
.country-flag.flag-mc {background-position: -160px -88px}
|
||||
.country-flag.flag-md {background-position: -176px -88px}
|
||||
.country-flag.flag-me {background-position: -192px -88px}
|
||||
.country-flag.flag-mg {background-position: -208px -88px}
|
||||
.country-flag.flag-mh {background-position: -224px -88px}
|
||||
.country-flag.flag-mk {background-position: -240px -88px}
|
||||
.country-flag.flag-ml {background-position: 0 -99px}
|
||||
.country-flag.flag-mm {background-position: -16px -99px}
|
||||
.country-flag.flag-mn {background-position: -32px -99px}
|
||||
.country-flag.flag-mo {background-position: -48px -99px}
|
||||
.country-flag.flag-mp {background-position: -64px -99px}
|
||||
.country-flag.flag-mq {background-position: -80px -99px}
|
||||
.country-flag.flag-mr {background-position: -96px -99px}
|
||||
.country-flag.flag-ms {background-position: -112px -99px}
|
||||
.country-flag.flag-mt {background-position: -128px -99px}
|
||||
.country-flag.flag-mu {background-position: -144px -99px}
|
||||
.country-flag.flag-mv {background-position: -160px -99px}
|
||||
.country-flag.flag-mw {background-position: -176px -99px}
|
||||
.country-flag.flag-mx {background-position: -192px -99px}
|
||||
.country-flag.flag-my {background-position: -208px -99px}
|
||||
.country-flag.flag-mz {background-position: -224px -99px}
|
||||
.country-flag.flag-na {background-position: -240px -99px}
|
||||
.country-flag.flag-nc {background-position: 0 -110px}
|
||||
.country-flag.flag-ne {background-position: -16px -110px}
|
||||
.country-flag.flag-nf {background-position: -32px -110px}
|
||||
.country-flag.flag-ng {background-position: -48px -110px}
|
||||
.country-flag.flag-ni {background-position: -64px -110px}
|
||||
.country-flag.flag-nl {background-position: -80px -110px}
|
||||
.country-flag.flag-no {background-position: -96px -110px}
|
||||
.country-flag.flag-np {background-position: -112px -110px}
|
||||
.country-flag.flag-nr {background-position: -128px -110px}
|
||||
.country-flag.flag-nu {background-position: -144px -110px}
|
||||
.country-flag.flag-nz {background-position: -160px -110px}
|
||||
.country-flag.flag-om {background-position: -176px -110px}
|
||||
.country-flag.flag-pa {background-position: -192px -110px}
|
||||
.country-flag.flag-pe {background-position: -208px -110px}
|
||||
.country-flag.flag-pf {background-position: -224px -110px}
|
||||
.country-flag.flag-pg {background-position: -240px -110px}
|
||||
.country-flag.flag-ph {background-position: 0 -121px}
|
||||
.country-flag.flag-pk {background-position: -16px -121px}
|
||||
.country-flag.flag-pl {background-position: -32px -121px}
|
||||
.country-flag.flag-pm {background-position: -48px -121px}
|
||||
.country-flag.flag-pn {background-position: -64px -121px}
|
||||
.country-flag.flag-pr {background-position: -80px -121px}
|
||||
.country-flag.flag-ps {background-position: -96px -121px}
|
||||
.country-flag.flag-pt {background-position: -112px -121px}
|
||||
.country-flag.flag-pw {background-position: -128px -121px}
|
||||
.country-flag.flag-py {background-position: -144px -121px}
|
||||
.country-flag.flag-qa {background-position: -160px -121px}
|
||||
.country-flag.flag-re {background-position: -176px -121px}
|
||||
.country-flag.flag-ro {background-position: -192px -121px}
|
||||
.country-flag.flag-rs {background-position: -208px -121px}
|
||||
.country-flag.flag-ru {background-position: -224px -121px}
|
||||
.country-flag.flag-rw {background-position: -240px -121px}
|
||||
.country-flag.flag-sa {background-position: 0 -132px}
|
||||
.country-flag.flag-sb {background-position: -16px -132px}
|
||||
.country-flag.flag-sc {background-position: -32px -132px}
|
||||
.country-flag.flag-scotland {background-position: -48px -132px}
|
||||
.country-flag.flag-sd {background-position: -64px -132px}
|
||||
.country-flag.flag-se {background-position: -80px -132px}
|
||||
.country-flag.flag-sg {background-position: -96px -132px}
|
||||
.country-flag.flag-sh {background-position: -112px -132px}
|
||||
.country-flag.flag-si {background-position: -128px -132px}
|
||||
.country-flag.flag-sk {background-position: -144px -132px}
|
||||
.country-flag.flag-sl {background-position: -160px -132px}
|
||||
.country-flag.flag-sm {background-position: -176px -132px}
|
||||
.country-flag.flag-sn {background-position: -192px -132px}
|
||||
.country-flag.flag-so {background-position: -208px -132px}
|
||||
.country-flag.flag-somaliland {background-position: -224px -132px}
|
||||
.country-flag.flag-sr {background-position: -240px -132px}
|
||||
.country-flag.flag-ss {background-position: 0 -143px}
|
||||
.country-flag.flag-st {background-position: -16px -143px}
|
||||
.country-flag.flag-sv {background-position: -32px -143px}
|
||||
.country-flag.flag-sx {background-position: -48px -143px}
|
||||
.country-flag.flag-sy {background-position: -64px -143px}
|
||||
.country-flag.flag-sz {background-position: -80px -143px}
|
||||
.country-flag.flag-tc {background-position: -96px -143px}
|
||||
.country-flag.flag-td {background-position: -112px -143px}
|
||||
.country-flag.flag-tf {background-position: -128px -143px}
|
||||
.country-flag.flag-tg {background-position: -144px -143px}
|
||||
.country-flag.flag-th {background-position: -160px -143px}
|
||||
.country-flag.flag-tj {background-position: -176px -143px}
|
||||
.country-flag.flag-tk {background-position: -192px -143px}
|
||||
.country-flag.flag-tl {background-position: -208px -143px}
|
||||
.country-flag.flag-tm {background-position: -224px -143px}
|
||||
.country-flag.flag-tn {background-position: -240px -143px}
|
||||
.country-flag.flag-to {background-position: 0 -154px}
|
||||
.country-flag.flag-tr {background-position: -16px -154px}
|
||||
.country-flag.flag-tt {background-position: -32px -154px}
|
||||
.country-flag.flag-tv {background-position: -48px -154px}
|
||||
.country-flag.flag-tw {background-position: -64px -154px}
|
||||
.country-flag.flag-tz {background-position: -80px -154px}
|
||||
.country-flag.flag-ua {background-position: -96px -154px}
|
||||
.country-flag.flag-ug {background-position: -112px -154px}
|
||||
.country-flag.flag-um {background-position: -128px -154px}
|
||||
.country-flag.flag-us {background-position: -144px -154px}
|
||||
.country-flag.flag-uy {background-position: -160px -154px}
|
||||
.country-flag.flag-uz {background-position: -176px -154px}
|
||||
.country-flag.flag-va {background-position: -192px -154px}
|
||||
.country-flag.flag-vc {background-position: -208px -154px}
|
||||
.country-flag.flag-ve {background-position: -224px -154px}
|
||||
.country-flag.flag-vg {background-position: -240px -154px}
|
||||
.country-flag.flag-vi {background-position: 0 -165px}
|
||||
.country-flag.flag-vn {background-position: -16px -165px}
|
||||
.country-flag.flag-vu {background-position: -32px -165px}
|
||||
.country-flag.flag-wales {background-position: -48px -165px}
|
||||
.country-flag.flag-wf {background-position: -64px -165px}
|
||||
.country-flag.flag-ws {background-position: -80px -165px}
|
||||
.country-flag.flag-ye {background-position: -96px -165px}
|
||||
.country-flag.flag-yt {background-position: -112px -165px}
|
||||
.country-flag.flag-za {background-position: -128px -165px}
|
||||
.country-flag.flag-zanzibar {background-position: -144px -165px}
|
||||
.country-flag.flag-zm {background-position: -160px -165px}
|
||||
.country-flag.flag-zw {background-position: -176px -165px}
|
||||
|
82
gui/slick/css/lib/bootstrap.css
vendored
@ -1111,7 +1111,7 @@ p {
|
||||
font-weight: 300;
|
||||
line-height: 1.4;
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
@media (min-width: 1010px) {
|
||||
.lead {
|
||||
font-size: 21px;
|
||||
}
|
||||
@ -1257,7 +1257,7 @@ dt {
|
||||
dd {
|
||||
margin-left: 0;
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
@media (min-width: 1010px) {
|
||||
.dl-horizontal dt {
|
||||
float: left;
|
||||
width: 160px;
|
||||
@ -1393,12 +1393,12 @@ pre code {
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
@media (min-width: 1010px) {
|
||||
.container {
|
||||
width: 750px;
|
||||
}
|
||||
}
|
||||
@media (min-width: 992px) {
|
||||
@media (min-width: 1011px) {
|
||||
.container {
|
||||
width: 970px;
|
||||
}
|
||||
@ -1580,7 +1580,7 @@ pre code {
|
||||
.col-xs-offset-0 {
|
||||
margin-left: 0;
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
@media (min-width: 1010px) {
|
||||
.col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {
|
||||
float: left;
|
||||
}
|
||||
@ -1738,7 +1738,7 @@ pre code {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
@media (min-width: 992px) {
|
||||
@media (min-width: 1011px) {
|
||||
.col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 {
|
||||
float: left;
|
||||
}
|
||||
@ -2662,7 +2662,7 @@ select[multiple].form-group-lg .form-control {
|
||||
margin-bottom: 10px;
|
||||
color: #737373;
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
@media (min-width: 1010px) {
|
||||
.form-inline .form-group {
|
||||
display: inline-block;
|
||||
margin-bottom: 0;
|
||||
@ -2728,7 +2728,7 @@ select[multiple].form-group-lg .form-control {
|
||||
margin-right: -15px;
|
||||
margin-left: -15px;
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
@media (min-width: 1010px) {
|
||||
.form-horizontal .control-label {
|
||||
padding-top: 7px;
|
||||
margin-bottom: 0;
|
||||
@ -2738,12 +2738,12 @@ select[multiple].form-group-lg .form-control {
|
||||
.form-horizontal .has-feedback .form-control-feedback {
|
||||
right: 15px;
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
@media (min-width: 1010px) {
|
||||
.form-horizontal .form-group-lg .control-label {
|
||||
padding-top: 14.3px;
|
||||
}
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
@media (min-width: 1010px) {
|
||||
.form-horizontal .form-group-sm .control-label {
|
||||
padding-top: 6px;
|
||||
}
|
||||
@ -3305,7 +3305,7 @@ tbody.collapse.in {
|
||||
bottom: 100%;
|
||||
margin-bottom: 1px;
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
@media (min-width: 1010px) {
|
||||
.navbar-right .dropdown-menu {
|
||||
right: 0;
|
||||
left: auto;
|
||||
@ -3721,7 +3721,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
|
||||
top: auto;
|
||||
left: auto;
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
@media (min-width: 1010px) {
|
||||
.nav-tabs.nav-justified > li {
|
||||
display: table-cell;
|
||||
width: 1%;
|
||||
@ -3739,7 +3739,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
|
||||
.nav-tabs.nav-justified > .active > a:focus {
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
@media (min-width: 1010px) {
|
||||
.nav-tabs.nav-justified > li > a {
|
||||
border-bottom: 1px solid #ddd;
|
||||
border-radius: 4px 4px 0 0;
|
||||
@ -3786,7 +3786,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
|
||||
top: auto;
|
||||
left: auto;
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
@media (min-width: 1010px) {
|
||||
.nav-justified > li {
|
||||
display: table-cell;
|
||||
width: 1%;
|
||||
@ -3807,7 +3807,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
|
||||
.nav-tabs-justified > .active > a:focus {
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
@media (min-width: 1010px) {
|
||||
.nav-tabs-justified > li > a {
|
||||
border-bottom: 1px solid #ddd;
|
||||
border-radius: 4px 4px 0 0;
|
||||
@ -3837,12 +3837,12 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
|
||||
margin-bottom: 20px;
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
@media (min-width: 1010px) {
|
||||
.navbar {
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
@media (min-width: 1010px) {
|
||||
.navbar-header {
|
||||
float: left;
|
||||
}
|
||||
@ -3859,7 +3859,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
|
||||
.navbar-collapse.in {
|
||||
overflow-y: auto;
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
@media (min-width: 1010px) {
|
||||
.navbar-collapse {
|
||||
width: auto;
|
||||
border-top: 0;
|
||||
@ -3900,7 +3900,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
|
||||
margin-right: -15px;
|
||||
margin-left: -15px;
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
@media (min-width: 1010px) {
|
||||
.container > .navbar-header,
|
||||
.container-fluid > .navbar-header,
|
||||
.container > .navbar-collapse,
|
||||
@ -3913,7 +3913,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
|
||||
z-index: 1000;
|
||||
border-width: 0 0 1px;
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
@media (min-width: 1010px) {
|
||||
.navbar-static-top {
|
||||
border-radius: 0;
|
||||
}
|
||||
@ -3925,7 +3925,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
|
||||
left: 0;
|
||||
z-index: 1030;
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
@media (min-width: 1010px) {
|
||||
.navbar-fixed-top,
|
||||
.navbar-fixed-bottom {
|
||||
border-radius: 0;
|
||||
@ -3954,7 +3954,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
|
||||
.navbar-brand > img {
|
||||
display: block;
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
@media (min-width: 1010px) {
|
||||
.navbar > .container .navbar-brand,
|
||||
.navbar > .container-fluid .navbar-brand {
|
||||
margin-left: -15px;
|
||||
@ -3984,7 +3984,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
|
||||
.navbar-toggle .icon-bar + .icon-bar {
|
||||
margin-top: 4px;
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
@media (min-width: 1010px) {
|
||||
.navbar-toggle {
|
||||
display: none;
|
||||
}
|
||||
@ -4020,7 +4020,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
|
||||
background-image: none;
|
||||
}
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
@media (min-width: 1010px) {
|
||||
.navbar-nav {
|
||||
float: left;
|
||||
margin: 0;
|
||||
@ -4044,7 +4044,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
|
||||
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1);
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1);
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
@media (min-width: 1010px) {
|
||||
.navbar-form .form-group {
|
||||
display: inline-block;
|
||||
margin-bottom: 0;
|
||||
@ -4102,7 +4102,7 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
@media (min-width: 1010px) {
|
||||
.navbar-form {
|
||||
width: auto;
|
||||
padding-top: 0;
|
||||
@ -4141,14 +4141,14 @@ select[multiple].input-group-sm > .input-group-btn > .btn {
|
||||
margin-top: 15px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
@media (min-width: 1010px) {
|
||||
.navbar-text {
|
||||
float: left;
|
||||
margin-right: 15px;
|
||||
margin-left: 15px;
|
||||
}
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
@media (min-width: 1010px) {
|
||||
.navbar-left {
|
||||
float: left !important;
|
||||
}
|
||||
@ -5569,7 +5569,7 @@ button.close {
|
||||
height: 50px;
|
||||
overflow: scroll;
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
@media (min-width: 1010px) {
|
||||
.modal-dialog {
|
||||
width: 600px;
|
||||
margin: 30px auto;
|
||||
@ -5582,7 +5582,7 @@ button.close {
|
||||
width: 300px;
|
||||
}
|
||||
}
|
||||
@media (min-width: 992px) {
|
||||
@media (min-width: 1011px) {
|
||||
.modal-lg {
|
||||
width: 900px;
|
||||
}
|
||||
@ -6008,7 +6008,7 @@ button.close {
|
||||
.carousel-caption .btn {
|
||||
text-shadow: none;
|
||||
}
|
||||
@media screen and (min-width: 768px) {
|
||||
@media screen and (min-width: 1010px) {
|
||||
.carousel-control .glyphicon-chevron-left,
|
||||
.carousel-control .glyphicon-chevron-right,
|
||||
.carousel-control .icon-prev,
|
||||
@ -6172,7 +6172,7 @@ button.close {
|
||||
display: inline-block !important;
|
||||
}
|
||||
}
|
||||
@media (min-width: 768px) and (max-width: 991px) {
|
||||
@media (min-width: 1010px) and (max-width: 1012px) {
|
||||
.visible-sm {
|
||||
display: block !important;
|
||||
}
|
||||
@ -6187,22 +6187,22 @@ button.close {
|
||||
display: table-cell !important;
|
||||
}
|
||||
}
|
||||
@media (min-width: 768px) and (max-width: 991px) {
|
||||
@media (min-width: 1010px) and (max-width: 1012px) {
|
||||
.visible-sm-block {
|
||||
display: block !important;
|
||||
}
|
||||
}
|
||||
@media (min-width: 768px) and (max-width: 991px) {
|
||||
@media (min-width: 1010px) and (max-width: 1012px) {
|
||||
.visible-sm-inline {
|
||||
display: inline !important;
|
||||
}
|
||||
}
|
||||
@media (min-width: 768px) and (max-width: 991px) {
|
||||
@media (min-width: 1010px) and (max-width: 1012px) {
|
||||
.visible-sm-inline-block {
|
||||
display: inline-block !important;
|
||||
}
|
||||
}
|
||||
@media (min-width: 992px) and (max-width: 1199px) {
|
||||
@media (min-width: 1011px) and (max-width: 1199px) {
|
||||
.visible-md {
|
||||
display: block !important;
|
||||
}
|
||||
@ -6217,17 +6217,17 @@ button.close {
|
||||
display: table-cell !important;
|
||||
}
|
||||
}
|
||||
@media (min-width: 992px) and (max-width: 1199px) {
|
||||
@media (min-width: 1011px) and (max-width: 1199px) {
|
||||
.visible-md-block {
|
||||
display: block !important;
|
||||
}
|
||||
}
|
||||
@media (min-width: 992px) and (max-width: 1199px) {
|
||||
@media (min-width: 1011px) and (max-width: 1199px) {
|
||||
.visible-md-inline {
|
||||
display: inline !important;
|
||||
}
|
||||
}
|
||||
@media (min-width: 992px) and (max-width: 1199px) {
|
||||
@media (min-width: 1011px) and (max-width: 1199px) {
|
||||
.visible-md-inline-block {
|
||||
display: inline-block !important;
|
||||
}
|
||||
@ -6267,12 +6267,12 @@ button.close {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
@media (min-width: 768px) and (max-width: 991px) {
|
||||
@media (min-width: 1010px) and (max-width: 1012px) {
|
||||
.hidden-sm {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
@media (min-width: 992px) and (max-width: 1199px) {
|
||||
@media (min-width: 1011px) and (max-width: 1199px) {
|
||||
.hidden-md {
|
||||
display: none !important;
|
||||
}
|
||||
|
@ -544,20 +544,20 @@ home.tmpl
|
||||
}
|
||||
|
||||
.progress-100 {
|
||||
background-image: -moz-linear-gradient(#55aef1, #9cd0f7) !important;
|
||||
background-image: linear-gradient(#55aef1, #9cd0f7) !important;
|
||||
background-image: -webkit-linear-gradient(#55aef1, #9cd0f7) !important;
|
||||
background-image: -o-linear-gradient(#55aef1, #9cd0f7) !important;
|
||||
background-image: -moz-linear-gradient(#a6cf41, #5b990d) !important;
|
||||
background-image: linear-gradient(#a6cf41, #5b990d) !important;
|
||||
background-image: -webkit-linear-gradient(#a6cf41, #5b990d) !important;
|
||||
background-image: -o-linear-gradient(#a6cf41, #5b990d) !important;
|
||||
-moz-border-radius: 3px;
|
||||
-webkit-border-radius: 3px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.progress-80 {
|
||||
background-image: -moz-linear-gradient(#a6cf41, #5b990d) !important;
|
||||
background-image: linear-gradient(#a6cf41, #5b990d) !important;
|
||||
background-image: -webkit-linear-gradient(#a6cf41, #5b990d) !important;
|
||||
background-image: -o-linear-gradient(#a6cf41, #5b990d) !important;
|
||||
background-image: -moz-linear-gradient(#e1ff97, #9db269) !important;
|
||||
background-image: linear-gradient(#e1ff97, #9db269) !important;
|
||||
background-image: -webkit-linear-gradient(#e1ff97, #9db269) !important;
|
||||
background-image: -o-linear-gradient(#e1ff97, #9db269) !important;
|
||||
-moz-border-radius: 3px;
|
||||
-webkit-border-radius: 3px;
|
||||
border-radius: 3px;
|
||||
|
BIN
gui/slick/images/anidb24.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 5.4 KiB |
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 5.4 KiB |
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 5.4 KiB |
BIN
gui/slick/images/network/addiktv.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 4.9 KiB |
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 6.0 KiB |
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 1.8 KiB |
BIN
gui/slick/images/network/eo.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 1.6 KiB |
BIN
gui/slick/images/network/max.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 1.6 KiB |
BIN
gui/slick/images/network/npo 1.png
Normal file
After Width: | Height: | Size: 4.1 KiB |
BIN
gui/slick/images/network/npo 2.png
Normal file
After Width: | Height: | Size: 4.0 KiB |
BIN
gui/slick/images/network/npo 3.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
gui/slick/images/network/nps.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
gui/slick/images/network/ntr.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 3.5 KiB |
BIN
gui/slick/images/network/quest.png
Normal file
After Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 5.0 KiB |
BIN
gui/slick/images/network/sbs 9.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 5.0 KiB |
BIN
gui/slick/images/network/series+.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 6.1 KiB |
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 1.3 KiB |
BIN
gui/slick/images/network/tvi.png
Normal file
After Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 2.7 KiB |
BIN
gui/slick/images/providers/alpharatio.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.1 KiB |
BIN
gui/slick/images/providers/oldpiratebay.png
Normal file
After Width: | Height: | Size: 3.7 KiB |
BIN
gui/slick/images/providers/rarbg.png
Normal file
After Width: | Height: | Size: 488 B |
BIN
gui/slick/images/providers/shazbat.png
Normal file
After Width: | Height: | Size: 853 B |
BIN
gui/slick/images/providers/tntvillage.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
@ -31,7 +31,7 @@
|
||||
|
||||
<div id="core-component-group1" class="tab-pane active component-group">
|
||||
<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>
|
||||
<p>AniDB is non-profit database of anime information that is freely open to the public</p>
|
||||
</div>
|
||||
|
@ -63,6 +63,16 @@
|
||||
</label>
|
||||
</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">
|
||||
<label for="update_shows_on_start">
|
||||
<span class="component-title">Update shows on startup</span>
|
||||
|
@ -220,6 +220,20 @@
|
||||
<span class="component-desc">host running Plex Media Server (eg. 192.168.1.100:32400)</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="field-pair">
|
||||
<label for="plex_server_token">
|
||||
<span class="component-title">Plex Media Server Auth Token</span>
|
||||
<input type="text" name="plex_server_token" id="plex_server_token" value="$sickbeard.PLEX_SERVER_TOKEN" class="form-control input-sm input250" />
|
||||
</label>
|
||||
<label>
|
||||
<span class="component-title"> </span>
|
||||
<span class="component-desc">Auth Token used by plex</span>
|
||||
</label>
|
||||
<label>
|
||||
<span class="component-title"> </span>
|
||||
<span class="component-desc">(<a href="<%= anon_url('https://support.plex.tv/hc/en-us/articles/204059436-Finding-your-account-token-X-Plex-Token') %>" rel="noreferrer" onclick="window.open(this.href, '_blank'); return false;"><u>Finding your account token</u></a>)</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="field-pair">
|
||||
<label for="plex_host">
|
||||
<span class="component-title">Plex Client IP:Port</span>
|
||||
@ -1375,30 +1389,39 @@
|
||||
<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" />
|
||||
</label>
|
||||
<label>
|
||||
<span class="component-title"> </span>
|
||||
<p>
|
||||
<span class="component-desc">username of your Trakt account.</span>
|
||||
</label>
|
||||
</p>
|
||||
</div>
|
||||
<div class="field-pair">
|
||||
<label for="trakt_password">
|
||||
<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" />
|
||||
</label>
|
||||
<label>
|
||||
<span class="component-title"> </span>
|
||||
<p>
|
||||
<span class="component-desc">password of your Trakt account.</span>
|
||||
</label>
|
||||
</p>
|
||||
</div>
|
||||
<div class="field-pair">
|
||||
<label for="trakt_disable_ssl_verify">
|
||||
<span class="component-title">Disable SSL Verification:</span>
|
||||
<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 ""# />
|
||||
<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>
|
||||
</label>
|
||||
</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">
|
||||
<label for="trakt_default_indexer">
|
||||
<span class="component-title">Default indexer:</span>
|
||||
|
@ -530,6 +530,33 @@ var show_nzb_providers = #if $sickbeard.USE_NZBS then "true" else "false"#;
|
||||
</div>
|
||||
#end if
|
||||
|
||||
#if $hasattr($curTorrentProvider, 'cat') and $curTorrentProvider.getID() == 'tntvillage':
|
||||
<div class="field-pair">
|
||||
<label for="${curTorrentProvider.getID()}_cat">
|
||||
<span class="component-title">Category:</span>
|
||||
<span class="component-desc">
|
||||
<select name="${curTorrentProvider.getID()}_cat" id="${curTorrentProvider.getID()}_cat" class="form-control input-sm">
|
||||
#for $i in $curTorrentProvider.category_dict.keys():
|
||||
<option value="$curTorrentProvider.category_dict[$i]" #if $curTorrentProvider.category_dict[$i] == $curTorrentProvider.cat then "selected=\"selected\"" else ""#>$i</option>
|
||||
#end for
|
||||
</select>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
#end if
|
||||
|
||||
#if $hasattr($curTorrentProvider, 'subtitle') and $curTorrentProvider.getID() == 'tntvillage':
|
||||
<div class="field-pair">
|
||||
<label for="${curTorrentProvider.getID()}_subtitle">
|
||||
<span class="component-title">Subtitled</span>
|
||||
<span class="component-desc">
|
||||
<input type="checkbox" name="${curTorrentProvider.getID()}_subtitle" id="${curTorrentProvider.getID()}_subtitle" #if $curTorrentProvider.subtitle then "checked=\"checked\"" else ""#/>
|
||||
<p>select torrent with Italian subtitle</p>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
#end if
|
||||
|
||||
</div>
|
||||
#end for
|
||||
|
||||
|
@ -449,7 +449,6 @@
|
||||
<input type="text" name="torrent_host" id="torrent_host" value="$sickbeard.TORRENT_HOST" class="form-control input-sm input350" />
|
||||
<div class="clear-left">
|
||||
<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>
|
||||
</span>
|
||||
</label>
|
||||
@ -467,12 +466,29 @@
|
||||
</label>
|
||||
</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">
|
||||
<label for="torrent_verify_cert">
|
||||
<span class="component-title">Verify certificate</span>
|
||||
<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 '' %>/>
|
||||
<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>
|
||||
</label>
|
||||
</div>
|
||||
|
@ -379,7 +379,7 @@
|
||||
#if ($sickbeard.DISPLAY_FILESIZE == True):
|
||||
style="min-width: 190px"
|
||||
#end if
|
||||
>>Name</th>
|
||||
>Name</th>
|
||||
#if ($sickbeard.DISPLAY_FILESIZE == True):
|
||||
<th class="col-ep">Filesize</th>
|
||||
#end if
|
||||
@ -507,13 +507,15 @@
|
||||
|
||||
#if $sickbeard.USE_SUBTITLES and $show.subtitles:
|
||||
<td class="col-subtitles" align="center">
|
||||
#if $epResult["subtitles"]:
|
||||
#for $sub_lang in subliminal.language.language_list([x.strip() for x in $epResult["subtitles"].split(',')]):
|
||||
#if sub_lang.alpha2 != ""
|
||||
<img src="$sbRoot/images/flags/${sub_lang.alpha2}.png" width="16" height="11" alt="${sub_lang}" />
|
||||
#end if
|
||||
#end for
|
||||
#end if
|
||||
#if $epResult["subtitles"]:
|
||||
#for $sub_lang in subliminal.language.language_list([x.strip() for x in $epResult["subtitles"].split(',') if x != ""]):
|
||||
#if sub_lang.alpha2 != ""
|
||||
<img src="$sbRoot/images/flags/${sub_lang.alpha2}.png" width="16" height="11" alt="${sub_lang}" />
|
||||
#else
|
||||
<img src="$sbRoot/images/flags/unknown.png" width="16" height="11" alt="Unknown" />
|
||||
#end if
|
||||
#end for
|
||||
#end if
|
||||
</td>
|
||||
#end if
|
||||
|
||||
|
@ -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 align="center" #if $curStatus == SUBTITLED then 'class="subtitles_column"' else ''#>
|
||||
#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
|
||||
<span style="cursor: help; vertical-align:middle;" title="$os.path.basename($hItem["resource"])">$statusStrings[$curStatus]</span>
|
||||
</td>
|
||||
|
@ -104,7 +104,8 @@
|
||||
filter_columnFilters: false,
|
||||
filter_reset: '.resetshows'
|
||||
},
|
||||
sortStable: true
|
||||
sortStable: true,
|
||||
sortAppend: [[1,0]]
|
||||
});
|
||||
|
||||
\$("#showListTableAnime:has(tbody tr)").tablesorter({
|
||||
@ -126,13 +127,16 @@
|
||||
filter_columnFilters: false,
|
||||
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:
|
||||
\$.tablesorter.filter.bindSearch( "#showListTableAnime", \$('.search') );
|
||||
if (\$("#showListTableAnime").find("tbody").find("tr").size() > 0)
|
||||
\$.tablesorter.filter.bindSearch( "#showListTableAnime", \$('.search') );
|
||||
#end if
|
||||
|
||||
#set $fuzzydate = 'airdate'
|
||||
@ -403,7 +407,7 @@ $myShowList.sort(lambda x, y: cmp(x.name, y.name))
|
||||
<td class="show-table">
|
||||
#if $layout != 'simple':
|
||||
#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:
|
||||
<img class="show-network-image" src="$sbRoot/images/network/nonetwork.png" alt="No Network" title="No Network" />
|
||||
#end if
|
||||
@ -561,7 +565,7 @@ $myShowList.sort(lambda x, y: cmp(x.name, y.name))
|
||||
#if $layout != 'simple':
|
||||
<td align="center">
|
||||
#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:
|
||||
<img id="network" width="54" height="27" src="$sbRoot/images/network/nonetwork.png" alt="No Network" title="No Network" />
|
||||
#end if
|
||||
|
@ -25,7 +25,3 @@
|
||||
<input class="btn" type="button" id="defaultRootDir" value="Set as Default *" />
|
||||
</div>
|
||||
<input type="text" style="display: none" id="rootDirText" />
|
||||
|
||||
<script type="text/javascript">
|
||||
document.getElementById("rootDirs").selectedIndex = "0"
|
||||
</script>
|
||||
|
@ -90,7 +90,9 @@
|
||||
\$("#SubMenu a:contains('Clear History')").addClass('btn clearhistory').html('<span class="ui-icon ui-icon-trash pull-left"></span> Clear History');
|
||||
\$("#SubMenu a:contains('Trim History')").addClass('btn trimhistory').html('<span class="ui-icon ui-icon-trash pull-left"></span> Trim History');
|
||||
\$("#SubMenu a[href$='/errorlogs/clearerrors/']").addClass('btn').html('<span class="ui-icon ui-icon-trash pull-left"></span> Clear Errors');
|
||||
#if sickbeard.GIT_USERNAME and sickbeard.GIT_PASSWORD and sickbeard.GIT_AUTOISSUES == 1:
|
||||
\$("#SubMenu a[href$='/errorlogs/submit_errors/']").addClass('btn').html('<span class="ui-icon ui-icon-arrowreturnthick-1-n pull-left"></span> Submit Errors');
|
||||
#end if
|
||||
\$("#SubMenu a:contains('Re-scan')").addClass('btn').html('<span class="ui-icon ui-icon-refresh pull-left"></span> Re-scan');
|
||||
\$("#SubMenu a:contains('Backlog Overview')").addClass('btn').html('<span class="ui-icon ui-icon-refresh pull-left"></span> Backlog Overview');
|
||||
\$("#SubMenu a[href$='/home/updatePLEX/']").addClass('btn').html('<span class="ui-icon ui-icon-refresh pull-left"></span> Update PLEX');
|
||||
|
@ -46,22 +46,25 @@
|
||||
#end if
|
||||
#set $totalWanted = 0
|
||||
#set $totalQual = 0
|
||||
#set $totalSnatched = 0
|
||||
|
||||
#for $curShow in $sickbeard.showList:
|
||||
#set $totalWanted = $totalWanted + $showCounts[$curShow.indexerid][$Overview.WANTED]
|
||||
#set $totalQual = $totalQual + $showCounts[$curShow.indexerid][$Overview.QUAL]
|
||||
#set $totalSnatched = $totalSnatched + $showCounts[$curShow.indexerid][$Overview.SNATCHED]
|
||||
#end for
|
||||
|
||||
<div class="h2footer pull-right">
|
||||
<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 snatched">Snatched: <b>$totalSnatched</b></span>
|
||||
</div><br/>
|
||||
|
||||
<div class="float-left">
|
||||
Jump to Show
|
||||
<select id="pickShow" class="form-control form-control-inline input-sm">
|
||||
#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>
|
||||
#end if
|
||||
#end for
|
||||
@ -72,7 +75,7 @@ Jump to Show
|
||||
|
||||
#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
|
||||
#end if
|
||||
|
||||
@ -82,6 +85,7 @@ Jump to Show
|
||||
<div class="pull-right">
|
||||
<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 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>
|
||||
</div>
|
||||
</td>
|
||||
@ -97,7 +101,7 @@ Jump to Show
|
||||
#continue
|
||||
#end try
|
||||
|
||||
#if $overview not in ($Overview.QUAL, $Overview.WANTED):
|
||||
#if $overview not in ($Overview.QUAL, $Overview.WANTED, $Overview.SNATCHED):
|
||||
#continue
|
||||
#end if
|
||||
|
||||
|
@ -45,9 +45,9 @@ function updateImages(data) {
|
||||
if (el) {
|
||||
if (ep.searchstatus == 'searching') {
|
||||
//el=$('td#' + ep.season + 'x' + ep.episode + '.search img');
|
||||
img.attr('title','Searching');
|
||||
img.attr('alt','earching');
|
||||
img.attr('src',sbRoot+'/images/' + loadingImage);
|
||||
img.prop('title','Searching');
|
||||
img.prop('alt','Searching');
|
||||
img.prop('src',sbRoot+'/images/' + loadingImage);
|
||||
disableLink(el);
|
||||
// Update Status and Quality
|
||||
var rSearchTerm = /(\w+)\s\((.+?)\)/;
|
||||
@ -56,23 +56,24 @@ function updateImages(data) {
|
||||
}
|
||||
else if (ep.searchstatus == 'queued') {
|
||||
//el=$('td#' + ep.season + 'x' + ep.episode + '.search img');
|
||||
img.attr('title','Queued');
|
||||
img.attr('alt','queued');
|
||||
img.attr('src',sbRoot+'/images/' + queuedImage );
|
||||
img.prop('title','Queued');
|
||||
img.prop('alt','queued');
|
||||
img.prop('src',sbRoot+'/images/' + queuedImage );
|
||||
disableLink(el);
|
||||
HtmlContent = ep.searchstatus;
|
||||
}
|
||||
else if (ep.searchstatus == 'finished') {
|
||||
//el=$('td#' + ep.season + 'x' + ep.episode + '.search img');
|
||||
img.attr('title','Searching');
|
||||
img.attr('alt','searching');
|
||||
img.parent().attr('class','epRetry');
|
||||
img.attr('src',sbRoot+'/images/' + searchImage);
|
||||
img.prop('title','Searching');
|
||||
img.prop('alt','searching');
|
||||
img.parent().prop('class','epRetry');
|
||||
img.prop('src',sbRoot+'/images/' + searchImage);
|
||||
enableLink(el);
|
||||
|
||||
// Update Status and Quality
|
||||
var rSearchTerm = /(\w+)\s\((.+?)\)/;
|
||||
HtmlContent = ep.status.replace(rSearchTerm,"$1"+' <span class="quality '+ep.quality+'">'+"$2"+'</span>');
|
||||
parent.closest('tr').prop("class", ep.overview + " season-" + ep.season + " seasonstyle")
|
||||
|
||||
}
|
||||
// update the status column if it exists
|
||||
@ -91,13 +92,13 @@ $(document).ready(function () {
|
||||
|
||||
function enableLink(el) {
|
||||
el.on('click.disabled', false);
|
||||
el.attr('enableClick', '1');
|
||||
el.prop('enableClick', '1');
|
||||
el.fadeTo("fast", 1)
|
||||
}
|
||||
|
||||
function disableLink(el) {
|
||||
el.off('click.disabled');
|
||||
el.attr('enableClick', '0');
|
||||
el.prop('enableClick', '0');
|
||||
el.fadeTo("fast", .5)
|
||||
}
|
||||
|
||||
@ -121,11 +122,11 @@ function disableLink(el) {
|
||||
event.preventDefault();
|
||||
|
||||
// Check if we have disabled the click
|
||||
if ( $(this).attr('enableClick') == '0' ) {
|
||||
if ( $(this).prop('enableClick') == '0' ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( $(this).attr('class') == "epRetry" ) {
|
||||
if ( $(this).prop('class') == "epRetry" ) {
|
||||
if ( !confirm("Mark download as bad and retry?") )
|
||||
return false;
|
||||
};
|
||||
@ -137,12 +138,12 @@ function disableLink(el) {
|
||||
|
||||
// Create var for img under anchor and set options for the loading gif
|
||||
img=$(this).children('img');
|
||||
img.attr('title','loading');
|
||||
img.attr('alt','');
|
||||
img.attr('src',sbRoot+'/images/' + options.loadingImage);
|
||||
img.prop('title','loading');
|
||||
img.prop('alt','');
|
||||
img.prop('src',sbRoot+'/images/' + options.loadingImage);
|
||||
|
||||
|
||||
$.getJSON($(this).attr('href'), function(data){
|
||||
$.getJSON($(this).prop('href'), function(data){
|
||||
|
||||
// if they failed then just put the red X
|
||||
if (data.result == 'failure') {
|
||||
@ -161,15 +162,15 @@ function disableLink(el) {
|
||||
HtmlContent = data.result.replace(rSearchTerm,"$1"+' <span class="quality '+data.quality+'">'+"$2"+'</span>');
|
||||
// update the status column if it exists
|
||||
parent.siblings('.col-status').html(HtmlContent)
|
||||
// Only if the queing was succesfull, disable the onClick event of the loading image
|
||||
// Only if the queuing was successful, disable the onClick event of the loading image
|
||||
disableLink(link);
|
||||
}
|
||||
|
||||
// put the corresponding image as the result of queuing of the manual search
|
||||
img.attr('title',img_result);
|
||||
img.attr('alt',img_result);
|
||||
img.attr('height', options.size);
|
||||
img.attr('src',sbRoot+"/images/"+img_name);
|
||||
img.prop('title',img_result);
|
||||
img.prop('alt',img_result);
|
||||
img.prop('height', options.size);
|
||||
img.prop('src',sbRoot+"/images/"+img_name);
|
||||
});
|
||||
//
|
||||
|
||||
|
@ -14,9 +14,9 @@
|
||||
$.each(subtitles,function(index, language){
|
||||
if (language != "" && language != "und") {
|
||||
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 {
|
||||
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}));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -102,7 +102,7 @@ $(document).ready(function(){
|
||||
$('#boxcar2_accesstoken').removeClass('warning');
|
||||
$(this).prop('disabled', true);
|
||||
$('#testBoxcar2-result').html(loading);
|
||||
$.get(sbRoot + '/home/testBoxcar2', {'accessToken': boxcar2_accesstoken})
|
||||
$.get(sbRoot + '/home/testBoxcar2', {'accesstoken': boxcar2_accesstoken})
|
||||
.done(function (data) {
|
||||
$('#testBoxcar2-result').html(data);
|
||||
$('#testBoxcar2').prop('disabled', false);
|
||||
@ -426,20 +426,25 @@ $(document).ready(function(){
|
||||
return false;
|
||||
}
|
||||
|
||||
var current_pushbullet_device = $("#pushbullet_device").val();
|
||||
$.get(sbRoot + "/home/getPushbulletDevices", {'api': pushbullet_api},
|
||||
function (data) {
|
||||
var devices = jQuery.parseJSON(data).devices;
|
||||
var current_pushbullet_device = $("#pushbullet_device").val();
|
||||
$("#pushbullet_device_list").html('');
|
||||
for (var i = 0; i < devices.length; i++) {
|
||||
if(devices[i].active == true) {
|
||||
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 {
|
||||
$("#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) {
|
||||
$('#testPushbullet-result').html(msg);
|
||||
}
|
||||
|
@ -204,7 +204,7 @@ $(document).ready(function(){
|
||||
$(this).getCategories(isDefault, data);
|
||||
}
|
||||
else {
|
||||
updateNewznabCaps( null, data );
|
||||
$(this).updateNewznabCaps( null, data );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -579,4 +579,4 @@ $(document).ready(function(){
|
||||
|
||||
$("#provider_order_list").disableSelection();
|
||||
|
||||
});
|
||||
});
|
||||
|
@ -69,6 +69,9 @@ $(document).ready(function(){
|
||||
$(host_desc_rtorrent).hide();
|
||||
$(host_desc_torrent).show();
|
||||
$(torrent_verify_cert_option).hide();
|
||||
$(torrent_verify_deluge).hide();
|
||||
$(torrent_verify_rtorrent).hide();
|
||||
$(torrent_auth_type).hide();
|
||||
$(torrent_path_option).show();
|
||||
$(torrent_path_option).find('.fileBrowser').show();
|
||||
$(torrent_seed_time_option).hide();
|
||||
@ -83,6 +86,7 @@ $(document).ready(function(){
|
||||
client = 'uTorrent';
|
||||
$(torrent_path_option).hide();
|
||||
$(torrent_seed_time_option).show();
|
||||
$('#host_desc_torrent').text('URL to your uTorrent client (e.g. http://localhost:8000)');
|
||||
} else if ('transmission' == selectedProvider){
|
||||
client = 'Transmission';
|
||||
$(torrent_seed_time_option).show();
|
||||
@ -90,12 +94,16 @@ $(document).ready(function(){
|
||||
$(torrent_label_option).hide();
|
||||
$(torrent_label_anime_option).hide();
|
||||
$(torrent_rpcurl_option).show();
|
||||
$('#host_desc_torrent').text('URL to your Transmission client (e.g. http://localhost:9091)');
|
||||
//$('#directory_title').text(client + directory);
|
||||
} else if ('deluge' == selectedProvider){
|
||||
client = 'Deluge';
|
||||
$(torrent_verify_cert_option).show();
|
||||
$(torrent_verify_deluge).show();
|
||||
$(torrent_verify_rtorrent).hide();
|
||||
$(label_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);
|
||||
} else if ('download_station' == selectedProvider){
|
||||
client = 'Synology DS';
|
||||
@ -103,13 +111,17 @@ $(document).ready(function(){
|
||||
$(torrent_label_anime_option).hide();
|
||||
$('#torrent_paused_option').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);
|
||||
$(path_synology).show();
|
||||
} else if ('rtorrent' == selectedProvider){
|
||||
client = 'rTorrent';
|
||||
$(host_desc_torrent).hide();
|
||||
$(host_desc_rtorrent).show();
|
||||
$(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);
|
||||
}
|
||||
$('#host_title').text(client + host);
|
||||
|
@ -51,7 +51,7 @@ $(document).ready(function () {
|
||||
},
|
||||
success: function (data) {
|
||||
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 = '';
|
||||
|
||||
if (data.results.length === 0) {
|
||||
@ -68,7 +68,7 @@ $(document).ready(function () {
|
||||
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 != "") {
|
||||
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 {
|
||||
|
@ -144,7 +144,7 @@ case "$1" in
|
||||
stop_sickbeard
|
||||
sleep 2
|
||||
start_sickbeard
|
||||
return $?
|
||||
exit $?
|
||||
;;
|
||||
status)
|
||||
status_of_proc -p "$PID_FILE" "$DAEMON" "$DESC"
|
||||
|
@ -58,7 +58,11 @@ class CacheControlAdapter(HTTPAdapter):
|
||||
response = cached_response
|
||||
else:
|
||||
# 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(
|
||||
request, response
|
||||
|
@ -5,6 +5,7 @@ import os
|
||||
|
||||
from . import (LockBase, LockFailed, NotLocked, NotMyLock, LockTimeout,
|
||||
AlreadyLocked)
|
||||
import errno
|
||||
|
||||
class LinkLockFile(LockBase):
|
||||
"""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:
|
||||
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?
|
||||
nlinks = os.stat(self.unique_name).st_nlink
|
||||
if nlinks == 2:
|
||||
|
@ -13,7 +13,7 @@ Requests is an HTTP library, written in Python, for human beings. Basic GET
|
||||
usage:
|
||||
|
||||
>>> import requests
|
||||
>>> r = requests.get('http://python.org')
|
||||
>>> r = requests.get('https://www.python.org')
|
||||
>>> r.status_code
|
||||
200
|
||||
>>> 'Python is a programming language' in r.content
|
||||
@ -22,7 +22,7 @@ usage:
|
||||
... or POST:
|
||||
|
||||
>>> 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)
|
||||
{
|
||||
...
|
||||
@ -36,17 +36,17 @@ usage:
|
||||
The other HTTP methods are supported - see `requests.api`. Full documentation
|
||||
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.
|
||||
|
||||
"""
|
||||
|
||||
__title__ = 'requests'
|
||||
__version__ = '2.3.0'
|
||||
__build__ = 0x020300
|
||||
__version__ = '2.5.1'
|
||||
__build__ = 0x020501
|
||||
__author__ = 'Kenneth Reitz'
|
||||
__license__ = 'Apache 2.0'
|
||||
__copyright__ = 'Copyright 2014 Kenneth Reitz'
|
||||
__copyright__ = 'Copyright 2015 Kenneth Reitz'
|
||||
|
||||
# Attempt to enable urllib3's SNI support, if possible
|
||||
try:
|
||||
|
@ -9,23 +9,27 @@ and maintain connections.
|
||||
"""
|
||||
|
||||
import socket
|
||||
import copy
|
||||
|
||||
from .models import Response
|
||||
from .packages.urllib3 import Retry
|
||||
from .packages.urllib3.poolmanager import PoolManager, proxy_from_url
|
||||
from .packages.urllib3.response import HTTPResponse
|
||||
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,
|
||||
except_on_missing_scheme, get_auth_from_url)
|
||||
prepend_scheme_if_needed, get_auth_from_url, urldefragauth)
|
||||
from .structures import CaseInsensitiveDict
|
||||
from .packages.urllib3.exceptions import MaxRetryError
|
||||
from .packages.urllib3.exceptions import TimeoutError
|
||||
from .packages.urllib3.exceptions import SSLError as _SSLError
|
||||
from .packages.urllib3.exceptions import ConnectTimeoutError
|
||||
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 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 .exceptions import ConnectionError, Timeout, SSLError, ProxyError
|
||||
from .exceptions import (ConnectionError, ConnectTimeout, ReadTimeout, SSLError,
|
||||
ProxyError, RetryError)
|
||||
from .auth import _basic_auth_str
|
||||
|
||||
DEFAULT_POOLBLOCK = False
|
||||
@ -57,13 +61,17 @@ class HTTPAdapter(BaseAdapter):
|
||||
: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 int max_retries: The maximum number of retries each connection
|
||||
should attempt. Note, this applies only to failed connections and
|
||||
timeouts, never to requests where the server returns a response.
|
||||
should attempt. Note, this applies only to failed DNS lookups, socket
|
||||
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.
|
||||
|
||||
Usage::
|
||||
|
||||
>>> import lib.requests
|
||||
>>> import requests
|
||||
>>> s = requests.Session()
|
||||
>>> a = requests.adapters.HTTPAdapter(max_retries=3)
|
||||
>>> s.mount('http://', a)
|
||||
@ -74,7 +82,10 @@ class HTTPAdapter(BaseAdapter):
|
||||
def __init__(self, pool_connections=DEFAULT_POOLSIZE,
|
||||
pool_maxsize=DEFAULT_POOLSIZE, max_retries=DEFAULT_RETRIES,
|
||||
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.proxy_manager = {}
|
||||
|
||||
@ -102,14 +113,17 @@ class HTTPAdapter(BaseAdapter):
|
||||
self.init_poolmanager(self._pool_connections, self._pool_maxsize,
|
||||
block=self._pool_block)
|
||||
|
||||
def init_poolmanager(self, connections, maxsize, block=DEFAULT_POOLBLOCK):
|
||||
"""Initializes a urllib3 PoolManager. This method should not be called
|
||||
from user code, and is only exposed for use when subclassing the
|
||||
def init_poolmanager(self, connections, maxsize, block=DEFAULT_POOLBLOCK, **pool_kwargs):
|
||||
"""Initializes a urllib3 PoolManager.
|
||||
|
||||
This method should not be called from user code, and is only
|
||||
exposed for use when subclassing the
|
||||
:class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
|
||||
|
||||
:param connections: The number of urllib3 connection pools to cache.
|
||||
:param maxsize: The maximum number of connections to save in the pool.
|
||||
: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
|
||||
self._pool_connections = connections
|
||||
@ -117,7 +131,30 @@ class HTTPAdapter(BaseAdapter):
|
||||
self._pool_block = block
|
||||
|
||||
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):
|
||||
"""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)
|
||||
|
||||
if proxy:
|
||||
except_on_missing_scheme(proxy)
|
||||
proxy_headers = self.proxy_headers(proxy)
|
||||
|
||||
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)
|
||||
proxy = prepend_scheme_if_needed(proxy, 'http')
|
||||
proxy_manager = self.proxy_manager_for(proxy)
|
||||
conn = proxy_manager.connection_from_url(url)
|
||||
else:
|
||||
# Only scheme should be lower case
|
||||
parsed = urlparse(url)
|
||||
@ -250,7 +278,7 @@ class HTTPAdapter(BaseAdapter):
|
||||
proxy = proxies.get(scheme)
|
||||
|
||||
if proxy and scheme != 'https':
|
||||
url, _ = urldefrag(request.url)
|
||||
url = urldefragauth(request.url)
|
||||
else:
|
||||
url = request.path_url
|
||||
|
||||
@ -297,7 +325,10 @@ class HTTPAdapter(BaseAdapter):
|
||||
|
||||
:param request: The :class:`PreparedRequest <PreparedRequest>` being sent.
|
||||
: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 cert: (optional) Any user-provided SSL certificate to be trusted.
|
||||
: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)
|
||||
|
||||
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:
|
||||
if not chunked:
|
||||
@ -369,10 +411,16 @@ class HTTPAdapter(BaseAdapter):
|
||||
# All is well, return the connection to the pool.
|
||||
conn._put_conn(low_conn)
|
||||
|
||||
except socket.error as sockerr:
|
||||
raise ConnectionError(sockerr, request=request)
|
||||
except (ProtocolError, socket.error) as err:
|
||||
raise ConnectionError(err, request=request)
|
||||
|
||||
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)
|
||||
|
||||
except _ProxyError as e:
|
||||
@ -381,14 +429,9 @@ class HTTPAdapter(BaseAdapter):
|
||||
except (_SSLError, _HTTPError) as e:
|
||||
if isinstance(e, _SSLError):
|
||||
raise SSLError(e, request=request)
|
||||
elif isinstance(e, TimeoutError):
|
||||
raise Timeout(e, request=request)
|
||||
elif isinstance(e, ReadTimeoutError):
|
||||
raise ReadTimeout(e, request=request)
|
||||
else:
|
||||
raise
|
||||
|
||||
r = self.build_response(request, resp)
|
||||
|
||||
if not stream:
|
||||
r.content
|
||||
|
||||
return r
|
||||
return self.build_response(request, resp)
|
||||
|
@ -22,12 +22,17 @@ def request(method, url, **kwargs):
|
||||
: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 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 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 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.
|
||||
:type allow_redirects: bool
|
||||
: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 stream: (optional) if ``False``, the response content will be immediately downloaded.
|
||||
@ -41,7 +46,12 @@ def request(method, url, **kwargs):
|
||||
"""
|
||||
|
||||
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):
|
||||
@ -77,15 +87,16 @@ def 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.
|
||||
|
||||
: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 json: (optional) json data to send in the body of the :class:`Request`.
|
||||
: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):
|
||||
|
@ -16,7 +16,8 @@ from base64 import b64encode
|
||||
|
||||
from .compat import urlparse, str
|
||||
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_MULTI_PART = 'multipart/form-data'
|
||||
@ -25,7 +26,11 @@ CONTENT_TYPE_MULTI_PART = 'multipart/form-data'
|
||||
def _basic_auth_str(username, password):
|
||||
"""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):
|
||||
@ -62,6 +67,7 @@ class HTTPDigestAuth(AuthBase):
|
||||
self.nonce_count = 0
|
||||
self.chal = {}
|
||||
self.pos = None
|
||||
self.num_401_calls = 1
|
||||
|
||||
def build_digest_header(self, method, url):
|
||||
|
||||
@ -146,6 +152,11 @@ class HTTPDigestAuth(AuthBase):
|
||||
|
||||
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):
|
||||
"""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:
|
||||
|
||||
setattr(self, 'num_401_calls', num_401_calls + 1)
|
||||
self.num_401_calls += 1
|
||||
pat = re.compile(r'digest ', flags=re.IGNORECASE)
|
||||
self.chal = parse_dict_header(pat.sub('', s_auth, count=1))
|
||||
|
||||
@ -178,7 +189,7 @@ class HTTPDigestAuth(AuthBase):
|
||||
|
||||
return _r
|
||||
|
||||
setattr(self, 'num_401_calls', 1)
|
||||
self.num_401_calls = 1
|
||||
return r
|
||||
|
||||
def __call__(self, r):
|
||||
@ -188,6 +199,11 @@ class HTTPDigestAuth(AuthBase):
|
||||
try:
|
||||
self.pos = r.body.tell()
|
||||
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_redirect)
|
||||
return r
|
||||
|
@ -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
|
||||
packaged CA bundle.
|
||||
"""
|
||||
|
||||
import os.path
|
||||
|
||||
|
||||
def where():
|
||||
"""Return the preferred certificate bundle."""
|
||||
# vendored bundle inside Requests
|
||||
return os.path.join(os.path.dirname(__file__), 'cacert.pem')
|
||||
try:
|
||||
from certifi import where
|
||||
except ImportError:
|
||||
def where():
|
||||
"""Return the preferred certificate bundle."""
|
||||
# vendored bundle inside Requests
|
||||
return os.path.join(os.path.dirname(__file__), 'cacert.pem')
|
||||
|
||||
if __name__ == '__main__':
|
||||
print(where())
|
||||
|
@ -75,7 +75,9 @@ is_solaris = ('solar==' in str(sys.platform).lower()) # Complete guess.
|
||||
|
||||
try:
|
||||
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
|
||||
|
||||
# ---------
|
||||
@ -90,7 +92,6 @@ if is_py2:
|
||||
from Cookie import Morsel
|
||||
from StringIO import StringIO
|
||||
from .packages.urllib3.packages.ordered_dict import OrderedDict
|
||||
from httplib import IncompleteRead
|
||||
|
||||
builtin_str = str
|
||||
bytes = str
|
||||
@ -106,7 +107,6 @@ elif is_py3:
|
||||
from http.cookies import Morsel
|
||||
from io import StringIO
|
||||
from collections import OrderedDict
|
||||
from http.client import IncompleteRead
|
||||
|
||||
builtin_str = str
|
||||
str = str
|
||||
|
@ -157,26 +157,28 @@ class CookieConflictError(RuntimeError):
|
||||
|
||||
|
||||
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
|
||||
don't specify one, since some clients may expect response.cookies and
|
||||
session.cookies to support dict operations.
|
||||
|
||||
Don't use the dict interface internally; it's just for compatibility with
|
||||
with external client code. All `requests` code should work out of the box
|
||||
with externally provided instances of CookieJar, e.g., LWPCookieJar and
|
||||
FileCookieJar.
|
||||
|
||||
Caution: dictionary operations that are normally O(1) may be O(n).
|
||||
Requests does not use the dict interface internally; it's just for
|
||||
compatibility with external client code. All requests code should work
|
||||
out of the box with externally provided instances of ``CookieJar``, e.g.
|
||||
``LWPCookieJar`` and ``FileCookieJar``.
|
||||
|
||||
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):
|
||||
"""Dict-like get() that also supports optional domain and path args in
|
||||
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:
|
||||
return self._find_no_duplicates(name, domain, path)
|
||||
except KeyError:
|
||||
@ -199,37 +201,38 @@ class RequestsCookieJar(cookielib.CookieJar, collections.MutableMapping):
|
||||
return c
|
||||
|
||||
def iterkeys(self):
|
||||
"""Dict-like iterkeys() that returns an iterator of names of cookies from the jar.
|
||||
See itervalues() and iteritems()."""
|
||||
"""Dict-like iterkeys() that returns an iterator of names of cookies
|
||||
from the jar. See itervalues() and iteritems()."""
|
||||
for cookie in iter(self):
|
||||
yield cookie.name
|
||||
|
||||
def keys(self):
|
||||
"""Dict-like keys() that returns a list of names of cookies from the jar.
|
||||
See values() and items()."""
|
||||
"""Dict-like keys() that returns a list of names of cookies from the
|
||||
jar. See values() and items()."""
|
||||
return list(self.iterkeys())
|
||||
|
||||
def itervalues(self):
|
||||
"""Dict-like itervalues() that returns an iterator of values of cookies from the jar.
|
||||
See iterkeys() and iteritems()."""
|
||||
"""Dict-like itervalues() that returns an iterator of values of cookies
|
||||
from the jar. See iterkeys() and iteritems()."""
|
||||
for cookie in iter(self):
|
||||
yield cookie.value
|
||||
|
||||
def values(self):
|
||||
"""Dict-like values() that returns a list of values of cookies from the jar.
|
||||
See keys() and items()."""
|
||||
"""Dict-like values() that returns a list of values of cookies from the
|
||||
jar. See keys() and items()."""
|
||||
return list(self.itervalues())
|
||||
|
||||
def iteritems(self):
|
||||
"""Dict-like iteritems() that returns an iterator of name-value tuples from the jar.
|
||||
See iterkeys() and itervalues()."""
|
||||
"""Dict-like iteritems() that returns an iterator of name-value tuples
|
||||
from the jar. See iterkeys() and itervalues()."""
|
||||
for cookie in iter(self):
|
||||
yield cookie.name, cookie.value
|
||||
|
||||
def items(self):
|
||||
"""Dict-like items() that returns a list of name-value tuples from the jar.
|
||||
See keys() and values(). Allows client-code to call "dict(RequestsCookieJar)
|
||||
and get a vanilla python dict of key value pairs."""
|
||||
"""Dict-like items() that returns a list of name-value tuples from the
|
||||
jar. See keys() and values(). Allows client-code to call
|
||||
``dict(RequestsCookieJar)`` and get a vanilla python dict of key value
|
||||
pairs."""
|
||||
return list(self.iteritems())
|
||||
|
||||
def list_domains(self):
|
||||
@ -259,8 +262,9 @@ class RequestsCookieJar(cookielib.CookieJar, collections.MutableMapping):
|
||||
return False # there is only one domain in jar
|
||||
|
||||
def get_dict(self, domain=None, path=None):
|
||||
"""Takes as an argument an optional domain and path and returns a plain old
|
||||
Python dict of name-value pairs of cookies that meet the requirements."""
|
||||
"""Takes as an argument an optional domain and path and returns a plain
|
||||
old Python dict of name-value pairs of cookies that meet the
|
||||
requirements."""
|
||||
dictionary = {}
|
||||
for cookie in iter(self):
|
||||
if (domain is None or cookie.domain == domain) and (path is None
|
||||
@ -269,21 +273,24 @@ class RequestsCookieJar(cookielib.CookieJar, collections.MutableMapping):
|
||||
return dictionary
|
||||
|
||||
def __getitem__(self, name):
|
||||
"""Dict-like __getitem__() for compatibility with client code. Throws exception
|
||||
if there are more than one cookie with name. In that case, use the more
|
||||
explicit get() method instead. Caution: operation is O(n), not O(1)."""
|
||||
"""Dict-like __getitem__() for compatibility with client code. Throws
|
||||
exception if there are more than one cookie with name. In that case,
|
||||
use the more explicit get() method instead.
|
||||
|
||||
.. warning:: operation is O(n), not O(1)."""
|
||||
|
||||
return self._find_no_duplicates(name)
|
||||
|
||||
def __setitem__(self, name, value):
|
||||
"""Dict-like __setitem__ for compatibility with client code. Throws exception
|
||||
if there is already a cookie of that name in the jar. In that case, use the more
|
||||
explicit set() method instead."""
|
||||
"""Dict-like __setitem__ for compatibility with client code. Throws
|
||||
exception if there is already a cookie of that name in the jar. In that
|
||||
case, use the more explicit set() method instead."""
|
||||
|
||||
self.set(name, value)
|
||||
|
||||
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)
|
||||
|
||||
def set_cookie(self, cookie, *args, **kwargs):
|
||||
@ -300,10 +307,11 @@ class RequestsCookieJar(cookielib.CookieJar, collections.MutableMapping):
|
||||
super(RequestsCookieJar, self).update(other)
|
||||
|
||||
def _find(self, name, domain=None, path=None):
|
||||
"""Requests uses this method internally to get cookie values. Takes as args name
|
||||
and optional domain and path. Returns a cookie.value. If there are conflicting cookies,
|
||||
_find arbitrarily chooses one. See _find_no_duplicates if you want an exception thrown
|
||||
if there are conflicting cookies."""
|
||||
"""Requests uses this method internally to get cookie values. Takes as
|
||||
args name and optional domain and path. Returns a cookie.value. If
|
||||
there are conflicting cookies, _find arbitrarily chooses one. See
|
||||
_find_no_duplicates if you want an exception thrown if there are
|
||||
conflicting cookies."""
|
||||
for cookie in iter(self):
|
||||
if cookie.name == name:
|
||||
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))
|
||||
|
||||
def _find_no_duplicates(self, name, domain=None, path=None):
|
||||
"""__get_item__ and get call _find_no_duplicates -- never used in Requests internally.
|
||||
Takes as args name and optional domain and path. Returns a cookie.value.
|
||||
Throws KeyError if cookie is not found and CookieConflictError if there are
|
||||
multiple cookies that match name and optionally domain and path."""
|
||||
"""Both ``__get_item__`` and ``get`` call this function: it's never
|
||||
used elsewhere in Requests. Takes as args name and optional domain and
|
||||
path. Returns a cookie.value. Throws KeyError if cookie is not found
|
||||
and CookieConflictError if there are multiple cookies that match name
|
||||
and optionally domain and path."""
|
||||
toReturn = None
|
||||
for cookie in iter(self):
|
||||
if cookie.name == name:
|
||||
@ -440,7 +449,7 @@ def merge_cookies(cookiejar, cookies):
|
||||
"""
|
||||
if not isinstance(cookiejar, cookielib.CookieJar):
|
||||
raise ValueError('You can only merge into CookieJar')
|
||||
|
||||
|
||||
if isinstance(cookies, dict):
|
||||
cookiejar = cookiejar_from_dict(
|
||||
cookies, cookiejar=cookiejar, overwrite=False)
|
||||
|
@ -44,7 +44,23 @@ class SSLError(ConnectionError):
|
||||
|
||||
|
||||
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):
|
||||
@ -73,3 +89,11 @@ class ChunkedEncodingError(RequestException):
|
||||
|
||||
class ContentDecodingError(RequestException, BaseHTTPError):
|
||||
"""Failed to decode response content"""
|
||||
|
||||
|
||||
class StreamConsumedError(RequestException, TypeError):
|
||||
"""The content for this response was already consumed"""
|
||||
|
||||
|
||||
class RetryError(RequestException):
|
||||
"""Custom retries logic failed"""
|
||||
|
@ -19,31 +19,35 @@ from .cookies import cookiejar_from_dict, get_cookie_header
|
||||
from .packages.urllib3.fields import RequestField
|
||||
from .packages.urllib3.filepost import encode_multipart_formdata
|
||||
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 (
|
||||
HTTPError, RequestException, MissingSchema, InvalidURL,
|
||||
ChunkedEncodingError, ContentDecodingError)
|
||||
HTTPError, MissingSchema, InvalidURL, ChunkedEncodingError,
|
||||
ContentDecodingError, ConnectionError, StreamConsumedError)
|
||||
from .utils import (
|
||||
guess_filename, get_auth_from_url, requote_uri,
|
||||
stream_decode_response_unicode, to_key_val_list, parse_header_links,
|
||||
iter_slices, guess_json_utf, super_len, to_native_string)
|
||||
from .compat import (
|
||||
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
|
||||
|
||||
#: The set of HTTP status codes that indicate an automatically
|
||||
#: processable redirect.
|
||||
REDIRECT_STATI = (
|
||||
codes.moved, # 301
|
||||
codes.found, # 302
|
||||
codes.other, # 303
|
||||
codes.temporary_moved, # 307
|
||||
codes.moved, # 301
|
||||
codes.found, # 302
|
||||
codes.other, # 303
|
||||
codes.temporary_redirect, # 307
|
||||
codes.permanent_redirect, # 308
|
||||
)
|
||||
DEFAULT_REDIRECT_LIMIT = 30
|
||||
CONTENT_CHUNK_SIZE = 10 * 1024
|
||||
ITER_CHUNK_SIZE = 512
|
||||
|
||||
json_dumps = json.dumps
|
||||
|
||||
|
||||
class RequestEncodingMixin(object):
|
||||
@property
|
||||
@ -187,7 +191,8 @@ class Request(RequestHooksMixin):
|
||||
:param url: URL to send.
|
||||
:param headers: dictionary of headers to send.
|
||||
: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 auth: Auth handler or (user, pass) tuple.
|
||||
:param cookies: dictionary or CookieJar of cookies to attach to this request.
|
||||
@ -210,7 +215,8 @@ class Request(RequestHooksMixin):
|
||||
params=None,
|
||||
auth=None,
|
||||
cookies=None,
|
||||
hooks=None):
|
||||
hooks=None,
|
||||
json=None):
|
||||
|
||||
# Default empty dicts for dict params.
|
||||
data = [] if data is None else data
|
||||
@ -228,6 +234,7 @@ class Request(RequestHooksMixin):
|
||||
self.headers = headers
|
||||
self.files = files
|
||||
self.data = data
|
||||
self.json = json
|
||||
self.params = params
|
||||
self.auth = auth
|
||||
self.cookies = cookies
|
||||
@ -244,6 +251,7 @@ class Request(RequestHooksMixin):
|
||||
headers=self.headers,
|
||||
files=self.files,
|
||||
data=self.data,
|
||||
json=self.json,
|
||||
params=self.params,
|
||||
auth=self.auth,
|
||||
cookies=self.cookies,
|
||||
@ -287,14 +295,15 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
|
||||
self.hooks = default_hooks()
|
||||
|
||||
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."""
|
||||
|
||||
self.prepare_method(method)
|
||||
self.prepare_url(url, params)
|
||||
self.prepare_headers(headers)
|
||||
self.prepare_cookies(cookies)
|
||||
self.prepare_body(data, files)
|
||||
self.prepare_body(data, files, json)
|
||||
self.prepare_auth(auth, url)
|
||||
# Note that prepare_auth must be last to enable authentication schemes
|
||||
# such as OAuth to work on a fully prepared request.
|
||||
@ -309,8 +318,8 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
|
||||
p = PreparedRequest()
|
||||
p.method = self.method
|
||||
p.url = self.url
|
||||
p.headers = self.headers.copy()
|
||||
p._cookies = self._cookies.copy()
|
||||
p.headers = self.headers.copy() if self.headers is not None else None
|
||||
p._cookies = self._cookies.copy() if self._cookies is not None else None
|
||||
p.body = self.body
|
||||
p.hooks = self.hooks
|
||||
return p
|
||||
@ -324,21 +333,27 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
|
||||
def prepare_url(self, url, params):
|
||||
"""Prepares the given HTTP URL."""
|
||||
#: Accept objects that have string representations.
|
||||
try:
|
||||
url = unicode(url)
|
||||
except NameError:
|
||||
# We're on Python 3.
|
||||
url = str(url)
|
||||
except UnicodeDecodeError:
|
||||
pass
|
||||
#: We're unable to blindy call unicode/str functions
|
||||
#: as this will include the bytestring indicator (b'')
|
||||
#: on python 3.x.
|
||||
#: https://github.com/kennethreitz/requests/pull/2238
|
||||
if isinstance(url, bytes):
|
||||
url = url.decode('utf8')
|
||||
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'):
|
||||
self.url = url
|
||||
return
|
||||
|
||||
# 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:
|
||||
raise MissingSchema("Invalid URL {0!r}: No schema supplied. "
|
||||
@ -395,7 +410,7 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
|
||||
else:
|
||||
self.headers = CaseInsensitiveDict()
|
||||
|
||||
def prepare_body(self, data, files):
|
||||
def prepare_body(self, data, files, json=None):
|
||||
"""Prepares the given HTTP body data."""
|
||||
|
||||
# Check if file, fo, generator, iterator.
|
||||
@ -406,11 +421,13 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
|
||||
content_type = None
|
||||
length = None
|
||||
|
||||
if json is not None:
|
||||
content_type = 'application/json'
|
||||
body = json_dumps(json)
|
||||
|
||||
is_stream = all([
|
||||
hasattr(data, '__iter__'),
|
||||
not isinstance(data, basestring),
|
||||
not isinstance(data, list),
|
||||
not isinstance(data, dict)
|
||||
not isinstance(data, (basestring, list, tuple, dict))
|
||||
])
|
||||
|
||||
try:
|
||||
@ -433,9 +450,9 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
|
||||
if files:
|
||||
(body, content_type) = self._encode_files(files, data)
|
||||
else:
|
||||
if data:
|
||||
if data and json is None:
|
||||
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
|
||||
else:
|
||||
content_type = 'application/x-www-form-urlencoded'
|
||||
@ -443,7 +460,7 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
|
||||
self.prepare_content_length(body)
|
||||
|
||||
# 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.body = body
|
||||
@ -457,7 +474,7 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
|
||||
l = super_len(body)
|
||||
if 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'
|
||||
|
||||
def prepare_auth(self, auth, url=''):
|
||||
@ -558,6 +575,10 @@ class Response(object):
|
||||
#: and the arrival of the response (as a timedelta)
|
||||
self.elapsed = datetime.timedelta(0)
|
||||
|
||||
#: The :class:`PreparedRequest <PreparedRequest>` object to which this
|
||||
#: is a response.
|
||||
self.request = None
|
||||
|
||||
def __getstate__(self):
|
||||
# Consume everything; accessing the content attribute makes
|
||||
# sure the content has been fully read.
|
||||
@ -596,7 +617,7 @@ class Response(object):
|
||||
def ok(self):
|
||||
try:
|
||||
self.raise_for_status()
|
||||
except RequestException:
|
||||
except HTTPError:
|
||||
return False
|
||||
return True
|
||||
|
||||
@ -607,6 +628,11 @@ class Response(object):
|
||||
"""
|
||||
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
|
||||
def apparent_encoding(self):
|
||||
"""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
|
||||
read into memory. This is not necessarily the length of each item
|
||||
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():
|
||||
try:
|
||||
# Special case for urllib3.
|
||||
try:
|
||||
for chunk in self.raw.stream(chunk_size, decode_content=True):
|
||||
yield chunk
|
||||
except IncompleteRead as e:
|
||||
except ProtocolError as e:
|
||||
raise ChunkedEncodingError(e)
|
||||
except DecodeError as e:
|
||||
raise ContentDecodingError(e)
|
||||
except ReadTimeoutError as e:
|
||||
raise ConnectionError(e)
|
||||
except AttributeError:
|
||||
# Standard file-like object.
|
||||
while True:
|
||||
@ -643,14 +670,21 @@ class Response(object):
|
||||
|
||||
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:
|
||||
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
|
||||
stream=True is set on the request, this avoids reading the
|
||||
content at once into memory for large responses.
|
||||
@ -662,7 +696,11 @@ class Response(object):
|
||||
|
||||
if pending is not None:
|
||||
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]:
|
||||
pending = lines.pop()
|
||||
@ -793,8 +831,8 @@ class Response(object):
|
||||
raise HTTPError(http_error_msg, response=self)
|
||||
|
||||
def close(self):
|
||||
"""Closes the underlying file descriptor and releases the connection
|
||||
back to the pool.
|
||||
"""Releases the connection back to the pool. Once this method has been
|
||||
called the underlying ``raw`` object must not be accessed again.
|
||||
|
||||
*Note: Should not normally need to be called explicitly.*
|
||||
"""
|
||||
|