1900 lines
98 KiB
Python
1900 lines
98 KiB
Python
from normalizer import Normalizer
|
||
from tokenizer import *
|
||
# import jalali
|
||
import re
|
||
from re import sub
|
||
import textwrap
|
||
from html import escape
|
||
import traceback
|
||
import re
|
||
import json
|
||
import sys,os
|
||
try:
|
||
from rapidfuzz import distance
|
||
from thefuzz import fuzz
|
||
from bs4 import BeautifulSoup
|
||
from config_base import *
|
||
from jalali import Persian
|
||
except:
|
||
pass
|
||
|
||
# from lxml import etree
|
||
import datetime
|
||
#enumerate(token_list):
|
||
_normalizer = Normalizer(date_normalizing_needed=True)
|
||
|
||
regex_patterns = {
|
||
"ref asle N asasi" : r"اصل\s*شماره\s*(\d+)\s*قانون\s*اساسی\s*جمهوری\s*اسلامی\s*ایران", # اصل شماره فلان قانون اساسی جمهوری اسلامی ایران
|
||
"ref qanone asasi" : r"قانون\sاساسی\sجمهوری\sاسلامی\sایران", # قانون اساسی جمهوری اسلامی ایران که در اول پاراگراف نباشد
|
||
"ref qanone asasi" : r"قانون\sاساسی", # قانون اساسی که در اول پاراگراف نباشد
|
||
"ref qanon * mosavvab tarikh": r"قانون(.*?)مصوب\s((y\d{2,4}m\d{1,2}d\d{1,2})|\d{2,4})", # قانون * مصوب تاریخ
|
||
#"qanon * mosavvab tarikh" : r"قانون[\s\w]*مصوب\s((y\d{2,4}m\d{1,2}d\d{1,2})|\d{2,4})", # قانون * مصوب تاریخ
|
||
"ref qanone bodje 1" : r"قانون\sبودجه\sسال\s(\d{2,4}|\(\s*\d{2,4}\s*\))\sکل\sکشور", # قانون بودجه سال فلان کل کشور
|
||
"ref qanone bodje 2" : r"قانون\sبودجه\s(y\d{2,4}m0d0)\stttt\sکل\sکشور", # قانون بودجه سال فلان کل کشور
|
||
"in qanon" : r"این\sقانون", # این قانون
|
||
"qanone foq" : r"قانون\sفوق", # قانون فوق
|
||
"eslahe qanon" : r"قانون\sاصلاح", # اصلاح قانون
|
||
"tabsare foq" : r"تبصره\sفوق", # تبصره فوق
|
||
"made foq" : r"ماده\sفوق", # ماده فوق
|
||
"made vahede" : r"ماده\sواحده", # ماده واحده
|
||
"made vahed" : r"ماده\sواحد", # ماده واحد
|
||
"tabsare N" : r"^\bتبصره\s*شماره\s*(\d+)\s*", # تبصره شماره فلان که فقط اول پاراگراف باشد
|
||
"f tabsare N" : r"(?<!^)\bتبصره\sشماره\s(\d+)\s", # تبصره شماره فلان که همه جا غیر از اول پاراگراف باشد
|
||
"tabsare N" : r"(?<!^)\bتبصره ?\(? ?\d+? ?\)?[ :.]", # تبصره شماره فلان که همه جا غیر از اول پاراگراف باشد
|
||
"made N" : r"(?<!^)\bماده ?\(? ?\d+? ?\)?[ :.]", # *** ماده فلان که هرجای پاراگراف غیر از اول آن باشد
|
||
"f made N" : r"^\bماده\s*[(]?\s*(\d+)\s*[)]?\s*" # ماده فلان که فقط اول پاراگراف باشد با یا بدون ترکیب عدد با پرانتز
|
||
}
|
||
yeAr = r"ﻱ|ې|ێ|ے|ى|ي|ئ"
|
||
yeFr= r"ی"
|
||
keAr = r"ڭ|ﻚ|ﮎ|ﻜ|ﮏ|ګ|ﻛ|ﮑ|ﮐ|ڪ|ك"
|
||
keFr = r"ک"
|
||
mark1 = r'#\[#'
|
||
mark2 = r'#\]#'
|
||
hTag1 = r'<'
|
||
hTag2 = r'>'
|
||
tableTag=["table","tr", "th", "tc"]
|
||
strTable = ''
|
||
for tag in tableTag:
|
||
if strTable != '':
|
||
strTable += '|'
|
||
strTable += '('+tag+')'
|
||
regTable = r'<(?P<slash>/)*(?P<tag>'+strTable+')(?P<class>[^>]+)*>'
|
||
regTableReplace = r'#[#\g<slash>\g<tag>\g<class>#]#'
|
||
|
||
def removeHtmlTags(html, exeptionTag=[]):
|
||
#reg1 = r'<[^>]+>'
|
||
|
||
if exeptionTag.__len__ :
|
||
exceptTags = ''
|
||
for tag in exeptionTag:
|
||
if exceptTags != '':
|
||
exceptTags += '|'
|
||
exceptTags += '('+tag+')'
|
||
reg1 = r'<(?P<slash>/)*(?P<tag>'+exceptTags+')(?P<class>[^>]+)*>'
|
||
html = sub(reg1, regTableReplace, html)
|
||
|
||
|
||
soup = BeautifulSoup(html, "html.parser")
|
||
text = soup.get_text("\n", strip=True)
|
||
|
||
if exeptionTag.__len__ :
|
||
text = sub(mark1, hTag1, text)
|
||
text = sub(mark2, hTag2, text)
|
||
|
||
return text
|
||
|
||
|
||
def removeHtmlNoTableTag(html):
|
||
|
||
html = sub(regTable, regTableReplace, html)
|
||
|
||
soup = BeautifulSoup(html, "html.parser")
|
||
text = soup.get_text("\n", strip=True)
|
||
|
||
text = sub(mark1, hTag1, text)
|
||
text = sub(mark2, hTag2, text)
|
||
return text
|
||
|
||
def normalizerData(data):
|
||
global _normalizer
|
||
normalTitle, dates = _normalizer.normalize(data, return_dates=True)
|
||
tdates = []
|
||
for d in dates:
|
||
if not d.startswith("num"):
|
||
try:
|
||
tsd = jdate2timestamp(d)
|
||
cdate = d
|
||
except:
|
||
try:
|
||
d = d.replace("y", "")
|
||
d = d.replace("m", "/")
|
||
d = d.replace("d", "/")
|
||
m = re.match(r"^(\d{4})\D(\d{1,2})\D(\d{1,2})$", d)
|
||
if m:
|
||
[year, month, day] = [
|
||
int(m.group(1)),
|
||
int(m.group(2)),
|
||
int(m.group(3)),
|
||
]
|
||
if year > 1200 and year < 1550:
|
||
if month < 1 or month > 12:
|
||
month = 1
|
||
if day < 1 or day > 31:
|
||
day = 1
|
||
cdate = str(year) + "/" + str(month) + "/" + str(day)
|
||
tsd = jdate2timestamp(cdate)
|
||
else:
|
||
# cdate = "1403/03/03"
|
||
# tsd = jdate2timestamp(cdate)
|
||
continue
|
||
else:
|
||
# cdate = "1403/03/03"
|
||
# tsd = jdate2timestamp(cdate)
|
||
continue
|
||
except:
|
||
# print("Error in:"+ d +" for id: " + id)
|
||
# cdate = "1403/03/03"
|
||
# tsd = jdate2timestamp(cdate)
|
||
continue
|
||
tdates.append({"date": cdate, "timestamp": tsd, "index": 0, "slice": ""})
|
||
|
||
return normalTitle,tdates
|
||
|
||
def normalizerDate2(inputString):
|
||
global _normalizer
|
||
normalizedString, dates, recognized_dates, recognized_numbers = _normalizer.normalize(inputString, return_dates=True)
|
||
tdates = []
|
||
for date_item in recognized_dates:
|
||
date_part = date_item['date']
|
||
date_token_index = date_item['date_token_index']
|
||
start_date_token_index = date_item['start_date_token_index']
|
||
end_date_token_index = date_item['end_date_token_index']
|
||
if not date_part.startswith("num"):
|
||
try:
|
||
cdate = date_part
|
||
tsd = jdate2timestamp(date_part)
|
||
except:
|
||
try:
|
||
date_part = date_part.replace("y", "")
|
||
date_part = date_part.replace("m", "/")
|
||
date_part = date_part.replace("d", "/")
|
||
m = re.match(r"^(\d{4})\D(\d{1,2})\D(\d{1,2})$", date_part)
|
||
if m:
|
||
[year, month, day] = [
|
||
int(m.group(1)),
|
||
int(m.group(2)),
|
||
int(m.group(3)),
|
||
]
|
||
if year > 1200 and year < 1550:
|
||
if month < 1 or month > 12:
|
||
month = 1
|
||
if day < 1 or day > 31:
|
||
day = 1
|
||
cdate = str(year) + "/" + str(month) + "/" + str(day)
|
||
tsd = jdate2timestamp(cdate)
|
||
else:
|
||
# cdate = "1403/03/03"
|
||
# tsd = jdate2timestamp(cdate)
|
||
continue
|
||
# else:
|
||
# # cdate = "1403/03/03"
|
||
# # tsd = jdate2timestamp(cdate)
|
||
# continue
|
||
except:
|
||
# print("Error in:"+ d +" for id: " + id)
|
||
# cdate = "1403/03/03"
|
||
# tsd = jdate2timestamp(cdate)
|
||
continue
|
||
import tokenizer as t
|
||
inputString_token = t.Tokenizer.tokenize_words(None,inputString)
|
||
# if start_date_token_index == end_date_token_index:
|
||
# end_date_token_index += 1
|
||
# original_date_part = inputString_token[start_date_token_index:end_date_token_index]
|
||
# else:
|
||
original_date_part = inputString_token[start_date_token_index:end_date_token_index + 1]
|
||
original_date = ''
|
||
for part in original_date_part:
|
||
original_date = original_date + ' ' + part
|
||
original_date = original_date.strip()
|
||
tdates.append({"converted_date": date_item['date'],
|
||
"date": cdate ,
|
||
"original_date" : original_date,
|
||
# "timestamp": tsd,
|
||
"date_token_index": date_token_index,
|
||
"start_date_token_index": start_date_token_index,
|
||
"end_date_token_index":end_date_token_index})
|
||
'''
|
||
for d in dates:
|
||
if not d.startswith("num"):
|
||
try:
|
||
tsd = jdate2timestamp(d)
|
||
cdate = d
|
||
except:
|
||
try:
|
||
d = d.replace("y", "")
|
||
d = d.replace("m", "/")
|
||
d = d.replace("d", "/")
|
||
m = re.match(r"^(\d{4})\D(\d{1,2})\D(\d{1,2})$", d)
|
||
if m:
|
||
[year, month, day] = [
|
||
int(m.group(1)),
|
||
int(m.group(2)),
|
||
int(m.group(3)),
|
||
]
|
||
if year > 1200 and year < 1550:
|
||
if month < 1 or month > 12:
|
||
month = 1
|
||
if day < 1 or day > 31:
|
||
day = 1
|
||
cdate = str(year) + "/" + str(month) + "/" + str(day)
|
||
tsd = jdate2timestamp(cdate)
|
||
else:
|
||
# cdate = "1403/03/03"
|
||
# tsd = jdate2timestamp(cdate)
|
||
continue
|
||
else:
|
||
# cdate = "1403/03/03"
|
||
# tsd = jdate2timestamp(cdate)
|
||
continue
|
||
except:
|
||
# print("Error in:"+ d +" for id: " + id)
|
||
# cdate = "1403/03/03"
|
||
# tsd = jdate2timestamp(cdate)
|
||
continue
|
||
tdates.append({"date": cdate, "timestamp": tsd, "index": 0, "slice": ""})'''
|
||
return normalizedString,tdates,recognized_numbers
|
||
|
||
def OtherDateFormatNormalizer(inputString,pattern):
|
||
mainTextTemp = inputString
|
||
regex_pattern_Mah = r"y(\d{1,4})m(\d{1,2})d(\d{1,2})\sماه\s(\d{1,4})\sو\s(\d{1,3})\sو\s(\d{1,2})\sو\s(\d{1})\s" # y0m4d4 ماه 1000 و 300 و 50 و 4
|
||
regex_pattern_MahSal = r"y(\d{1,4})m(\d{1,2})d(\d{1,2})\sماه\sسال\s(\d{1,4})\sو\s(\d{1,3})\sو\s(\d{1,2})\sو\s(\d{1})\s" # y0m4d4 ماه سال 1000 و 300 و 50 و 4
|
||
regex_pattern_MahSal2 = r"y(\d{1,4})m(\d{1,2})d(\d{1,2})\sماه\sسال\sy(\d{1,4})m(\d{1,2})d(\d{1,2})\sو\s(\d{1,3})\sو\s(\d{1,2})\sو\s(\d{1})\s" # y0m4d4 ماه سال y1000m0d0 و 300 و 50 و 4
|
||
regex_pattern_MahSal3 = r"y(\d{1,4})m(\d{1,2})d(\d{1,2})\sماه\sسال\sy(\d{1,4})m(\d{1,2})d(\d{1,2})" # y0m3d1 ماه سال y1353m0d0
|
||
|
||
if(pattern==1):
|
||
regex = re.compile(regex_pattern_Mah)
|
||
elif(pattern==2):
|
||
regex = re.compile(regex_pattern_MahSal)
|
||
elif(pattern==3):
|
||
regex = re.compile(regex_pattern_MahSal2)
|
||
elif(pattern==4):
|
||
regex = re.compile(regex_pattern_MahSal3)
|
||
|
||
matches = regex.finditer(inputString)
|
||
for match in matches:
|
||
foundedPattern = match.group()
|
||
foundedPatternTemp = match.group()
|
||
if(pattern==1):
|
||
foundedPattern = foundedPattern.replace('ماه','')
|
||
else:
|
||
foundedPattern = foundedPattern.replace('سال','')
|
||
foundedPattern = foundedPattern.replace('ماه','')
|
||
foundedPattern = foundedPattern.strip()
|
||
tempString = foundedPattern
|
||
standardDatePattern = r"y(\d{1,4})m(\d{1,2})d(\d{1,2})"
|
||
#regex = re.compile(regex_pattern_Mah)
|
||
matchItems = re.finditer(standardDatePattern,tempString)
|
||
for item in matchItems:
|
||
tempPattern = item.group()
|
||
tempString = tempString.replace(tempPattern,'')
|
||
tempString = tempString.strip()
|
||
tempString = tempString.replace('و','')
|
||
tempString = tempString.strip()
|
||
tempArray = tempString.split()
|
||
year = 0
|
||
for item in tempArray:
|
||
dateMatch = re.finditer(standardDatePattern,item)
|
||
regexFlag = True
|
||
for dateItem in dateMatch:
|
||
yearStr = dateItem.group()[1:5]
|
||
year += int(yearStr)
|
||
regexFlag = False
|
||
break
|
||
if(item.isalnum() and regexFlag):
|
||
year += int(item)
|
||
tempPattern = tempPattern.replace('y0','y'+str(year))
|
||
mainTextTemp = mainTextTemp.replace(foundedPatternTemp,tempPattern+' ')
|
||
return mainTextTemp
|
||
|
||
#foundedPattern = jdate2timestamp(foundedPattern)
|
||
#convertedText = regex.sub(foundedPattern,convertedText)
|
||
|
||
def normalizerLongData(data):
|
||
dates = []
|
||
if len(data) > 10000:
|
||
textParts = textwrap.wrap(data, 10000, break_long_words=False)
|
||
for part in textParts:
|
||
dates.extend(normalizerData(part))
|
||
else:
|
||
dates = normalizerData(data)
|
||
return dates
|
||
|
||
# ##################
|
||
# در ویندوز برای اعداد منفی که تاریخهای قبلی بود را خطا می داد
|
||
# rr = gdt.timestamp()
|
||
# #################
|
||
def jdate2timestamp_old(dt):
|
||
ndt = dt.replace("y", "")
|
||
ndt = ndt.replace("m", "/")
|
||
ndt = ndt.replace("d", "/")
|
||
gd = jalali.Persian(ndt).gregorian_datetime()
|
||
# print(gd)
|
||
ztime = datetime.time(0, 0, 0, 0)
|
||
gdt = datetime.datetime.combine(gd, ztime)
|
||
# print(gdt)
|
||
rr = gdt.timestamp()
|
||
tst = int( round(rr) * 1000)
|
||
return tst
|
||
|
||
def jdate2timestamp(dt):
|
||
ndt = dt.replace("y", "")
|
||
ndt = ndt.replace("m", "/")
|
||
ndt = ndt.replace("d", "/")
|
||
gd = jalali.Persian(ndt).gregorian_datetime()
|
||
base = datetime.date(1970, 1, 1)
|
||
rr = (gd-base).total_seconds()
|
||
tst = int( round(rr) * 1000)
|
||
return tst
|
||
|
||
|
||
|
||
def getSortTimestamp(ts_date):
|
||
empty_date = -15000000000
|
||
ts_ts = empty_date
|
||
try:
|
||
if ts_date != "":
|
||
ts_ts = jdate2timestamp(ts_date)
|
||
except:
|
||
ts_ts = empty_date
|
||
|
||
return ts_ts
|
||
|
||
def normalize_content(text):
|
||
# text = normalYehKe(content)
|
||
if(text == None) :
|
||
return ''
|
||
|
||
# جایگزین کردن یک فرمت استاندارد از حروف فارسی به جای فرمت های مختلف فارسی و
|
||
text = _normalizer.sub_alphabets(text)
|
||
# کلماتی که با نیم فاصله از هم جدا شده اند، را به هم می چسباند
|
||
# در این صورت، اگر با یک اسپیس جایگزین شود، یک توکن به متن اصلی اضافه می کند
|
||
text = sub('\u00A0','',text)
|
||
text = sub('\u200c','',text)
|
||
text = sub('\u200F','',text)
|
||
pattern = r'؟|ʕ|_|ـ'# r',|٬|٫|‚|,|؟|ʕ|،|_|ـ'
|
||
# خط زیر باعث حذف کاراکتر دش از متن مقررات می شود و در خروجی نهایی، باعث جا به جایی توکن موجودیت های تشخیص داده می شود
|
||
text = sub(pattern,'', text)
|
||
|
||
return text.strip()
|
||
|
||
def normalYehKe(text):
|
||
if(text == None) :
|
||
return ''
|
||
|
||
c1 = sub(yeAr, yeFr, text)
|
||
c2 = sub(keAr, keFr, c1)
|
||
c2 = c2.replace('\u00A0', '')
|
||
return c2.strip()
|
||
|
||
_term_list = []
|
||
def setTermList():
|
||
global _term_list
|
||
if(_term_list.__len__() > 0):
|
||
return
|
||
_term_list = [
|
||
{
|
||
"begin": jdate2timestamp("1285/07/14"),
|
||
"end": jdate2timestamp("1287/04/2"),
|
||
"term": "مجلس شورای ملی-دوره1",
|
||
"term_number": 1,
|
||
"majles_name": "شورای ملی",
|
||
},
|
||
{
|
||
"begin": jdate2timestamp("1288/8/24"),
|
||
"end": jdate2timestamp("1290/10/3"),
|
||
"term": "مجلس شورای ملی-دوره2",
|
||
"term_number": 2,
|
||
"majles_name": "شورای ملی",
|
||
},
|
||
{
|
||
"begin": jdate2timestamp("1293/9/14"),
|
||
"end": jdate2timestamp("1294/8/21"),
|
||
"term": "مجلس شورای ملی-دوره3",
|
||
"term_number": 3,
|
||
"majles_name": "شورای ملی",
|
||
},
|
||
{
|
||
"begin": jdate2timestamp("1300/4/1"),
|
||
"end": jdate2timestamp("1302/3/30"),
|
||
"term": "مجلس شورای ملی-دوره4",
|
||
"term_number": 4,
|
||
"majles_name": "شورای ملی",
|
||
},
|
||
{
|
||
"begin": jdate2timestamp("1302/11/22"),
|
||
"end": jdate2timestamp("1304/11/22"),
|
||
"term": "مجلس شورای ملی-دوره5",
|
||
"term_number": 5,
|
||
"majles_name": "شورای ملی",
|
||
},
|
||
{
|
||
"begin": jdate2timestamp("1305/4/19"),
|
||
"end": jdate2timestamp("1307/5/22"),
|
||
"term": "مجلس شورای ملی-دوره6",
|
||
"term_number": 6,
|
||
"majles_name": "شورای ملی",
|
||
},
|
||
{
|
||
"begin": jdate2timestamp("1307/7/19"),
|
||
"end": jdate2timestamp("1309/8/14"),
|
||
"term": "مجلس شورای ملی-دوره7",
|
||
"term_number": 7,
|
||
"majles_name": "شورای ملی",
|
||
},
|
||
{
|
||
"begin": jdate2timestamp("1309/9/24"),
|
||
"end": jdate2timestamp("1311/10/24"),
|
||
"term": "مجلس شورای ملی-دوره8",
|
||
"term_number": 8,
|
||
"majles_name": "شورای ملی",
|
||
},
|
||
{
|
||
"begin": jdate2timestamp("1311/12/24"),
|
||
"end": jdate2timestamp("1314/1/24"),
|
||
"term": "مجلس شورای ملی-دوره9",
|
||
"term_number": 9,
|
||
"majles_name": "شورای ملی",
|
||
},
|
||
{
|
||
"begin": jdate2timestamp("1314/3/15"),
|
||
"end": jdate2timestamp("1316/3/22"),
|
||
"term": "مجلس شورای ملی-دوره10",
|
||
"term_number": 10,
|
||
"majles_name": "شورای ملی",
|
||
},
|
||
{
|
||
"begin": jdate2timestamp("1316/6/20"),
|
||
"end": jdate2timestamp("1318/6/27"),
|
||
"term": "مجلس شورای ملی-دوره11",
|
||
"term_number": 11,
|
||
"majles_name": "شورای ملی",
|
||
},
|
||
{
|
||
"begin": jdate2timestamp("1318/8/3"),
|
||
"end": jdate2timestamp("1320/8/9"),
|
||
"term": "مجلس شورای ملی-دوره12",
|
||
"term_number": 12,
|
||
"majles_name": "شورای ملی",
|
||
},
|
||
{
|
||
"begin": jdate2timestamp("1320/8/22"),
|
||
"end": jdate2timestamp("1322/9/1"),
|
||
"term": "مجلس شورای ملی-دوره13",
|
||
"term_number": 13,
|
||
"majles_name": "شورای ملی",
|
||
},
|
||
{
|
||
"begin": jdate2timestamp("1322/12/16"),
|
||
"end": jdate2timestamp("1324/12/21"),
|
||
"term": "مجلس شورای ملی-دوره14",
|
||
"term_number": 14,
|
||
"majles_name": "شورای ملی",
|
||
},
|
||
{
|
||
"begin": jdate2timestamp("1326/4/25"),
|
||
"end": jdate2timestamp("1328/5/6"),
|
||
"term": "مجلس شورای ملی-دوره15",
|
||
"term_number": 15,
|
||
"majles_name": "شورای ملی",
|
||
},
|
||
{
|
||
"begin": jdate2timestamp("1328/11/20"),
|
||
"end": jdate2timestamp("1330/11/29"),
|
||
"term": "مجلس شورای ملی-دوره16",
|
||
"term_number": 16,
|
||
"majles_name": "شورای ملی",
|
||
},
|
||
{
|
||
"begin": jdate2timestamp("1331/2/7"),
|
||
"end": jdate2timestamp("1332/8/28"),
|
||
"term": "مجلس شورای ملی-دوره17",
|
||
"term_number": 17,
|
||
"majles_name": "شورای ملی",
|
||
},
|
||
{
|
||
"begin": jdate2timestamp("1332/12/27"),
|
||
"end": jdate2timestamp("1335/1/26"),
|
||
"term": "مجلس شورای ملی-دوره18",
|
||
"term_number": 18,
|
||
"majles_name": "شورای ملی",
|
||
},
|
||
{
|
||
"begin": jdate2timestamp("1335/3/10"),
|
||
"end": jdate2timestamp("1339/3/29"),
|
||
"term": "مجلس شورای ملی-دوره19",
|
||
"term_number": 19,
|
||
"majles_name": "شورای ملی",
|
||
},
|
||
{
|
||
"begin": jdate2timestamp("1339/12/2"),
|
||
"end": jdate2timestamp("1340/2/19"),
|
||
"term": "مجلس شورای ملی-دوره20",
|
||
"term_number": 20,
|
||
"majles_name": "شورای ملی",
|
||
},
|
||
{
|
||
"begin": jdate2timestamp("1342/7/14"),
|
||
"end": jdate2timestamp("1346/7/13"),
|
||
"term": "مجلس شورای ملی-دوره21",
|
||
"term_number": 21,
|
||
"majles_name": "شورای ملی",
|
||
},
|
||
{
|
||
"begin": jdate2timestamp("1346/7/14"),
|
||
"end": jdate2timestamp("1350/6/9"),
|
||
"term": "مجلس شورای ملی-دوره22",
|
||
"term_number": 22,
|
||
"majles_name": "شورای ملی",
|
||
},
|
||
{
|
||
"begin": jdate2timestamp("1350/6/9"),
|
||
"end": jdate2timestamp("1354/6/16"),
|
||
"term": "مجلس شورای ملی-دوره23",
|
||
"term_number": 23,
|
||
"majles_name": "شورای ملی",
|
||
},
|
||
{
|
||
"begin": jdate2timestamp("1354/6/17"),
|
||
"end": jdate2timestamp("1357/11/20"),
|
||
"term": "مجلس شورای ملی-دوره24",
|
||
"term_number": 24,
|
||
"majles_name": "شورای ملی",
|
||
},
|
||
{
|
||
"begin": jdate2timestamp("1359/3/7"),
|
||
"end": jdate2timestamp("1363/3/6"),
|
||
"term": "مجلس شورای اسلامی-دوره1",
|
||
"term_number": 1,
|
||
"majles_name": "شورای اسلامی",
|
||
},
|
||
{
|
||
"begin": jdate2timestamp("1363/3/7"),
|
||
"end": jdate2timestamp("1367/3/6"),
|
||
"term": "مجلس شورای اسلامی-دوره2",
|
||
"term_number": 2,
|
||
"majles_name": "شورای اسلامی",
|
||
},
|
||
{
|
||
"begin": jdate2timestamp("1367/3/7"),
|
||
"end": jdate2timestamp("1371/3/6"),
|
||
"term": "مجلس شورای اسلامی-دوره3",
|
||
"term_number": 3,
|
||
"majles_name": "شورای اسلامی",
|
||
},
|
||
{
|
||
"begin": jdate2timestamp("1371/3/7"),
|
||
"end": jdate2timestamp("1375/3/11"),
|
||
"term": "مجلس شورای اسلامی-دوره4",
|
||
"term_number": 4,
|
||
"majles_name": "شورای اسلامی",
|
||
},
|
||
{
|
||
"begin": jdate2timestamp("1375/3/12"),
|
||
"end": jdate2timestamp("1379/3/6"),
|
||
"term": "مجلس شورای اسلامی-دوره5",
|
||
"term_number": 5,
|
||
"majles_name": "شورای اسلامی",
|
||
},
|
||
{
|
||
"begin": jdate2timestamp("1379/3/7"),
|
||
"end": jdate2timestamp("1383/3/6"),
|
||
"term": "مجلس شورای اسلامی-دوره6",
|
||
"term_number": 6,
|
||
"majles_name": "شورای اسلامی",
|
||
},
|
||
{
|
||
"begin": jdate2timestamp("1383/3/7"),
|
||
"end": jdate2timestamp("1387/3/6"),
|
||
"term": "مجلس شورای اسلامی-دوره7",
|
||
"term_number": 7,
|
||
"majles_name": "شورای اسلامی",
|
||
},
|
||
{
|
||
"begin": jdate2timestamp("1387/3/7"),
|
||
"end": jdate2timestamp("1391/3/6"),
|
||
"term": "مجلس شورای اسلامی-دوره8",
|
||
"term_number": 8,
|
||
"majles_name": "شورای اسلامی",
|
||
},
|
||
{
|
||
"begin": jdate2timestamp("1391/3/7"),
|
||
"end": jdate2timestamp("1395/3/7"),
|
||
"term": "مجلس شورای اسلامی-دوره9",
|
||
"term_number": 9,
|
||
"majles_name": "شورای اسلامی",
|
||
},
|
||
{
|
||
"begin": jdate2timestamp("1395/3/8"),
|
||
"end": jdate2timestamp("1399/3/6"),
|
||
"term": "مجلس شورای اسلامی-دوره10",
|
||
"term_number": 10,
|
||
"majles_name": "شورای اسلامی",
|
||
},
|
||
{
|
||
"begin": jdate2timestamp("1399/3/7"),
|
||
"end": jdate2timestamp("1403/3/6"),
|
||
"term": "مجلس شورای اسلامی-دوره11",
|
||
"term_number": 11,
|
||
"majles_name": "شورای اسلامی",
|
||
},
|
||
]
|
||
|
||
|
||
def getTermQanon(ts_date_timestamp, ts_ref):
|
||
setTermList()
|
||
global _term_list
|
||
term = ""
|
||
term_number = 0
|
||
majles_name = ""
|
||
|
||
if ts_ref == "هيات وزيران (دوره فترت)":
|
||
term = ts_ref
|
||
if ts_ref == "نخست وزير (مصدق)":
|
||
term = ts_ref
|
||
if ts_ref == "وزير عدليه (داور)":
|
||
term = ts_ref
|
||
if ts_ref == "شوراي انقلاب جمهوري اسلامي ايران":
|
||
term = ts_ref
|
||
|
||
majles_name = term
|
||
if term == "":
|
||
for i in range(len(_term_list) - 1, -1, -1):
|
||
begin = _term_list[i]["begin"]
|
||
end = _term_list[i]["end"]
|
||
if ts_date_timestamp >= begin and ts_date_timestamp <= end:
|
||
term = _term_list[i]["term"]
|
||
term_number = _term_list[i]["term_number"]
|
||
majles_name = _term_list[i]["majles_name"]
|
||
break
|
||
|
||
error = ""
|
||
if term == "":
|
||
# if ts_date_timestamp >= _term_list[0]["begin"] and ts_date_timestamp <= _term_list[len(_term_list)-1]["end"] :
|
||
if ts_date_timestamp <= _term_list[len(_term_list) - 1]["end"]:
|
||
for i in range(0, len(_term_list) - 1, 1):
|
||
end = _term_list[i]["end"]
|
||
if ts_date_timestamp <= end:
|
||
term = _term_list[i]["term"]
|
||
term_number = _term_list[i]["term_number"]
|
||
majles_name = _term_list[i]["majles_name"]
|
||
error = "تاریخ بین دو دوره"
|
||
break
|
||
else:
|
||
term_number = -1
|
||
error = "تاریخ خارج از محدوده"
|
||
|
||
return term, term_number, majles_name, error
|
||
|
||
# این متد یک متن و ایندکس آغاز و پایان یک عبارت درون آن متن را دریافت می کند
|
||
# و شماره توکن آغازین و توکن پایانی مربوط به عبارت در متن را بر می گرداند
|
||
def token_state_finder(normalized_section_content, start_index, end_index):
|
||
before_substring = normalized_section_content[0:start_index-1].strip()
|
||
pattern_substring = normalized_section_content[start_index-1:end_index+1].strip()
|
||
before_substring_token_list = before_substring.strip().split()
|
||
pattern_token_list = pattern_substring.strip().split()
|
||
start_token_state = len(before_substring_token_list)
|
||
end_token_state = len(before_substring_token_list) + (len(pattern_token_list)-1)
|
||
pattern_tokens_state ={
|
||
"start_token_state": start_token_state,
|
||
"end_token_state" : end_token_state
|
||
}
|
||
return pattern_tokens_state
|
||
|
||
def find_number_indexes_in_string(normalized_string,recognized_numbers):
|
||
complete_recognized_numbers = []
|
||
for item in recognized_numbers:
|
||
number_start_index, number_end_index = find_token_indexes_in_string(normalized_string,item['start_token_index'],item['end_token_index'])
|
||
content = normalized_string.split()
|
||
# if item['start_token_index']==item['end_token_index']:
|
||
# # حذف این بخش و باقی گذاشتن دستور ذیل الز زیر در کفایت درست کار کردن متد بررسی شود
|
||
|
||
# number_token_list = content[item['start_token_index']]
|
||
# else:
|
||
number_token_list = content[item['start_token_index']:item['end_token_index']+1]
|
||
complete_recognized_numbers.append(
|
||
{
|
||
'number_value' : item['number_value'],
|
||
'number_token_list' : number_token_list,
|
||
'start_token_index' : item['start_token_index'],
|
||
'end_token_index' : item['end_token_index'],
|
||
"start_number_state": number_start_index,
|
||
"end_number_state" : number_end_index
|
||
}
|
||
)
|
||
return complete_recognized_numbers
|
||
|
||
# این متد متن اصلی یک متن، توکن آغازین و توکن پایانی مربوط به یک عبارت را می گیرد
|
||
# و ایندکس آغاز و ایندکس پایان متن وارد شده را بر می گرداند
|
||
def find_token_indexes_in_string(normalized_string,start_token_state,end_token_state):
|
||
before_tokens = normalized_string.split()[0:start_token_state]
|
||
content_tokens = normalized_string.split()[start_token_state:end_token_state + 1]
|
||
content_start_index = 0
|
||
content_end_index = 0
|
||
# شمردن تعداد کاراکترهای هر توکن در لیست توکن قبل از عدد
|
||
for token in before_tokens:
|
||
content_start_index += len(token)
|
||
# اضافه کردن تعداد فاصله های خالی یا همان اسپیس به عدد ایندکس شروع عدد
|
||
content_start_index += len(before_tokens) + 1
|
||
|
||
# شمردن تعداد کاراکترهای هر توکن در لیست توکن مربوط به عدد
|
||
for token in content_tokens:
|
||
content_end_index += len(token)
|
||
# اضافه کردن تعداد فاصله های خالی یا همان اسپیس به عدد ایندکس پایان عدد
|
||
content_end_index += (content_start_index - 1) + (len(content_tokens) - 1)
|
||
|
||
return content_start_index, content_end_index
|
||
|
||
# این متد، متنی را دریافت می کند و الگوهای تعریف شده را در آن جستجو می کند و آرایه ای از عبارات مطابق با هر الگو،
|
||
# شماره ایندکس شروع و پایان هر عبارت، عنوان و محتوای الگو، و شماره توکن شروع و توکن پایانی هر عبارت
|
||
# پیدا شده را بر می گرداند
|
||
def regex_patterns_finder(sectoin_content, law_dict):
|
||
# regex_patterns = {
|
||
# "ref asle N asasi" : r"اصل\s*شماره\s*(\d+)\s*قانون\s*اساسی\s*جمهوری\s*اسلامی\s*ایران", # اصل شماره فلان قانون اساسی جمهوری اسلامی ایران
|
||
# "ref qanone asasi" : r"قانون\sاساسی\sجمهوری\sاسلامی\sایران", # قانون اساسی جمهوری اسلامی ایران که در اول پاراگراف نباشد
|
||
# "ref qanone asasi" : r"قانون\sاساسی", # قانون اساسی که در اول پاراگراف نباشد
|
||
# "ref qanon * mosavvab tarikh": r"قانون(.*?)مصوب\s((y\d{2,4}m\d{1,2}d\d{1,2})|\d{2,4})", # قانون * مصوب تاریخ
|
||
# #"qanon * mosavvab tarikh" : r"قانون[\s\w]*مصوب\s((y\d{2,4}m\d{1,2}d\d{1,2})|\d{2,4})", # قانون * مصوب تاریخ
|
||
# "ref qanone bodje 1" : r"قانون\sبودجه\sسال\s(\d{2,4}|\(\s*\d{2,4}\s*\))\sکل\sکشور", # قانون بودجه سال فلان کل کشور
|
||
# "ref qanone bodje 2" : r"قانون\sبودجه\s(y\d{2,4}m0d0)\stttt\sکل\sکشور", # قانون بودجه سال فلان کل کشور
|
||
# "in qanon" : r"این\sقانون", # این قانون
|
||
# "qanone foq" : r"قانون\sفوق", # قانون فوق
|
||
# "eslahe qanon" : r"قانون\sاصلاح", # اصلاح قانون
|
||
# "tabsare foq" : r"تبصره\sفوق", # تبصره فوق
|
||
# "made foq" : r"ماده\sفوق", # ماده فوق
|
||
# "made vahede" : r"ماده\sواحده", # ماده واحده
|
||
# "made vahed" : r"ماده\sواحد", # ماده واحد
|
||
# "tabsare N" : r"^\bتبصره\s*شماره\s*(\d+)\s*", # تبصره شماره فلان که فقط اول پاراگراف باشد
|
||
# "f tabsare N" : r"(?<!^)\bتبصره\sشماره\s(\d+)\s", # تبصره شماره فلان که همه جا غیر از اول پاراگراف باشد
|
||
# "tabsare N" : r"(?<!^)\bتبصره ?\(? ?\d+? ?\)?[ :.]", # تبصره شماره فلان که همه جا غیر از اول پاراگراف باشد
|
||
# "made N" : r"(?<!^)\bماده ?\(? ?\d+? ?\)?[ :.]", # *** ماده فلان که هرجای پاراگراف غیر از اول آن باشد
|
||
# "f made N" : r"^\bماده\s*[(]?\s*(\d+)\s*[)]?\s*" # ماده فلان که فقط اول پاراگراف باشد با یا بدون ترکیب عدد با پرانتز
|
||
# }
|
||
|
||
matched_array = []
|
||
for pattern_key,pattern_value in regex_patterns.items():
|
||
pattern_type = ''
|
||
regex = re.compile(pattern_value)
|
||
matches = regex.finditer(sectoin_content)
|
||
if pattern_key.startswith('ref'):
|
||
pattern_type = 'reference'
|
||
else:
|
||
pattern_type = 'half-reference'
|
||
for match in matches:
|
||
# انجام عملیات مرتبط با هر الگو در اینجا
|
||
founded_item = match.group()
|
||
start_index = match.start() + 1
|
||
end_index = match.end() - 1
|
||
pattern_tokens_state = token_state_finder(sectoin_content, start_index, end_index)
|
||
law_id = 0
|
||
# اگر مورد پیدا شده یک عنوان قانون بود، شناسه آن قانون را پیدا کن
|
||
if pattern_type == 'reference':
|
||
law_id = find_lawid_by_title(founded_item, law_dict)
|
||
matched_array.append(
|
||
{
|
||
"law_id" : law_id,
|
||
"founded_item" : founded_item,
|
||
"start_index" : start_index,
|
||
"end_index" : end_index,
|
||
"pattern_key" : pattern_key,
|
||
"pattern_value" : pattern_value,
|
||
"start_token_state": pattern_tokens_state["start_token_state"],
|
||
"end_token_state" : pattern_tokens_state["end_token_state"],
|
||
"pattern_type" : pattern_type
|
||
}
|
||
)
|
||
# convertedText = regex.sub(' wwwwwwwww ',convertedText)
|
||
# مرتب کردن آرایه بر اساس توکن شروع عبارت
|
||
matched_array.sort(key=lambda x: int(x['start_token_state']), reverse=False)
|
||
return matched_array
|
||
|
||
def find_lawid_by_title(founded_item, law_dict):
|
||
founded_laws = []
|
||
founded_item_temp = ''
|
||
law_id = 0
|
||
# اگر عنوان پیدا شده با عبارت قانون اساسی شروع می شود، شناسه زیر را برگردان
|
||
if founded_item.startswith('قانون اساسی'):
|
||
law_id = 38162 # شناسه قانون اساسی جمهوری اسلامی ایران
|
||
return law_id
|
||
# اگر عنوان پیدا شده با عبارت قانون بودجه شروع می شود، شناسه آن را مطابق کدهای زیر برگردان
|
||
if founded_item.startswith('قانون بودجه'):
|
||
founded_item_temp = founded_item
|
||
founded_item_temp = normalize_content(founded_item_temp)
|
||
# اگر عبارت بالا با قانون شروع می شود، کلمه قانون را از اول آن حذف کن
|
||
founded_item_temp = founded_item_temp.lstrip('قانون').strip()
|
||
|
||
# ... اگر دو حالت قبلی نبود
|
||
else:
|
||
try:
|
||
# عبارت پیدا شده را با بر اساس توکن "مصوب" جداکن و بخش دوم جدا شده را به عنوان تاریخ در متغیر دیت بریز
|
||
# date = founded_item.split('مصوب')[1].strip()
|
||
# مطابق بالا، بخش اول جدا شده را نیز در متغیر تمپ بریز ، احتمالا این عنوان مطابق با یک عنوان قانونی خواهد بود
|
||
founded_item_temp = founded_item.split('مصوب')[0].strip()
|
||
founded_item_temp = normalize_content(founded_item_temp)
|
||
# اگر عبارت بالا با قانون شروع می شود، کلمه قانون را از اول آن حذف کن
|
||
founded_item_temp = founded_item_temp.lstrip('قانون').strip()
|
||
# اگر تاریخی که در عنوان وجود دارد با فرمت y1389m5d12 بود
|
||
# if date.startswith('y') and (not date.endswith('m0d0')):
|
||
# search_only_for_year = False
|
||
# # اگر تاریخی با فرمت فقط سال یا y1358m0d0 بود
|
||
# else:
|
||
# search_only_for_year = True
|
||
except Exception as e:
|
||
save_error(0,e)
|
||
|
||
# در این بخش، عنوان پیداشده را با تک تک عناوین قانون که در دیکشنری قانون وجود دارند مقایسه می کنیم
|
||
for law in law_dict:
|
||
law_caption = law['caption']
|
||
if law_caption == 'خالی':
|
||
continue
|
||
# ...استاندارد سازی عنوان قانون برای مقایسه با عنوانی که پیدا کرده ایم.
|
||
# law_caption = _normalizer.normalize(law_caption).strip()
|
||
law_caption = normalize_content(law_caption).strip()
|
||
law_caption = law_caption.lstrip('قانون').strip()
|
||
law_caption = law_caption.split('مصوب')[0].strip()
|
||
# به دست آوردن اختلاف لونشتاین بین عنوان پیدا شده و عنوان قانون
|
||
Levenshtein_distance = distance.Levenshtein.distance(founded_item_temp,law_caption)
|
||
# rate = fuzz.token_set_ratio(founded_item_temp,law_caption,True,True)
|
||
# همه عناوین قانونی که مشابهت بالایی با این عنوان قانون دارند را ذخیره کن
|
||
# هرچه اختلاف بین این دو کمتر باشد، به این معناست که فاصله کمتری از هم دارند و به عبارت دیگر شباهت بیشتری با هم دارند
|
||
if Levenshtein_distance < 5:
|
||
founded_laws.append({
|
||
"Levenshtein_distance": Levenshtein_distance,
|
||
"law" : law,
|
||
"compared_law_title" : law_caption
|
||
})
|
||
# founded_item = founded_item
|
||
# founded_item_temp = founded_item_temp
|
||
# ... اگر تعداد عناوین قانونی مشابه با متن موردنظر ما بیش از یکی بود
|
||
if len(founded_laws) > 1:
|
||
# مرتب سازی قانون های پیدا شده بر اساس فاصله کمتر نسبت به متن موردنظر
|
||
sorted_founded_laws = sorted(founded_laws, key=lambda x: x['Levenshtein_distance'],reverse=True)
|
||
# از اینجا به بعد بررسی می کنیم که ببینیم کمترین اختلاف با متن مورد نظر چه عددی است
|
||
# از فاز فاصله صفر شروع می کنیم تا فاز فاصله 4 پیش می رویم
|
||
# در هر فاز اگر یک مورد عنوان قانونی پیدا شد، همان جواب ماست و شناسه همان را برمیگردانیم
|
||
# در هر فاز اگر تعداد عناوین پیداشده با فاصله مربوط به آن فاز، بیش از یکی بود، وارد
|
||
temp_laws = []
|
||
for law in sorted_founded_laws:
|
||
# بررسی فاز فاصله با مقدار صفر
|
||
# =========================
|
||
if int(law['Levenshtein_distance']) == 0:
|
||
temp_laws.append(law)
|
||
if len(temp_laws) > 0:
|
||
if len(temp_laws) == 1:
|
||
# اگر تنها یک مورد وجود داشت که فاصله آن با متن مورد نظر برابر با مقدار مربوط به این فاز بود، شناسه همان عنوان را بر می گردانیم
|
||
law_id = temp_laws[0]['law']['id']
|
||
return law_id
|
||
# اگر تعداد عناوین قانونی با فاصله مطابق با مقدار مربوط به این فاز، بیش از یک مورد بود،
|
||
# مرحله دوم از الگوریتم را پیاده می کنیم
|
||
# یعنی تعداد عناوین پیدا شده را بر اساس تعداد توکن هر عنوان قانونی مرتب می کنیم
|
||
elif len(temp_laws) > 1:
|
||
# مرتب سازی لیست بر اساس تعداد توکن و مقایسه با تعداد توکن متن مورد نظر و انتخاب مورد با کمترین اختلاف
|
||
temp_laws = find_minimum_token_distance(temp_laws, founded_item_temp)
|
||
if len(temp_laws) == 1:
|
||
# اگر فقط یک مورد عنوان قانونی در لیست پیدا شده همان جواب ماست و شناسه آن را بر می گردانیم
|
||
law_id = temp_laws[0]['law']['id']
|
||
return law_id
|
||
elif len(temp_laws) >1:
|
||
# این قسمت مرحله سوم الگوریتم است
|
||
# در مرحله اول، کمترین فاصله لونشتاین را ملاک قرار دادیم
|
||
# در مرحله دوم، کمترین اختلاف توکن را ملاک قرار دادیم
|
||
# در این مرحله، لیست باقیمانده را بر اساس تاریخ مرتب می کنیم و شناسه عنوان قانونی که جدیدترین تاریخ را دارد برمی گردانیم
|
||
# مرتب سازی بر اساس تاریخ و پاپ یک گزینه و استخراج شناسه از همان و برگرداندن آن
|
||
sorted_strings = sorted(temp_laws, key=lambda x: len(x['law']['approve_date']))
|
||
final_row = sorted_strings.pop()
|
||
law_id = int(final_row['law']['id'])
|
||
return law_id
|
||
# اگر هیچ عنوان قانونی را پیدا نکردیم که اختلاف تعداد توکنش با عنوان مورد نظر ما کم باشد
|
||
# مقدار صفر برگردان
|
||
else:
|
||
return 0
|
||
# اگر هیچ کدام از عناوین پیدا شده، فاصله ای با مقدار مربوط به این فاز را نداشت، وارد فاز بعدی می شویم،
|
||
# یعنی اختلاف به جای بررسی اختلاف با مقدار صفر، اختلاف با مقدار یک را بررسی می کنیم
|
||
elif len(temp_laws) == 0:
|
||
for law in sorted_founded_laws:
|
||
# بررسی فاز فاصله با مقدار یک
|
||
# =========================
|
||
if int(law['Levenshtein_distance']) == 1:
|
||
temp_laws.append(law)
|
||
if len(temp_laws) > 0:
|
||
if len(temp_laws) == 1:
|
||
law_id = temp_laws[0]['law']['id']
|
||
return law_id
|
||
elif len(temp_laws) > 1:
|
||
# مرتب سازی لیست بر اساس تعداد توکن و مقایسه با تعداد توکن متن مورد نظر و انتخاب مورد با کمترین اختلاف
|
||
temp_laws = find_minimum_token_distance(temp_laws, founded_item_temp)
|
||
if len(temp_laws) == 1:
|
||
return temp_laws[0]['law']['id']
|
||
elif len(temp_laws) >1:
|
||
# مرتب سازی بر اساس تاریخ و پاپ یک گزینه و استخراج شناسه از همان و برگرداندن آن
|
||
sorted_strings = sorted(temp_laws, key=lambda x: len(x['law']['approve_date']))
|
||
final_row = sorted_strings.pop()
|
||
return int(final_row['law']['id'])
|
||
else:
|
||
return 0
|
||
elif len(temp_laws) == 0:
|
||
for law in sorted_founded_laws:
|
||
# بررسی فاز فاصله با مقدار دو
|
||
# =========================
|
||
if int(law['Levenshtein_distance']) == 2:
|
||
temp_laws.append(law)
|
||
if len(temp_laws) > 0:
|
||
if len(temp_laws) == 1:
|
||
law_id = temp_laws[0]['law']['id']
|
||
return law_id
|
||
elif len(temp_laws) > 1:
|
||
# مرتب سازی لیست بر اساس تعداد توکن و مقایسه با تعداد توکن متن مورد نظر و انتخاب مورد با کمترین اختلاف
|
||
temp_laws = find_minimum_token_distance(temp_laws, founded_item_temp)
|
||
if len(temp_laws) == 1:
|
||
return temp_laws[0]['law']['id']
|
||
elif len(temp_laws) >1:
|
||
# مرتب سازی بر اساس تاریخ و پاپ یک گزینه و استخراج شناسه از همان و برگرداندن آن
|
||
sorted_strings = sorted(temp_laws, key=lambda x: len(x['law']['approve_date']))
|
||
final_row = sorted_strings.pop()
|
||
return int(final_row['law']['id'])
|
||
else:
|
||
return 0
|
||
elif len(temp_laws) == 0:
|
||
for law in sorted_founded_laws:
|
||
# بررسی فاز فاصله با مقدار سه
|
||
# =========================
|
||
if int(law['Levenshtein_distance']) == 3:
|
||
temp_laws.append(law)
|
||
if len(temp_laws) > 0:
|
||
if len(temp_laws) == 1:
|
||
law_id = temp_laws[0]['law']['id']
|
||
return law_id
|
||
elif len(temp_laws) > 1:
|
||
# مرتب سازی لیست بر اساس تعداد توکن و مقایسه با تعداد توکن متن مورد نظر و انتخاب مورد با کمترین اختلاف
|
||
temp_laws = find_minimum_token_distance(temp_laws, founded_item_temp)
|
||
if len(temp_laws) == 1:
|
||
return temp_laws[0]['law']['id']
|
||
elif len(temp_laws) >1:
|
||
# مرتب سازی بر اساس تاریخ و پاپ یک گزینه و استخراج شناسه از همان و برگرداندن آن
|
||
sorted_strings = sorted(temp_laws, key=lambda x: len(x['law']['approve_date']))
|
||
final_row = sorted_strings.pop()
|
||
return int(final_row['law']['id'])
|
||
else:
|
||
return 0
|
||
elif len(temp_laws) == 0:
|
||
for law in sorted_founded_laws:
|
||
# بررسی فاز فاصله با مقدار چهار
|
||
# =========================
|
||
if int(law['Levenshtein_distance']) == 4:
|
||
temp_laws.append(law)
|
||
if len(temp_laws) > 0:
|
||
if len(temp_laws) == 1:
|
||
law_id = temp_laws[0]['law']['id']
|
||
return law_id
|
||
elif len(temp_laws) > 1:
|
||
# مرتب سازی لیست بر اساس تعداد توکن و مقایسه با تعداد توکن متن مورد نظر و انتخاب مورد با کمترین اختلاف
|
||
temp_laws = find_minimum_token_distance(temp_laws, founded_item_temp)
|
||
if len(temp_laws) == 1:
|
||
# اگر فقط یک مورد عنوان قانونی در لیست پیدا شده همان جواب ماست و شناسه آن را بر می گردانیم
|
||
law_id = temp_laws[0]['law']['id']
|
||
return law_id
|
||
elif len(temp_laws) >1:
|
||
# مرتب سازی بر اساس تاریخ و پاپ یک گزینه و استخراج شناسه از همان و برگرداندن آن
|
||
sorted_strings = sorted(temp_laws, key=lambda x: len(x['law']['approve_date']))
|
||
final_row = sorted_strings.pop()
|
||
return int(final_row['law']['id'])
|
||
# اگر هیچ عنوان قانونی را پیدا نکردیم که اختلاف تعداد توکنش با عنوان مورد نظر ما کم باشد
|
||
else:
|
||
return 0
|
||
|
||
|
||
# print(99999999999)
|
||
|
||
elif len(founded_laws) == 0:
|
||
# print(00000000000)
|
||
law_id = 0
|
||
return law_id
|
||
# اگر تعداد عناوین قانونی مشابه عنوان موردنظر ما که پیدا کردیم فقط یک مورد بود، شناسه همان قانون را برگردان
|
||
else:
|
||
# print(11111111111)
|
||
final_row = founded_laws.pop()
|
||
law_id = int(final_row['law']['id'])
|
||
return law_id
|
||
|
||
return law_id
|
||
|
||
# این متد یک لیست از رشته ها و یک رشته را می گیرد و لیست داده شده را براساس کمترین اختلاف توکن نسبت
|
||
# به تعداد توکن رشته پاس شده به متد، مرتب می کند
|
||
def find_minimum_token_distance(str_list, caption):
|
||
str_dict = []
|
||
caption_tokens_count = len(caption.split(' '))
|
||
|
||
# مرتبسازی لیست بر اساس تعداد کلمات در caption
|
||
sorted_strings = sorted(str_list, key=lambda x: len(x['law']['caption'].split()))
|
||
|
||
# اضافه کردن تعداد کلمات مورد نظر به هر دیکشنری
|
||
for item in sorted_strings:
|
||
item['token_count'] = len(item['law']['caption'].split())
|
||
|
||
similar_list = []
|
||
for i in range(0,5):
|
||
for value in sorted_strings:
|
||
# مقایسه برای پیدا کردن کمترین اختلاف توکن،
|
||
# از اختلاف صفر شروع می کند تا چهار توکن اختلاف
|
||
if caption_tokens_count + i == value['token_count']:
|
||
similar_list.append(value)
|
||
# در هر مرحله از حلقه، اگر تعداد مقادیر موجود در لیست ما بیش از صفر بود،
|
||
# همان لیست را برگرداند و حلقه را ادامی ندهد
|
||
if len(similar_list)>0:
|
||
return similar_list
|
||
# در غیر صورت بالا، حلقه را با مقدار ایندکس به علاوه یک ادامه دهد
|
||
i+=1
|
||
return similar_list
|
||
|
||
|
||
|
||
def change_reference_tokens(normalized_section_content, recognized_patterns_array):
|
||
token_list = normalized_section_content.strip().split()
|
||
for ref_item in recognized_patterns_array:
|
||
if(str(ref_item['type']).__contains__('reference')):
|
||
start_token_state = ref_item.get('index_start')
|
||
end_token_state = ref_item.get('index_end')
|
||
for i in range(start_token_state, end_token_state+1):
|
||
if i >= len(token_list):
|
||
break
|
||
token_list[i] = 'eeee'
|
||
normalized_section_content = ''
|
||
for token in token_list:
|
||
normalized_section_content = ''.join([normalized_section_content, (' ' + token)])
|
||
return normalized_section_content.strip()
|
||
|
||
def getMetaData(text, law_dict):
|
||
text = normalize_content(text)
|
||
normalized_section_content, recognized_dates, recognized_numbers = normalizerDate2(text.strip())
|
||
recognized_numbers = find_number_indexes_in_string(text,recognized_numbers)
|
||
normalized_section_content = normalized_section_content.strip()
|
||
recognized_patterns_array = regex_patterns_finder(normalized_section_content, law_dict)
|
||
nlp_parser = []
|
||
date_list = recognized_dates
|
||
ref_list = recognized_patterns_array
|
||
|
||
for date_item in date_list:
|
||
nlp_parser.append({
|
||
"index_start": int(date_item['start_date_token_index']),
|
||
"index_end" : int(date_item['end_date_token_index']),
|
||
"text" : date_item['original_date'],
|
||
"result" : date_item['converted_date'],
|
||
#"timestamp" : date_item['timestamp'],
|
||
"type" : "date",
|
||
"ref_link" : ''
|
||
})
|
||
for ref_item in ref_list:
|
||
law_id = int(ref_item['law_id'])
|
||
nlp_parser.append({
|
||
"law_id" : int(ref_item['law_id']),
|
||
"index_start" : int(ref_item['start_token_state']),
|
||
"index_end" : int(ref_item['end_token_state']),
|
||
"text" : ref_item['founded_item'],
|
||
"result" : ref_item['pattern_value'],
|
||
"type" : ref_item['pattern_type'],
|
||
"ref_link" : ''
|
||
})
|
||
|
||
return nlp_parser, normalized_section_content
|
||
|
||
def get_ref_parser(content, law_dict):
|
||
final_found_law = law_title_search(content, law_dict)
|
||
ref_parser = []
|
||
for ref_value in final_found_law:
|
||
ref_parser.append({
|
||
"law_id" : ref_value['law_id'],# شناسه قانون
|
||
"index_start" : int(ref_value['start_token_index']),
|
||
"index_end" : int(ref_value['end_token_index']),
|
||
"text" : ref_value['matched_string'],# توکن هایی که متناظر آنها در عناوین قانون ها وجود داشته
|
||
"text_tokens" : ref_value['original_string'],# ده توکنی که احتمالا عنوان یک قانون باشد
|
||
"result" : ref_value['found_law_list'],# لیست عناوین یافت شده
|
||
"type" : "law_title",
|
||
"ref_link" : ''
|
||
})
|
||
return ref_parser
|
||
|
||
def save_error(error_text,filename):
|
||
with open(filename, 'a+', encoding='utf-8') as file:
|
||
# نوشتن خطا در فایل
|
||
file.write(error_text + '\n' + 50*'*' + '\n')
|
||
|
||
def save_error(id=0, e=Exception):
|
||
err_date = datetime.datetime.now()
|
||
filename = 'ner_reg_errors2.txt'
|
||
exc_type, exc_value, exc_traceback = sys.exc_info()
|
||
frame = exc_traceback.tb_frame
|
||
function_array = traceback.extract_tb(exc_traceback)
|
||
current_function = function_array[len(function_array)-1]
|
||
error = f'''
|
||
id : {id}
|
||
filename : {current_function.filename}
|
||
function : {current_function.name}
|
||
err line no : {current_function.lineno}
|
||
err line : {current_function.line}
|
||
err message : {e}
|
||
err date : {err_date}
|
||
'''
|
||
print( '*'*60 + error + '*'*60)
|
||
with open(filename, 'a+', encoding='utf-8') as file:
|
||
# نوشتن خطا در فایل
|
||
file.write(error + '\n' + 50*'*' + '\n')
|
||
return error
|
||
|
||
def read_section_table():
|
||
cursor, cnxn = create_cursor()
|
||
query = """SELECT s.ID as section_id,s.SECTIONTEXT as section_text, l.ID as law_id, l.ISLAW as law_islaw
|
||
from lwSection s
|
||
left join lwLaw l on s.F_LWLAWID = l.ID
|
||
where l.ISLAW = 1"""
|
||
|
||
cursor.execute(query)
|
||
|
||
section_list = {}
|
||
i = 0
|
||
for item in cursor.fetchall():
|
||
i+=1
|
||
if i == 10000:# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! برداشته شود
|
||
break
|
||
# if i%1000 == 0:
|
||
# print(i)
|
||
#row = cursor.fetchone()
|
||
id = int(item.section_id)
|
||
try:
|
||
text = removeHtmlNoTableTag(item.section_text)
|
||
except Exception as e:
|
||
text = item.section_text
|
||
section_text = normalize_content(text)
|
||
section_list[id] = {"id": id, "section_text": section_text}
|
||
cursor.close()
|
||
cnxn.close()
|
||
return section_list
|
||
|
||
def read_law_table():
|
||
cursor, cnxn = create_cursor()
|
||
query = """SELECT [ID],[CAPTION],[APPROVEDATE]
|
||
FROM [Qavanin].[dbo].[lwLaw]
|
||
where [ISLAW] = 1
|
||
order by [APPROVEDATE] desc"""
|
||
cursor.execute(query)
|
||
|
||
law_dict = {}
|
||
approve_date_error = []
|
||
for item in cursor.fetchall():
|
||
#row = cursor.fetchone()
|
||
id = int(item.ID)
|
||
caption = normalize_content(item.CAPTION)
|
||
# تبدیل تاریخ با فرمت رشته به فرمت تاریخ
|
||
date = str(item.APPROVEDATE).split('/')
|
||
try:
|
||
approve_date = Persian(int(date[0]),int(date[1]),int(date[2]))
|
||
except:
|
||
approve_date_error.append(date)
|
||
# در موارد خطا، اپروو دیت کنترل شود
|
||
|
||
law_dict[id] = {"id": id ,"caption": caption,'approve_date': approve_date}
|
||
|
||
cursor.close()
|
||
cnxn.close()
|
||
return law_dict
|
||
|
||
def law_recognizer(text, law_dict):
|
||
i = 0
|
||
|
||
# try:
|
||
# nlp_parser, normalized_content = getMetaData(text)
|
||
# except Exception as e:
|
||
# save_error(0, e)
|
||
normalized_content = text
|
||
text_token_list = normalized_content.strip().split()
|
||
matched_token_index_list = []
|
||
|
||
# جمع آوری عناوین احتمالی قانون در یک متن بر اساس کلیدواژه قانون
|
||
for index,token in enumerate(text_token_list):
|
||
if 'قانون' in token:
|
||
matched_token_index_list.append(index)
|
||
|
||
content_token_list = []
|
||
law_token_list = []
|
||
for index, item in enumerate(matched_token_index_list):
|
||
# اگر آیتم، آخرین عنصر موجود در آرایه نبود ...
|
||
if item < len(text_token_list):
|
||
#content_token_list.append(text_token_list[item])
|
||
# نُه توکن بعدی را به عنوان عبارات تکمیلی احتمالی عنوان قانون ذخیره می کنیم
|
||
if item + 9 < len(text_token_list):
|
||
for i in range(9):
|
||
if item + (i+1) >= len(text_token_list):
|
||
break
|
||
content_token_list.append(text_token_list[item + (i+1)])
|
||
i = 0
|
||
# توکن های باقیمانده(که کمتر از نُه توکن است) تا پایان آرایه را ذخیره کن
|
||
else:
|
||
j = 0
|
||
while j < len(text_token_list)-index:
|
||
if item + (j+1) >= len(text_token_list)-index:
|
||
break
|
||
content_token_list.append(text_token_list[item + (j+1)])
|
||
j += 1
|
||
j = 0
|
||
law_token_list.append({
|
||
'start_token_index': item,
|
||
'law_token' : content_token_list
|
||
})
|
||
content_token_list = []
|
||
matched_law_list = []
|
||
c = 0
|
||
for key, law_value in enumerate(law_token_list):
|
||
c += 1
|
||
law_token = law_value['law_token']
|
||
start_token_index = law_value['start_token_index']
|
||
end_token_index = 0
|
||
found_law_list_1 = []
|
||
found_law_list_2 = []
|
||
found_law_list_3 = []
|
||
found_law_list_4 = []
|
||
found_law_list_5 = []
|
||
found_law_list_6 = []
|
||
found_law_list_7 = []
|
||
found_law_list_8 = []
|
||
found_law_list_9 = []
|
||
# اگر تعداد توکن های متنی که احتمالا عنوان یک قانون است، صفر بود،
|
||
# از حلقه خارج می شویم و به سراغ بررسی عنوان قانون بعدی می رویم
|
||
if len(law_token) < 1:
|
||
break
|
||
|
||
# در ابتدا اولین توکن عبارتی که احتمالا عنوان یک قانون است را در عنوان قانون موجود در بانک بررسی می کنیم
|
||
# در مراحل بعدی تا به نُه گام برسیم، یکی یکی توکن ها را به توکن اول اضافه و سپس با عناوین قانون ها مقایسه می کنیم
|
||
law_section = law_token[0]
|
||
for index, value in enumerate(law_dict):
|
||
# عنوان قانونی که در حال مقایسه متن مورد نظر با آن هستیم
|
||
id = value['id']
|
||
current_caption = value['caption']
|
||
current_approve_date = value['approve_date']
|
||
# بررسی وجود عبارت مورد نظر در عنوان قانون
|
||
if current_caption.__contains__(law_section):
|
||
# به دست آوردن اولین توکن از عنوان قانون
|
||
current_law_first_token = current_caption.strip().split(' ')[0]
|
||
# اگر اولین توکن از عنوان قانون برابر با کلمه "قانون" بود، این کلمه را نادیده میگیریم
|
||
# زیرا در لیست مربوط به لیست توکن های احتمالی مربوط به قوانین، کلمه قانون را در نظر نگرفته ایم
|
||
if current_law_first_token == 'قانون':
|
||
current_law_first_token = current_caption.strip().split(' ')[1]
|
||
if law_section == current_law_first_token:
|
||
# اگر زیر رشته موردنظر ما در عنوان قانون وجود داشت، نام قانون را در یک لیست ذخیره می کنیم.
|
||
# در مرحله بعد متن احتمالی قانون که در حال بررسی آن هستیم را با این لیست مقایسه می کنیم تا مقایسه محدود تری داشته باشیم
|
||
# found_law_list_1.append(current_caption + '#' + str(id) + '#' + current_approve_date)
|
||
found_law_list_1.append({"id": id ,"caption": current_caption, "approve_date":current_approve_date})
|
||
else:
|
||
continue
|
||
|
||
if len(found_law_list_1) == 0:
|
||
continue
|
||
else:
|
||
if len(found_law_list_1) == 1:
|
||
found_law = []
|
||
found_law.append(found_law_list_1.pop())
|
||
k = 0
|
||
matched_string = ''
|
||
found_law_caption = found_law[0]['caption'].strip()
|
||
if found_law_caption.startswith('قانون'):
|
||
found_law_caption = found_law_caption[5:]
|
||
# :متد زیر در ویندوز کار می کند اما در لینوکس کار نمی کند
|
||
# removeprefix
|
||
# found_law_caption = found_law[1]['caption'].strip().removeprefix('قانون')
|
||
found_law_caption_tokens = found_law_caption.strip().split()
|
||
# if item[0] != 'لازم':
|
||
for k in range(len(law_token)):
|
||
if k >= len(found_law_caption_tokens):
|
||
break
|
||
if law_token[k] == found_law_caption_tokens[k]:
|
||
matched_string += law_token[k] + ' '
|
||
else:
|
||
end_token_index = start_token_index + len(matched_string.strip().split())
|
||
matched_law_list.append({
|
||
"law_id" : found_law[0]['id'],
|
||
"start_token_index": start_token_index,
|
||
"end_token_index" : end_token_index,
|
||
"found_law_list" : found_law,
|
||
"law_captions" : found_law[0]['caption'],
|
||
"matched_string" : matched_string.strip(),
|
||
"original_string" : law_token,
|
||
"multi_flag" : False
|
||
})
|
||
break
|
||
|
||
end_token_index = start_token_index + len(matched_string.strip().split())
|
||
matched_law_list.append({
|
||
"law_id" : found_law[0]['id'],
|
||
"start_token_index" : start_token_index,
|
||
"end_token_index" : end_token_index,
|
||
"found_law_list": found_law,
|
||
"law_captions" : found_law[0]['caption'],
|
||
"matched_string": matched_string.strip(),
|
||
"original_string": law_token,
|
||
"multi_flag": False
|
||
})
|
||
continue
|
||
|
||
# اگر تعداد توکن های متنی که احتمالا عنوان یک قانون است، یکی بود،
|
||
# از حلقه خارج می شویم و به سراغ بررسی عنوان قانون بعدی می رویم
|
||
if len(law_token) < 2:
|
||
continue
|
||
|
||
law_section = law_token[0]+' '+law_token[1]
|
||
for value in found_law_list_1:
|
||
id = value['id']
|
||
current_caption = value['caption']
|
||
current_approve_date = value['approve_date']
|
||
rate = fuzz.token_set_ratio(current_caption,law_section)
|
||
# if current_caption.__contains__(law_section):
|
||
if rate == 100:
|
||
# found_law_list_2.append(current_caption + '#' + str(id) + '#' +current_approve_date)
|
||
found_law_list_2.append({"id": id ,"caption": current_caption, "approve_date":current_approve_date})
|
||
if len(found_law_list_2) == 0:
|
||
# اگر در مرحله قبل بیش از یک مورد پیدا کرده اما در این مرحله تعداد موارد مشابه به صفر رسیده
|
||
if len(found_law_list_1) > 1 and len(found_law_list_1) < 6:
|
||
# به دقت کنترل شود
|
||
# مرتب سازی بر اساس قدیم به جدیدترین شناسه
|
||
sorted_found_law_list = sorted(found_law_list_1, key=lambda x: x['approve_date'])
|
||
found_law = sorted_found_law_list.pop()
|
||
end_token_index = start_token_index + len(law_section.strip().split())
|
||
# آخرین توکنی که اخیرا به عنوان قانون اضافه شده را باید برگردانیم
|
||
# زیرا متناظر با این توکن اضافه شده، عنوان قانونی پیدا نشده
|
||
law_section = remove_latest_added_token(law_section)
|
||
matched_law_list.append({
|
||
"found_law_list": sorted_found_law_list,
|
||
"law_id" : found_law['id'],
|
||
"start_token_index": start_token_index,
|
||
"end_token_index" : end_token_index,
|
||
"law_captions" : found_law['caption'],
|
||
"matched_string": law_section,
|
||
"original_string": law_token,
|
||
"multi_flag": True
|
||
})
|
||
|
||
continue
|
||
else:
|
||
if len(found_law_list_2) == 1:
|
||
found_law = []
|
||
found_law.append(found_law_list_2.pop()) # = found_law_list_2.pop()
|
||
end_token_index = start_token_index + len(law_section.strip().split())
|
||
matched_law_list.append({
|
||
"law_id" : found_law[0]['id'],
|
||
"start_token_index": start_token_index,
|
||
"end_token_index" : end_token_index,
|
||
"found_law_list": found_law,
|
||
"law_captions" : found_law[0]['caption'],
|
||
"matched_string": law_section,
|
||
"original_string": law_token,
|
||
"multi_flag": False
|
||
})
|
||
# اگر در جستجوی عنوان قانون، به یک مورد منحصر به فرد رسیده بودیم، فقط همین یک عنوان را ذخیره کند
|
||
continue
|
||
|
||
|
||
# اگر تعداد توکن های متنی که احتمالا عنوان یک قانون است، دوتا بود،
|
||
# از حلقه خارج می شویم و به سراغ بررسی عنوان قانون بعدی می رویم
|
||
if len(law_token) < 3:
|
||
continue
|
||
law_section = law_token[0] + ' ' + law_token[1] + ' ' + law_token[2]
|
||
for value in found_law_list_2:
|
||
id = value['id']
|
||
current_caption = value['caption']
|
||
current_approve_date = value['approve_date']
|
||
rate = fuzz.token_set_ratio(current_caption,law_section)
|
||
# if current_caption.__contains__(law_section):
|
||
if rate == 100:
|
||
# found_law_list_3.append(current_caption + '#' + str(id) + '#' +current_approve_date)
|
||
found_law_list_3.append({"id": id ,"caption": current_caption, "approve_date":current_approve_date})
|
||
if len(found_law_list_3) == 0:
|
||
if len(found_law_list_2) > 1 and len(found_law_list_2) < 6:
|
||
# به دقت کنترل شود
|
||
# مرتب سازی بر اساس قدیم به جدیدترین شناسه
|
||
sorted_found_law_list = sorted(found_law_list_2, key=lambda x: x['approve_date'])
|
||
found_law = sorted_found_law_list.pop()
|
||
end_token_index = start_token_index + len(law_section.strip().split())
|
||
# آخرین توکنی که اخیرا به عنوان قانون اضافه شده را باید برگردانیم
|
||
# زیرا متناظر با این توکن اضافه شده، عنوان قانونی پیدا نشده
|
||
law_section = remove_latest_added_token(law_section)
|
||
matched_law_list.append({
|
||
"found_law_list": sorted_found_law_list,
|
||
"law_id" : found_law['id'],
|
||
"start_token_index": start_token_index,
|
||
"end_token_index" : end_token_index,
|
||
"law_captions" : found_law['caption'],
|
||
"matched_string": law_section,
|
||
"original_string": law_token,
|
||
"multi_flag": True
|
||
})
|
||
|
||
continue
|
||
else:
|
||
if len(found_law_list_3) == 1:
|
||
found_law = []
|
||
found_law.append(found_law_list_3.pop())
|
||
end_token_index = start_token_index + len(law_section.strip().split())
|
||
matched_law_list.append({
|
||
"law_id" : found_law[0]['id'],
|
||
"start_token_index": start_token_index,
|
||
"end_token_index" : end_token_index,
|
||
"found_law_list": found_law,
|
||
"law_captions" : found_law[0]['caption'],
|
||
"matched_string": law_section,
|
||
"original_string": law_token,
|
||
"multi_flag": False
|
||
})
|
||
continue
|
||
|
||
# اگر تعداد توکن های متنی که احتمالا عنوان یک قانون است، سه تا بود،
|
||
# از حلقه خارج می شویم و به سراغ بررسی عنوان قانون بعدی می رویم
|
||
if len(law_token) < 4:
|
||
continue
|
||
law_section = law_token[0] + ' ' + law_token[1] + ' ' + law_token[2] + ' ' + law_token[3]
|
||
for value in found_law_list_3:
|
||
id = value['id']
|
||
current_caption = value['caption']
|
||
current_approve_date = value['approve_date']
|
||
rate = fuzz.token_set_ratio(current_caption,law_section)
|
||
# if current_caption.__contains__(law_section):
|
||
if rate == 100:
|
||
# found_law_list_4.append(current_caption + '#' + str(id) + '#' +current_approve_date)
|
||
found_law_list_4.append({"id": id ,"caption": current_caption, "approve_date":current_approve_date})
|
||
if len(found_law_list_4) == 0:
|
||
# اگر در مرحله قبل بیش از یک مورد پیدا کرده اما در این مرحله تعداد موارد مشابه به صفر رسیده
|
||
if len(found_law_list_3) > 1 and len(found_law_list_3) < 6:
|
||
# به دقت کنترل شود
|
||
# مرتب سازی بر اساس قدیم به جدیدترین شناسه
|
||
sorted_found_law_list = sorted(found_law_list_3, key=lambda x: x['approve_date'])
|
||
found_law = sorted_found_law_list.pop()
|
||
end_token_index = start_token_index + len(law_section.strip().split())
|
||
# آخرین توکنی که اخیرا به عنوان قانون اضافه شده را باید برگردانیم
|
||
# زیرا متناظر با این توکن اضافه شده، عنوان قانونی پیدا نشده
|
||
law_section = remove_latest_added_token(law_section)
|
||
matched_law_list.append({
|
||
"found_law_list": sorted_found_law_list,
|
||
"law_id" : found_law['id'],
|
||
"start_token_index": start_token_index,
|
||
"end_token_index" : end_token_index,
|
||
"law_captions" : found_law['caption'],
|
||
"matched_string": law_section,
|
||
"original_string": law_token,
|
||
"multi_flag": True
|
||
})
|
||
|
||
continue
|
||
else:
|
||
if len(found_law_list_4) == 1:
|
||
found_law = []
|
||
found_law.append(found_law_list_4.pop())
|
||
end_token_index = start_token_index + len(law_section.strip().split())
|
||
matched_law_list.append({
|
||
"law_id" : found_law[0]['id'],
|
||
"start_token_index": start_token_index,
|
||
"end_token_index" : end_token_index,
|
||
"found_law_list": found_law,
|
||
"law_captions" : found_law[0]['caption'],
|
||
"matched_string": law_section,
|
||
"original_string": law_token,
|
||
"multi_flag": False
|
||
})
|
||
continue
|
||
|
||
# اگر تعداد توکن های متنی که احتمالا عنوان یک قانون است، چهارتا بود،
|
||
# از حلقه خارج می شویم و به سراغ بررسی عنوان قانون بعدی می رویم
|
||
if len(law_token) < 5:
|
||
continue
|
||
law_section = law_token[0] + ' ' + law_token[1] + ' ' + law_token[2] + ' ' + law_token[3] + ' ' + law_token[4]
|
||
for value in found_law_list_4:
|
||
id = value['id']
|
||
current_caption = value['caption']
|
||
current_approve_date = value['approve_date']
|
||
rate = fuzz.token_set_ratio(current_caption,law_section)
|
||
# if current_caption.__contains__(law_section):
|
||
if rate == 100:
|
||
# found_law_list_5.append(current_caption + '#' + str(id) + '#' +current_approve_date)
|
||
found_law_list_5.append({"id": id ,"caption": current_caption, "approve_date":current_approve_date})
|
||
|
||
if len(found_law_list_5) == 0:
|
||
# اگر در مرحله قبل بیش از یک مورد پیدا کرده اما در این مرحله تعداد موارد مشابه به صفر رسیده
|
||
if len(found_law_list_4) > 1 and len(found_law_list_4) < 6:
|
||
# به دقت کنترل شود
|
||
# مرتب سازی بر اساس قدیم به جدیدترین شناسه
|
||
sorted_found_law_list = sorted(found_law_list_4, key=lambda x: x['approve_date'])
|
||
found_law = sorted_found_law_list.pop()
|
||
end_token_index = start_token_index + len(law_section.strip().split())
|
||
# آخرین توکنی که اخیرا به عنوان قانون اضافه شده را باید برگردانیم
|
||
# زیرا متناظر با این توکن اضافه شده، عنوان قانونی پیدا نشده
|
||
law_section = remove_latest_added_token(law_section)
|
||
matched_law_list.append({
|
||
"found_law_list": sorted_found_law_list,
|
||
"law_id" : found_law['id'],
|
||
"start_token_index": start_token_index,
|
||
"end_token_index" : end_token_index,
|
||
"law_captions" : found_law['caption'],
|
||
"matched_string": law_section,
|
||
"original_string": law_token,
|
||
"multi_flag": True
|
||
})
|
||
|
||
continue
|
||
else:
|
||
if len(found_law_list_5) == 1:
|
||
found_law = []
|
||
found_law.append(found_law_list_5.pop())
|
||
end_token_index = start_token_index + len(law_section.strip().split())
|
||
matched_law_list.append({
|
||
"law_id" : found_law[0]['id'],
|
||
"start_token_index": start_token_index,
|
||
"end_token_index" : end_token_index,
|
||
"found_law_list": found_law,
|
||
"law_captions" : found_law[0]['caption'],
|
||
"matched_string": law_section,
|
||
"original_string": law_token,
|
||
"multi_flag": False
|
||
})
|
||
continue
|
||
|
||
# اگر تعداد توکن های متنی که احتمالا عنوان یک قانون است، پنج تا بود،
|
||
# از حلقه خارج می شویم و به سراغ بررسی عنوان قانون بعدی می رویم
|
||
if len(law_token) < 6:
|
||
continue
|
||
law_section = law_token[0] + ' ' + law_token[1] + ' ' + law_token[2] + ' ' + law_token[3] + \
|
||
' ' + law_token[4] + ' ' + law_token[5]
|
||
for value in found_law_list_5:
|
||
id = value['id']
|
||
current_caption = value['caption']
|
||
current_approve_date = value['approve_date']
|
||
rate = fuzz.token_set_ratio(current_caption,law_section)
|
||
# if current_caption.__contains__(law_section):
|
||
if rate == 100:
|
||
# found_law_klist_6.append(current_caption + '#' + str(id) + '#' +current_approve_date)
|
||
found_law_list_6.append({"id": id ,"caption": current_caption, "approve_date":current_approve_date})
|
||
if len(found_law_list_6) == 0:
|
||
# اگر در مرحله قبل بیش از یک مورد پیدا کرده اما در این مرحله تعداد موارد مشابه به صفر رسیده
|
||
if len(found_law_list_5) > 1 and len(found_law_list_5) < 6:
|
||
# به دقت کنترل شود
|
||
# مرتب سازی بر اساس قدیم به جدیدترین شناسه
|
||
sorted_found_law_list = sorted(found_law_list_5, key=lambda x: x['approve_date'])
|
||
found_law = sorted_found_law_list.pop()
|
||
end_token_index = start_token_index + len(law_section.strip().split())
|
||
# آخرین توکنی که اخیرا به عنوان قانون اضافه شده را باید برگردانیم
|
||
# زیرا متناظر با این توکن اضافه شده، عنوان قانونی پیدا نشده
|
||
law_section = remove_latest_added_token(law_section)
|
||
matched_law_list.append({
|
||
"found_law_list": sorted_found_law_list,
|
||
"law_id" : found_law['id'],
|
||
"start_token_index": start_token_index,
|
||
"end_token_index" : end_token_index,
|
||
"law_captions" : found_law['caption'],
|
||
"matched_string": law_section,
|
||
"original_string": law_token,
|
||
"multi_flag": True
|
||
})
|
||
|
||
continue
|
||
else:
|
||
if len(found_law_list_6) == 1:
|
||
found_law = []
|
||
found_law.append(found_law_list_6.pop())
|
||
end_token_index = start_token_index + len(law_section.strip().split())
|
||
matched_law_list.append({
|
||
"law_id" : found_law[0]['id'],
|
||
"start_token_index": start_token_index,
|
||
"end_token_index" : end_token_index,
|
||
"found_law_list": found_law,
|
||
"law_captions" : found_law[0]['caption'],
|
||
"matched_string": law_section,
|
||
"original_string": law_token,
|
||
"multi_flag": False
|
||
})
|
||
continue
|
||
|
||
# اگر تعداد توکن های متنی که احتمالا عنوان یک قانون است، شش تا بود،
|
||
# از حلقه خارج می شویم و به سراغ بررسی عنوان قانون بعدی می رویم
|
||
if len(law_token) < 7:
|
||
continue
|
||
law_section = law_token[0] + ' ' + law_token[1] + ' ' + law_token[2] + ' ' + law_token[3] + \
|
||
' ' + law_token[4] + ' ' + law_token[5]+ ' ' + law_token[6]
|
||
for value in found_law_list_6:
|
||
id = value['id']
|
||
current_caption = value['caption']
|
||
current_approve_date = value['approve_date']
|
||
rate = fuzz.token_set_ratio(current_caption,law_section)
|
||
# if current_caption.__contains__(law_section):
|
||
if rate == 100:
|
||
# found_law_list_7.append(current_caption + '#' + str(id) + '#' +current_approve_date)
|
||
found_law_list_7.append({"id": id ,"caption": current_caption, "approve_date":current_approve_date})
|
||
if len(found_law_list_7) == 0:
|
||
# اگر در مرحله قبل بیش از یک مورد پیدا کرده اما در این مرحله تعداد موارد مشابه به صفر رسیده
|
||
if len(found_law_list_6) > 1 and len(found_law_list_6) < 6:
|
||
# به دقت کنترل شود
|
||
# مرتب سازی بر اساس قدیم به جدیدترین شناسه
|
||
sorted_found_law_list = sorted(found_law_list_6, key=lambda x: x['approve_date'])
|
||
found_law = sorted_found_law_list.pop()
|
||
end_token_index = start_token_index + len(law_section.strip().split())
|
||
# آخرین توکنی که اخیرا به عنوان قانون اضافه شده را باید برگردانیم
|
||
# زیرا متناظر با این توکن اضافه شده، عنوان قانونی پیدا نشده
|
||
law_section = remove_latest_added_token(law_section)
|
||
matched_law_list.append({
|
||
"found_law_list": sorted_found_law_list,
|
||
"law_id" : found_law['id'],
|
||
"start_token_index": start_token_index,
|
||
"end_token_index" : end_token_index,
|
||
"law_captions" : found_law['caption'],
|
||
"matched_string": law_section,
|
||
"original_string": law_token,
|
||
"multi_flag": True
|
||
})
|
||
|
||
continue
|
||
else:
|
||
if len(found_law_list_7) == 1:
|
||
found_law = []
|
||
found_law.append(found_law_list_7.pop())
|
||
end_token_index = start_token_index + len(law_section.strip().split())
|
||
matched_law_list.append({
|
||
"law_id" : found_law[0]['id'],
|
||
"start_token_index": start_token_index,
|
||
"end_token_index" : end_token_index,
|
||
"found_law_list": found_law,
|
||
"law_captions" : found_law[0]['caption'],
|
||
"matched_string": law_section,
|
||
"original_string": law_token,
|
||
"multi_flag": False
|
||
})
|
||
continue
|
||
# اگر تعداد توکن های متنی که احتمالا عنوان یک قانون است، هفت تا بود،
|
||
# از حلقه خارج می شویم و به سراغ بررسی عنوان قانون بعدی می رویم
|
||
if len(law_token) < 8:
|
||
continue
|
||
law_section = law_token[0] + ' ' + law_token[1] + ' ' + law_token[2] + ' ' + law_token[3] + \
|
||
' ' + law_token[4] + ' ' + law_token[5]+ ' ' + law_token[6]+ ' ' + law_token[7]
|
||
for value in found_law_list_7:
|
||
id = value['id']
|
||
current_caption = value['caption']
|
||
current_approve_date = value['approve_date']
|
||
rate = fuzz.token_set_ratio(current_caption,law_section)
|
||
# if current_caption.__contains__(law_section):
|
||
if rate == 100:
|
||
# found_law_list_8.append(current_caption + '#' + str(id) + '#' +current_approve_date)
|
||
found_law_list_8.append({"id": id ,"caption": current_caption, "approve_date":current_approve_date})
|
||
if len(found_law_list_8) == 0:
|
||
# اگر در مرحله قبل بیش از یک مورد پیدا کرده اما در این مرحله تعداد موارد مشابه به صفر رسیده
|
||
if len(found_law_list_7) > 1 and len(found_law_list_7) < 6:
|
||
# به دقت کنترل شود
|
||
# مرتب سازی بر اساس قدیم به جدیدترین شناسه
|
||
sorted_found_law_list = sorted(found_law_list_7, key=lambda x: x['approve_date'])
|
||
found_law = sorted_found_law_list.pop()
|
||
end_token_index = start_token_index + len(law_section.strip().split())
|
||
# آخرین توکنی که اخیرا به عنوان قانون اضافه شده را باید برگردانیم
|
||
# زیرا متناظر با این توکن اضافه شده، عنوان قانونی پیدا نشده
|
||
law_section = remove_latest_added_token(law_section)
|
||
matched_law_list.append({
|
||
"found_law_list": sorted_found_law_list,
|
||
"law_id" : found_law['id'],
|
||
"start_token_index": start_token_index,
|
||
"end_token_index" : end_token_index,
|
||
"law_captions" : found_law['caption'],
|
||
"matched_string": law_section,
|
||
"original_string": law_token,
|
||
"multi_flag": True
|
||
})
|
||
|
||
continue
|
||
else:
|
||
if len(found_law_list_8) == 1:
|
||
found_law = []
|
||
found_law.append(found_law_list_8.pop())
|
||
end_token_index = start_token_index + len(law_section.strip().split())
|
||
matched_law_list.append({
|
||
"law_id" : found_law[0]['id'],
|
||
"start_token_index": start_token_index,
|
||
"end_token_index" : end_token_index,
|
||
"found_law_list": found_law,
|
||
"law_captions" : found_law[0]['caption'],
|
||
"matched_string": law_section,
|
||
"original_string": law_token,
|
||
"multi_flag": False
|
||
})
|
||
continue
|
||
# اگر تعداد توکن های متنی که احتمالا عنوان یک قانون است، هشت تا بود،
|
||
# از حلقه خارج می شویم و به سراغ بررسی عنوان قانون بعدی می رویم
|
||
if len(law_token) < 9:
|
||
continue
|
||
law_section = law_token[0] + ' ' + law_token[1] + ' ' + law_token[2] + ' ' + law_token[3] + \
|
||
' ' + law_token[4] + ' ' + law_token[5]+ ' ' + law_token[6]+ ' ' + law_token[7]+ ' ' + law_token[8]
|
||
for value in found_law_list_8:
|
||
id = value['id']
|
||
current_caption = value['caption']
|
||
current_approve_date = value['approve_date']
|
||
rate = fuzz.token_set_ratio(current_caption,law_section)
|
||
# if current_caption.__contains__(law_section):
|
||
if rate == 100:
|
||
# found_law_list_9.append(current_caption + '#' + str(id) + '#' +current_approve_date)
|
||
found_law_list_9.append({"id": id ,"caption": current_caption, "approve_date":current_approve_date})
|
||
if len(found_law_list_9) == 0:
|
||
# اگر در مرحله قبل بیش از یک مورد پیدا کرده اما در این مرحله تعداد موارد مشابه به صفر رسیده
|
||
if len(found_law_list_8) > 1 and len(found_law_list_8) < 6:
|
||
# به دقت کنترل شود
|
||
# مرتب سازی بر اساس قدیم به جدیدترین شناسه
|
||
sorted_found_law_list = sorted(found_law_list_8, key=lambda x: x['approve_date'])
|
||
found_law = sorted_found_law_list.pop()
|
||
end_token_index = start_token_index + len(law_section.strip().split())
|
||
# آخرین توکنی که اخیرا به عنوان قانون اضافه شده را باید برگردانیم
|
||
# زیرا متناظر با این توکن اضافه شده، عنوان قانونی پیدا نشده
|
||
law_section = remove_latest_added_token(law_section)
|
||
matched_law_list.append({
|
||
"found_law_list": sorted_found_law_list,
|
||
"law_id" : found_law['id'],
|
||
"start_token_index": start_token_index,
|
||
"end_token_index" : end_token_index,
|
||
"law_captions" : found_law['caption'],
|
||
"matched_string": law_section,
|
||
"original_string": law_token,
|
||
"multi_flag": True
|
||
})
|
||
|
||
continue
|
||
else:
|
||
if len(found_law_list_9) == 1:
|
||
sorted_found_law_list = sorted(found_law_list_9, key=lambda x: x['approve_date'])
|
||
found_law = []
|
||
found_law.append(found_law_list_9.pop())
|
||
end_token_index = start_token_index + len(law_section.strip().split())
|
||
matched_law_list.append({
|
||
"law_id" : found_law[0]['id'],
|
||
"start_token_index": start_token_index,
|
||
"end_token_index" : end_token_index,
|
||
"found_law_list": found_law,
|
||
"law_captions" : found_law[0]['caption'],
|
||
"matched_string": law_section,
|
||
"original_string": law_token,
|
||
"multi_flag": False
|
||
})
|
||
elif len(found_law_list_9) > 1 and len(found_law_list_9) < 6:
|
||
sorted_found_law_list = sorted(found_law_list_8, key=lambda x: x['approve_date'] )
|
||
found_law = sorted_found_law_list.pop()
|
||
end_token_index = start_token_index + len(law_section.strip().split())
|
||
matched_law_list.append({
|
||
"law_id" : found_law['id'],
|
||
"start_token_index": start_token_index,
|
||
"end_token_index" : end_token_index,
|
||
"found_law_list": found_law_list_9,
|
||
"law_captions" : found_law['caption'],
|
||
"matched_string": law_section,
|
||
"original_string": law_token,
|
||
"multi_flag": True
|
||
})
|
||
|
||
if matched_law_list:
|
||
for law_item in matched_law_list:
|
||
temp_list = []
|
||
found_list = law_item['found_law_list']
|
||
for item in found_list:
|
||
temp_list.append(item['caption'] + '#' + str(item['id']) + '#' + item['approve_date'])
|
||
|
||
law_item['found_law_list'] = temp_list
|
||
return matched_law_list, law_token_list
|
||
|
||
def law_title_search(content,law_dict):
|
||
# section_dict = read_section_table()
|
||
#law_dict = read_law_table()
|
||
#write_to_json(law_dict,'law_title.json')
|
||
# law_dict = read_from_json('law_title.json')
|
||
# i = 0
|
||
# probable = 0
|
||
# foundlist = 0
|
||
# found_law = 0
|
||
final_found_law = []
|
||
# for id, value in section_dict.items():
|
||
final_found_law, law_token_list = law_recognizer(content, law_dict)
|
||
|
||
# if(len(law_token_list))>0:
|
||
# probable += len(law_token_list)
|
||
# for ref_value in matched_law_list:
|
||
# foundlist += 1
|
||
# final_found_law.append({
|
||
# "law_id" : ref_value['law_id'],# شناسه قانون
|
||
# "index_start" : int(ref_value['start_token_index']),
|
||
# "index_end" : int(ref_value['end_token_index']),
|
||
# "text" : ref_value['matched_string'],# توکن هایی که متناظر آنها در عناوین قانون ها وجود داشته
|
||
# "text_tokens" : ref_value['original_string'],# ده توکنی که احتمالا عنوان یک قانون باشد
|
||
# "result" : ref_value['found_law_list'],# لیست عناوین یافت شده
|
||
# "type" : "law_title",
|
||
# "ref_link" : ''
|
||
# })
|
||
# for value in matched_law_list:
|
||
# if value['multi_flag']:
|
||
# foundlist += 1
|
||
# final_found_law.append( {
|
||
# "law_id" : value['law_id'],
|
||
# "start_token_index": value['start_token_index'],
|
||
# "end_token_index" : value['end_token_index'],
|
||
# "multi_flag" : value['multi_flag'],
|
||
# "found_law_list" : value["found_law_list"],
|
||
# "law_caption" : value['law_captions'],
|
||
# "matched_string" : value["matched_string"],
|
||
# "original_string" : value["original_string"]
|
||
# })
|
||
# if not value['multi_flag']:
|
||
# found_law += 1
|
||
# final_found_law.append({
|
||
# "law_id" : value['law_id'],
|
||
# "start_token_index": value['start_token_index'],
|
||
# "end_token_index" : value['end_token_index'],
|
||
# "multi_flag" : value['multi_flag'],
|
||
# "found_law_list" : value["found_law_list"],
|
||
# "law_caption" : value['law_captions'],
|
||
# "matched_string" : value["matched_string"],
|
||
# "original_string" : value["original_string"]
|
||
# })
|
||
# print(i+1)
|
||
# i+=1
|
||
|
||
# print("************ Result ************")
|
||
# print("probable: " + str(probable))
|
||
# print("found_law: " + str(found_law)+ " - " + str(int((found_law/probable)*100)) + " %")
|
||
# print("found_list: " + str(foundlist) + " - " + str(int((foundlist/probable)*100)) + " %")
|
||
return final_found_law
|
||
|
||
|
||
def write_to_json(dict,file_name):
|
||
data = []
|
||
for key,value in dict.items():
|
||
date_obj = value["approve_date"]
|
||
year = date_obj.persian_year
|
||
month = date_obj.persian_month
|
||
day = date_obj.persian_day
|
||
aprove_date = f'{year}-{month}-{day}'
|
||
data.append({
|
||
'id' : value["id"],
|
||
'caption' : value["caption"],
|
||
'approve_date': aprove_date
|
||
})
|
||
|
||
# تبدیل دیکشنری به فرمت JSON
|
||
json_data = json.dumps(data, indent=2, ensure_ascii=False)
|
||
|
||
# ذخیره فایل
|
||
with open(file_name, 'w', encoding='utf-8') as file:
|
||
file.write(json_data)
|
||
|
||
def read_from_json(file_name):
|
||
data_dict = []
|
||
path = ''
|
||
# خواندن اطلاعات از فایل JSON
|
||
try:
|
||
with open(path + file_name, 'r', encoding='utf-8') as file:
|
||
loaded_data = json.load(file)
|
||
except Exception as err:
|
||
err = err
|
||
path = os.getcwd()
|
||
path = path + '/repairQanon/'
|
||
with open(path + file_name, 'r', encoding='utf-8') as file:
|
||
loaded_data = json.load(file)
|
||
|
||
# نمایش اطلاعات خوانده شده
|
||
for item in loaded_data:
|
||
data_dict.append(item)
|
||
return data_dict
|
||
|
||
def remove_latest_added_token(text):
|
||
temp = text.strip().split(' ')
|
||
temp.pop()
|
||
text = ''
|
||
for token in temp:
|
||
text = text + ' ' + token
|
||
|
||
return text.strip()
|
||
|
||
|
||
|
||
|