def select_file(self): self.statusBar().showMessage(Lang.get_string("status_bar_msg_bom_file")) file_name_bom, _ = QFileDialog.getOpenFileName(self,Lang.get_string("file_dialog_bom_name"),"",Lang.get_string("file_dialog_bom_type")) if file_name_bom: self.file_name_bom = file_name_bom self.label_bom.setText(file_name_bom) self.statusBar().showMessage(Lang.get_string("status_bar_msg_bom_sel_file") + file_name_bom, 5000) else: self.statusBar().clearMessage()
def select_database_folder(self): self.statusBar().showMessage(Lang.get_string("status_bar_msg_database_folder")) path_database = QFileDialog.getExistingDirectory(self,Lang.get_string("file_dialog_database_name")) if path_database: self.path_database = path_database self.label_database.setText(path_database) self.statusBar().showMessage(Lang.get_string("status_bar_msg_database_sel_folder") + path_database, 5000) else: self.statusBar().clearMessage()
def day(timestamp): if timestamp: today = datetime.today() tomorrow = today + timedelta(days=1) yesterday = today - timedelta(days=1) if today.date() == timestamp.date(): return get_string('Today') elif tomorrow.date() == timestamp.date(): return get_string('Tomorrow') elif yesterday.date() == timestamp.date(): return get_string('Yesterday') else: return get_string(timestamp.strftime("%A"))
def generate_matches(self): if self.path_database and self.file_name_bom: self.statusBar().showMessage(Lang.get_string("status_bar_msg_search_running")) self.checkbox_grouped.setEnabled(True) self.button_export.setEnabled(True) try: self.dispatcher.set_bom_file_path(self.file_name_bom) self.dispatcher.set_database_path(self.path_database) self.dispatcher.find_matches() self.statusBar().showMessage(Lang.get_string("status_bar_msg_search_finished"), 5000) self.show_matches() except Exception as e: self.statusBar().showMessage(Lang.get_string("status_bar_msg_error")) error_msg = QMessageBox() error_msg.setIcon(QMessageBox.Critical) error_msg.setText(Lang.get_string("error")) error_msg.setInformativeText(e.args[0]) error_msg.setWindowTitle(Lang.get_string("error")) error_msg.exec_() raise Exception from e else: error_msg = QMessageBox() error_msg.setIcon(QMessageBox.Critical) error_msg.setText(Lang.get_string("error")) error_msg.setInformativeText(Lang.get_string("error_msg_file_and_folder")) error_msg.setWindowTitle(Lang.get_string("error")) error_msg.exec_() self.statusBar().clearMessage()
def ffmpeg_location(): ffmpeg_src = xbmc.translatePath(plugin.get_setting('ffmpeg', str)) if xbmc.getCondVisibility('system.platform.android'): ffmpeg_dst = '/data/data/%s/ffmpeg' % android_get_current_appid() if (plugin.get_setting('ffmpeg', str) != plugin.get_setting( 'ffmpeg.last', str)) or (not xbmcvfs.exists(ffmpeg_dst) and ffmpeg_src != ffmpeg_dst): xbmcvfs.copy(ffmpeg_src, ffmpeg_dst) plugin.set_setting('ffmpeg.last', plugin.get_setting('ffmpeg', str)) ffmpeg = ffmpeg_dst else: ffmpeg = ffmpeg_src if ffmpeg: try: st = os.stat(ffmpeg) if not (st.st_mode & stat.S_IXUSR): try: os.chmod(ffmpeg, st.st_mode | stat.S_IXUSR) except: pass except: pass if xbmcvfs.exists(ffmpeg): return ffmpeg else: xbmcgui.Dialog().notification("IPTV Recorder", get_string("ffmpeg exe not found!"))
def create_part_templates(self): self.part_templates = [] self.assigned_reference_symbols = [] self.assigned_database_file_keywords = [] for element in Setup.PTI: template = Parts.PartTemplate(element) if template.get_keyword_database_file( ) in self.assigned_database_file_keywords: raise Exception("keyword assigned twice: " + template.get_keyword_database_file()) if not template.get_reference_symbols(): raise Exception( "there are no reference symbols defined for template: " + template.get_part_type()) for symbol in template.get_reference_symbols(): if symbol in self.assigned_reference_symbols: raise Exception("reference symbol assigned twice: " + symbol) self.assigned_reference_symbols.extend( template.get_reference_symbols()) self.assigned_database_file_keywords.append( template.get_keyword_database_file()) self.part_templates.append(template) # add an additional part template for all parts, not belonging to user defined part templates args = { "part_type": "others", "requested_properties": copy.deepcopy(Setup.PTI_REQ_PROPERTIES), "reference_symbols": None, "keyword_database_file": None, "description": Lang.get_string("PTI_category_others_description") } self.part_templates.append(Parts.PartTemplate(args))
def export(self): try: # use BOM file to determine folder and filename path,filename = os.path.split(self.file_name_bom) # remove file ending filename,_ = os.path.splitext(filename) self.dispatcher.export(path,filename) self.statusBar().showMessage(Lang.get_string("status_bar_msg_done"), 2000) except Exception as e: self.statusBar().showMessage(Lang.get_string("status_bar_msg_error")) error_msg = QMessageBox() error_msg.setIcon(QMessageBox.Critical) error_msg.setText(Lang.get_string("error")) error_msg.setInformativeText(e.args[0]) error_msg.setWindowTitle(Lang.get_string("error")) error_msg.exec_() raise Exception from e
def check_has_db_filled_show_error_message_ifn(db_cursor): table_found = db_cursor.execute( "SELECT name FROM sqlite_master WHERE type='table' AND name='streams'" ).fetchone() if not table_found: xbmcgui.Dialog().notification("IPTV Recorder", get_string("Database not found")) return False return True
def index(): items = [] context_items = [] items.append({ 'label': get_string("Recordings Folder"), 'path': plugin.get_setting('recordings', str), 'thumbnail': get_icon_path('recordings'), 'context_menu': context_items, }) items.append({ 'label': get_string("Delete all settings"), 'path': plugin_url_for(plugin, 'nuke'), 'thumbnail': get_icon_path('settings'), 'context_menu': context_items, }) return items
def nuke(): if not (xbmcgui.Dialog().yesno( "IPTV Archive Downloader", get_string("Delete Everything and Start Again?"))): return xbmcvfs.delete( xbmc.translatePath('%sxmltv.db' % plugin.addon.getAddonInfo('profile'))) time.sleep(5) full_service()
def init_ui(self): # boxes self.box_window = QVBoxLayout() self.box_header = QVBoxLayout() self.box_header_bom = QHBoxLayout() self.box_header_database = QHBoxLayout() self.box_commands = QHBoxLayout() self.scroll_body = QScrollArea() self.scroll_widget = QWidget() self.box_body = QVBoxLayout() self.box_footer = QHBoxLayout() # add elements to boxes # bom button + label self.button_bom = QPushButton(Lang.get_string("button_bom"), self) self.button_bom.setToolTip(Lang.get_string("button_bom_tooltip")) self.button_bom.setFixedSize(Definitions.GUI_WIDTH_BUTTON, Definitions.GUI_HEIGHT_BUTTON) self.button_bom.clicked.connect(self.select_file) self.label_bom = QLabel(self.file_name_bom, self) self.box_header_bom.addWidget(self.button_bom) self.box_header_bom.addWidget(self.label_bom) self.box_header_bom.addStretch() # database button + label self.button_database = QPushButton(Lang.get_string("button_database"),self) self.button_database.setToolTip(Lang.get_string("button_database_tooltip")) self.button_database.setFixedSize(Definitions.GUI_WIDTH_BUTTON, Definitions.GUI_HEIGHT_BUTTON) self.button_database.clicked.connect(self.select_database_folder) self.label_database = QLabel(self.path_database, self) self.box_header_database.addWidget(self.button_database) self.box_header_database.addWidget(self.label_database) self.box_header_database.addStretch() # drop down menu for CAD system self.combobox_cad = QComboBox() self.combobox_cad.addItems(self.dispatcher.get_cad_system().get_system_names()) self.combobox_cad.setCurrentIndex(self.combobox_cad.findText(self.dispatcher.get_cad_system().get_name_of_selected_system(),Qt.MatchFixedString)) self.combobox_cad.setFixedWidth(Definitions.GUI_WIDTH_BUTTON) self.combobox_cad.activated[str].connect(self.select_cad_system) # button regroup self.button_regroup = QPushButton(Lang.get_string("button_regroup"),self) self.button_regroup.setToolTip(Lang.get_string("button_regroup_tooltip")) self.button_regroup.setEnabled(self.window_settings["view_grouped"]) self.button_regroup.setFixedSize(Definitions.GUI_WIDTH_BUTTON, Definitions.GUI_HEIGHT_BUTTON) self.button_regroup.clicked.connect(self.regroup) # checkbox for grouped/ungrouped view self.checkbox_grouped = QCheckBox(Lang.get_string("checkbox_grouped")) self.checkbox_grouped.setChecked(self.window_settings["view_grouped"]) self.checkbox_grouped.setEnabled(False) self.checkbox_grouped.stateChanged.connect(lambda: self.checkbox_changed(self.checkbox_grouped)) # export ordering numbers self.button_export = QPushButton(Lang.get_string("button_export"),self) self.button_export.setToolTip(Lang.get_string("button_export_tooltip")) self.button_export.setEnabled(False) self.button_export.setFixedSize(Definitions.GUI_WIDTH_BUTTON, Definitions.GUI_HEIGHT_BUTTON) self.button_export.clicked.connect(self.export) # generate button self.button_generate = QPushButton(Lang.get_string("button_generate"),self) self.button_generate.setToolTip(Lang.get_string("button_generate_tooltip")) self.button_generate.setFixedSize(Definitions.GUI_WIDTH_BUTTON, Definitions.GUI_HEIGHT_BUTTON) self.button_generate.clicked.connect(self.generate_matches) # label requesting user to select files self.label_hint = QLabel(Lang.get_string("label_hint"),self) # close button self.button_close = QPushButton(Lang.get_string("button_close"), self) self.button_close.setToolTip(Lang.get_string("button_close_tooltip")) self.button_close.setFixedSize(Definitions.GUI_WIDTH_BUTTON, Definitions.GUI_HEIGHT_BUTTON) self.button_close.clicked.connect(QCoreApplication.quit) # pack header box self.box_header.addLayout(self.box_header_bom) self.box_header.addLayout(self.box_header_database) # pack command box self.box_commands.addWidget(self.combobox_cad) self.box_commands.addWidget(self.checkbox_grouped) self.box_commands.addStretch() self.box_commands.addWidget(self.button_export) self.box_commands.addWidget(self.button_regroup) self.box_commands.addWidget(self.button_generate) # pack body self.box_body.addWidget(self.label_hint) self.box_body.addStretch() self.box_body.setAlignment(Qt.AlignTop) self.scroll_widget.setLayout(self.box_body) self.scroll_body.setWidget(self.scroll_widget) # pack footer self.box_footer.addStretch() self.box_footer.addWidget(self.button_close) # pack window self.box_window.addLayout(self.box_header) self.box_window.addLayout(self.box_commands) self.box_window.addWidget(self.scroll_body) self.box_window.addLayout(self.box_footer) # set scroll area properties self.scroll_body.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) self.scroll_body.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded) self.scroll_body.setWidgetResizable(True) # build central widget and select it self.central_widget = QWidget() self.setCentralWidget(self.central_widget) self.centralWidget().setLayout(self.box_window) # add status bar self.status_bar = QStatusBar(self) self.setStatusBar(self.status_bar) # show window self.setGeometry(50,50,1024,768) self.setWindowTitle(Lang.get_string("window_title")) self.showMaximized() self.show()
def xmltv(): load_groups = plugin.get_storage('load_groups') load_channels = {} dialog = xbmcgui.DialogProgressBG() dialog.create("IPTV Recorder", get_string("Loading data...")) profilePath = xbmc.translatePath(plugin.addon.getAddonInfo('profile')) xbmcvfs.mkdirs(profilePath) shifts = {} streams_to_insert = [] for x in ["1", "2"]: dialog.update(0, message=get_string("Finding streams")) mode = plugin.get_setting('external.m3u.' + x, str) if mode == "0": if x == "1": try: m3uPathType = xbmcaddon.Addon('pvr.iptvsimple').getSetting( 'm3uPathType') if m3uPathType == "0": path = xbmcaddon.Addon('pvr.iptvsimple').getSetting( 'm3uPath') else: path = xbmcaddon.Addon('pvr.iptvsimple').getSetting( 'm3uUrl') except: path = "" else: path = "" elif mode == "1": if x == "1": try: m3uPathType = xbmcaddon.Addon( 'pvr.iptvarchive').getSetting('m3uPathType') if m3uPathType == "0": path = xbmcaddon.Addon('pvr.iptvarchive').getSetting( 'm3uPath') else: path = xbmcaddon.Addon('pvr.iptvarchive').getSetting( 'm3uUrl') except: path = "" else: path = "" elif mode == "2": path = plugin.get_setting('external.m3u.file.' + x, str) else: path = plugin.get_setting('external.m3u.url.' + x, str) if path: m3uFile = 'special://profile/addon_data/plugin.video.iptv.archive.downloader/channels' + x + '.m3u' xbmcvfs.copy(path, m3uFile) f = open(xbmc.translatePath(m3uFile), 'rb') data = f.read() data = data.decode('utf8') settings_shift = float( plugin.get_setting('external.m3u.shift.' + x, str)) global_shift = settings_shift header = re.search('#EXTM3U(.*)', data) if header: tvg_shift = re.search('tvg-shift="(.*?)"', header.group(1)) if tvg_shift: tvg_shift = tvg_shift.group(1) if tvg_shift: global_shift = float(tvg_shift) + settings_shift channels = re.findall( '#EXTINF:(.*?)(?:\r\n|\r|\n)(.*?)(?:\r\n|\r|\n|$)', data, flags=(re.I | re.DOTALL)) total = len(channels) i = 0 for channel in channels: name = None if ',' in re.sub('tvg-[a-z]+"[^"]*"', '', channel[0], flags=re.I): name = channel[0].rsplit(',', 1)[-1].strip() name = name.replace('+', '') name = name.replace(':', '') name = name.replace('#', '') #name = name.encode("utf8") tvg_name = re.search('tvg-name="(.*?)"', channel[0], flags=re.I) if tvg_name: tvg_name = tvg_name.group(1) or None #else: #tvg_name = name tvg_id = re.search('tvg-id="(.*?)"', channel[0], flags=re.I) if tvg_id: tvg_id = tvg_id.group(1) or None tvg_logo = re.search('tvg-logo="(.*?)"', channel[0], flags=re.I) if tvg_logo: tvg_logo = tvg_logo.group(1) or None shifts[tvg_id] = global_shift tvg_shift = re.search('tvg-shift="(.*?)"', channel[0], flags=re.I) if tvg_shift: tvg_shift = tvg_shift.group(1) if tvg_shift and tvg_id: shifts[tvg_id] = float(tvg_shift) + settings_shift url = channel[1] search = plugin.get_setting('m3u.regex.search', str) replace = plugin.get_setting('m3u.regex.replace', str) if search: url = re.sub(search, replace, url) groups = re.search('group-title="(.*?)"', channel[0], flags=re.I) if groups: groups = groups.group(1) or None streams_to_insert.append( (name, tvg_name, tvg_id, tvg_logo, groups, url.strip(), i)) i += 1 percent = 0 + int(100.0 * i / total) dialog.update(percent, message=get_string("Finding streams")) ''' missing_streams = conn.execute('SELECT name, tvg_name FROM streams WHERE tvg_id IS null OR tvg_id IS ""').fetchall() sql_channels = conn.execute('SELECT id, name FROM channels').fetchall() lower_channels = {x[1].lower():x[0] for x in sql_channels} for name, tvg_name in missing_streams: if tvg_name: tvg_id = None _tvg_name = tvg_name.replace("_"," ").lower() if _tvg_name in lower_channels: tvg_id = lower_channels[_tvg_name] conn.execute("UPDATE streams SET tvg_id=? WHERE tvg_name=?", (tvg_id, tvg_name)) elif name.lower() in lower_channels: tvg_id = lower_channels[name.lower()] conn.execute("UPDATE streams SET tvg_id=? WHERE name=?", (tvg_id, name)) ''' for _, _, tvg_id, _, groups, _, _ in streams_to_insert: if groups in load_groups: load_channels[tvg_id] = "" dialog.update(0, message=get_string("Creating database")) databasePath = os.path.join(profilePath, 'xmltv.db') conn = sqlite3.connect(databasePath, detect_types=sqlite3.PARSE_DECLTYPES) conn.execute('PRAGMA foreign_keys = ON') conn.row_factory = sqlite3.Row conn.execute('DROP TABLE IF EXISTS streams') conn.execute( 'CREATE TABLE IF NOT EXISTS streams(uid INTEGER PRIMARY KEY ASC, name TEXT, tvg_name TEXT, tvg_id TEXT, tvg_logo TEXT, groups TEXT, url TEXT, tv_number INTEGER)' ) dialog.update(0, message=get_string("Updating database")) conn.executemany( "INSERT OR IGNORE INTO streams(name, tvg_name, tvg_id, tvg_logo, groups, url, tv_number) VALUES (?, ?, ?, ?, ?, ?, ?)", streams_to_insert) conn.commit() conn.close() dialog.update(100, message=get_string("Finished loading data")) time.sleep(1) dialog.close() return