Commit e77142b8 authored by Mario Chirinos Colunga's avatar Mario Chirinos Colunga 💬

audio list

parent beef9215
No preview for this file type
import sys
import argparse
import os
import subprocess
from numpy import array_equal
from datetime import datetime, timedelta
BASEDIR = "/home/mario/"
#-------------------------------------------------------------------------------
def getRecordingDays(initTimestamp, endTimestamp):
initialDate = datetime.fromtimestamp(initTimestamp) #+ timedelta(hours=6)
endDate = datetime.fromtimestamp(endTimestamp) #+ timedelta(hours=6)
print(initialDate)
print(endDate)
iDate = [initialDate.day, initialDate.month, initialDate.year]
eDate = [endDate.day, endDate.month, endDate.year]
days = 1
if array_equal(iDate, eDate):
# Iterate over the same day dir
return days
else:
while not array_equal(iDate, eDate):
days += 1
initialDate += timedelta(days=1)
iDate = [initialDate.day, initialDate.month, initialDate.year]
return days
#-------------------------------------------------------------------------------
def getAudiosList2Convert(streamPublisher, initTimestamp, endTimestamp, days):
recordingsPath = BASEDIR+'virtualHDD/m3/recordings/'
initialDate = datetime.fromtimestamp(initTimestamp) #+ timedelta(hours=6)
endDate = datetime.fromtimestamp(endTimestamp) #+ timedelta(hours=6)
audiosList = []
for i in range(days):
audiosPath = '{0}/{1}/{2:02d}/{3:02d}/'.format(
streamPublisher,
initialDate.year,
initialDate.month,
initialDate.day
)
print('Now enter in: {0}'.format(audiosPath))
print(recordingsPath+audiosPath)
if os.path.exists(recordingsPath+audiosPath):
print ("PATH EXIST")
for file in os.listdir(recordingsPath+audiosPath):
# print (file)
audioTimestamp = int(file.split(".")[0])
if audioTimestamp >= initTimestamp and audioTimestamp <= endTimestamp:
audiosList.append(recordingsPath+audiosPath+file)
#audiosList.append((recordingsPath+audiosPath, file))
# Next day dir
initialDate += timedelta(days=1)
return audiosList
#-------------------------------------------------------------------------------
def convertAudios2Mp3(audiosList):
mp3Path = BASEDIR+'virtualHDD/m3/recordings/mp3/'
if not os.path.exists(mp3Path):
print('Mp3 created...')
os.mkdir(mp3Path)
for (audioPath, audioName) in audiosList:
timestamp = audioName.split('.')[0]
print('Timestamp: {0} - Date format: {1}'.format(timestamp, datetime.fromtimestamp(float(timestamp))))
mp3Name = timestamp + '.mp3'
convertionCommand = 'ffmpeg -i "{0}" -qscale:a 20 {1}'.format(audioPath+audioName, mp3Path+mp3Name)
subprocess.run(convertionCommand, shell=True)
#-------------------------------------------------------------------------------
def getAudioList(streamPublisher, initTimestamp, endTimestamp):
print("getAudioList(", streamPublisher, ",", initTimestamp, ",", endTimestamp, ")")
initTimestamp = float(initTimestamp)
endTimestamp = float(endTimestamp)
days = getRecordingDays(initTimestamp, endTimestamp)
print('Recording days: {0}'.format(days))
audiosList = getAudiosList2Convert(streamPublisher, initTimestamp, endTimestamp, days)
return audiosList
......@@ -2,33 +2,32 @@
from django import forms
#from django.contrib.auth.forms import UserCreationForm
#from django.contrib.auth.models import User
from catalog.models import Publisher, News, Profile
from catalog.models import Publisher, News, Profile, Search
from django.db.models import Q
from django.contrib.admin.widgets import FilteredSelectMultiple
import os
from django.conf import settings
from django.urls import reverse
class SearchForm(forms.ModelForm):
class Meta:
model = Search
exclude = ["user"]
# fields = '__all__'
class SearchForm(forms.Form):
startDate = forms.DateField(label="Fecha de Inicio", widget=forms.DateInput(attrs={'type':'date', 'class':"form-control"}), required=False)
endDate = forms.DateField(label="Fecha de Fin", widget=forms.DateInput(attrs={'type':'date', 'class':"form-control"}), required=False)
widgets = {'startDate': forms.DateInput(attrs={'type':'date', 'class':"form-control"}),
'endDate': forms.DateInput(attrs={'type':'date', 'class':"form-control"}),
'text':forms.TextInput(attrs={'class':"form-control", "placeholder":"Palabras clave"}),
'publishers':forms.SelectMultiple(attrs={'class':"form-control"}),
'user': forms.HiddenInput(),
}
labels = {'startDate':"Fecha de Inicio", 'endDate':"Fecha de Fin", 'text': "Palabras Clave", 'publishers':"Fuentes",}
# news = News.objects.all()
# publishersList = Publisher.objects.all().filter( Q(id__in = news.values('publisher').distinct()))
# choice = [ (r.id,r.name) for r in publishersList ]
# publishers = forms.MultipleChoiceField(label="Fuentes", widget=forms.SelectMultiple(attrs={'class':"form-control"}), choices=choice, required=False)
def save(self, user):
form = super(SearchForm, self).save(commit=False)
form.user = user
form.save()
publishers = forms.MultipleChoiceField(label="Fuentes", widget=forms.SelectMultiple(attrs={'class':"form-control"}), choices=[], required=False)
text = forms. CharField(label="Palabras Clave", widget=forms.TextInput(attrs={'class':"form-control", "placeholder":"Palabras clave"}), required=False)
def __init__(self, *args, **kwargs):
super(SearchForm, self).__init__(*args, **kwargs)
news = News.objects.all()
publishersList = Publisher.objects.all().filter( Q(id__in = news.values('publisher').distinct()))
choice = [ (r.id,r.name) for r in publishersList ]
self.fields['publishers'] = forms.MultipleChoiceField(label="Fuentes", widget=forms.SelectMultiple(attrs={'class':"form-control"}), choices=choice, required=False)
class ProfileForm(forms.Form):
subscriptions = forms.ModelMultipleChoiceField(queryset=Publisher.objects.all(), widget=FilteredSelectMultiple("Publishers", is_stacked=False), required=False)
......@@ -39,3 +38,30 @@ class ProfileForm(forms.Form):
# in the temple
css = {'all': (os.path.join(settings.BASE_DIR, '/static/admin/css/widgets.css'),),}
js = ('/catalog/js/jsi18n',)
class SubscriptionsForm(forms.ModelForm):
# def __init__(self, *args, **kwargs):
# super(SubscriptionsForm, self).__init__(*args, **kwargs)
# news = News.objects.all()
# publishersList = Publisher.objects.all().filter( Q(id__in = news.values('publisher').distinct()))
# choice = [ (r.id,r.name) for r in publishersList ]
# self.fields['subscriptions'].choices = []
class Meta:
model = Profile
fields = ('subscriptions',)
# field_classes = {'subscriptions': forms.ModelMultipleChoiceField,}
widgets = {'subscriptions': FilteredSelectMultiple("Publishers", is_stacked=False),}
class Media:
# Django also includes a few javascript files necessary
# for the operation of this form element. You need to
# include <script src="/admin/jsi18n"></script>
# in the temple
css = {'all': (os.path.join(settings.BASE_DIR, '/static/admin/css/widgets.css'),),}
js = ('/catalog/js/jsi18n')
#forms.MultipleChoiceField(label="Fuentes", widget=forms.SelectMultiple(attrs={'class':"form-control"}), choices=choice, required=False)
No preview for this file type
from django.core.management.base import BaseCommand, CommandError
from catalog.models import News, Publisher, Topic
from catalog.models import News, Publisher, Topic, audioTime
from django.db.models import Q
import os
import json
import datetime
from django.utils import timezone
import dateutil.parser
import itertools
from datetime import date
class Command(BaseCommand):
help = 'Update database'
......@@ -14,6 +17,25 @@ class Command(BaseCommand):
parser.add_argument('basedir', nargs=1, type=str)
def handle(self, *args, **options):
#update radio stations recotding time
print("Recording Time:")
recordingsDir = "/home/mario/virtualHDD/m3/recordings/"
audioTime.objects.all().delete()
publishers = Publisher.objects.all().filter(type="audio")
for p in publishers:
files = [files for r, d, files in os.walk(recordingsDir+p.shortName)]
files = list(itertools.chain.from_iterable(files))
minutes = len(files)
sortedFiles = sorted([(f[:f.find(".flac")]) for f in files if f.find(".flac")>0 and f.count(".")==1])
print(p.shortName+": "+ str(minutes))
if len(sortedFiles)>2:
print("timestamp: " + sortedFiles[0])
print("len timestamp: " + str(len(sortedFiles[0])))
#print (files)
#print (sortedFiles)
since = datetime.datetime.utcfromtimestamp(int(sortedFiles[0]))
audioTime.objects.update_or_create(publisher=p, defaults={'minutes': minutes, "startDate": since},)
#load news
os.chdir(options['basedir'][0])
publisherList = os.listdir(options['basedir'][0])
for p in publisherList:
......
# -*- coding: utf-8 -*-
# Generated by Django 1.11.7 on 2017-12-14 18:25
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('catalog', '0008_profile_subscriptions'),
]
operations = [
migrations.CreateModel(
name='Search',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('startDate', models.DateTimeField(verbose_name=b'Start Date')),
('endDate', models.DateTimeField(verbose_name=b'End Date')),
('text', models.CharField(max_length=128)),
('publishers', models.ManyToManyField(to='catalog.Publisher')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
]
# -*- coding: utf-8 -*-
# Generated by Django 1.11.7 on 2017-12-14 18:52
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('catalog', '0009_search'),
]
operations = [
migrations.AlterField(
model_name='search',
name='publishers',
field=models.ManyToManyField(blank=True, to='catalog.Publisher'),
),
]
# -*- coding: utf-8 -*-
# Generated by Django 1.11.7 on 2017-12-18 18:43
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('catalog', '0010_auto_20171214_1852'),
]
operations = [
migrations.AlterField(
model_name='search',
name='text',
field=models.CharField(blank=True, max_length=128),
),
]
# -*- coding: utf-8 -*-
# Generated by Django 1.11.7 on 2017-12-21 16:47
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('catalog', '0011_auto_20171218_1843'),
]
operations = [
migrations.AlterField(
model_name='search',
name='endDate',
field=models.DateTimeField(blank=True, verbose_name=b'End Date'),
),
migrations.AlterField(
model_name='search',
name='startDate',
field=models.DateTimeField(blank=True, verbose_name=b'Start Date'),
),
]
# -*- coding: utf-8 -*-
# Generated by Django 1.11.7 on 2017-12-21 17:28
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('catalog', '0012_auto_20171221_1647'),
]
operations = [
migrations.AlterField(
model_name='search',
name='endDate',
field=models.DateTimeField(blank=True, null=True, verbose_name=b'End Date'),
),
migrations.AlterField(
model_name='search',
name='startDate',
field=models.DateTimeField(blank=True, null=True, verbose_name=b'Start Date'),
),
]
# -*- coding: utf-8 -*-
# Generated by Django 1.11.7 on 2017-12-21 18:20
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('catalog', '0013_auto_20171221_1728'),
]
operations = [
migrations.AlterField(
model_name='search',
name='endDate',
field=models.DateTimeField(verbose_name=b'End Date'),
),
migrations.AlterField(
model_name='search',
name='startDate',
field=models.DateTimeField(verbose_name=b'Start Date'),
),
]
# -*- coding: utf-8 -*-
# Generated by Django 1.11.9 on 2018-01-31 20:50
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('catalog', '0014_auto_20171221_1820'),
]
operations = [
migrations.CreateModel(
name='audioTime',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('startDate', models.DateTimeField(verbose_name=b'Start Date')),
('seconds', models.BigIntegerField(default=0)),
('publisher', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='catalog.Publisher')),
],
),
]
# -*- coding: utf-8 -*-
# Generated by Django 1.11.9 on 2018-01-31 21:05
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('catalog', '0015_audiotime'),
]
operations = [
migrations.RenameField(
model_name='audiotime',
old_name='seconds',
new_name='minutes',
),
]
......@@ -8,6 +8,8 @@ from django.dispatch import receiver
# Create your models here.
#-------------------------------------------------------------------------------
class Publisher(models.Model):
name = models.CharField(max_length=128)
shortName = models.CharField(max_length=32, default="")
......@@ -23,7 +25,7 @@ class Publisher(models.Model):
verbose_name_plural = 'Medios'
ordering = ('name',)
#-------------------------------------------------------------------------------
class Topic(models.Model):
name = models.CharField(verbose_name='Tema', max_length=256)
......@@ -34,12 +36,12 @@ class Topic(models.Model):
verbose_name = 'Tema'
verbose_name_plural = 'Temas'
ordering = ('name',)
#-------------------------------------------------------------------------------
class PostManager(models.Manager):
def with_documents(self):
vector = SearchVector('text')
return self.get_queryset().annotate(document=vector)
#-------------------------------------------------------------------------------
class News(models.Model):
title = models.CharField(max_length=512)
publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE, default='')
......@@ -65,19 +67,36 @@ class News(models.Model):
verbose_name_plural = 'Noticias'
ordering = ('date',)
indexes = [ GinIndex(fields=['search_vector']) ]
#-------------------------------------------------------------------------------
class Search(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
startDate = models.DateTimeField(verbose_name='Start Date')
endDate = models.DateTimeField(verbose_name='End Date')
text = models.CharField(max_length=128,blank=True)
publishers = models.ManyToManyField(Publisher,blank=True)
#-------------------------------------------------------------------------------
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
subscriptions = models.ManyToManyField(Publisher)
# def __init__(self, *args, **kwargs):
# self.subscriptions = Publisher.objects.all()
# super().__init__(*args, **kwargs)
@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
Profile.objects.create(user=instance)#, subscriptions=Publisher.objects.all())
print ("profile created")
@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
instance.profile.save()
#-------------------------------------------------------------------------------
class audioTime(models.Model):
publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE)
startDate = models.DateTimeField(verbose_name='Start Date')
minutes = models.BigIntegerField(default=0)
No preview for this file type
body {padding: 0; color: #888;}
.page-wrapper {margin-top: 0px; overflow: hidden;}
.page-content, .footer-content {padding:0px 0; padding-bottom: 30px;}
.head-content {padding-top: 80px;}
.container {padding: 0;}
.navbar-fixed-top {padding: 20px 0; height: auto; background-color: rgba(255, 255, 255, 0.5); border: none; margin: 0;}
.navbar-fixed-top .btn{font-size: 16px; font-weight: bold; padding: 0 15px;}
.navbar-default .navbar-brand {padding: 0; margin: 0;}
.navbar-fixed-top .navbar-collapse {width: 100%;}
.logo {}
.logo .path { fill: #fff;}
.logo {width: 130px;height: 140px;}
.footer-content {margin-top: 60px; background-color: #555; padding: 30px;}
.footer-content .download{padding: 30px;text-align: center;border-bottom: 1px solid #666;width: 100%;margin-bottom: 30px;}
.footer-content .download .glyphicon{font-size: 40px;color: #FFF;}
.footer-content .download .btn {border: 0;}
.jumbotron {padding:20px 15px;border: none; background: none; margin-bottom: 0;}
.jumbotron .btn-group .btn {background-color: transparent;border: 1px solid transparent; font-size: 22px; font-weight: bold; padding: 15px 30px; border: 0; }
.jumbotron .btn-group .btn .glyphicon {color: rgba(0,0,0,0.2); margin-right: 10px;font-size: 20px;}
.jumbotron .btn-group .btn:hover .glyphicon {color: #fff;}
.calendar-view .sample-calendar { margin: 30px 0;}
.range-cal-trigger{ border: 0; height: 100%; background-color: transparent;}
.range-cal-trigger .glyphicon {}
.themes-group .btn { border: 0; margin: 0 0px; padding: 10px 15px; height: 10px; position: relative;}
.themes-group .btn .glyphicon {font-size: 14px; line-height: 16px; opacity: .0; display: none; color: rgba(255,255,255,.8); margin: 0; padding: 0;margin-right: 10px; display: none; }
.themes-group .btn .title {font-weight: 100;font-size: 14px; float: left;}
.themes-group .btn .half-color { right: 0; top: 0; width: 50%;height: 100%; position: absolute; background-color: #f9f9f9;}
.themes-group .btn.selected {border: 1px solid rgba(255,255,255,0.5);}
.themes-group .btn.selected .glyphicon {color: #fff; opacity: 1.0; margin: 0; display: none;float: left; margin-right: 5px; margin-top: -10px; height: 20px;}
.themes-group .btn.selected .title {display: block;}
.themes-group .btn.selected .half-color { opacity: 0.5;}
.themes-group .colors-info .title{ font-weight: bold; font-size: 16px; display: block; clear: both; margin-bottom: 5px; opacity: 0.5; }
.themes-group .colors-info .subtitle{ font-weight: 100; font-size: 16px; width: 100px;display: block; clear: both;}
.themes-group .colors-info .title .glyphicon {margin-right: 5px; opacity: 0.5;}
.page-content .calendar-values { display: none;}
.calendar-values {margin-top: 30px;margin-bottom: 30px;}
.calendar-values .col { text-align: center; color: #888;}
.calendar-values > .col-md-3,.calendar-values >.col-md-4 { border-right: 1px solid #eee;}
.calendar-values .col.last { border: 0;}
.calendar-values .col .glyphicon {font-size: 40px;padding: 5px 0;margin-bottom: 5px;}
.calendar-values .col .glyphicon-comment {margin-top: 0;font-size: 63px;padding-top: 0;}
.calendar-values .col .title {width: 100%;text-align: center;font-size: 20px;font-weight: bold;display: block;clear: both;text-transform: uppercase;}
.calendar-values .col .subtitle {width: 100%;text-align: center;font-size: 12px;font-weight: bold;display: block;clear: both;text-transform: uppercase;}
.calendar-values .col .value {width: 100%; text-align: center; font-size: 40px; font-weight: bold; display: block; clear: both}
.calendar-values .col .label {width: 100%;text-align: center; font-size: 14px;font-weight: bold; display: block; clear: both; text-transform: uppercase; color: #666 }
.calendar-values .col .label small { margin-left: 5px;color: #888; font-weight: 100}
#how .pre {border: 1px solid #eee; background-color: transparent;}
.modal {}
.modal .modal-content {box-shadow: none; border: 0; margin: 0; background-color: #f9f9f9;}
.modal .modal-footer {box-shadow: none; border: 0; margin: 0;}
.modal .btn-close {position: absolute;top: 0;right: 0;border: 0;margin: 15px;}
.modal .calendar-values { padding: 20px 0; margin: 0px;}
.modal .range-calendar {padding: 10px 0;}
.modal .calendar-values .col .glyphicon {font-size: 22px;}
.modal .calendar-values .col .glyphicon-comment {font-size: 22px;}
.modal .calendar-values .col .title {font-size: 12px;}
.modal .calendar-values .col .subtitle {font-size: 12px;}
.modal .calendar-values .col .value {font-size: 30px;}
.modal .calendar-values .col .label {font-size: 14px;}
#langs {margin-left: 10px;}
#langs .dropdown-toggle {color: #666;}
.colorization-group { margin-top: 15px;}
.colorization-group .btn {padding: 15px; border: 0; border-radius: 1px;}
.colorization-group .btn .glyphicon {font-size: 14px; line-height: 16px; opacity: .0; display: none; color: rgba(255,255,255,.8); margin: 0; padding: 0;margin-right: 10px; display: none; }
.colorization-group .btn .title {font-weight: 100;font-size: 14px; float: left;}
.colorization-group .btn .half-color { right: 0; top: 0; width: 50%;height: 100%; position: absolute; background-color: #f9f9f9;}
.colorization-group .btn.selected {border: 1px solid rgba(255,255,255,0.5);}
.colorization-group .btn.selected .glyphicon {color: #fff; opacity: 1.0; margin: 0; display: none;float: left; margin-right: 5px; margin-top: -10px; height: 20px;}
.colorization-group .btn.selected .title {display: block;}
.colorization-group .btn.selected .half-color { opacity: 0.5;}
.colorization-group .colors-info .title{ font-weight: bold; font-size: 16px; display: block; clear: both; margin-bottom: 5px; opacity: 0.5; }
.colorization-group .colors-info .subtitle{ font-weight: 100; font-size: 16px; width: 100px;display: block; clear: both;}
.colorization-group .colors-info .title .glyphicon {margin-right: 5px; opacity: 0.5;}
.section {padding-bottom: 15px; margin-bottom: 15px;clear: both; display: block;}
.section .section-title {color: #666; margin-bottom: 15px;}
.section .content {margin-bottom: 15px;}
.section .code {padding: 30px 15px;background-color: #333; color: #f9f9f9; width: 100%;display: block;border-radius: 0; line-height: 25px; display: block;clear: both; margin-bottom: 10px;}
.section .code .sample-title {clear: both;margin-bottom: 15px;width: 100%;display: block;line-height: 60px;font-size: 25px;font-weight: bold;}
.section .range-calendar {margin-top: 15px;}
p {font-size: 22px;}
.form-required { display: none; }
/**
* rangecalendar.css v 1.0.2
*
* Copyright 2013, Libero Angelo
* Email: angelo@afreeux.com
*
* rangecalendar.css v 1.1.0
*
* Copyright 2017, José Luis Uc
* Email: ucp.jose@gmail.com
**/
.range-calendar { clear: both; overflow: hidden; width: 100%; position: relative; -webkit-touch-callout: none;-webkit-user-select: none;-khtml-user-select: none;-moz-user-select: none;-ms-user-select: none;user-select: none;padding: 10px 0; background-color: transparent; }
.range-calendar.triggerable {display: none ;}
.calendar-wrapper {position: relative; left: 0;top: 0;z-index: 2; list-style: none; display: block;clear: both; overflow: hidden; padding: 10px 0; }
.range-calendar .calendar { z-index: 1; list-style: none;float: left;margin: 0; padding: 0 ; position: relative; width: 99999px;}
.range-calendar .calendar .cell {float: left;width: 70px; padding:25px 20px; margin: 0px; border-right: 1px solid rgba(0,0,0,0.03); text-align: center; position: relative;color: #888 ;}
.range-calendar .calendar .cell .day-number {display: block;clear: both; font-weight: bold;font-size: 20px; z-index: 1; position: relative; }
.range-calendar .calendar .cell .day {display: block;clear: both; text-transform: uppercase; width: 100%; font-weight: 100; font-size: 12px; margin-top: 0px; z-index: 1; position: relative;}
.range-calendar .calendar .cell .month { width: 100%; font-size: 12px;z-index: 1; text-transform: uppercase; position: absolute;opacity: 1;left: 0;top: 10px;font-weight: bold;}
.range-calendar .calendar .cell .day.ferial {font-weight: bold;}
.range-calendar .calendar .cell .month.first {opacity: 1;}
.range-calendar .calendar .cell:hover { background-color: rgba(0,0,0,.0); color: #888; }
.range-calendar .calendar .cell:hover .day-number {}
.range-calendar .calendar .cell:hover .day{ }
.range-calendar .calendar .cell:hover .month { }
.range-calendar .calendar .cell.selected {background: transparent;color: #fff;border-right: 1px solid rgba(0, 0, 0, 0.04);}
.range-calendar .calendar .cell.selected.last {border: none !important;}
.range-calendar .calendar .cell.selected .day-number, .calendar .cell.ui-selecting .day-number { z-index: 2; position: relative;}
.range-calendar .calendar .cell.selected .month, .calendar .cell.ui-selecting .month {z-index: 2; position: relative; opacity: 1;}
.range-calendar .calendar .cell.selected .day, .calendar .cell.ui-selecting day{ z-index: 2; position: relative;}
.range-calendar .calendar .cell.selected .day.ferial, .calendar .cell.ui-selecting day.ferial{ z-index: 2; position: relative;font-weight: bold;}
.range-calendar .months { z-index: 1; list-style: none;float: left;margin: 0; padding: 0; position: relative; width: 99999px; border-bottom: 0px solid #f9f9f9; margin-bottom: 10px;}
.range-calendar.auto-hide-months .months {display: none;}
.range-calendar .months .cell {float: left;width: 105px; padding: 10px 10px; margin: 0px 0; text-align: center; position: relative;color: #888; border-right: 0px solid rgba(0,0,0,0.03); position: relative; }
.range-calendar .months .cell .month-name { font-weight: bold;font-size: 12px; z-index: 1; position: relative; text-transform: uppercase;}
.range-calendar .months .cell .date-formatted {font-weight: 100; font-size: 12px; }
.range-calendar .months .cell .bullet {position: absolute;left: 15px;top: 15px;height: 7px;width: 7px;background-color: #888; display: none; border-radius: 1px;}
.range-calendar .months .cell.selected {float: left; text-align: center; position: relative;color: #fff; background-color:#888; }
.range-calendar .months .cell.selected .month-name {color: #fff;}
.range-calendar .months .cell.selected .date-formatted {color: #fff;}
.range-calendar .months .cell.selected .bullet { background-color: #fff; }
.range-calendar .months .cell.current .bullet {display: block;}
.range-bar {width: 210px; height: 100%; top: 0px; left: 0; position: absolute; z-index: 1; padding: 0; margin: 0; background-image: none; z-index: 1 ; background-color: #888; }
.range-bar.resizable {height: 100%;position: absolute;}
.range-bar.range-bar-content {width: 100%; height: 100%; display: block;float: left;}
.range-bar .ui-resizable-handle.ui-resizable-e{width: 6px;height: 100%;background-position: 25px 53%;background-repeat: no-repeat;right: 0px;padding: 20px;opacity: 0.5;}
.range-calendar .ui-draggable {cursor: move;cursor: -moz-grab;cursor: -webkit-grab; }
.range-calendar .ui-draggable-dragging {cursor: -moz-grabbing;cursor: -webkit-grabbing;}
/*CSS celdas de tiempo*/
.range-calendar .timeline { top: 10px; z-index: 1; list-style: none;float: left;margin: 0; padding: 0 ; position: relative; width: 99999px;}
.range-calendar .timeline .cell {float: left;width: 70px; padding:25px 20px; margin: 0px; border-right: 1px solid rgba(0,0,0,0.03); text-align: center; position: relative;color: #888 ;}
.range-calendar .timeline .cell .hour-number {display: block;clear: both; font-weight: bold;font-size: 12px; z-index: 1; position: relative; }
.range-calendar .timeline .cell:hover { background-color: rgba(0,0,0,.0); color: #888; }
.range-calendar .timeline .cell:hover .hour-number {}
.range-calendar .timeline .cell.selected {background: transparent;color: #fff;border-right: 1px solid rgba(0, 0, 0, 0.04);}
.range-calendar .timeline .cell.selected .hour-number, .timeline .cell.ui-selecting .hour-number { z-index: 2; position: relative;}
.range-calendar .timeline .cell.selected.last {border: none !important;}
.time-range-bar {width: 210px; height: 100%; top: 0px; left: 0; position: absolute; z-index: 1; padding: 0; margin: 0; background-image: none; z-index: 1 ; background-color: #888; }
.time-range-bar.resizable {height: 100%;position: absolute;}
.time-range-bar.time-range-bar-content {width: 100%; height: 100%; display: block;float: left;}
.time-range-bar .ui-resizable-handle.ui-resizable-e{width: 6px;height: 100%;background-position: 25px 53%;background-repeat: no-repeat;right: 0px;padding: 20px;opacity: 0.5;}
/*CSS para las casillas desactivadas*/
.range-calendar .calendar .cell-disabled{background: #dddddd;pointer-events: none;}
.range-calendar .months .cell-disabled{background: #dddddd;pointer-events: none;}
/* Default Theme */
.default-theme .months {background-color: transparent ;}
.default-theme .months .cell {color: #888 ;}
.default-theme .months .cell.selected .month-name {color: #fff ;}
.default-theme .months .cell.selected .bullet { background-color: #fff;}
.default-theme .calendar {background-color: transparent ;}
.default-theme .calendar .cell {color: rgba(0, 0, 0, 0.4) ;}
.default-theme .calendar .cell .day-number {color: #888 ;}
.default-theme .calendar .cell:hover {background: transparent ;}
.default-theme .calendar .cell:hover .day-number{color:#888 ;}
.default-theme .calendar .cell.selected {color: #fff;border-right: 1px solid rgba(0, 0, 0, 0.2);}
.default-theme .calendar .cell.selected:hover {background: none ;}
.default-theme .calendar .cell.selected .day-number {color: #fff ;}
.default-theme .range-bar { background-color: #888 ;}
/*CSS celdas de tiempo*/
.default-theme .timeline {background-color: transparent ;}
.default-theme .timeline .cell {color: rgba(0, 0, 0, 0.4) ;}
.default-theme .timeline .cell .hour-number {color: #888 ;}
.default-theme .timeline .cell:hover {background: transparent ;}
.default-theme .timeline .cell:hover .hour-number{color:#888 ;}
.default-theme .timeline .cell.selected {color: #fff;border-right: 1px solid rgba(0, 0, 0, 0.2);}
.default-theme .timeline .cell.selected:hover {background: none ;}
.default-theme .timeline .cell.selected .hour-number {color: #fff ;}
.default-theme .time-range-bar { background-color: #888 ;}
/* green-theme */
.blue-theme-bg {background-color: #448FFF ; color: #fff ;border-color: rgba(255,255,255,0.3); }
.blue-theme-color {color: #448FFF ;}
.blue-theme .range-calendar {background-color: #fff;}
.blue-theme .months {background-color: transparent ;}
.blue-theme .months .cell {color: rgba(0, 0, 0, 0.6) ;}
.blue-theme .months .cell .month-name {color: #448FFF ;}
.blue-theme .months .cell.selected {background-color: #448FFF ;}
.blue-theme .months .cell.selected .month-name {color: #fff ;}
.blue-theme .months .cell .bullet { background-color: #448FFF;}
.blue-theme .months .cell.selected .bullet { background-color: #fff;}
.blue-theme .calendar {background-color: transparent ;}
.blue-theme .calendar .cell {color: rgba(0, 0, 0, 0.4) ;}
.blue-theme .calendar .cell .day-number {color: #448FFF ;}
.blue-theme .calendar .cell:hover {background: transparent ;}
.blue-theme .calendar .cell:hover .day-number{color:#888 ;}
.blue-theme .calendar .cell.selected {color: #fff ;}
.blue-theme .calendar .cell.selected:hover {background: none ;}
.blue-theme .calendar .cell.selected .day-number {color: #fff ;}
.blue-theme .range-bar { background-color: #448FFF ; }
/*CSS celdas de tiempo*/
.blue-theme .timeline {background-color: transparent ;}
.blue-theme .timeline .cell {color: rgba(0, 0, 0, 0.4) ;}
.blue-theme .timeline .cell .hour-number {color: #448FFF ;}
.blue-theme .timeline .cell:hover {background: transparent ;}
.blue-theme .timeline .cell:hover .hour-number{color:#888 ;}
.blue-theme .timeline .cell.selected {color: #fff ;}
.blue-theme .timeline .cell.selected:hover {background: none ;}
.blue-theme .timeline .cell.selected .hour-number {color: #fff ;}
.blue-theme .time-range-bar { background-color: #448FFF ; }
/* SKY COLOR #00CCFF */
.cyano-theme-bg {background-color: #00CCFF ;color: #fff ;border-color: rgba(255,255,255,0.3); }
.cyano-theme-color {color: #00CCFF ;}
.cyano-theme .months {background-color: transparent ;}
.cyano-theme .months .cell {color: rgba(0, 0, 0, 0.6) ;}
.cyano-theme .months .cell .month-name {color: #00CCFF ;}
.cyano-theme .months .cell.selected {background-color: #00CCFF ;}
.cyano-theme .months .cell.selected .month-name {}
.cyano-theme .calendar {background-color: transparent ;}
.cyano-theme .calendar .cell {color: rgba(0, 0, 0, 0.4) ;}
.cyano-theme .calendar .cell .day-number {color: #00CCFF ;}
.cyano-theme .calendar .cell:hover {background: transparent ;}
.cyano-theme .calendar .cell:hover .day-number {color: #888 ;}
.cyano-theme .calendar .cell.selected {color: #fff ;}
.cyano-theme .calendar .cell.selected:hover {background: none ;}
.cyano-theme .calendar .cell.selected .day-number {color: #fff ;}
.cyano-theme .range-bar { background-color: #00CCFF ;}
/*CSS celdas de tiempo*/
.cyano-theme .timeline {background-color: transparent ;}
.cyano-theme .timeline .cell {color: rgba(0, 0, 0, 0.4) ;}
.cyano-theme .timeline .cell .hour-number {color: #00CCFF ;}
.cyano-theme .timeline .cell:hover {background: transparent ;}
.cyano-theme .timeline .cell:hover .hour-number {color: #888 ;}
.cyano-theme .timeline .cell.selected {color: #fff ;}
.cyano-theme .timeline .cell.selected:hover {background: none ;}
.cyano-theme .timeline .cell.selected .hour-number {color: #fff ;}
.cyano-theme .time-range-bar { background-color: #00CCFF ;}
/* RED COLOR #FF5D3A */
.orange-light-theme-bg {background-color: #ff7400;color: #fff ;border-color: rgba(255,255,255,0.3);}
.orange-light-theme-color {color: #ff7400 ;}
.orange-light-theme .months {background-color: transparent ;}
.orange-light-theme .months .cell {color: rgba(0, 0, 0, 0.6) ;}
.orange-light-theme .months .cell .month-name {color: #ff7400 ;}
.orange-light-theme .months .cell:hover .month-name {color: #888 ;}
.orange-light-theme .months .cell.selected {background-color: #ff7400 ;}
.orange-light-theme .months .cell.selected .month-name {color: #fff ;}
.orange-light-theme .months .cell .bullet { background-color: #ff7400;}
.orange-light-theme .months .cell.current .bullet { background-color: #ff7400;}
.orange-light-theme .months .cell.selected .bullet { background-color: #fff;}
.orange-light-theme .calendar {background-color: transparent ;}
.orange-light-theme .calendar .cell {color: #888 ;}
.orange-light-theme .calendar .cell:hover {background: transparent ;}
.orange-light-theme .calendar .cell:hover .day-number {color: #888 ;}
.orange-light-theme .calendar .cell .day-number {color: #ff7400 ;}
.orange-light-theme .calendar .cell.selected {color: #fff ;}
.orange-light-theme .calendar .cell.selected:hover {background: none ;}
.orange-light-theme .calendar .cell.selected .day-number {color: rgba(255, 255, 255, 1) ;}
.orange-light-theme .range-bar { background-color: #ff7400 ; }
/*CSS celdas de tiempo*/
.orange-light-theme .timeline {background-color: transparent ;}
.orange-light-theme .timeline .cell {color: #888 ;}
.orange-light-theme .timeline .cell:hover {background: transparent ;}
.orange-light-theme .timeline .cell:hover .hour-number {color: #888 ;}
.orange-light-theme .timeline .cell .hour-number {color: #ff7400 ;}
.orange-light-theme .timeline .cell.selected {color: #fff ;}
.orange-light-theme .timeline .cell.selected:hover {background: none ;}
.orange-light-theme .timeline .cell.selected .hour-number {color: rgba(255, 255, 255, 1) ;}
.orange-light-theme .time-range-bar { background-color: #ff7400 ; }
/* full-green-theme */
.full-green-theme-bg {background-color: #02d9aa ;color: #fff ;border-color: rgba(255,255,255,0.3);}
.full-green-theme-color {color: #fff ;}
.full-green-theme.range-calendar,.full-green-theme .range-calendar {background-color: #03DAAB;}
.full-green-theme .months {background-color: transparent ;}
.full-green-theme .months .cell {color: #f9f9f9 ;}
.full-green-theme .months .cell .month-name {color: #f9f9f9 ;}
.full-green-theme .months .cell .bullet { background-color: #999;}
.full-green-theme .months .cell.selected {background-color: rgba(0,0,0,.1); border-radius: 1px;}
.full-green-theme .months .cell.selected .month-name {color: #fff ;}
.full-green-theme .months .cell.selected .bullet { background-color: #03DAAB;}
.full-green-theme .months .cell.current .bullet { background-color: #fff;}
.full-green-theme .calendar {background-color: transparent ;}
.full-green-theme .calendar .cell {color: #f9f9f9 ;}
.full-green-theme .calendar .cell:hover {background: transparent; color: #888;}
.full-green-theme .calendar .cell .day-number {color: #fff;}
.full-green-theme .calendar .cell:hover .day-number{ color: #888;}
.full-green-theme .calendar .cell.selected {color: #fff ;}
.full-green-theme .calendar .cell.selected:hover {background: transparent ;}
.full-green-theme .calendar .cell.selected .day-number {color: #fff ;}
.full-green-theme .range-bar { background-color: rgba(0,0,0,.1);}
/*CSS celdas de tiempo*/
.full-green-theme .timeline {background-color: transparent ;}
.full-green-theme .timeline .cell {color: #f9f9f9 ;}
.full-green-theme .timeline .cell:hover {background: transparent; color: #888;}
.full-green-theme .timeline .cell .hour-number {color: #fff;}
.full-green-theme .timeline .cell:hover .hour-number{ color: #888;}
.full-green-theme .timeline .cell.selected {color: #fff ;}
.full-green-theme .timeline .cell.selected:hover {background: transparent ;}
.full-green-theme .timeline .cell.selected .hour-number {color: #fff ;}
.full-green-theme .time-range-bar { background-color: rgba(0,0,0,.1);}
/* full-red-theme */
.full-red-theme-bg {background-color: #FF5D3A ;color: #fff ;border-color: rgba(255,255,255,0.3);}
.full-red-theme-color {color: #fff ;}
.full-red-theme.range-calendar,.full-red-theme .range-calendar {background-color: #FF5D3A;}
.full-red-theme .months {background-color: transparent ;}
.full-red-theme .months .cell {color: #f9f9f9 ;}
.full-red-theme .months .cell .month-name {color: #f9f9f9 ;}
.full-red-theme .months .cell .bullet { background-color: #999;}
.full-red-theme .months .cell:hover .month-name{color: #444;}
.full-red-theme .months .cell.selected {background-color: rgba(0,0,0,.1);border-radius: 1px; border-color: rgba(1, 1,1, 0.05);}
.full-red-theme .months .cell.selected .month-name {color: #fff ;}
.full-red-theme .months .cell.selected .bullet { background-color: #FF5D3A;}
.full-red-theme .months .cell.current .bullet { background-color: #fff;}
.full-red-theme .calendar {background-color: transparent ;}
.full-red-theme .calendar .cell {color: #f9f9f9 ;}
.full-red-theme .calendar .cell .day-number {color: #fff;}
.full-red-theme .calendar .cell:hover .day-number{ color: #444;}
.full-red-theme .calendar .cell:hover .day{ color: #fff;}
.full-red-theme .calendar .cell.selected {color: #fff;}
.full-red-theme .calendar .cell.selected:hover {background: transparent ;}
.full-red-theme .calendar .cell.selected .day-number {color: #fff ;}
.full-red-theme .range-bar { background-color: rgba(0,0,0,.1) ;}
/*CSS celdas de tiempo*/
.full-red-theme .timeline {background-color: transparent ;}
.full-red-theme .timeline .cell {color: #f9f9f9 ;}
.full-red-theme .timeline .cell .hour-number {color: #fff;}
.full-red-theme .timeline .cell:hover .hour-number{ color: #444;}
.full-red-theme .timeline .cell.selected {color: #fff;}
.full-red-theme .timeline .cell.selected:hover {background: transparent ;}
.full-red-theme .timeline .cell.selected .hour-number {color: #fff ;}
.full-red-theme .time-range-bar { background-color: rgba(0,0,0,.1) ;}
/* dark-theme */
.dark-theme-bg {background-color: #333 ;color: #fff ;border-color: rgba(255,255,255,0.3);}
.dark-theme-color {color: #333 ;}
.dark-theme.range-calendar,.dark-theme .range-calendar {background-color: #333;}
.dark-theme .months {background-color: transparent ;}
.dark-theme .months .cell {color: #999 ;}
.dark-theme .months .cell .month-name {color: #999 ;}
.dark-theme .months .cell .bullet { background-color: #999;}
.dark-theme .months .cell.current .bullet { background-color: #999;}
.dark-theme .months .cell.selected {background-color: #444 ;box-shadow: 0px 1px 2px #2f2f2f; border-radius: 1px;}
.dark-theme .months .cell.selected .month-name {color: #EEE ;}
.dark-theme .months .cell.selected .bullet { background-color: #333;}
.dark-theme .calendar {background-color: transparent ;}
.dark-theme .calendar .cell {color: #666 ;}
.dark-theme .calendar .cell:hover {background: #333 ; color: #fff;}
.dark-theme .calendar .cell .day-number {color: #999 ;}
.dark-theme .calendar .cell:hover .day-number{ color: #fff;}
.dark-theme .calendar .cell.selected {color: #fff ;}
.dark-theme .calendar .cell.selected:hover {background: none ;}
.dark-theme .calendar .cell.selected .day-number {color: rgba(255, 255, 255, 1) ;}
.dark-theme .range-bar { background-color: #444 ;}
/*CSS celdas de tiempo*/
.dark-theme .timeline {background-color: transparent ;}
.dark-theme .timeline .cell {color: #666 ;}
.dark-theme .timeline .cell:hover {background: #333 ; color: #fff;}
.dark-theme .timeline .cell .hour-number {color: #999 ;}
.dark-theme .timeline .cell:hover .hour-number{ color: #fff;}
.dark-theme .timeline .cell.selected {color: #fff ;}
.dark-theme .timeline .cell.selected:hover {background: none ;}
.dark-theme .timeline .cell.selected .hour-number {color: rgba(255, 255, 255, 1) ;}
.dark-theme .time-range-bar { background-color: #444 ;}
/* Context Colors*/
.blue-theme .color, .blue-theme.color {background-color: #448FFF !important; color: #fff;fill:#fff;}
.blue-theme .text-color, .blue-theme.text-color {color: #448FFF; }
.cyano-theme .color,.cyano-theme.color {background-color: #00CCFF !important;color: #fff;fill:#fff;}
.cyano-theme .text-color,.cyano-theme.text-color {color: #00CCFF;}
.orange-light-theme .color,.orange-light-theme.text-color {background-color: #ff7400 !important;color: #fff;fill:#fff;}
.orange-light-theme .text-color,.orange-light-theme.text-color {color: #ff7400;}
.dark-theme .color,.dark-theme.color {background-color: #444;color: #fff;fill:#fff;}
.dark-theme .text-color,.dark-theme.text-color {color: #444; }
.full-green-theme .color,.full-green-theme.color {background-color: #02d9aa !important;color: #fff; fill:#fff;}
.full-green-theme .text-color,.full-green-theme.text-color {color: #02d9aa;}
.full-red-theme .color,.full-red-theme.color {background-color: #FF5D3A !important;color: #fff; fill:#fff;}
.full-red-theme .text-color,.full-red-theme.text-color {color: #FF5D3A;}
.range-bar .ui-resizable-handle {
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAbCAYAAAEog86bAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDozOEM3RUEzMjIyQUUxMUUzQjQ5NUMwMEM3OEVEMzc0MCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDozOEM3RUEzMzIyQUUxMUUzQjQ5NUMwMEM3OEVEMzc0MCI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkU5Q0Q4QzdGMjI3RjExRTNCNDk1QzAwQzc4RUQzNzQwIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkU5Q0Q4QzgwMjI3RjExRTNCNDk1QzAwQzc4RUQzNzQwIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+XfsRugAAAGZJREFUeNpi+P//PwMTAxAgCIAAYoCJ/YeLMQIEECNIDKECJgcCAAHEgMUINAIggOC6kU3A4PzHKYPCYUSRAQgg/Eb/J2garTmMWGUAAgzF1Tj1Y5P4T4yO/0QZNWgkGJElGIk2CgB+4BtJMclJ0wAAAABJRU5ErkJggg==');
}
.time-range-bar .ui-resizable-handle {
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAbCAYAAAEog86bAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDozOEM3RUEzMjIyQUUxMUUzQjQ5NUMwMEM3OEVEMzc0MCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDozOEM3RUEzMzIyQUUxMUUzQjQ5NUMwMEM3OEVEMzc0MCI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkU5Q0Q4QzdGMjI3RjExRTNCNDk1QzAwQzc4RUQzNzQwIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkU5Q0Q4QzgwMjI3RjExRTNCNDk1QzAwQzc4RUQzNzQwIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+XfsRugAAAGZJREFUeNpi+P//PwMTAxAgCIAAYoCJ/YeLMQIEECNIDKECJgcCAAHEgMUINAIggOC6kU3A4PzHKYPCYUSRAQgg/Eb/J2garTmMWGUAAgzF1Tj1Y5P4T4yO/0QZNWgkGJElGIk2CgB+4BtJMclJ0wAAAABJRU5ErkJggg==');
}
@media only screen and (max-width: 768px) {
.range-calendar .calendar .cell {width: 70px; padding:20px 15px;}
.range-calendar .calendar .cell .day-number {font-size: 15px;}
.range-calendar .calendar .cell .day {font-size: 8px;}
.range-calendar .months .cell {width: 85px; padding: 10px 10px; }
.range-bar .ui-resizable-handle.ui-resizable-e{width:6px;height:27px;background-position: 8px 5px;background-repeat: no-repeat; right: 0px;top: 30%; padding: 20px 10px;opacity:0.5;}
.range-calendar .timeline .cell {width: 70px; padding:20px 15px;}
.range-calendar .timeline .cell .hour-number {font-size: 15px;}
.time-range-bar .ui-resizable-handle.ui-resizable-e{width:6px;height:27px;background-position: 8px 5px;background-repeat: no-repeat; right: 0px;top: 30%; padding: 20px 10px;opacity:0.5;}
}
/**
* jquery.rangecalendar.js v 1.0.2
* Copyright 2013, Angelo Libero Mangieri
* Email: angelo@afreeux.com
*
* jquery.rangecalendar.js v 1.1.0
* Copyright 2017, José Luis Uc
* Email: ucp.jose@gmail.com
*
*/
( function( $, window ) {
$.fn.rangeCalendar = function(options) {
var defaults = {
lang: "en",
theme: "default-theme",
themeContext: this,
startDate: moment(),
endDate: moment().add('months', 12),
start : "+7",
startRangeWidth : 3,
minRangeWidth: 1,
maxRangeWidth: 14,
weekends: true,
autoHideMonths: false,
visible: true,
trigger: null,
changeRangeCallback : function( el, cont, dateProp ) { return false; },
//Define el minimo, maximo y rango de la linea del tiempo
startTimeRangeWidth: 2,
minTimeRangeWidth: 2,
maxTimeRangeWidth: 4
};
this.each(function(i, el) {
var obj = el,
$el = $(el),
settings = $.extend( true, {},defaults, options );
obj.options = settings;
obj.showCalendar = function(animate) {
var calPos = obj.calendarObj.position();
var lastItemPos = obj.calendarObj.find(".cell").last().position();
var lastItemRight = (lastItemPos.left + obj.calendarObj.find(".cell").last().outerWidth() );
var selectedItemPos = obj.calendarObj.find(".cell").eq(0).position();
$el.slideDown((animate ? 300 : 0), function() {
var windowWidth = $(window).outerWidth();
$(obj.calendarObj).css({left: windowWidth });
$(obj.monthsObj).css({left: windowWidth });
$(obj.timeObj).css({left: windowWidth});
obj._placeElement(obj.calendarObj,(!selectedItemPos ? 0 : selectedItemPos.left) );
obj._placeElement(obj.monthsObj);
obj._placeElement(obj.timeObj);
});
obj.visible = true;
};
obj.hideCalendar = function() {
$el.slideUp(50);
obj.visible = false;
};
obj.toggleCalendar = function () {
if(obj.visible)
obj.showCalendar();
else
obj.hideCalendar();
};
obj.rangeWidth = function(){
var cellWidth = obj.calendarObj.find(".cell").outerWidth();
var rangeWidth = parseInt(obj.calendarObj.find('.range-bar').outerWidth()/cellWidth);
obj._rangeWidth = ( !rangeWidth ? obj._rangeWidth : rangeWidth) ;
return obj._rangeWidth;
};
//Define rangeWidth para la linea del tiempo
obj.timeRangeWidth = function () {
var cellWidth = obj.timeObj.find(".cell").outerWidth();
var rangeWidth = parseInt(obj.timeObj.find('.time-range-bar').outerWidth()/cellWidth);
obj._timeRangeWidth = ( !rangeWidth ? obj._timeRangeWidth : rangeWidth);
return obj._timeRangeWidth;
};
obj.setRangeWidth = function(rangeWidth) {
var cellWidth = obj.calendarObj.find(".cal-cell").eq(0).outerWidth();
var rangeWidth = parseInt(!rangeWidth || rangeWidth < obj.minRangeWidth ? obj.minRangeWidth : rangeWidth);
$el.find(".range-bar").width(cellWidth*rangeWidth);
$el.find(".range-bar").trigger("resize");
};
//Define setRangeWidth para la linea del tiempo
obj.setTimeRangeWidth = function (rangeWidth) {
var cellWidth = obj.timeObj.find(".time-cell").eq(0).outerWidth();
var rangeWidth = parseInt(!rangeWidth || rangeWidth < obj.minTimeRangeWidth ? obj.minTimeRangeWidth : rangeWidth);
$el.find(".time-range-bar").width(cellWidth*rangeWidth);
$el.find(".time-range-bar").trigger("resize");
};
obj.range = function() {
var startDateIndex = obj.calendarObj.find('.cell.selected:eq(0)').index();
var startDate = moment(obj.startDate.format()).add('days', startDateIndex);
var endDate = moment(obj.startDate.format()).add('days', startDateIndex);
//Obtiene la hora de inicio y final seleccionado
var startTime = obj.timeObj.find('.cell.selected:eq(0)')[0].textContent;
var endTime = obj.timeObj.find('.cell.selected').last()[0].textContent;
var startTimeSplit = startTime.split(':');
var startTimeMinutes = (+startTimeSplit[0]) * 60 + (+startTimeSplit[1]);
var endTimeSplit = endTime.split(':');
var endTimeMinutes = (+endTimeSplit[0]) * 60 + (+endTimeSplit[1]);
var start = startDate.add('m', startTimeMinutes);
var end = endDate.add('m', endTimeMinutes);
var startFormatted = start.format();
var endFormatted = end.format();
var range = $.data(obj, 'range', {
start: startFormatted,
end: endFormatted
});
return range;
};
obj.setStartDate = function(startDate) {
var date = moment(startDate);
var fullYear = date.format("YYYY");
var monthNumber = date.format("MM");
var dayNumber = date.format('D');
var dateId = fullYear+monthNumber+dayNumber;
var monthId = fullYear+monthNumber;
var dateCell = obj.calendarObj.find('.cell[date-id="'+dateId+'"]').eq(0);
dateCell.trigger("click");
var monthCell = obj.monthsObj.find('.cell[month-id="'+monthId+'"]').eq(0);
monthCell.trigger("click");
};
obj.lang = function (){
return obj.lang;
};
obj.setTheme = function (themeName){
var _themeName = $(obj.themeContext).attr("theme");
if(_themeName)
$(obj.themeContext).removeClass(_themeName);
$(obj.themeContext).attr("theme",""+themeName+"");
$(obj.themeContext).addClass(""+themeName+"");
obj.theme = themeName;
};
obj.update = function() {
moment.lang(obj.lang);
obj.setTheme(obj.theme);
obj._generateView();
};
//EVENTS
obj.didResizeBar = function() {
var prevRangeWidth = obj.rangeWidth();
var rangeWidth = prevRangeWidth;
var resizeBarPos = obj.calendarObj.find('.range-bar').position();
var resizeBarWidth = obj.calendarObj.find('.range-bar').outerWidth();
var resizeBarRight = resizeBarPos.left+resizeBarWidth;
var cellWidth = $(obj).find(".cell").first().outerWidth();
var lastCellPos = $(obj).find(".cell").last().position();
var deltaWidth = 0;
var objWidth = (lastCellPos.left+cellWidth);
if(resizeBarRight > objWidth){
deltaWidth = objWidth-resizeBarWidth;
prevRangeWidth = (resizeBarWidth-deltaWidth)/cellWidth;
}
obj.calendarObj.find('.cell').removeClass("selected");
obj.calendarObj.find('.cell').removeClass("last");
obj.calendarObj.find('.cell.start').addClass("selected");
obj.calendarObj.find('.cell.start').nextAll().slice(0, (!rangeWidth ? obj.minRangeWidth-1 : rangeWidth-1)).addClass('selected');
obj.calendarObj.find('.cell.selected').last().addClass("last");
};
//Define didResizeBar para la linea del tiempo
obj.didResizeTimeBar = function () {
var prevRangeWidth = obj.timeRangeWidth();
var rangeWidth = prevRangeWidth;
var resizeBarPos = obj.timeObj.find('.time-range-bar').position();
var resizeBarWidth = obj.timeObj.find('.time-range-bar').outerWidth();
var resizeBarRight = resizeBarPos.left+resizeBarWidth;
var cellWidth = $(obj).find(".cell").first().outerWidth();
var lastCellPos = $(obj).find(".cell").last().position();
var deltaWidth = 0;
var objWidth = (lastCellPos.left+cellWidth);
if(resizeBarRight > objWidth){
deltaWidth = objWidth-resizeBarWidth;
prevRangeWidth = (resizeBarWidth-deltaWidth)/cellWidth;
}
obj.timeObj.find('.cell').removeClass("selected");
obj.timeObj.find('.cell').removeClass("last");
obj.timeObj.find('.cell.start').addClass("selected");
obj.timeObj.find('.cell.start').nextAll().slice(0, (!rangeWidth ? obj.minTimeRangeWidth-1 : rangeWidth-1)).addClass('selected');
obj.timeObj.find('.cell.selected').last().addClass("last");
obj._dispatchEvent(obj.changeRangeCallback,obj.range(),obj);
};
obj.didSelectMonth = function(e) {
if(obj.isDragging || $(obj.lastTarget).is(obj.monthsObj) ){
delete obj.lastTarget;
return;
}
var currentMonthId = $(this).attr("month-id");
var currentCellMonth = obj.calendarObj.find('.cell[month-id="'+currentMonthId+'"].selected').eq(0);
var monthPosition = (!currentCellMonth.length ? obj.calendarObj.find('.cell[month-id="'+currentMonthId+'"]').eq(0).position() : currentCellMonth.position());
var calendarViewWidth = $($el).outerWidth();
//Recupera los dias del mes que se deshabilitaran
$.ajax({
url: 'demo.json',
success: function(result){
//Recorre los dias para deshabilitarlos
var days = obj.calendarObj.find('.cell[month-id="'+currentMonthId+'"]');
for(var i = 0; i < days.length; i++){
var dayDate = days[i].attributes[1].textContent;
var dayYear = dayDate.substring(0,4);
var dayMonth = dayDate.substring(4,6);
var dayDay = dayDate.substring(6,8);
for(var index = 0; index < result.length; index++){
if(result[index].day === dayDay && result[index].month === dayMonth && result[index].year === dayYear){
$(days[i]).addClass('cell-disabled');
break;
}
}
}
}
});
obj.monthsObj.find('.cell').not(this).removeClass('selected');
$(this).addClass('selected');
obj._placeElement(obj.calendarObj,monthPosition);
};
obj.didChangeRange = function(e,ui) {
if(obj.isDragging || $(obj.lastTarget).is(obj.calendarObj)){
delete obj.lastTarget;
return;
}
var rangeWidth = obj.rangeWidth();
var currentCalItem = $(this);
var lastCalItem = obj.calendarObj.find('.cell').last();
var delta = lastCalItem.index()-currentCalItem.index();
var rightBar = currentCalItem.index()+rangeWidth-1;
if(rightBar > lastCalItem.index()){
obj.calendarObj.find(' .cell').eq(currentCalItem.index()-rangeWidth+delta+1).trigger("click");
return;
}
obj.calendarObj.find(".start").removeClass("start");
currentCalItem.addClass("start");
obj._updateRangeBar();
obj._updateMonths();
obj._dispatchEvent(obj.changeRangeCallback,obj.range(),obj);
};
//Define didChangeRange para la linea del tiempo
obj.didChangeTimeRange = function (e, ui) {
if(obj.isDragging || $(obj.lastTarget).is(obj.timeObj)){
delete obj.lastTarget;
return;
}
var rangeWidth = obj.timeRangeWidth();
var currentCalItem = $(this);
var lastCalItem = obj.timeObj.find('.cell').last();
var delta = lastCalItem.index()-currentCalItem.index();
var rightBar = currentCalItem.index()+rangeWidth-1;
if(rightBar > lastCalItem.index()){
obj.timeObj.find(' .cell').eq(currentCalItem.index()-rangeWidth+delta+1).trigger("click");
return;
}
obj.timeObj.find(".start").removeClass("start");
currentCalItem.addClass("start");
obj._updateRangeBar();
obj._updateTimeRangeBar();
obj._dispatchEvent(obj.changeRangeCallback,obj.range(),obj);
};
///////////////////////////////////////////////////////*
// PRIVATE METHODS
obj._initRangeBar = function(){
$(window).unbind("resize"); //Prevents window.resize event triggering
var rangeWidth = obj.rangeWidth() ;
var cellWidth = obj.calendarObj.find(".cell").eq(0).outerWidth();
var cellHeight = obj.calendarObj.find(".cell").eq(0).outerHeight();
var selectedCell = obj.calendarObj.find(".cell.selected:eq(0)");
if(!selectedCell.length)
return;
obj.calendarObj.find(".range-bar").unbind( "resize");
obj.calendarObj.find(".range-bar").remove();
$(selectedCell).append('<div class="range-bar resizable"><div class="range-bar-content"></div></div>');
if(obj.maxRangeWidth > 1){
obj.calendarObj.find(".range-bar").resizable({
grid:[cellWidth,0],
maxWidth: obj.maxRangeWidth*cellWidth,
minWidth: cellWidth*obj.minRangeWidth,
maxHeight:cellHeight,
minHeight:cellHeight,
handles: "e"
});
}
obj.setRangeWidth(rangeWidth);
obj.calendarObj.find(".range-bar").on( "resize", obj.didResizeBar);
$(window).bind("resize",obj._resize);
};
//Inicializa la barra para la linea del tiempo
obj._initTimeRangeBar = function () {
$(window).unbind("resize"); //Prevents window.resize event triggering
var rangeWidth = obj.timeRangeWidth();
var cellWidth = obj.timeObj.find(".cell").eq(0).outerWidth();
var cellHeight = obj.timeObj.find(".cell").eq(0).outerHeight();
var selectedCell = obj.timeObj.find(".cell.selected:eq(0)");
if(!selectedCell.length)
return;
obj.timeObj.find(".time-range-bar").unbind( "resize");
obj.timeObj.find(".time-range-bar").remove();
$(selectedCell).append('<div class="time-range-bar resizable"><div class="time-range-bar-content"></div></div>');
if(obj.maxTimeRangeWidth > 1){
obj.timeObj.find(".time-range-bar").resizable({
grid:[cellWidth,0],
maxWidth: obj.maxTimeRangeWidth*cellWidth,
minWidth: cellWidth*obj.minTimeRangeWidth,
maxHeight:cellHeight,
minHeight:cellHeight,
handles: "e"
});
}
obj.setTimeRangeWidth(rangeWidth);
obj.timeObj.find(".time-range-bar").on( "resize", obj.didResizeTimeBar);
$(window).bind("resize",obj._resize);
};
obj._initMonths = function() {
obj.monthsObj.draggable({
axis: "x" ,
scrollSensitivity: 100,
scrollSpeed: 100 ,
cursor: "move",
create: function (e, ui) {
obj._updateMonths();
//Mueve la barra del mes hacia el mes inicial
var currentMonthId = parseInt(obj.monthsObj.find(".cell.selected").attr("month-id"));
var currentMonthCell = obj.monthsObj.find('.cell[month-id="'+currentMonthId+'"]');
obj._placeElement(obj.monthsObj,currentMonthCell.position());
},
start: function (e, ui) {
obj.isDragging = true;
obj.monthsObj.find('.cell').unbind("click");
},
drag: function (e, ui) {
},
stop: function(e, ui) {
$(this).css({top: 0});
obj.lastTarget = e.target;
setTimeout(function(){
obj.isDragging = false;
delete obj.lastTarget;
obj._placeElement(obj.monthsObj);
obj.monthsObj.find('.cell').bind("click",obj.didSelectMonth);
},10);
}
});
};
obj._initCalendar = function() {
var xpos;
obj.calendarObj.draggable({
axis: "x" ,
scrollSensitivity: 100,
scrollSpeed: 100 ,
cursor: "move",
create: function () {
obj.calendarObj.find('.cell').removeClass("selected");
obj.calendarObj.find('.cell').removeClass("last");
obj.calendarObj.find(".cell").eq(obj.start-1).addClass("start");
obj.calendarObj.find(".cell").eq(obj.start-1).addClass("selected");
obj.calendarObj.find('.cell.start').nextAll().slice(0, obj._rangeWidth-1).addClass('selected');
obj.calendarObj.find('.cell').bind("click",obj.didChangeRange);
obj.calendarObj.find('.cell.selected').last().addClass("last");
obj._placeElement(obj.calendarObj);
},
start: function(e, ui) {
xpos = ui.position.left;
$(window).unbind("resize"); //Prevents window.resize event triggering
obj.isDragging = true;
obj.calendarObj.find('.cell').unbind("click");
},
drag: function (e, ui) {
var xmove = ui.position.left - xpos;
var direction = xmove >= 0 ? 'right' : 'left';
var rangeCalendarWidth = $el.outerWidth();
var calendarOffset = obj.calendarObj.position();
var monthMaxId = parseInt(obj.monthsObj.find(".cell").last().attr("month-id"));
var monthMinId = parseInt(obj.monthsObj.find(".cell").first().attr("month-id"));
var currentMonthId = parseInt(obj.monthsObj.find(".cell.selected").attr("month-id"));
var nextMonthId = parseInt(obj.monthsObj.find(".cell.selected").next().attr("month-id"));
var prevMonthId = parseInt(obj.monthsObj.find(".cell.selected").prev().attr("month-id"));
if(nextMonthId && currentMonthId && nextMonthId <= monthMaxId && direction == "left") {
var nextMonthsCell = obj.monthsObj.find('.cell[month-id="'+nextMonthId+'"]');
var nextMonthCalendarCell = obj.calendarObj.find('.cell[month-id="'+nextMonthId+'"]').first();
var nextMonthCalendarCellPos = nextMonthCalendarCell.position();
var nextMonthLeftCenter = (rangeCalendarWidth/2 -(nextMonthCalendarCellPos.left )) ;
if( nextMonthLeftCenter >= calendarOffset.left && calendarOffset.left != 0){
obj.monthsObj.find(".cell").removeClass("selected");
$(nextMonthsCell).addClass("selected");
obj._placeElement(obj.monthsObj,nextMonthsCell.position());
}
}
else if(prevMonthId && currentMonthId && prevMonthId >= monthMinId && direction == "right") {
var prevMonthCell = obj.monthsObj.find('.cell[month-id="'+prevMonthId+'"]');
var prevMonthCalendarCell = obj.calendarObj.find('.cell[month-id="'+prevMonthId+'"]').last();
var prevMonthCalendarCellPos = prevMonthCalendarCell.position();
var prevMonthLeftCenter = (rangeCalendarWidth/2 -(prevMonthCalendarCellPos.left )) ;
if(prevMonthLeftCenter <= calendarOffset.left+prevMonthCalendarCell.outerWidth() ) {
obj.monthsObj.find(".cell").removeClass("selected");
$(prevMonthCell).addClass("selected");
obj._placeElement(obj.monthsObj,prevMonthCell.position());
}
}
},
stop: function(e, ui) {
//alert("Drag easing da inserire");
//var calendarOffset = obj.calendarObj.position();
//obj.calendarObj.animate({left: parseInt(calendarOffset.left)-100},300,'easeOutCirc');
obj.lastTarget = e.target;
obj._placeElement(obj.calendarObj);
setTimeout(function(){
obj.isDragging = false;
delete obj.lastTarget;
obj.calendarObj.find('.cell').bind("click",obj.didChangeRange);
$(window).bind("resize",obj._resize);
obj._placeElement(obj.monthsObj);
},100);
}
});
};
//Inicializa la linea del tiempo
obj._initTimeline = function () {
var xpos;
obj.timeObj.draggable({
axis: "x",
scrollSensitivity: 100,
scrollSpeed: 100,
cursor: "move",
create: function () {
obj.timeObj.find('.cell').removeClass("selected");
obj.timeObj.find('.cell').removeClass("last");
obj.timeObj.find(".cell").eq(0).addClass("start");
obj.timeObj.find(".cell").eq(0).addClass("selected");
obj.timeObj.find('.cell.start').nextAll().slice(0, obj._timeRangeWidth-1).addClass('selected');
obj.timeObj.find('.cell').bind("click",obj.didChangeTimeRange);
obj.timeObj.find('.cell.selected').last().addClass("last");
obj._placeElement(obj.timeObj);
},
start: function (e, ui) {
xpos = ui.position.left;
$(window).unbind("resize");
obj.isDragging = true;
obj.timeObj.find('.cell').unbind("click");
},
drag: function (e, ui) {
},
stop: function (e, ui) {
obj.lastTarget = e.target;
obj._placeElement(obj.timeObj);
setTimeout(function(){
obj.isDragging = false;
delete obj.lastTarget;
obj.timeObj.find('.cell').bind("click",obj.didChangeTimeRange);
$(window).bind("resize",obj._resize);
obj._placeElement(obj.timeObj);
},100);
}
});
};
obj._getCalendarHTML = function(startDate,endDate) {
var calendarHtml = '';
var cell;
var date = moment(startDate).add('days', obj.start);
var endDate = moment(endDate).add('days', obj.start);
var rangeWidth = obj.rangeWidth();
for (var index = 1; (date.isBefore(endDate) || date.isSame(endDate)) ; index++){
var fullYear = date.format("YYYY");
var month = date.format("MMM");
var monthNumber = date.format("MM");
var day = date.format('ddd');
var dayNumber = date.format('D');
var isWeekend = date.day()%6==0;
if(isWeekend && !obj.weekends){
date.add('days', 1);
continue;
}
for(var monthIndex = 0; monthIndex < obj.emptyMonths.length; monthIndex++){
if(obj.emptyMonths[monthIndex].month === monthNumber && obj.emptyMonths[monthIndex].year === fullYear){
cell = '<div class="cal-cell cell cell-disabled" date-id="'+fullYear+monthNumber+dayNumber+'" month-id="'+fullYear+''+monthNumber+'" month="'+monthNumber+'">';
break;
} else {
cell = '<div class="cal-cell cell" date-id="'+fullYear+monthNumber+dayNumber+'" month-id="'+fullYear+''+monthNumber+'" month="'+monthNumber+'">';
}
}
cell += '<div class="cell-content">';
cell += '<div class="day-number">'+dayNumber+'</div>';
cell += '<div class="day '+( isWeekend ? 'ferial' : '') +'">'+day+'</div>';
cell += '</div>';
cell += '</div>';
calendarHtml += cell;
date.add('days', 1);
}
return calendarHtml;
};
obj._getMonthsHTML = function(startDate,endDate) {
var monthsHtml = '';
var cell;
var date = moment(startDate).add('days', obj.start);
var endDate = moment(endDate).add('days', obj.start);
for (var index = 1; (date.isBefore(endDate) || date.isSame(endDate)) ; index++){
var year = date.format("YY");
var fullYear = date.format("YYYY");
var month = date.format("MMM");
var monthNumber = date.format("MM");
for(var monthIndex = 0; monthIndex < obj.emptyMonths.length; monthIndex++){
if(obj.emptyMonths[monthIndex].month === monthNumber && obj.emptyMonths[monthIndex].year === fullYear){
cell = '<div class="month-cell cell cell-disabled" month-id="'+fullYear+''+monthNumber+'" month="'+monthNumber+'">';
break;
} else {
cell = '<div class="month-cell cell" month-id="'+fullYear+''+monthNumber+'" month="'+monthNumber+'">';
}
}
cell += '<i class="bullet"></i>';
cell += '<div class="date-formatted"><span class="month-name">'+month+'</span> '+year+'</span></div>';
cell += '</div>';
monthsHtml += cell;
date.add('month', 1);
}
return monthsHtml;
};
//Genera el html de la linea del tiempo
obj._getTimeHTML = function () {
var timeHtml = '';
var cell;
var x = 15; //minutes interval
var times = []; // time array
var tt = 0; // start time
var ap = ['AM', 'PM']; // AM-PM
//loop to increment the time and push results in array
for (var i=0;tt<24*60; i++) {
var hh = Math.floor(tt/60); // getting hours of day in 0-24 format
var mm = (tt%60); // getting minutes of the hour in 0-55 format
if(hh < 10){
times[i] = ("0" + hh + ':' + ("0" + mm).slice(-2));
} else{
times[i] = (hh + ':' + ("0" + mm).slice(-2));
}
//times[i] = ("0" + (hh % 12)).slice(-2) + ':' + ("0" + mm).slice(-2) + ap[Math.floor(hh/12)]; // pushing data in array in [00:00 - 12:00 AM/PM format]
tt = tt + x;
}
for (var index = 0; index < times.length; index++){
cell = '<div class="time-cell cell">';
cell += '<div class="cell-content">';
cell += '<div class="hour-number">'+ times[index] +'</div>';
cell += '</div>';
cell += '</div>';
timeHtml += cell;
}
return timeHtml;
};
obj._updateMonths = function() {
var currentMonth = obj.calendarObj.find('.cell.selected:eq(0)').attr("month-id");
obj.monthsObj.find('.cell').removeClass('selected');
obj.monthsObj.find('.cell').removeClass('current');
obj.monthsObj.find('.cell[month-id="'+currentMonth+'"]').addClass('selected');
obj.monthsObj.find('.cell[month-id="'+currentMonth+'"]').addClass('current');
};
obj._updateRangeBar = function() {
obj.didResizeBar();
obj._initRangeBar();
};
//Define updateRangeBar para la linea del tiempo
obj._updateTimeRangeBar = function () {
obj.didResizeTimeBar();
obj._initTimeRangeBar();
};
obj._dispatchEvent = function (callback,options,el) {
if(!callback)
return false;
callback(el,options);
};
obj._placeElement = function (el) {
obj._placeElement(el,null);
};
obj._placeElement = function (el, position) {
var calendarViewWidth = $el.outerWidth();
var cellWidth = $(el).find(".cell").first().outerWidth();
var objChildrens = $(el).children().length;
var objWidth = (objChildrens*cellWidth);
var elPos = $(el).position();
left = ( !position ? parseInt(elPos.left) : -position.left);
if(calendarViewWidth > objWidth )
left = (calendarViewWidth-objWidth)/2;
else if (calendarViewWidth < objWidth && left >= 0)
left = 0 ;
else if(left < calendarViewWidth-objWidth)
left = -objWidth+calendarViewWidth;
$(el).stop().animate({left: left},300,'easeOutCirc');
};
obj._timedResize = function() {
clearTimeout(obj.resizeTimer);
obj.resizeTimer = setTimeout(obj._resize, obj.timeoutTime);
};
obj._bindEvents = function () {
if(obj.trigger){
$(obj.trigger).unbind("click");
$(obj.trigger).click(obj.toggleCalendar);
}
obj.timeout = false;
obj.timeoutTime = 100;
obj.calendarObj.find(".range-bar").on( "resize", obj.didResizeBar);
obj.monthsObj.find('.cell').bind("click",obj.didSelectMonth);
obj.timeObj.find(".time-range-bar").on("resize", obj.didResizeTimeBar);
$(window).bind('resize',obj._timedResize);
$el.hover(
function() {
if(obj.autoHideMonths)
obj.monthsObj.slideDown(100,'easeOutCirc');
},
function() {
if(obj.autoHideMonths)
obj.monthsObj.slideUp(0,'easeOutCirc');
}
);
$(obj).on('mousedown', '.range-bar', function (e) {
var topElement = document.elementFromPoint(e.clientX, e.clientY);
if($(topElement).hasClass('ui-resizable-handle')){
e.stopPropagation();
return false;
}
});
//Define mousedown para time-range-bar
$(obj).on('mousedown', '.time-range-bar', function (e) {
var topElement = document.elementFromPoint(e.clientX, e.clientY);
if($(topElement).hasClass('ui-resizable-handle')){
e.stopPropagation();
return false;
}
});
$(obj).on('mouseup', '.range-bar', function (e) {
if($(obj).find('.range-bar').hasClass('ui-resizable-resizing'))
return true;
$(this).hide();
var BottomElement = document.elementFromPoint(e.clientX, e.clientY);
$(this).show();
$(BottomElement).trigger('click'); //Manually fire the event for desired underlying element
return true;
});
//Define mouseup para time-range-bar
$(obj).on('mouseup', '.time-range-bar', function (e) {
if($(obj).find('.time-range-bar').hasClass('ui-resizable-resizing'))
return true;
$(this).hide();
var BottomElement = document.elementFromPoint(e.clientX, e.clientY);
$(this).show();
$(BottomElement).trigger('click'); //Manually fire the event for desired underlying element
return true;
});
};
obj._resize = function(){
obj._placeElement(obj.calendarObj);
obj._placeElement(obj.monthsObj);
obj._placeElement(obj.timeObj);
obj.timeout = false;
};
obj._updateView = function (startDate,endDate){
obj.calendarObj.append(obj._getCalendarHTML(startDate,endDate));
obj.monthsObj.append(obj._getMonthsHTML(startDate,endDate));
//Agrega el html de la linea del tiempo
obj.timeObj.append(obj._getTimeHTML());
if(obj.visible){
$el.css({display:"block"});
obj.showCalendar();
}
else
$el.css({display:"none"});
obj._initCalendar();
obj._initMonths();
//Inicializa la linea del tiempo
obj._initTimeline();
obj._initRangeBar();
//Inicializa la barra de la linea del tiempo
obj._initTimeRangeBar();
};
obj._generateView = function () {
var mainClass = "range-calendar";
$el.removeClass(mainClass)
$el.addClass(mainClass);
$el.empty();
obj.monthsObj = $('<div class="wrapper"><div class="months"></div></div>');
$el.append( obj.monthsObj );
obj.monthsObj = obj.monthsObj.find(".months");
(obj.autoHideMonths ? obj.monthsObj.addClass("auto-hide-months") : '');
obj.calendarObj = $('<div class="wrapper"><div class="calendar"></div></div>');
$el.append( obj.calendarObj );
obj.calendarObj = obj.calendarObj.find(".calendar");
//Define obj.time
obj.timeObj = $('<div class="wrapper"><div class="timeline"></div></div>');
$el.append(obj.timeObj);
obj.timeObj = obj.timeObj.find(".timeline");
obj._updateView(obj.startDate,obj.endDate);
obj._bindEvents();
};
obj._init = function( element,options ) {
obj.themeContext = options.themeContext;
obj.lang = options.lang ;
obj.isDragging = false;
obj.minRangeWidth = options.minRangeWidth;
obj.maxRangeWidth = options.maxRangeWidth;
//Define max y min timeRangeWIdth
obj.minTimeRangeWidth = options.minTimeRangeWidth;
obj.maxTimeRangeWidth = options.maxTimeRangeWidth;
obj.weekends = options.weekends;
obj.startDate = options.startDate;
obj.endDate = options.endDate;
obj.start = (!options.start ? "+7" : parseInt(options.start)) ;
obj.startRangeWidth = ( options.startRangeWidth > options.maxRangeWidth ? options.maxRangeWidth : options.startRangeWidth);
obj._rangeWidth = obj.startRangeWidth;
obj.trigger = options.trigger;
obj.visible = options.visible;
obj.changeRangeCallback = options.changeRangeCallback;
obj.autoHideMonths = options.autoHideMonths ;
//Inicializa los rangos de la linea del tiempo
obj.startTimeRangeWidth = ( options.startTimeRangeWidth > options.maxTimeRangeWidth ? options.maxTimeRangeWidth : options.startTimeRangeWidth);
obj._timeRangeWidth = obj.startTimeRangeWidth;
//Inicializa los meses a excluir
obj.emptyMonths = options.emptyMonths;
obj.theme = (options.theme ? options.theme : defaults.theme );
obj.update();
};
obj._init(el,obj.options);
$(obj).data('rangeCalendar', obj );
});
return this.data("rangeCalendar");
};
} )( jQuery, window );
{% extends "base_generic.html" %}
{% block lefPanel %}{% include "leftMenuBar.html" %}{% endblock %}
{% load humanize %}
{% load mathfilters %}
{% block dash-title %}
......@@ -37,12 +40,13 @@
<tbody>
{% for p in publishers %}
<tr class="odd gradeX">
<td><a href="{% url 'audio'%}{{p.shortName}}">{{p.name}}</a></td>
<td>{{p.shortName}}</td>
<td><a href="{{p.url}}" target="blank">{{p.url}}</a></td>
<td>{{p.date}}</td>
<td><a href="{% url 'news-list'%}?publishers={{p.id}}&{{queryurl}}">{{p.news|intcomma}}</a></td>
<td>{{p.type}}</td>
<td><a href="{% url 'audio'%}{{p.publisher.shortName}}">{{p.publisher.name}}</a></td>
<td>{{p.publisher.shortName}}</td>
<td><a href="{{p.publisher.url}}" target="blank">{{p.publisher.url}}</a></td>
<td>{{p.startDate}}</td>
<td>{{p.minutes|div:60|floatformat:2 }}</td>
<td>{{p.publisher.type}}</td>
</tr>
{% endfor %}
</tbody>
......
{% extends "base_generic.html" %}
{% block lefPanel %}{% include "leftMenuBar.html" %}{% endblock %}
{% block headMedia %}
{% load static %}
<link rel="stylesheet" id="rangecalendar-style-css" href="{% static 'css/rangecalendar.css' %}" type="text/css" media="all">
<link rel="stylesheet" id="rangecalendar-style-css" href="{% static 'css/calendar-style.css' %}" type="text/css" media="all">
<link rel="stylesheet" id="rangecalendar-style-css" href="{% static 'css/audioplayer.css' %}" type="text/css" media="all">
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.11.0/themes/smoothness/jquery-ui.css">
{% endblock %}
{% load humanize %}
{% block dash-title %}
......@@ -21,13 +30,10 @@
<!-- /.panel-heading -->
<div class="panel-body">
<div id="cal1">holas</div>
<div id="audioCalendar"></div>
<div id="audioDiv">audio tag</div>
<!-- /.table-responsive -->
</div>
<!-- /.panel-body -->
</div>
......@@ -41,13 +47,83 @@
{% block scripts %}
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/jqueryui-touch-punch/0.2.3/jquery.ui.touch-punch.min.js"></script>
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/moment.js/2.7.0/moment-with-langs.min.js"></script>
<script type="text/javascript" src="{% static 'js/jquery.rangecalendar.js' %}"></script>
<script>
$(document).ready(function() {
$('#dataTables-example').DataTable({
responsive: true,
"language": {"url": "/static/languages/Spanish.json" }
});
function getAudioList(publisher, startdate, enddate)
{
var xmlhttp;
if (window.XMLHttpRequest)
{//IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
// document.getElementById("topics").innerHTML=xmlhttp.responseText;
var jsonObj = JSON.parse(xmlhttp.responseText);
console.log(jsonObj);
}
}
xmlhttp.open("GET", "/catalog/ws/playlist/?startdate="+startdate+"&enddate="+enddate+"&publisher="+publisher,true);
xmlhttp.send();
};
$(document).ready(function () {
var emptyMonths = [
{month: '01', year: '2016'},
{month: '06', year: '2016'},
{month: '09', year: '2016'},
{month: '03', year: '2017'},
{month: '07', year: '2017'},
{month: '11', year: '2017'}
];
var calendar = $("#audioCalendar").rangeCalendar({
theme:"full-red-theme",
lang: "es",
startDate: moment(20160101, "YYYYMMDD"),
endDate: moment(),
start: "0",
minRangeWidth: 1,
maxRangeWidth: 1,
maxTimeRangeWidth: 6,
changeRangeCallback: rangeChanged,
emptyMonths: emptyMonths
});
var today = new Date();
calendar.setStartDate(today);
function rangeChanged(target, range) {
console.log(range);
var audioDiv = document.getElementById("audioDiv");
while (audioDiv.firstChild)
audioDiv.removeChild(audioDiv.firstChild);
var sound = document.createElement('audio');
sound.id = 'audio-player';
sound.controls = 'controls';
sound.src = 'media/Blue Browne.mp3';
sound.type = 'audio/mpeg';
audioDiv.appendChild(sound);
getAudioList("{{publisher.shortName}}",range.start,range.end);
}
});
</script>
{% endblock %}
......
......@@ -13,9 +13,9 @@
<title>Monitoreo de Multiples Medios</title>
{% load staticfiles %}
<script type="text/javascript" src="{% static 'static_jquery/js/jquery.js' %}" ></script>
<script type="text/javascript" src="{% static 'admin/js/jquery.init.js' %}" ></script>
<script type="text/javascript" src="{% static 'static_jquery/js/jquery.js' %}" ></script>
<script type="text/javascript" src="{% static 'admin/js/jquery.init.js' %}" ></script>
<link rel="stylesheet" href="{% static 'css/forms.css' %}">
<!-- Custom CSS -->
<!-- Bootstrap Core CSS -->
......
......@@ -11,31 +11,32 @@
<a href="#"><i class="fa fa-search fa-fw"></i>Busqueda<span class="fa arrow"></span></a>
<ul class="nav nav-second-level collapse in" aria-expanded="true">
<form role="form">
<form role="form" >
<li>
<div class="form-group">
{{form.publishers.label_tag}}
{{form.publishers}}
</div>
</li>
<!-- <div class="form-group">-->
<!-- {{form.publishers.label_tag}}-->
<!-- {{form.publishers}}-->
<!-- </div>-->
<!-- </li>-->
<li>
<div class="form-group">
{{form.startDate.label_tag}}
{{form.startDate}}
</div>
</li>
<li>
<div class="form-group">
{{form.endDate.label_tag}}
{{form.endDate}}
</div>
</li>
<li>
<div class="form-group">
{{form.text.label_tag}}
{{form.text}}
</div>
<!-- <li>-->
<!-- <div class="form-group">-->
<!-- {{form.startDate.label_tag}}-->
<!-- {{form.startDate}}-->
<!-- </div>-->
<!-- </li>-->
<!-- <li>-->
<!-- <div class="form-group">-->
<!-- {{form.endDate.label_tag}}-->
<!-- {{form.endDate}}-->
<!-- </div>-->
<!-- </li>-->
<!-- <li>-->
<!-- <div class="form-group">-->
<!-- {{form.text.label_tag}}-->
<!-- {{form.text}}-->
<!-- </div>-->
{{form}}
</li>
......
{% extends "settings_base.html" %}
{% block dash-title %}
<b>{{form.text.value|default:"Busquedas Realizadas"|capfirst}}</b>
[{{form.startDate.value}}, {{form.endDate.value}}]
{% endblock %}
{% block dash %}
<!-- /.row -->
<div class="row">
<div class="col-lg-12">
<div class="panel panel-default">
<div class="panel-heading">
Busquedas
</div>
<!-- /.panel-heading -->
<div class="panel-body">
<table width="100%" class="table table-striped table-bordered table-hover" id="dataTables-search">
<thead>
<tr>
<th>Texto</th>
<th>Inicio</th>
<th>Fin</th>
<th>Fuentes</th>
</tr>
</thead>
<tfoot>
<tr>
<th>Texto</th>
<th>Inicio</th>
<th>Fin</th>
<th>Fuentes</th>
</tr>
</tfoot>
</table>
<!-- /.table-responsive -->
</div>
<!-- /.panel-body -->
</div>
<!-- /.panel -->
</div>
<!-- /.col-lg-12 -->
</div>
<!-- /.row -->
{% endblock %}
{% block scripts %}
<script>
$(document).ready(function() {
$('#dataTables-search').DataTable({
"order": [[ 2, "desc" ]],
"responsive": true,
"processing": true,
"serverSide": true,
"language": {"url": "/static/languages/Spanish.json" },
"ajax": {
"url":"/catalog/ws/searches/",
"data":{},
}
});
});
//console.log(" {{form.publishers.data|safe}} ");
</script>
{% endblock %}
......@@ -13,6 +13,10 @@
<li>
<a href="{% url 'settings-subscriptions' %}"><i class="fa fa-rss fa-fw"></i>Subscripciones</a>
</li>
<li>
<a href="{% url 'settings-search' %}"><i class="fa fa-search fa-fw"></i>Busquedas</a>
</li>
<!-- <li>-->
<!-- <a href=""><i class="fa fa-user fa-rss"></i>Subscripciones</a>-->
<!-- </li>-->
......
......@@ -12,10 +12,14 @@ urlpatterns = [
url(r'^publishers/(?P<type>\w+)$', views.publisherList, name='publishers-list'),
url(r'^news/details/(?P<newsId>\w+)/$', views.newsDetails, name='news-details'),
url(r'^news/$', views.newsList, name='news-list'),
url(r'^ws/news/$', views.wsNewsList, name='ws-news-list'),
url(r'^ws/jsonnews/$', views.wsNewsList2, name='ws-news-list2'),
url(r'^ws/graphs/$', views.wsGraphs, name='ws-graphs'),
url(r'^ws/download/$', views.wsDownloadNews, name='ws-download-news'),
url(r'^ws/searches/$', views.wsSearchList, name='ws-search-list'),
url(r'^ws/playlist/$', views.wsAudioList, name='ws-audio-list'),
url(r'^audio/$', views.audioList, name='audio'),
url(r'^audio/(?P<publisher>\w+)$', views.audioPublisher, name='audio'),
......@@ -23,6 +27,7 @@ urlpatterns = [
url(r'^settings/profile$', views.settings, name='settings-profile'),
url(r'^settings/subscriptions$', views.settings, name='settings-subscriptions'),
url(r'^settings/password$', views.settings, name='settings-password'),
url(r'^settings/searches$', views.settingsSearches, name='settings-search'),
]
No preview for this file type
......@@ -6,28 +6,99 @@ from django.shortcuts import render
# Create your views here.
from catalog.models import Publisher, News
from catalog.models import Publisher, News, Search, audioTime
from django.core.exceptions import ObjectDoesNotExist
from django.shortcuts import redirect
from django.http import HttpResponse
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.db.models import Count
from django.core.urlresolvers import reverse
from django.db.models.functions import TruncMonth, TruncYear
from .forms import SearchForm, ProfileForm, SubscriptionsForm
from django.db.models import Q
import json
import datetime
import time
from dateutil.relativedelta import relativedelta
import dateutil.parser
from django.db.models import Q
from .forms import SearchForm, ProfileForm
import urllib
from django.db.models import Count
from django.core.urlresolvers import reverse
import json
import StringIO
#from io import StringIO
import time
import zipfile
import csv
from django.db.models.functions import TruncMonth, TruncYear
from quantiphy import Quantity
from .audioList import getAudioList
#-------------------------------------------------------------------------------
def getAudiosList2Convert(streamPublisher, initTimestamp, endTimestamp, days):
recordingsPath = '/home/mario/virtualHDD/m3/recordings/'
initialDate = datetime.fromtimestamp(initTimestamp) #+ timedelta(hours=6)
endDate = datetime.fromtimestamp(endTimestamp) #+ timedelta(hours=6)
audiosList = []
for i in range(days):
audiosPath = '{0}/{1}/{2:02d}/{3:02d}/'.format(
streamPublisher,
initialDate.year,
initialDate.month,
initialDate.day
)
print('Now enter in: {0}'.format(audiosPath))
if os.path.exists(recordingsPath+audiosPath):
for file in os.listdir(recordingsPath+audiosPath):
audioTimestamp = int(file.split(".")[0])
if audioTimestamp >= initTimestamp and audioTimestamp <= endTimestamp:
audiosList.append(recordingsPath+audiosPath+file)
#audiosList.append((recordingsPath+audiosPath, file))
# Next day dir
initialDate += timedelta(days=1)
return audiosList
#-------------------------------------------------------------------------------
def getRecordingDays(initTimestamp, endTimestamp):
initialDate = datetime.fromtimestamp(initTimestamp) #+ timedelta(hours=6)
endDate = datetime.fromtimestamp(endTimestamp) #+ timedelta(hours=6)
print(initialDate)
print(endDate)
iDate = [initialDate.day, initialDate.month, initialDate.year]
eDate = [endDate.day, endDate.month, endDate.year]
days = 1
if array_equal(iDate, eDate):
# Iterate over the same day dir
return days
else:
while not array_equal(iDate, eDate):
days += 1
initialDate += timedelta(days=1)
iDate = [initialDate.day, initialDate.month, initialDate.year]
return days
#-------------------------------------------------------------------------------
def getAudiosList(streamPublisher, initTimestamp, endTimestamp):
initTimestamp = float(initTimestamp)
endTimestamp = float(endTimestamp)
days = getRecordingDays(initTimestamp, endTimestamp)
print('Recording days: {0}'.format(days))
audiosList = getAudiosList2Convert(streamPublisher, initTimestamp, endTimestamp, days)
return audiosList
#-------------------------------------------------------------------------------
def news2JSON(news):
data = list()
......@@ -42,18 +113,30 @@ def news2JSON(news):
return data
#-------------------------------------------------------------------------------
def settings(request):
form = ProfileForm(request.POST.copy())
print(request.POST)
# form = ProfileForm( initial={'subscriptions':[ v for v in request.user.profile.subscriptions.all().values_list('id', flat=True)]})
print ("subS",[ v for v in request.user.profile.subscriptions.all().values_list('id', flat=True)])
print(request.POST)
# print(form)
#User.objects.get(username=)
print( request.user.profile.subscriptions )
if 'subscriptions' in request.POST:
request.user.profile.subscriptions = Publisher.objects.all().filter(id__in=request.POST['subscriptions'])
request.user.save()
print( request.user.profile.subscriptions )
if request.method == "POST":
form = ProfileForm(request.POST)
if form.is_valid():
request.user.profile.subscriptions=form.cleaned_data['subscriptions']
else:
form = ProfileForm( initial={'subscriptions':[ v for v in request.user.profile.subscriptions.all().values_list('id', flat=True)]})
news = News.objects.all()
publishersList = Publisher.objects.all().filter( Q(id__in = news.values('publisher').distinct()))
choice = [ (r.id,r.name) for r in publishersList ]
form.fields['subscriptions'].choices=choice
print( request.user.profile.subscriptions.all() )
return render(request,'userprofile.html',{"form":form})
#-------------------------------------------------------------------------------
def settingsSearches(request):
return render(request,'searches.html',{})
#-------------------------------------------------------------------------------
def getNewsByRequest(request):
print ("getNewsByRequest\n\n\n")
......@@ -64,6 +147,8 @@ def getNewsByRequest(request):
if 'publishers' in request.GET and request.GET['publishers']!="None" and request.GET['publishers']!="" and request.GET['publishers']!="[]":
myQuery &= Q(publisher_id__in=form['publishers'].value())
else:
myQuery &= Q(publisher_id__in=[ r.id for r in request.user.profile.subscriptions.all()])
if 'startDate' in request.GET and request.GET['startDate']!="None" and request.GET['startDate']!="":
myQuery &= Q(date__gte=request.GET['startDate'])
......@@ -87,8 +172,20 @@ def index(request):
View function for home page of site.
"""
news = getNewsByRequest(request)
form = SearchForm(request.GET.copy())
data = request.GET.copy()
form = SearchForm(data)
if form.is_valid():
print("DATA",form.data)
form.save(request.user)
form.save_m2m()
print ("form is valid")
else:
print ("form is NOT valid", form.errors)
subscriptions = [ (r.id,r.name) for r in request.user.profile.subscriptions.all()]
form.fields['publishers'].choices= subscriptions
if news.count()>0:
if 'startDate' not in form or ('startDate' in form and form['startDate'].value == ""):
form.data.update({'startDate':news.earliest('date').date.strftime("%Y-%m-%d")})
......@@ -109,7 +206,7 @@ def index(request):
myRequest = request.GET.copy()
myRequest.update({"publishers":q['publisher']})
urlDict[q['publisher']] = urllib.urlencode(myRequest)
print (urlDict)
# print (urlDict)
donutChart = [{"label": Publisher.objects.get(id=q['publisher']).name, "value":q["count"], "url":urlDict[q['publisher']]} for q in queryset]
......@@ -160,6 +257,33 @@ def newsList(request, publisherShortName="all"):
form = SearchForm(request.GET)
return render(request,'newsList.html',{"form":form})
#-------------------------------------------------------------------------------
def wsAudioList(request):
data = dict()
print("wsAudioList", request.GET)
startDate = dateutil.parser.parse(request.GET['startdate']).strftime('%s')
endDate = dateutil.parser.parse(request.GET['enddate']).strftime('%s')
print ("STARTDATE", startDate)
audioList = getAudioList(request.GET['publisher'], startDate, endDate)
# audioList = getAudioList('RadioFormula1041', '1512158400', '1512396000')
print ("audioList", audioList)
return HttpResponse(json.dumps(data), content_type="application/json")
#-------------------------------------------------------------------------------
def wsSearchList(request):
searches = Search.objects.all().filter(user=request.user)
data = dict()
data['data']=[[s.text, "*" if s is None else s.startDate.strftime('%Y-%m-%d'), "*" if s is None else s.endDate.strftime('%Y-%m-%d'), ','.join([ sub.shortName for sub in s.publishers.all()])] for s in searches]
data['recordsTotal'] = searches.count()
data['recordsFiltered'] = searches.count()
return HttpResponse(json.dumps(data), content_type="application/json")
#-------------------------------------------------------------------------------
def wsNewsList2(request):
......@@ -262,7 +386,7 @@ def wsDownloadNews(request):
def audioList(request):
form = SearchForm(request.GET)
publishers = Publisher.objects.all().filter( type="audio")
publishers = audioTime.objects.all().filter(minutes__gt=0 ) #type="audio")
return render(request,'audioList.html',{"form":form, "publishers":publishers})
#-------------------------------------------------------------------------------
......
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.shortcuts import render
# Create your views here.
from catalog.models import Publisher, News
from django.core.exceptions import ObjectDoesNotExist
from django.shortcuts import redirect
from django.http import HttpResponse
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
import json
import datetime
from dateutil.relativedelta import relativedelta
from django.db.models import Q
from .forms import SearchForm, ProfileForm, SubscriptionsForm
import urllib
from django.db.models import Count
from django.core.urlresolvers import reverse
import json
import StringIO
#from io import StringIO
import time
import zipfile
import csv
from django.db.models.functions import TruncMonth, TruncYear
from quantiphy import Quantity
#-------------------------------------------------------------------------------
def news2JSON(news):
data = list()
for n in news:
item = dict()
item['date'] = n.date.strftime('%Y-%m-%d')
item['publisher'] = n.publisher.name
item['title'] = n.title
item['text'] = n.text
item['url'] = n.url
data.append(item)
return data
#-------------------------------------------------------------------------------
def settings(request):
# form = ProfileForm( initial={'subscriptions':[ v for v in request.user.profile.subscriptions.all().values_list('id', flat=True)]})
print ("subS",[ v for v in request.user.profile.subscriptions.all().values_list('id', flat=True)])
print(request.POST)
# print(form)
#User.objects.get(username=)
if request.method == "POST":
form = ProfileForm(request.POST)
if form.is_valid():
request.user.profile.subscriptions=form.cleaned_data['subscriptions']
else:
form = ProfileForm( initial={'subscriptions':[ v for v in request.user.profile.subscriptions.all().values_list('id', flat=True)]})
news = News.objects.all()
publishersList = Publisher.objects.all().filter( Q(id__in = news.values('publisher').distinct()))
choice = [ (r.id,r.name) for r in publishersList ]
form.fields['subscriptions'].choices=choice
print( request.user.profile.subscriptions.all() )
return render(request,'userprofile.html',{"form":form})
#-------------------------------------------------------------------------------
def settings(request):
return render(request,'usersearch.html',{"form":form})
#-------------------------------------------------------------------------------
def getNewsByRequest(request):
print ("getNewsByRequest\n\n\n")
form = SearchForm(request.GET)
myQuery = ~Q()
if 'publishers' in request.GET and request.GET['publishers']!="None" and request.GET['publishers']!="" and request.GET['publishers']!="[]":
myQuery &= Q(publisher_id__in=form['publishers'].value())
else:
myQuery &= Q(publisher_id__in=[ r.id for r in request.user.profile.subscriptions.all()])
if 'startDate' in request.GET and request.GET['startDate']!="None" and request.GET['startDate']!="":
myQuery &= Q(date__gte=request.GET['startDate'])
else:
myQuery &= Q(date__gte=(datetime.date.today()- relativedelta(years=1)).strftime("%Y-%m-%d"))
if 'endDate' in request.GET and request.GET['endDate']!="None" and request.GET['endDate']!="":
myQuery &= Q(date__lte=request.GET['endDate'])
if "text" in request.GET and request.GET['text']!="None" and request.GET['text']!="":
# myQuery &= Q(text__search=request.GET['text'])
myQuery &= Q(search_vector=request.GET['text'])
print (myQuery)
return News.objects.all().filter(myQuery)
#-------------------------------------------------------------------------------
def index(request):
"""
View function for home page of site.
"""
news = getNewsByRequest(request)
form = SearchForm(request.GET.copy())#, initial={'publishers':[]})
subscriptions = [ (r.id,r.name) for r in request.user.profile.subscriptions.all()]
print (subscriptions)
form.fields['publishers'].choices= subscriptions
if news.count()>0:
if 'startDate' not in form or ('startDate' in form and form['startDate'].value == ""):
form.data.update({'startDate':news.earliest('date').date.strftime("%Y-%m-%d")})
if 'endDate' not in form or ('endDate' in form and form['endDate'].value == ""):
form.data.update({'endDate':news.latest('date').date.strftime("%Y-%m-%d")})
info = dict()
info['nPublishers'] = news.values('publisher').distinct().count()
info['nNews'] = news.count()
info['nNewsText'] = Quantity(news.count()).render(prec=3)
info['nAudio'] = Publisher.objects.all().filter(type="audio").count()
queryset = news.values("publisher").order_by("publisher").annotate(count = Count('publisher') )
urlDict = dict()
for q in queryset:
myRequest = request.GET.copy()
myRequest.update({"publishers":q['publisher']})
urlDict[q['publisher']] = urllib.urlencode(myRequest)
print (urlDict)
donutChart = [{"label": Publisher.objects.get(id=q['publisher']).name, "value":q["count"], "url":urlDict[q['publisher']]} for q in queryset]
publishers = Publisher.objects.all().filter( Q(id__in = news.values('publisher').distinct()))
queryset = news.values("publisher").annotate(day=TruncMonth('date') )
dateList =[q['day'].strftime("%Y-%m-%d") for q in queryset.values("day").distinct().order_by("-day")]
dateDicts = {p.shortName:{ n['day'].strftime("%Y-%m-%d"):n['count'] for n in queryset.filter(publisher=p.id).values("day").distinct().order_by("-day").annotate(count = Count('publisher')) } for p in publishers}
histogramsData = [ { "date":d, "data":{ k:(dateDicts[k][d] if d in dateDicts[k] else 0) for k in dateDicts.keys()} } for d in dateList]
histogramsLabels = [p.shortName for p in publishers]
# return render(request,'index.html',{"form":form, "info":info, "donutChart":{}, "histogram": {}, "histogramsLabels":{}})
return render(request,'index.html',{"form":form, "info":info, "donutChart":donutChart, "histogram": histogramsData, "histogramsLabels":histogramsLabels})
#-------------------------------------------------------------------------------
def publisherList(request, type="all"):
form = SearchForm(request.GET)
typeQuery = ~Q()
if type!="all":
typeQuery = Q(type=type)
news = getNewsByRequest(request)
publishers = Publisher.objects.all().filter( Q(id__in = news.values('publisher').distinct()) & typeQuery)
for p in publishers:
newsTemp = news.filter(publisher=p).order_by("date")
p.news = newsTemp.count()
p.date = 0
if p.news>0:
p.date = newsTemp[0].date.date()
else:
p.date = "-"
myRequest=request.GET.copy()
if 'publishers' in myRequest:
del myRequest['publishers']
return render(request,'publisherList.html',{"form":form, "publishers":publishers, "queryurl":urllib.urlencode(myRequest)})
#-------------------------------------------------------------------------------
def newsList(request, publisherShortName="all"):
form = SearchForm(request.GET)
return render(request,'newsList.html',{"form":form})
#-------------------------------------------------------------------------------
def wsNewsList2(request):
news = getNewsByRequest(request)
data = [{"id":n.id, "text":n.text, "date":n.date.strftime('%Y-%m-%d')} for n in news]
return HttpResponse(json.dumps(data), content_type="application/json")
#-------------------------------------------------------------------------------
def wsNewsList(request):#, publisherShortName="all"):
print (request.GET)
columns = ['title', 'url', 'date']
order = dict()
order["asc"]=""
order["desc"]="-"
orderBy = columns[ int(request.GET["order[0][column]"]) ]
direction = order[request.GET["order[0][dir]"]]
startDate = datetime.datetime(1950,1,1,0,0,0)
endDate = datetime.datetime.today()
request.GET = request.GET.copy()
if 'ajaxPublishers[]' in request.GET:
request.GET.setlist('publishers', request.GET.getlist('ajaxPublishers[]'))
del request.GET['ajaxPublishers[]']
news = getNewsByRequest(request).order_by(direction+orderBy)
if 'search[value]' in request.GET and request.GET['search[value]'] != "":
search = request.GET['search[value]']
news = news.filter(text__icontains=search)
data = dict()
data['data']=list()
data['recordsTotal'] = news.count()
data['recordsFiltered'] = news.count()
paginator = Paginator(news, request.GET['length'])
page = (int(request.GET['start'])/int(request.GET['length']))+1
try:
news = paginator.page(page)
except PageNotAnInteger:
news = paginator.page(1)
except EmptyPage:
news = paginator.page(paginator.num_pages)
for n in news:
row = list()
row.append('<a href="'+reverse('news-details', args =(n.id,) )+ "?"+ request.GET.urlencode() +'">'+ n.title+ '</a>')
row.append('<a href="'+n.url+'" target="blank">'+n.publisher.shortName+'</a>')
row.append(n.date.strftime("%Y-%m-%d"))
data['data'].append(row)
# print request.GET
return HttpResponse(json.dumps(data), content_type="application/json")
#-------------------------------------------------------------------------------
def newsDetails(request, newsId):
form = SearchForm(request.GET)
news = News.objects.get(id=newsId)
# news.text = news.text.replace(request.GET['text'], "<b>"+request.GET['text']+"</b>")
return render(request,'newsDetails.html',{"form":form,"news":news})
#-------------------------------------------------------------------------------
def wsGraphs(request):
data=dict()
if request.GET['type']=="histogram":
data = 0;
return HttpResponse(json.dumps(data), content_type="application/json")
#-------------------------------------------------------------------------------
def wsDownloadNews(request):
news = getNewsByRequest(request)
s = StringIO.StringIO() # Open StringIO to grab in-memory ZIP contents
zf = zipfile.ZipFile(s, "w") # The zip compressor
zf.writestr("setting.txt", json.dumps(request.GET))
data = news2JSON(news);
if request.GET['format']=="JSON":
zf.writestr("data.json", json.dumps(data))
if request.GET['format']=="CSV":
csvString = StringIO.StringIO()
writer = csv.writer(csvString,quoting=csv.QUOTE_ALL)#, fieldnames=[k for k in data[0]])
# writer.writeheader()
for d in data:
row = [ d[k].encode('utf-8') for k in d ]
writer.writerow( row )
zf.writestr("data.csv", csvString.getvalue())
zf.close()
response = HttpResponse(s.getvalue(), content_type="application/x-zip-compressed")
response['Content-Disposition'] = 'attachment; filename="news_'+ str(int(time.time()))+'.zip"'
return response
#-------------------------------------------------------------------------------
def audioList(request):
form = SearchForm(request.GET)
publishers = Publisher.objects.all().filter( type="audio")
return render(request,'audioList.html',{"form":form, "publishers":publishers})
#-------------------------------------------------------------------------------
def audioPublisher(request, publisher):
form = SearchForm(request.GET)
info=dict()
if Publisher.objects.all().filter(shortName=publisher).count() > 0:
p = Publisher.objects.all().filter(shortName=publisher)[0]
return render(request,'audioPlay.html',{"form":form, "publisher":p})
No preview for this file type
......@@ -38,6 +38,7 @@ INSTALLED_APPS = [
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.humanize',
'mathfilters',
'catalog.apps.CatalogConfig',
'django.contrib.postgres',
'django_static_jquery',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment