Browse Source

Import C4 Reports

master
Adam McGuigan 4 years ago
parent
commit
4601d36add
  1. 36
      Constants.py
  2. 2
      Costs.py
  3. 477
      Counter4.py
  4. 108
      FetchData.py
  5. 35
      GeneralUtils.py
  6. 274
      ImportFile.py
  7. 16
      ManageDB.py
  8. 8
      README.md
  9. 2
      Search.py
  10. 50
      Visual.py
  11. BIN
      executables/Linux/Counter 5 Report Tool.zip
  12. BIN
      executables/Windows/COUNTER 5 Report Tool.zip
  13. BIN
      executables/macOS/Counter 5 Report Tool.zip
  14. BIN
      images/import-report-updated.png
  15. 30
      tests/test_ImportFile.py
  16. 379
      ui/ImportReportTab.py
  17. 588
      ui/ImportReportTab.ui
  18. 160
      ui/VisualTab.py
  19. 916
      ui/VisualTab.ui
  20. 1
      vendor-lists/template-vendor-lists
  21. 115
      vendor-lists/vendors-template-R5-only.tsv
  22. 183
      vendor-lists/vendors-template-with-r4-vendors.tsv

36
Constants.py

@ -1,7 +1,7 @@
from enum import Enum
# Variable Constants for MainDriver.py
HELP_SITE = "https://git.library.upei.ca/mbelvadi/COUNTER-5-Report-Tool/wiki"
HELP_SITE = "https://github.com/CS-4820-Library-Project/COUNTER-5-Report-Tool/wiki"
# region Variable Constants for ManageDB
@ -427,6 +427,7 @@ CURRENCY_LIST = ('USD', 'EUR', 'JPY', 'GBP', 'CHF', 'CAD', 'AUD')
JSON_FILTER = ('JSON files (*.dat)',)
TSV_FILTER = ('TSV files (*.tsv)',)
CSV_FILTER = ('CSV files (*.csv)',)
TSV_AND_CSV_FILTER = ('Report files (*.csv *.tsv)',)
EXCEL_FILTER = ('Excel files (*.xlsx)',)
# endregion
@ -607,3 +608,36 @@ VENDORS_FILE_PATH = VENDORS_FILE_DIR + VENDORS_FILE_NAME
EXPORT_VENDORS_FILE_NAME = "exported_vendor_data.tsv"
# endregion
# region Variable Constants for ImportFile
COUNTER_4_REPORT_EQUIVALENTS = {
"BR1": "TR, TR_B1",
"BR1, BR2": "TR, TR_B1",
"BR1, BR2, BR3, JR1, JR2": "TR, TR_B1, TR_B2, TR_J1, TR_J2",
"BR2": "TR, TR_B1",
"BR3": "TR, TR_B2",
"DB1": "DR, DR_D1",
"DB1, DB2": "DR, DR_D1, DR_D2",
"DB2": "DR, DR_D2",
"JR1": "TR, TR_J1",
"JR1, JR2": "TR, TR_J1, TR_J2",
"JR2": "TR, TR_J2",
"PR1": "PR, PR_P1"
}
COUNTER_5_REPORT_EQUIVALENTS = {
"TR_B1": "BR1, BR2",
"TR_B2": "BR3",
"TR_J1": "JR1",
"TR_J2": "JR2",
"TR": "BR1, BR2, BR3, JR1, JR2",
"DR_D1": "DB1",
"DR_D2": "DB2",
"DR": "DB1, DB2",
"JR1": "TR_J1",
"JR2": "TR_J2",
"PR_P1": "PR1",
"PR": "PR1"
}
# endregion

2
Costs.py

@ -148,7 +148,7 @@ class CostsController:
self.names = [result[0] for result in names_results]
else:
self.names = []
if self.settings.show_debug_messages: print(names_results)
# if self.settings.show_debug_messages: print(names_results)
costs_sql_text, costs_data = ManageDB.get_names_with_costs_sql_text(self.report_parameter,
self.vendor_parameter,

477
Counter4.py

@ -0,0 +1,477 @@
import csv
from datetime import datetime, timezone
from os import path, makedirs
from PyQt5.QtCore import QDate
import GeneralUtils
from Constants import COUNTER_4_REPORT_EQUIVALENTS, COUNTER_5_REPORT_EQUIVALENTS, MajorReportType
from FetchData import ReportRow, ReportHeaderModel, TypeValueModel, NameValueModel, ReportWorker
from ManageVendors import Vendor
class Counter4ReportHeader:
def __init__(self, report_type: str, customer: str, institution_id: str, reporting_period: str, date_run: str):
self.report_type = report_type
self.customer = customer
self.institution_id = institution_id
self.reporting_period = reporting_period
self.date_run = date_run
class Counter4ReportModel:
def __init__(self, report_header: Counter4ReportHeader, header_list: list, row_dicts: list):
self.report_header = report_header
self.header_list = header_list
self.row_dicts = row_dicts
class Counter4To5Converter:
def __init__(self, vendor: Vendor, c4_report_types: str, file_paths: list, save_dir: str, date: QDate):
self.vendor = vendor
self.c4_report_types = c4_report_types
self.file_paths = file_paths
self.save_dir = save_dir
self.begin_date = QDate(date.year(), 1, 1)
self.end_date = QDate(date.year(), 12, 31)
self.target_c5_report_types = self.get_c5_equivalent(c4_report_types)
self.final_rows_dict = {}
def do_conversion(self) -> dict:
file_paths = {}
report_rows_dict = {} # {report_type: report_rows_dict}
c4_report_types_processed = []
c4_customer = ""
c4_institution_id = ""
for file_path in self.file_paths:
report_model = self.c4_file_to_c4_model(file_path)
c4_report_header = report_model.report_header
short_c4_report_type = self.get_short_c4_report_type(c4_report_header.report_type)
if short_c4_report_type not in self.c4_report_types:
continue
c4_report_types_processed.append(short_c4_report_type)
c4_customer = c4_report_header.customer
c4_institution_id = c4_report_header.institution_id
report_rows = self.c4_model_to_rows(report_model)
report_rows_dict[short_c4_report_type] = report_rows
if not c4_report_types_processed:
raise Exception("No valid COUNTER 4 report selected for this operation")
# Create a final COUNTER 5 file for each target c5 report type
for c5_report_type in self.target_c5_report_types.split(", "):
required_c4_report_types = self.get_c4_equivalent(c5_report_type).split(", ")
c4_report_types_used = []
c5_report_type_rows = []
# Fill up c5_report_type_rows with rows from required_c4_report_types
for c4_report_type in required_c4_report_types:
if c4_report_type in report_rows_dict:
c5_report_type_rows += report_rows_dict[c4_report_type]
c4_report_types_used.append(c4_report_type)
if not c4_report_types_used: # If no c4 file for this c5 report type is available
continue
# Sort the rows
c5_major_report_type = GeneralUtils.get_major_report_type(c5_report_type)
c5_report_type_rows = ReportWorker.sort_rows(c5_report_type_rows, c5_major_report_type)
# Create header for this report
c5_report_header = self.get_c5_report_header(c5_report_type,
", ".join(c4_report_types_used),
c4_customer,
c4_institution_id)
# Create the c5 file
file_path = self.create_c5_file(c5_report_header, c5_report_type_rows)
file_paths[c5_report_type] = file_path
return file_paths
def c4_file_to_c4_model(self, file_path: str) -> Counter4ReportModel:
file = open(file_path, 'r', encoding="utf-8")
extension = file_path[-4:]
delimiter = ""
if extension == ".csv":
delimiter = ","
elif extension == ".tsv":
delimiter = "\t"
# Process process report header into model
csv_reader = csv.reader(file, delimiter=delimiter)
report_type = ""
customer = ""
institution_id = ""
reporting_period = ""
date_run = ""
curr_line = 1
last_header_line = 7
for row in csv_reader:
if curr_line == 1:
report_type = row[0]
elif curr_line == 2:
customer = row[0]
elif curr_line == 3:
institution_id = row[0]
elif curr_line == 4 and row[0].lower() != "period covered by report:":
file.close()
raise Exception("'Period covered by Report:' missing from header line 4")
elif curr_line == 5:
reporting_period = row[0]
elif curr_line == 6 and row[0].lower() != "date run:":
file.close()
raise Exception("'Date run:' missing from header line 6")
elif curr_line == 7:
date_run = row[0]
is_valid_date = QDate().fromString(date_run, "yyyy-MM-dd").isValid() or \
QDate().fromString(date_run, "MM-dd-yy").isValid() or \
QDate().fromString(date_run, "M-d-yy").isValid()
if not is_valid_date:
file.close()
raise Exception("Invalid date on line 7")
curr_line += 1
if curr_line > last_header_line:
break
if curr_line <= last_header_line:
file.close()
raise Exception("Not enough lines in report header")
report_header = Counter4ReportHeader(report_type, customer, institution_id, reporting_period, date_run)
# Process process report rows into model
csv_dict_reader = csv.DictReader(file, delimiter=delimiter)
header_dict = csv_dict_reader.fieldnames
row_dicts = []
for row in csv_dict_reader:
row_dicts.append(row)
report_model = Counter4ReportModel(report_header, header_dict, row_dicts)
file.close()
return report_model
def c4_model_to_rows(self, report_model: Counter4ReportModel) -> list:
short_c4_report_type = self.get_short_c4_report_type(report_model.report_header.report_type)
c4_major_report_type = self.get_c4_major_report_type(short_c4_report_type)
report_rows_dict = {} # {name, metric_type: report_row}
for row_dict in report_model.row_dicts:
report_row = self.convert_c4_row_to_c5(short_c4_report_type, row_dict)
if report_row.total_count == 0: # Exclude rows with reporting total of 0
continue
if c4_major_report_type == MajorReportType.DATABASE:
if report_row.database.lower().startswith("total for all"): # Exclude total rows
continue
if (report_row.database, report_row.metric_type) not in report_rows_dict:
report_rows_dict[report_row.database, report_row.metric_type] = report_row
else:
existing_row: ReportRow = report_rows_dict[report_row.database, report_row.metric_type]
existing_metric_type_total = existing_row.total_count
new_metric_type_total = report_row.total_count
if existing_row.metric_type == "Total_Item_Investigations":
if new_metric_type_total > existing_metric_type_total:
report_rows_dict[report_row.database, report_row.metric_type] = report_row
elif c4_major_report_type == MajorReportType.TITLE:
if report_row.title.lower().startswith("total for all"): # Exclude total rows
continue
if (report_row.title, report_row.metric_type) not in report_rows_dict:
report_rows_dict[report_row.title, report_row.metric_type] = report_row
else:
existing_row: ReportRow = report_rows_dict[report_row.title, report_row.metric_type]
existing_metric_type_total = existing_row.total_count
new_metric_type_total = report_row.total_count
if existing_row.metric_type == "Total_Item_Investigations":
if new_metric_type_total > existing_metric_type_total:
report_rows_dict[report_row.title, report_row.metric_type] = report_row
elif c4_major_report_type == MajorReportType.PLATFORM:
report_rows_dict[report_row.platform, report_row.metric_type] = report_row
return list(report_rows_dict.values())
def convert_c4_row_to_c5(self, c4_report_type: str, row_dict: dict) -> ReportRow:
report_row = ReportRow(self.begin_date, self.end_date)
c4_major_report_type = self.get_c4_major_report_type(c4_report_type)
if c4_major_report_type == MajorReportType.DATABASE:
if "Database" in row_dict:
report_row.database = row_dict["Database"]
if "Publisher" in row_dict:
report_row.publisher = row_dict["Publisher"]
if "Platform" in row_dict:
report_row.platform = row_dict["Platform"]
# Metric type
if c4_report_type == "DB1":
if "User Activity" in row_dict:
ua = row_dict["User Activity"]
if ua == "Regular Searches":
report_row.metric_type = "Searches_Regular"
elif "federated and automated" in ua: # Searches-federated and automated
report_row.metric_type = "Searches_Automated"
elif ua == "Result Clicks" or ua == "Record Views":
report_row.metric_type = "Total_Item_Investigations"
elif c4_report_type == "DB2":
adc = None
if "Access Denied Category" in row_dict:
adc = row_dict["Access Denied Category"]
elif "Access denied category" in row_dict:
adc = row_dict["Access denied category"]
if adc:
if "limit exceded" in adc or "limit exceeded" in adc:
report_row.metric_type = "Limit_Exceeded"
elif "not licenced" in adc or "not licensed" in adc:
report_row.metric_type = "No_License"
elif c4_major_report_type == MajorReportType.TITLE:
if "" in row_dict:
report_row.title = row_dict[""]
if "Title" in row_dict:
report_row.title = row_dict["Title"]
if "Journal" in row_dict:
report_row.title = row_dict["Journal"]
if "Publisher" in row_dict:
report_row.publisher = row_dict["Publisher"]
if "Platform" in row_dict:
report_row.platform = row_dict["Publisher"]
if "Book DOI" in row_dict:
report_row.doi = row_dict["Book DOI"]
if "Journal DOI" in row_dict:
report_row.doi = row_dict["Journal DOI"]
if "Proprietary Identifier" in row_dict:
report_row.proprietary_id = row_dict["Proprietary Identifier"]
if "ISBN" in row_dict:
report_row.isbn = row_dict["ISBN"]
if "ISSN" in row_dict:
report_row.online_issn = row_dict["ISSN"]
if "Print ISSN" in row_dict:
report_row.print_issn = row_dict["Print ISSN"]
if "Online ISSN" in row_dict:
report_row.print_issn = row_dict["Online ISSN"]
# Metric type
if c4_report_type == "BR1":
report_row.metric_type = "Unique_Title_Requests"
elif c4_report_type == "BR2" or c4_report_type == "JR1":
report_row.metric_type = "Total_Item_Requests"
elif c4_report_type == "BR3" or c4_report_type == "JR2":
adc = None
if "Access Denied Category" in row_dict:
adc = row_dict["Access Denied Category"]
elif "Access denied category" in row_dict:
adc = row_dict["Access denied category"]
if adc:
if "limit exceded" in adc or "limit exceeded" in adc:
report_row.metric_type = "Limit_Exceeded"
elif "not licenced" in adc or "not licensed" in adc:
report_row.metric_type = "No_License"
elif c4_major_report_type == MajorReportType.PLATFORM:
if "Platform" in row_dict:
report_row.platform = row_dict["Platform"]
if "Publisher" in row_dict:
report_row.publisher = row_dict["Publisher"]
# Metric type
if c4_report_type == "PR1":
if "User Activity" in row_dict:
ua = row_dict["User Activity"]
if ua == "Regular Searches":
report_row.metric_type = "Searches_Regular"
elif ua == "Searches-federated and automated":
report_row.metric_type = "Searches_Automated"
elif ua == "Result Clicks" or ua == "Record Views":
report_row.metric_type = "Total_Item_Investigations"
if "Reporting Period Total" in row_dict:
if row_dict["Reporting Period Total"]:
report_row.total_count = int(row_dict["Reporting Period Total"])
else:
report_row.total_count = 0
# Month Columns
year = int(self.begin_date.toString("yyyy"))
year2 = int(self.begin_date.toString("yy"))
for i in range(0, 12):
month = QDate(year, i + 1, 1).toString("MMM")
month_year = f"{month}-{year}"
month_year2 = f"{month}-{year2}"
year_month = f"{year}-{month}"
year_month2 = f"{year2}-{month}"
month_value = ""
if month_year in row_dict:
month_value = row_dict[month_year]
elif month_year2 in row_dict:
month_value = row_dict[month_year2]
elif year_month in row_dict:
month_value = row_dict[year_month]
elif year_month2 in row_dict:
month_value = row_dict[year_month2]
if month_value:
report_row.month_counts[month_year] = int(month_value)
return report_row
def get_c5_report_header(self, target_c5_report_type, c4_report_types: str, customer: str,
institution_id: str) -> ReportHeaderModel:
return ReportHeaderModel(self.get_long_c5_report_type(target_c5_report_type),
target_c5_report_type,
"5",
customer,
[TypeValueModel("Institution_ID", institution_id)],
self.get_c5_header_report_filters(target_c5_report_type),
[],
[],
self.get_c5_header_created(),
self.get_c5_header_created_by(c4_report_types))
def create_c5_file(self, c5_report_header: ReportHeaderModel, report_rows: list) -> str:
c5_report_type = c5_report_header.report_id
file_path = self.save_dir + f"temp_converted_c5_file_{c5_report_type}.tsv"
if not path.isdir(self.save_dir):
makedirs(self.save_dir)
file = open(file_path, 'w', encoding="utf-8", newline='')
ReportWorker.add_report_header_to_file(c5_report_header, file, True)
ReportWorker.add_report_rows_to_file(c5_report_type, report_rows, self.begin_date, self.end_date,
file, False)
file.close()
return file_path
@staticmethod
def get_short_c4_report_type(long_c4_report_type: str) -> str:
short_report_type = ""
if "Book Report 1 (R4)" in long_c4_report_type:
short_report_type = "BR1"
elif "Book Report 2 (R4)" in long_c4_report_type:
short_report_type = "BR2"
elif "Book Report 3 (R4)" in long_c4_report_type:
short_report_type = "BR3"
elif "Database Report 1 (R4)" in long_c4_report_type:
short_report_type = "DB1"
elif "Database Report 2 (R4)" in long_c4_report_type:
short_report_type = "DB2"
elif "Journal Report 1 (R4)" in long_c4_report_type:
short_report_type = "JR1"
elif "Journal Report 2 (R4)" in long_c4_report_type:
short_report_type = "JR2"
elif "Platform Report 1 (R4)" in long_c4_report_type:
short_report_type = "PR1"
return short_report_type
@staticmethod
def get_long_c5_report_type(short_c5_report_type: str) -> str:
long_c5_report_type = ""
if short_c5_report_type == "DR":
long_c5_report_type = "Database Master Report"
elif short_c5_report_type == "DR_D1":
long_c5_report_type = "Database Search and Item Usage"
elif short_c5_report_type == "DR_D2":
long_c5_report_type = "Database Access Denied"
elif short_c5_report_type == "TR":
long_c5_report_type = "Title Master Report"
elif short_c5_report_type == "TR_B1":
long_c5_report_type = "Book Requests (Excluding OA_Gold)"
elif short_c5_report_type == "TR_B2":
long_c5_report_type = "Book Access Denied"
elif short_c5_report_type == "TR_J1":
long_c5_report_type = "Journal Requests (Excluding OA_Gold)"
elif short_c5_report_type == "TR_J2":
long_c5_report_type = "Journal Access Denied"
elif short_c5_report_type == "PR_P1":
long_c5_report_type = "Platform Usage"
return long_c5_report_type
def get_c5_header_report_filters(self, target_c5_report_type: str) -> list:
filters = []
if target_c5_report_type == "DR_D1":
filters = [NameValueModel("Access_Method", "Regular"),
NameValueModel("Metric_Type", "Searches_Automated|Searches_Federated|Searches_Regular|"
"Total_Item_Investigations|Total_Item_Requests")]
elif target_c5_report_type == "DR_D2":
filters = [NameValueModel("Access_Method", "Regular"),
NameValueModel("Metric_Type", "Limit_Exceeded|No_License")]
elif target_c5_report_type == "PR_P1":
filters = [NameValueModel("Access_Method", "Regular"),
NameValueModel("Metric_Type", "Searches_Platform|Total_Item_Requests|Unique_Item_Requests|"
"Unique_Title_Requests")]
elif target_c5_report_type == "TR_B1":
filters = [NameValueModel("Data_Type", "Book"),
NameValueModel("Access_Type", "Controlled"),
NameValueModel("Access_Method", "Regular"),
NameValueModel("Metric_Type", "Total_Item_Requests|Unique_Title_Requests")]
elif target_c5_report_type == "TR_B2":
filters = [NameValueModel("Data_Type", "Book"),
NameValueModel("Access_Method", "Regular"),
NameValueModel("Metric_Type", "Limit_Exceeded|No_License")]
elif target_c5_report_type == "TR_J1":
filters = [NameValueModel("Data_Type", "Journal"),
NameValueModel("Access_Type", "Controlled"),
NameValueModel("Access_Method", "Regular"),
NameValueModel("Metric_Type", "Total_Item_Requests|Unique_Item_Requests")]
elif target_c5_report_type == "TR_J2":
filters = [NameValueModel("Data_Type", "Journal"),
NameValueModel("Access_Method", "Regular"),
NameValueModel("Metric_Type", "Limit_Exceeded|No_License")]
filters += [NameValueModel("Begin_Date", self.begin_date.toString("yyyy-MM-dd")),
NameValueModel("End_Date", self.end_date.toString("yyyy-MM-dd"))]
return filters
@staticmethod
def get_c5_header_created() -> str:
return datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
def get_c5_header_created_by(self, short_c4_report_type: str) -> str:
return f"COUNTER 5 Report Tool, converted from {self.vendor.name} COP4 {short_c4_report_type}"
@staticmethod
def get_c5_equivalent(counter4_report_type: str) -> str:
return COUNTER_4_REPORT_EQUIVALENTS[counter4_report_type]
@staticmethod
def get_c4_equivalent(counter5_report_type: str) -> str:
return COUNTER_5_REPORT_EQUIVALENTS[counter5_report_type]
@staticmethod
def get_c4_major_report_type(c4_report_type: str) -> MajorReportType:
"""Returns a major report type that a report type falls under"""
if c4_report_type == "DB1" or c4_report_type == "DB2":
return MajorReportType.DATABASE
elif c4_report_type == "BR1" or c4_report_type == "BR2" or c4_report_type == "BR3" \
or c4_report_type == "JR1" or c4_report_type == "JR2":
return MajorReportType.TITLE
elif c4_report_type == "PR1":
return MajorReportType.PLATFORM

108
FetchData.py

@ -191,7 +191,7 @@ class ReportModel(JsonModel):
report_header = ReportHeaderModel.from_json(json_dict["Report_Header"])
report_type = report_header.report_id
major_report_type = get_major_report_type(report_type)
major_report_type = GeneralUtils.get_major_report_type(report_type)
report_header.major_report_type = major_report_type
report_items = []
@ -509,23 +509,6 @@ def get_models(model_key: str, model_type, json_dict: dict) -> list:
return models
def get_major_report_type(report_type: str) -> MajorReportType:
"""Returns a major report type that a report type falls under"""
if report_type == "PR" or report_type == "PR_P1":
return MajorReportType.PLATFORM
elif report_type == "DR" or report_type == "DR_D1" or report_type == "DR_D2":
return MajorReportType.DATABASE
elif report_type == "TR" or report_type == "TR_B1" or report_type == "TR_B2" \
or report_type == "TR_B3" or report_type == "TR_J1" or report_type == "TR_J2" \
or report_type == "TR_J3" or report_type == "TR_J4":
return MajorReportType.TITLE
elif report_type == "IR" or report_type == "IR_A1" or report_type == "IR_M1":
return MajorReportType.ITEM
def get_month_years(begin_date: QDate, end_date: QDate) -> list:
"""Returns a list of month-year (MMM-yyyy) strings within a date range"""
month_years = []
@ -623,19 +606,6 @@ class ReportRow:
self.month_counts = {}
# This only works with 12 months
# for i in range(12):
# curr_date: QDate
# if QDate(begin_date.year(), i + 1, 1) < begin_date:
# curr_date = QDate(end_date.year(), i + 1, 1)
# else:
# curr_date = QDate(begin_date.year(), i + 1, 1)
#
# self.month_counts[curr_date.toString("MMM-yyyy")] = 0
#
# self.total_count = 0
# This works with more than 12 months
for month_year_str in get_month_years(begin_date, end_date):
self.month_counts[month_year_str] = 0
@ -1513,18 +1483,8 @@ class FetchSpecialReportsController(FetchReportsAbstract):
"""
if date_type == "begin_date":
self.begin_date = QDate(date.year(),self.begin_date.month(),self.begin_date.day())
# if self.begin_date.year() != self.end_date.year():
# self.end_date.setDate(self.begin_date.year(),
# self.end_date.month(),
# self.end_date.day())
# self.end_date_edit.setDate(self.end_date)
elif date_type == "end_date":
self.end_date = QDate(date.year(),self.end_date.month(),self.end_date.day())
# if self.end_date.year() != self.begin_date.year():
# self.begin_date.setDate(self.end_date.year(),
# self.begin_date.month(),
# self.begin_date.day())
# self.begin_date_edit.setDate(self.begin_date)
def on_date_month_changed(self, month: int, date_type: str):
"""Handles the signal emitted when a date's month is changed
@ -2068,7 +2028,7 @@ class ReportWorker(QObject):
attributes_to_show += f"|{option_name}"
attr_count += 1
elif self.is_yearly and self.is_master:
major_report_type = get_major_report_type(self.report_type)
major_report_type = GeneralUtils.get_major_report_type(self.report_type)
if major_report_type == MajorReportType.PLATFORM:
attributes_to_show = "|".join(PLATFORM_REPORTS_ATTRIBUTES)
elif major_report_type == MajorReportType.DATABASE:
@ -2460,7 +2420,8 @@ class ReportWorker(QObject):
report_rows = self.sort_rows(report_rows, major_report_type)
self.save_tsv_files(report_model.report_header, report_rows)
def sort_rows(self, report_rows: list, major_report_type: MajorReportType) -> list:
@staticmethod
def sort_rows(report_rows: list, major_report_type: MajorReportType) -> list:
"""Sorts the rows of the report
:param report_rows: The report's rows
@ -2507,7 +2468,8 @@ class ReportWorker(QObject):
else:
self.add_report_header_to_file(report_header, file, True)
if not self.add_report_rows_to_file(report_type, report_rows, file, False):
if not self.add_report_rows_to_file(report_type, report_rows, self.begin_date, self.end_date, file, False,
self.is_special, self.special_options):
self.process_result.completion_status = CompletionStatus.WARNING
file.close()
@ -2528,12 +2490,13 @@ class ReportWorker(QObject):
protected_file_path = f"{protected_file_dir}{file_name}"
protected_file = open(protected_file_path, 'w', encoding="utf-8", newline='')
self.add_report_header_to_file(report_header, protected_file, True)
self.add_report_rows_to_file(report_type, report_rows, protected_file, True)
self.add_report_rows_to_file(report_type, report_rows, self.begin_date, self.end_date, protected_file, True)
protected_file.close()
self.process_result.protected_file_path = protected_file_path
def add_report_header_to_file(self, report_header: ReportHeaderModel, file, include_attributes: bool):
@staticmethod
def add_report_header_to_file(report_header: ReportHeaderModel, file, include_attributes: bool):
"""Adds the report header to a TSV file
:param report_header: The report header model
@ -2580,21 +2543,28 @@ class ReportWorker(QObject):
tsv_writer.writerow(["Created_By", report_header.created_by])
tsv_writer.writerow([])
def add_report_rows_to_file(self, report_type: str, report_rows: list, file, include_all_attributes: bool) -> bool:
@staticmethod
def add_report_rows_to_file(report_type: str, report_rows: list, begin_date: QDate, end_date: QDate, file,
include_all_attributes: bool, is_special: bool = False,
special_options: SpecialReportOptions = None) -> bool:
"""Adds the report's rows to a TSV file
:param report_type: The report type
:param report_rows: The report's rows
:param begin_date: The first date in the report
:param end_date: The last date in the report
:param file: The TSV file to write to
:param include_all_attributes: Option to include all possible attributes for this report type to the report
:param is_special: If this is a special report
:param special_options: The special options if this is a special report
"""
column_names = []
row_dicts = []
if report_type == "PR":
column_names += ["Platform"]
if self.is_special:
special_options_dict = self.special_options.__dict__
if is_special:
special_options_dict = special_options.__dict__
if special_options_dict["data_type"][0]: column_names.append("Data_Type")
if special_options_dict["access_method"][0]: column_names.append("Access_Method")
elif include_all_attributes:
@ -2604,8 +2574,8 @@ class ReportWorker(QObject):
row: ReportRow
for row in report_rows:
row_dict = {"Platform": row.platform}
if self.is_special:
special_options_dict = self.special_options.__dict__
if is_special:
special_options_dict = special_options.__dict__
if special_options_dict["data_type"][0]: row_dict["Data_Type"] = row.data_type
if special_options_dict["access_method"][0]: row_dict["Access_Method"] = row.access_method
@ -2635,8 +2605,8 @@ class ReportWorker(QObject):
elif report_type == "DR":
column_names += ["Database", "Publisher", "Publisher_ID", "Platform", "Proprietary_ID"]
if self.is_special:
special_options_dict = self.special_options.__dict__
if is_special:
special_options_dict = special_options.__dict__
if special_options_dict["data_type"][0]: column_names.append("Data_Type")
if special_options_dict["access_method"][0]: column_names.append("Access_Method")
elif include_all_attributes:
@ -2651,8 +2621,8 @@ class ReportWorker(QObject):
"Platform": row.platform,
"Proprietary_ID": row.proprietary_id}
if self.is_special:
special_options_dict = self.special_options.__dict__
if is_special:
special_options_dict = special_options.__dict__
if special_options_dict["data_type"][0]: row_dict["Data_Type"] = row.data_type
if special_options_dict["access_method"][0]: row_dict["Access_Method"] = row.access_method
@ -2687,8 +2657,8 @@ class ReportWorker(QObject):
elif report_type == "TR":
column_names += ["Title", "Publisher", "Publisher_ID", "Platform", "DOI", "Proprietary_ID", "ISBN",
"Print_ISSN", "Online_ISSN", "URI"]
if self.is_special:
special_options_dict = self.special_options.__dict__
if is_special:
special_options_dict = special_options.__dict__
if special_options_dict["data_type"][0]: column_names.append("Data_Type")
if special_options_dict["section_type"][0]: column_names.append("Section_Type")
if special_options_dict["yop"][0]: column_names.append("YOP")
@ -2714,8 +2684,8 @@ class ReportWorker(QObject):
"Online_ISSN": row.online_issn,
"URI": row.uri}
if self.is_special:
special_options_dict = self.special_options.__dict__
if is_special:
special_options_dict = special_options.__dict__
if special_options_dict["data_type"][0]: row_dict["Data_Type"] = row.data_type
if special_options_dict["section_type"][0]: row_dict["Section_Type"] = row.section_type
if special_options_dict["yop"][0]: row_dict["YOP"] = row.yop
@ -2851,8 +2821,8 @@ class ReportWorker(QObject):
elif report_type == "IR":
column_names += ["Item", "Publisher", "Publisher_ID", "Platform"]
if self.is_special:
special_options_dict = self.special_options.__dict__
if is_special:
special_options_dict = special_options.__dict__
if special_options_dict["authors"][0]: column_names.append("Authors")
if special_options_dict["publication_date"][0]: column_names.append("Publication_Date")
if special_options_dict["article_version"][0]: column_names.append("Article_version")
@ -2861,8 +2831,8 @@ class ReportWorker(QObject):
column_names.append("Publication_Date")
column_names.append("Article_version")
column_names += ["DOI", "Proprietary_ID", "ISBN", "Print_ISSN", "Online_ISSN", "URI"]
if self.is_special:
special_options_dict = self.special_options.__dict__
if is_special:
special_options_dict = special_options.__dict__
if special_options_dict["include_parent_details"][0]:
column_names += ["Parent_Title", "Parent_Authors", "Parent_Publication_Date",
"Parent_Article_Version", "Parent_Data_Type", "Parent_DOI",
@ -2901,8 +2871,8 @@ class ReportWorker(QObject):
"Online_ISSN": row.online_issn,
"URI": row.uri}
if self.is_special:
special_options_dict = self.special_options.__dict__
if is_special:
special_options_dict = special_options.__dict__
if special_options_dict["authors"][0]: row_dict["Authors"] = row.authors
if special_options_dict["publication_date"][0]: row_dict["Publication_Date"] = row.publication_date
if special_options_dict["article_version"][0]: row_dict["Article_version"] = row.article_version
@ -3028,12 +2998,12 @@ class ReportWorker(QObject):
column_names += ["Metric_Type", "Reporting_Period_Total"]
if self.is_special:
special_options_dict = self.special_options.__dict__
if is_special:
special_options_dict = special_options.__dict__
if not special_options_dict["exclude_monthly_details"][0]:
column_names += get_month_years(self.begin_date, self.end_date)
column_names += get_month_years(begin_date, end_date)
else:
column_names += get_month_years(self.begin_date, self.end_date)
column_names += get_month_years(begin_date, end_date)
tsv_dict_writer = csv.DictWriter(file, column_names, delimiter='\t')
tsv_dict_writer.writeheader()

35
GeneralUtils.py

@ -7,6 +7,7 @@ from typing import Sequence, Any
from os import path, makedirs, system
from PyQt5.QtWidgets import QWidget, QMessageBox, QFileDialog
from PyQt5.QtCore import QDate
from Constants import *
main_window: QWidget = None
@ -66,7 +67,7 @@ def open_file_or_dir(target_path: str):
def choose_file(name_filters) -> str:
file_path = ""
dialog = QFileDialog(main_window, directory=".")
dialog = QFileDialog(main_window)
dialog.setFileMode(QFileDialog.ExistingFile)
dialog.setNameFilters(name_filters)
if dialog.exec_():
@ -75,9 +76,20 @@ def choose_file(name_filters) -> str:
return file_path
def choose_files(name_filters) -> list:
file_paths = []
dialog = QFileDialog(main_window)
dialog.setFileMode(QFileDialog.ExistingFiles)
dialog.setNameFilters([x for x in name_filters])
if dialog.exec_():
file_paths = dialog.selectedFiles()
return file_paths
def choose_directory() -> str:
dir_path = ""
dialog = QFileDialog(main_window, directory=".")
dialog = QFileDialog(main_window)
dialog.setFileMode(QFileDialog.Directory)
if dialog.exec_():
dir_path = dialog.selectedFiles()[0] + "/"
@ -87,7 +99,7 @@ def choose_directory() -> str:
def choose_save(name_filters) -> str:
file_path = ""
dialog = QFileDialog(main_window, directory=".")
dialog = QFileDialog(main_window)
dialog.setFileMode(QFileDialog.AnyFile)
dialog.setAcceptMode(QFileDialog.AcceptSave)
dialog.setNameFilters(name_filters)
@ -125,6 +137,23 @@ def get_other_file_name(vendor_name: str, report_type: str, begin_date: QDate, e
return f"{vendor_name}_{report_type}_{begin_date.toString('yyyy-MMM')}_{end_date.toString('yyyy-MMM')}.tsv"
def get_major_report_type(report_type: str) -> MajorReportType:
"""Returns a major report type that a report type falls under"""
if report_type == "PR" or report_type == "PR_P1":
return MajorReportType.PLATFORM
elif report_type == "DR" or report_type == "DR_D1" or report_type == "DR_D2":
return MajorReportType.DATABASE
elif report_type == "TR" or report_type == "TR_B1" or report_type == "TR_B2" \
or report_type == "TR_B3" or report_type == "TR_J1" or report_type == "TR_J2" \
or report_type == "TR_J3" or report_type == "TR_J4":
return MajorReportType.TITLE
elif report_type == "IR" or report_type == "IR_A1" or report_type == "IR_M1":
return MajorReportType.ITEM
def save_data_as_tsv(file_name: str, data: Sequence[Any]):
"""Saves data in a TSV file

274
ImportFile.py

@ -4,17 +4,19 @@ import shutil
import platform
import ctypes
import csv
from tempfile import TemporaryDirectory
from os import path, makedirs
from PyQt5.QtCore import QModelIndex, QDate, Qt
from PyQt5.QtWidgets import QWidget, QDialog, QDialogButtonBox
from PyQt5.QtCore import QDate, Qt
from PyQt5.QtWidgets import QWidget, QDialog, QDialogButtonBox, QLabel
from PyQt5.QtGui import QStandardItemModel, QStandardItem
from PyQt5 import QtWidgets
import GeneralUtils
from Constants import *
from Counter4 import Counter4To5Converter
from ui import ImportReportTab, ReportResultWidget
from ManageVendors import Vendor
from FetchData import ALL_REPORTS, CompletionStatus
from FetchData import CompletionStatus
from Settings import SettingsModel
from ManageDB import UpdateDatabaseWorker
@ -25,6 +27,7 @@ class ProcessResult:
:param vendor: The target vendor
:param report_type: The target report type
"""
def __init__(self, vendor: Vendor, report_type: str):
self.vendor = vendor
self.report_type = report_type
@ -35,6 +38,10 @@ class ProcessResult:
self.file_path = ""
def get_c5_equivalent(counter4_report_type: str) -> str:
return COUNTER_4_REPORT_EQUIVALENTS[counter4_report_type]
class ImportReportController:
"""Controls the Import Report tab
@ -43,6 +50,7 @@ class ImportReportController:
:param import_report_widget: The import report widget.
:param import_report_ui: The UI for the import_report_widget.
"""
def __init__(self, vendors: list, settings: SettingsModel, import_report_widget: QWidget,
import_report_ui: ImportReportTab.Ui_import_report_tab):
@ -51,43 +59,75 @@ class ImportReportController:
self.vendors = vendors
self.date = QDate.currentDate()
self.selected_vendor_index = -1
self.selected_report_type_index = -1
self.selected_file_path: str = ""
self.selected_c5_report_type_index = -1
self.selected_c4_report_type_index = -1
self.c5_selected_file_path: str = ""
self.c4_selected_file_paths: list = []
self.settings = settings
self.result_dialog = None
# endregion
# region Vendors
self.vendor_list_view = import_report_ui.vendors_list_view_import
self.vendor_list_model = QStandardItemModel(self.vendor_list_view)
self.vendor_list_view.setModel(self.vendor_list_model)
self.vendor_list_view.clicked.connect(self.on_vendor_selected)
self.vendor_combo_box = import_report_ui.vendor_combo_box
self.vendor_list_model = QStandardItemModel(self.vendor_combo_box)
self.vendor_combo_box.setModel(self.vendor_list_model)
self.vendor_combo_box.currentIndexChanged.connect(self.on_vendor_selected)
self.update_vendors_ui()
self.selected_vendor_index = self.vendor_combo_box.currentIndex()
# endregion
# region Report Types
self.report_type_list_view = import_report_ui.report_types_list_view_import
self.report_type_list_model = QStandardItemModel(self.report_type_list_view)
self.report_type_list_view.setModel(self.report_type_list_model)
self.report_type_list_view.clicked.connect(self.on_report_type_selected)
# region Counter 5
self.c5_report_type_combo_box = import_report_ui.c5_report_type_combo_box
self.c5_report_type_model = QStandardItemModel(self.c5_report_type_combo_box)
self.c5_report_type_combo_box.setModel(self.c5_report_type_model)
self.c5_report_type_combo_box.currentIndexChanged.connect(self.on_c5_report_type_selected)
for report_type in ALL_REPORTS:
item = QStandardItem(report_type)
item.setEditable(False)
self.report_type_list_model.appendRow(item)
self.c5_report_type_model.appendRow(item)
self.selected_c5_report_type_index = self.c5_report_type_combo_box.currentIndex()
self.c5_select_file_btn = import_report_ui.c5_select_file_button
self.c5_select_file_btn.clicked.connect(self.on_c5_select_file_clicked)
self.c5_selected_file_edit = import_report_ui.c5_selected_file_edit
self.c5_import_report_button = import_report_ui.c5_import_report_button
self.c5_import_report_button.clicked.connect(self.on_c5_import_clicked)
# endregion
# region Others
self.year_date_edit = import_report_ui.report_year_date_edit
self.year_date_edit.setDate(self.date)
self.year_date_edit.dateChanged.connect(self.on_date_changed)
# region Counter 4
self.c4_report_type_combo_box = import_report_ui.c4_report_type_combo_box
self.c4_report_type_model = QStandardItemModel(self.c4_report_type_combo_box)
self.c4_report_type_combo_box.setModel(self.c4_report_type_model)
self.c4_report_type_combo_box.currentIndexChanged.connect(self.on_c4_report_type_selected)
self.c4_report_type_equiv_label = import_report_ui.c4_report_type_equiv_label
self.select_file_btn = import_report_ui.select_file_button
self.select_file_btn.clicked.connect(self.on_select_file_clicked)
for report_type in COUNTER_4_REPORT_EQUIVALENTS.keys():
item = QStandardItem(report_type)
item.setEditable(False)
self.c4_report_type_model.appendRow(item)
self.selected_c4_report_type_index = self.c4_report_type_combo_box.currentIndex()
self.c4_report_type_equiv_label.setText(get_c5_equivalent(self.c4_report_type_combo_box.currentText()))
self.selected_file_edit = import_report_ui.selected_file_edit
self.c4_select_file_btn = import_report_ui.c4_select_file_button
self.c4_select_file_btn.clicked.connect(self.on_c4_select_file_clicked)
self.c4_selected_files_frame = import_report_ui.c4_selected_files_frame
self.c4_selected_files_frame_layout = self.c4_selected_files_frame.layout()
self.c4_import_report_button = import_report_ui.c4_import_report_button
self.c4_import_report_button.clicked.connect(self.on_c4_import_clicked)
self.import_report_button = import_report_ui.import_report_button
self.import_report_button.clicked.connect(self.on_import_clicked)
# endregion
# region Date
self.year_date_edit = import_report_ui.report_year_date_edit
self.year_date_edit.setDate(self.date)
self.year_date_edit.dateChanged.connect(self.on_date_changed)
# endregion
def on_vendors_changed(self, vendors: list):
@ -95,9 +135,9 @@ class ImportReportController:
:param vendors: An updated list of the system's vendors
"""
self.selected_vendor_index = -1
self.update_vendors(vendors)
self.update_vendors_ui()
self.selected_vendor_index = self.vendor_combo_box.currentIndex()
def update_vendors(self, vendors: list):
""" Updates the local copy of vendors that support report import
@ -114,54 +154,135 @@ class ImportReportController:
item.setEditable(False)
self.vendor_list_model.appendRow(item)
def on_vendor_selected(self, model_index: QModelIndex):
def on_vendor_selected(self, index: int):
"""Handles the signal emitted when a vendor is selected"""
self.selected_vendor_index = model_index.row()
self.selected_vendor_index = index
def on_report_type_selected(self, model_index: QModelIndex):
def on_c5_report_type_selected(self, index: int):
"""Handles the signal emitted when a report type is selected"""
self.selected_report_type_index = model_index.row()
self.selected_c5_report_type_index = index
def on_c4_report_type_selected(self, index: int):
"""Handles the signal emitted when a report type is selected"""
self.selected_c4_report_type_index = index
self.c4_report_type_equiv_label.setText(get_c5_equivalent(self.c4_report_type_combo_box.currentText()))
def on_date_changed(self, date: QDate):
"""Handles the signal emitted when the target date is changed"""
self.date = date
def on_select_file_clicked(self):
def on_c5_select_file_clicked(self):
"""Handles the signal emitted when the select file button is clicked"""
file_path = GeneralUtils.choose_file(TSV_FILTER + CSV_FILTER)
if file_path:
self.selected_file_path = file_path
self.selected_file_edit.setText(file_path)
self.c5_selected_file_path = file_path
file_name = file_path.split("/")[-1]
self.c5_selected_file_edit.setText(file_name)
def on_import_clicked(self):
def on_c4_select_file_clicked(self):
"""Handles the signal emitted when the select file button is clicked"""
file_paths = GeneralUtils.choose_files(TSV_AND_CSV_FILTER)
if file_paths:
self.c4_selected_file_paths = file_paths
file_names = [file_path.split("/")[-1] for file_path in file_paths]
# Remove existing options from ui
for i in reversed(range(self.c4_selected_files_frame_layout.count())):
widget = self.c4_selected_files_frame_layout.itemAt(i).widget()
# remove it from the layout list
self.c4_selected_files_frame_layout.removeWidget(widget)
# remove it from the gui
widget.deleteLater()
# Add new file names
for file_name in file_names:
label = QLabel(file_name)
self.c4_selected_files_frame_layout.addWidget(label)
def on_c5_import_clicked(self):
"""Handles the signal emitted when the import button is clicked"""
if self.selected_vendor_index == -1:
GeneralUtils.show_message("Select a vendor")
return
elif self.selected_report_type_index == -1:
elif self.selected_c5_report_type_index == -1:
GeneralUtils.show_message("Select a report type")
return
elif self.selected_file_path == "":
elif self.c5_selected_file_path == "":
GeneralUtils.show_message("Select a file")
return
vendor = self.vendors[self.selected_vendor_index]
report_type = ALL_REPORTS[self.selected_report_type_index]
report_type = ALL_REPORTS[self.selected_c5_report_type_index]
process_result = self.import_report(vendor, report_type)
self.show_result(process_result)
process_result = self.import_report(vendor, report_type, self.c5_selected_file_path)
self.show_results([process_result])
def on_c4_import_clicked(self):
"""Handles the signal emitted when the import button is clicked"""
if self.selected_vendor_index == -1:
GeneralUtils.show_message("Select a vendor")
return
elif not self.c4_selected_file_paths:
GeneralUtils.show_message("Select a file")
return
def import_report(self, vendor: Vendor, report_type: str) -> ProcessResult:
vendor = self.vendors[self.selected_vendor_index]
report_types = get_c5_equivalent(self.c4_report_type_combo_box.currentText())
# Check if target C5 file already exists
existing_report_types = []
for report_type in report_types.split(", "):
if self.check_if_c5_report_exists(vendor.name, report_type):
existing_report_types.append(report_type)
# Confirm overwrite
if existing_report_types:
if not GeneralUtils.ask_confirmation(f"COUNTER 5 [{', '.join(existing_report_types)}] already exist in the "
"database for this vendor, do you want to overwrite them?"):
return
with TemporaryDirectory("") as dir_path:
converter = Counter4To5Converter(self.vendors[self.selected_vendor_index],
self.c4_report_type_combo_box.currentText(),
self.c4_selected_file_paths,
dir_path + path.sep,
self.year_date_edit.date())
try:
c5_file_paths = converter.do_conversion()
except Exception as e:
process_result = ProcessResult(vendor, report_types)
process_result.completion_status = CompletionStatus.FAILED
process_result.message = "Error converting file. " + str(e)
self.show_results([process_result])
return
if not c5_file_paths: # If nothing was processed
process_result = ProcessResult(vendor, report_types)
process_result.completion_status = CompletionStatus.FAILED
process_result.message = "No COUNTER 5 report was created, make sure the COUNTER 4 input files are " \
"correct"
self.show_results([process_result])
return
process_results = []
for report_type in c5_file_paths:
file_path = c5_file_paths[report_type]
process_result = self.import_report(vendor, report_type, file_path)
process_results.append(process_result)
self.show_results(process_results)
def import_report(self, vendor: Vendor, report_type: str, origin_file_path: str) -> ProcessResult:
""" Imports the selected file using the selected parameters
:param vendor: The target vendor
:param report_type: The target report type
:param origin_file_path: The path of the file to be imported
:raises Exception: If anything goes wrong while importing the report
"""
process_result = ProcessResult(vendor, report_type)
try:
dest_file_dir = GeneralUtils.get_yearly_file_dir(self.settings.yearly_directory, vendor.name, self.date)
dest_file_name = GeneralUtils.get_yearly_file_name(vendor.name, report_type, self.date)
dest_file_path = f"{dest_file_dir}{dest_file_name}"
@ -171,8 +292,8 @@ class ImportReportController:
makedirs(dest_file_dir)
# Validate report header
delimiter = DELIMITERS[self.selected_file_path[-4:].lower()]
file = open(self.selected_file_path, 'r', encoding='utf-8-sig')
delimiter = DELIMITERS[origin_file_path[-4:].lower()]
file = open(origin_file_path, 'r', encoding='utf-8-sig')
reader = csv.reader(file, delimiter=delimiter, quotechar='\"')
if file.mode == 'r':
header = {}
@ -199,7 +320,7 @@ class ImportReportController:
raise Exception('Could not open file')
# Copy selected_file_path to dest_file_path
self.copy_file(self.selected_file_path, dest_file_path)
self.copy_file(origin_file_path, dest_file_path)
process_result.file_dir = dest_file_dir
process_result.file_name = dest_file_name
@ -214,7 +335,7 @@ class ImportReportController:
ctypes.windll.kernel32.SetFileAttributesW(PROTECTED_DATABASE_FILE_DIR, 2) # Hide folder
protected_file_path = f"{protected_file_dir}{dest_file_name}"
self.copy_file(self.selected_file_path, protected_file_path)
self.copy_file(origin_file_path, protected_file_path)
# Add file to database
database_worker = UpdateDatabaseWorker([{'file': protected_file_path,
@ -229,56 +350,63 @@ class ImportReportController:
return process_result
def check_if_c5_report_exists(self, vendor_name, report_type) -> bool:
protected_file_dir = f"{PROTECTED_DATABASE_FILE_DIR}{self.date.toString('yyyy')}/{vendor_name}/"
protected_file_name = GeneralUtils.get_yearly_file_name(vendor_name, report_type, self.date)
protected_file_path = f"{protected_file_dir}{protected_file_name}"
return path.isfile(protected_file_path)
def copy_file(self, origin_path: str, dest_path: str):
"""Copies a file from origin_path to dest_path"""
shutil.copy2(origin_path, dest_path)
def show_result(self, process_result: ProcessResult):
def show_results(self, process_results: list):
"""Shows the result of the import process to the user
:param process_result: The result of the import process
:param process_results: The results of the import process
"""
self.result_dialog = QDialog(self.import_report_widget, flags=Qt.WindowCloseButtonHint)
self.result_dialog.setWindowTitle("Import Result")
vertical_layout = QtWidgets.QVBoxLayout(self.result_dialog)
vertical_layout.setContentsMargins(5, 5, 5, 5)
report_result_widget = QWidget(self.result_dialog)
report_result_ui = ReportResultWidget.Ui_ReportResultWidget()
report_result_ui.setupUi(report_result_widget)
for process_result in process_results:
report_result_widget = QWidget(self.result_dialog)
report_result_ui = ReportResultWidget.Ui_ReportResultWidget()
report_result_ui.setupUi(report_result_widget)
button_box = QtWidgets.QDialogButtonBox(QDialogButtonBox.Ok, self.result_dialog)
button_box.setCenterButtons(True)
button_box.accepted.connect(self.result_dialog.accept)
vendor = process_result.vendor
report_type = process_result.report_type
vendor = process_result.vendor
report_type = process_result.report_type
report_result_ui.report_type_label.setText(f"{vendor.name} - {report_type}")
report_result_ui.success_label.setText(process_result.completion_status.value)
report_result_ui.report_type_label.setText(f"{vendor.name} - {report_type}")
report_result_ui.success_label.setText(process_result.completion_status.value)
if process_result.completion_status == CompletionStatus.SUCCESSFUL:
report_result_ui.message_label.hide()
report_result_ui.retry_frame.hide()
if process_result.completion_status == CompletionStatus.SUCCESSFUL:
report_result_ui.message_label.hide()
report_result_ui.retry_frame.hide()
report_result_ui.file_label.setText(f"Saved as: {process_result.file_name}")
report_result_ui.file_label.mousePressEvent = \
lambda event, file_path = process_result.file_path: GeneralUtils.open_file_or_dir(file_path)
report_result_ui.file_label.setText(f"Saved as: {process_result.file_name}")
report_result_ui.file_label.mousePressEvent = \
lambda event: GeneralUtils.open_file_or_dir(process_result.file_path)
report_result_ui.folder_button.clicked.connect(
lambda: GeneralUtils.open_file_or_dir(process_result.file_dir))
report_result_ui.folder_button.clicked.connect(
lambda: GeneralUtils.open_file_or_dir(process_result.file_dir))
report_result_ui.success_label.setText("Successful!")
report_result_ui.retry_frame.hide()
report_result_ui.success_label.setText("Successful!")
report_result_ui.retry_frame.hide()
elif process_result.completion_status == CompletionStatus.FAILED:
report_result_ui.file_frame.hide()
report_result_ui.retry_frame.hide()
elif process_result.completion_status == CompletionStatus.FAILED:
report_result_ui.file_frame.hide()
report_result_ui.retry_frame.hide()
report_result_ui.message_label.setText(process_result.message)
report_result_ui.message_label.setText(process_result.message)
vertical_layout.addWidget(report_result_widget)
vertical_layout.addWidget(report_result_widget)
button_box = QtWidgets.QDialogButtonBox(QDialogButtonBox.Ok, self.result_dialog)
button_box.setCenterButtons(True)
button_box.accepted.connect(self.result_dialog.accept)
vertical_layout.addWidget(button_box)
self.result_dialog.show()
self.result_dialog.show()

16
ManageDB.py

@ -398,7 +398,7 @@ def read_report_file(file_name: str, vendor: str, year: int) -> Union[Tuple[str,
:param vendor: the vendor name of the data in the file
:param year: the year of the data in the file
:returns: (file_name, report, values) a Tuple with the file name, the kind of report, and the data from the file"""
if ManageDBSettingsHandler.settings.show_debug_messages: print('READ ' + file_name)
# if ManageDBSettingsHandler.settings.show_debug_messages: print('READ ' + file_name)
delimiter = DELIMITERS[file_name[-4:].lower()]
file = open(file_name, 'r', encoding='utf-8-sig')
reader = csv.reader(file, delimiter=delimiter, quotechar='\"')
@ -411,13 +411,13 @@ def read_report_file(file_name: str, vendor: str, year: int) -> Union[Tuple[str,
header[key] = cells[1].strip()
else:
header[key] = None
if ManageDBSettingsHandler.settings.show_debug_messages: print(header)
# if ManageDBSettingsHandler.settings.show_debug_messages: print(header)
for row in range(BLANK_ROWS):
next(reader)
column_headers = next(reader)
column_headers = list(map((lambda column_header: column_header.lower()),
column_headers)) # reads column headers
if ManageDBSettingsHandler.settings.show_debug_messages: print(column_headers)
# if ManageDBSettingsHandler.settings.show_debug_messages: print(column_headers)
values = []
for cells in list(reader):
for month in MONTHS: # makes value from each month with metric > 0 for each row
@ -458,7 +458,7 @@ def read_costs_file(file_name: str) -> Union[Sequence[Dict[str, Any]], None]:
column_headers = next(reader)
column_headers = list(map((lambda column_header: column_header.lower()),
column_headers)) # reads column headers
if ManageDBSettingsHandler.settings.show_debug_messages: print(column_headers)
# if ManageDBSettingsHandler.settings.show_debug_messages: print(column_headers)
values = []
for cells in list(reader):
value = {}
@ -843,9 +843,9 @@ def run_sql(connection: sqlite3.Connection, sql_text: str, data: Sequence[Sequen
:param emit_signal: whether to emit a signal upon completion"""
try:
cursor = connection.cursor()
if ManageDBSettingsHandler.settings.show_debug_messages: print(sql_text)
# if ManageDBSettingsHandler.settings.show_debug_messages: print(sql_text)
if data is not None:
if ManageDBSettingsHandler.settings.show_debug_messages: print(data)
# if ManageDBSettingsHandler.settings.show_debug_messages: print(data)
cursor.executemany(sql_text, data)
else:
cursor.execute(sql_text)
@ -866,9 +866,9 @@ def run_select_sql(connection: sqlite3.Connection, sql_text: str, data: Sequence
:returns: a list of rows that return from the statement"""
try:
cursor = connection.cursor()
if ManageDBSettingsHandler.settings.show_debug_messages: print(sql_text)
# if ManageDBSettingsHandler.settings.show_debug_messages: print(sql_text)
if data is not None:
if ManageDBSettingsHandler.settings.show_debug_messages: print(data)
# if ManageDBSettingsHandler.settings.show_debug_messages: print(data)
cursor.execute(sql_text, data)
else:
cursor.execute(sql_text)

8
README.md

@ -19,7 +19,7 @@ The project is written with Python 3.7. The PyQt GUI framework is used to create
- Urvesh Boodhun uboodhun@upei.ca
- Ziheng Huang Zihhuang@upei.ca
## Download Project
## Download Project
https://github.com/CS-4820-Library-Project/COUNTER-5-Report-Tool/releases
## Developer Documentation
@ -37,9 +37,9 @@ https://github.com/CS-4820-Library-Project/COUNTER-5-Report-Tool/blob/master/doc
- Click Browse
- Browse to where python is downloaded, by default: C:\Users\USER_NAME\AppData\Local\Programs\Python\Python38
- Add another variable in the same way that we just did.
- Add another variable in the same way that we just did.
- Except this time set the filepath to C:\Users\apjm4\AppData\Local\Programs\Python\Python38\Scripts
Python should now be accessible in Windows Command Prompt.
Python should now be accessible in Windows Command Prompt.
Open command prompt and type Python --version. This should return the version of python that is installed.
If not the path may be wrong or python was not installed correctly.
@ -78,3 +78,5 @@ type pip -v into command prompt, this should return the version of PIP that is i
- Choose Existing environment and set the location to anaconda_install_location/python.exe, OK, OK
- Allow the IDE to complete set up then launch the program from MainDriver.py. There should be a play icon next to the line "if __name__ == "__main__":"
- We Good To Go!

2
Search.py

@ -246,7 +246,7 @@ class SearchController:
results = ManageDB.run_select_sql(connection, sql_text, data)
connection.close()
results.insert(0, headers)
if self.settings.show_debug_messages: print(results)
# if self.settings.show_debug_messages: print(results)
save_data_as_tsv(file_name, results)
if self.open_results_folder_checkbox.isChecked():
open_file_or_dir(os.path.dirname(file_name))

50
Visual.py

@ -201,7 +201,7 @@ class VisualController:
self.names = [result[0] for result in names_results]
else:
self.names = []
if self.settings.show_debug_messages: print(names_results)
# if self.settings.show_debug_messages: print(names_results)
costs_sql_text, costs_data = ManageDB.get_names_with_costs_sql_text(self.report_parameter.currentText(),
self.vendor_parameter,
@ -212,7 +212,7 @@ class VisualController:
self.costs_names = [result[0] for result in costs_results]
else:
self.costs_names = []
if self.settings.show_debug_messages: print(costs_results)
# if self.settings.show_debug_messages: print(costs_results)
connection.close()
model = QStandardItemModel()
@ -267,15 +267,15 @@ class VisualController:
if self.monthly_radio.isChecked() and message == "":
# sql query to get search results
sql_text, data = ManageDB.monthly_chart_search_sql_text(report, start_year, end_year, name, metric, vendor)
print(sql_text) # testing
# print(sql_text) # testing
headers = tuple([field['name'] for field in ManageDB.get_monthly_chart_report_fields_list(report)])
connection = ManageDB.create_connection(DATABASE_LOCATION)
if connection is not None:
self.results = ManageDB.run_select_sql(connection, sql_text, data)
print(self.results)
# print(self.results)
self.results.insert(0, headers)
print(self.results)
# print(self.results)
connection.close()
else:
print('Error, no connection')
@ -289,15 +289,15 @@ class VisualController:
if self.yearly_radio.isChecked() and message == "":
# sql query to get search results
sql_text, data = ManageDB.yearly_chart_search_sql_text(report, start_year, end_year, name, metric, vendor)
print(sql_text) # testing
# print(sql_text) # testing
headers = tuple([field['name'] for field in ManageDB.get_yearly_chart_report_fields_list(report)])
connection = ManageDB.create_connection(DATABASE_LOCATION)
if connection is not None:
self.results = ManageDB.run_select_sql(connection, sql_text, data)
print(self.results)
# print(self.results)
self.results.insert(0, headers)
print(self.results)
# print(self.results)
connection.close()
else:
print('Error, no connection')
@ -311,15 +311,15 @@ class VisualController:
if self.costRatio_radio.isChecked() and message == "":
# sql query to get search results
sql_text, data = ManageDB.cost_chart_search_sql_text(report, start_year, end_year, name, metric, vendor)
print(sql_text) # testing
# print(sql_text) # testing
headers = tuple([field['name'] for field in ManageDB.get_cost_chart_report_fields_list(report)])
connection = ManageDB.create_connection(DATABASE_LOCATION)
if connection is not None:
self.results = ManageDB.run_select_sql(connection, sql_text, data)
print(self.results)
# print(self.results)
self.results.insert(0, headers)
print(self.results)
# print(self.results)
connection.close()
else:
print('Error, no connection')
@ -381,9 +381,9 @@ class VisualController:
data1.append(self.results[i][j])
self.data.append(data1)
# testing to make sure its working good
print(self.data[0]) # this is the first column in the excel file/vertical axis data in the chart
print(self.data[1])
print(len(self.data))
# print(self.data[0]) # this is the first column in the excel file/vertical axis data in the chart
# print(self.data[1])
# print(len(self.data))
self.chart_type()
def process_yearly_data(self):
@ -404,9 +404,9 @@ class VisualController:
self.data.append(data2)
# testing to make sure its working good
print(self.data[0]) # this is the first column in the excel file/vertical axis data in the chart
print(self.data[1])
print(len(self.data))
# print(self.data[0]) # this is the first column in the excel file/vertical axis data in the chart
# print(self.data[1])
# print(len(self.data))
self.chart_type()
def process_cost_ratio_data(self):
@ -471,8 +471,8 @@ class VisualController:
self.legendEntry.append(self.metric.currentText())
# testing to see data in array of array
print(self.data[0]) # first column in excel (year)
print(self.data[1]) # second column (cost per metric)
# print(self.data[0]) # first column in excel (year)
# print(self.data[1]) # second column (cost per metric)
# print(self.data[2]) # third column (cost)
# print(self.data[4]) # fourth column (total)
# print(len(self.data)) #testing
@ -481,8 +481,8 @@ class VisualController:
def process_top_X_data(self):
"""Invoked when calculation type: top # is selected"""
m = len(self.results)
#print(self.results)
print(m)
# print(self.results)
# print(m)
self.temp_results = []
self.legendEntry = [] # legend entry data
@ -491,8 +491,8 @@ class VisualController:
for i in range(1, m):
self.temp_results.append(self.results[i])
self.temp_results = sorted(self.temp_results, key=itemgetter(4))
print(len(self.temp_results))
print(self.temp_results)
# print(len(self.temp_results))
# print(self.temp_results)
n = len(self.temp_results)
# data is an array with the sorted usage figures
@ -509,7 +509,7 @@ class VisualController:
data = self.temp_results[i][0]
data1.append(data)
self.data.append(data1)
print(data1)
# print(data1)
# get all reporting total
metri = self.temp_results[0][3]
@ -518,7 +518,7 @@ class VisualController:
metri = self.temp_results[i][3]
data2.append(metri)
self.data.append(data2)
print(data2)
# print(data2)
# get all ranking
rank = self.temp_results[0][4]

BIN
executables/Linux/Counter 5 Report Tool.zip

Binary file not shown.

BIN
executables/Windows/COUNTER 5 Report Tool.zip

Binary file not shown.

BIN
executables/macOS/Counter 5 Report Tool.zip

Binary file not shown.

BIN
images/import-report-updated.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

30
tests/test_ImportFile.py

@ -105,9 +105,9 @@ def test_on_report_type_selected(controller_v):
index_to_select = 3
model_index = QStandardItemModel.createIndex(QStandardItemModel(), index_to_select, 0)
controller_v.on_report_type_selected(model_index)
controller_v.on_c5_report_type_selected(model_index)
assert controller_v.selected_report_type_index == index_to_select
assert controller_v.selected_c5_report_type_index == index_to_select
def test_on_date_changed(controller_v):
@ -119,38 +119,38 @@ def test_on_date_changed(controller_v):
def test_on_import_clicked(controller_v):
# No vendor selected
controller_v.on_import_clicked()
controller_v.on_c5_import_clicked()
controller_v.selected_vendor_index = 1
# No report type selected
controller_v.on_import_clicked()
controller_v.selected_report_type_index = 1
controller_v.on_c5_import_clicked()
controller_v.selected_c5_report_type_index = 1
vendor = controller_v.vendors[controller_v.selected_vendor_index]
report_type = ALL_REPORTS[controller_v.selected_report_type_index]
report_type = ALL_REPORTS[controller_v.selected_c5_report_type_index]
file_dir = f"{controller_v.settings.yearly_directory}{controller_v.date.toString('yyyy')}/{vendor.name}/"
file_name = f"{controller_v.date.toString('yyyy')}_{vendor.name}_{report_type}.tsv"
file_path = file_dir + file_name
# No file selected
controller_v.on_import_clicked()
controller_v.on_c5_import_clicked()
# Invalid file selected
controller_v.selected_file_path = "./data/invalid_file"
controller_v.on_import_clicked()
controller_v.c5_selected_file_path = "./data/invalid_file"
controller_v.on_c5_import_clicked()
# Valid file selected
controller_v.selected_file_path = "./data/test_file_for_import.tsv"
controller_v.on_import_clicked()
controller_v.c5_selected_file_path = "./data/test_file_for_import.tsv"
controller_v.on_c5_import_clicked()
assert path.isfile(file_path)
def test_import_file(controller_v):
controller_v.selected_vendor_index = 1
controller_v.selected_report_type_index = 1
controller_v.selected_c5_report_type_index = 1
vendor = controller_v.vendors[controller_v.selected_vendor_index]
report_type = ALL_REPORTS[controller_v.selected_report_type_index]
report_type = ALL_REPORTS[controller_v.selected_c5_report_type_index]
file_dir = f"{controller_v.settings.yearly_directory}{controller_v.date.toString('yyyy')}/{vendor.name}/"
file_name = f"{controller_v.date.toString('yyyy')}_{vendor.name}_{report_type}.tsv"
file_path = file_dir + file_name
@ -159,11 +159,11 @@ def test_import_file(controller_v):
assert controller_v.import_report(vendor, report_type).completion_status == CompletionStatus.FAILED
# Invalid file selected
controller_v.selected_file_path = "./data/invalid_file"
controller_v.c5_selected_file_path = "./data/invalid_file"
assert controller_v.import_report(vendor, report_type).completion_status == CompletionStatus.FAILED
# Valid file selected
controller_v.selected_file_path = "./data/test_file_for_import.tsv"
controller_v.c5_selected_file_path = "./data/test_file_for_import.tsv"
assert controller_v.import_report(vendor, report_type).completion_status == CompletionStatus.SUCCESSFUL
assert path.isfile(file_path)

379
ui/ImportReportTab.py

@ -2,28 +2,25 @@
# Form implementation generated from reading ui file 'ImportReportTab.ui'
#
# Created by: PyQt5 UI code generator 5.9.2
# Created by: PyQt5 UI code generator 5.12.3
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_import_report_tab(object):
def setupUi(self, import_report_tab):
import_report_tab.setObjectName("import_report_tab")
import_report_tab.resize(1008, 530)
import_report_tab.resize(1007, 467)
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(":/ui/resources/tab_icons/import_report_icon.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
import_report_tab.setWindowIcon(icon)
self.verticalLayout = QtWidgets.QVBoxLayout(import_report_tab)
self.verticalLayout.setObjectName("verticalLayout")
self.frame = QtWidgets.QFrame(import_report_tab)
self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame.setObjectName("frame")
self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.frame)
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
self.frame_21 = QtWidgets.QFrame(self.frame)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
self.frame_21 = QtWidgets.QFrame(import_report_tab)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.frame_21.sizePolicy().hasHeightForWidth())
@ -31,109 +28,70 @@ class Ui_import_report_tab(object):
self.frame_21.setMinimumSize(QtCore.QSize(200, 0))
self.frame_21.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame_21.setObjectName("frame_21")
self.verticalLayout_12 = QtWidgets.QVBoxLayout(self.frame_21)
self.verticalLayout_12.setObjectName("verticalLayout_12")
self.gridLayout = QtWidgets.QGridLayout(self.frame_21)
self.gridLayout.setHorizontalSpacing(20)
self.gridLayout.setObjectName("gridLayout")
self.label_18 = QtWidgets.QLabel(self.frame_21)
self.label_18.setMinimumSize(QtCore.QSize(200, 0))
font = QtGui.QFont()
font.setFamily("Segoe UI")
font.setPointSize(11)
font.setBold(True)
font.setWeight(75)
self.label_18.setFont(font)
self.label_18.setObjectName("label_18")
self.verticalLayout_12.addWidget(self.label_18)
self.vendors_list_view_import = QtWidgets.QListView(self.frame_21)
font = QtGui.QFont()
font.setFamily("Segoe UI")
font.setPointSize(11)
self.vendors_list_view_import.setFont(font)
self.vendors_list_view_import.setAlternatingRowColors(True)
self.vendors_list_view_import.setObjectName("vendors_list_view_import")
self.verticalLayout_12.addWidget(self.vendors_list_view_import)
self.horizontalLayout_2.addWidget(self.frame_21)
self.frame_20 = QtWidgets.QFrame(self.frame)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.frame_20.sizePolicy().hasHeightForWidth())
self.frame_20.setSizePolicy(sizePolicy)
self.frame_20.setMinimumSize(QtCore.QSize(200, 0))
self.frame_20.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame_20.setObjectName("frame_20")
self.verticalLayout_11 = QtWidgets.QVBoxLayout(self.frame_20)
self.verticalLayout_11.setObjectName("verticalLayout_11")
self.label_17 = QtWidgets.QLabel(self.frame_20)
self.gridLayout.addWidget(self.label_18, 0, 0, 1, 1)
self.vendor_combo_box = QtWidgets.QComboBox(self.frame_21)
self.vendor_combo_box.setObjectName("vendor_combo_box")
self.gridLayout.addWidget(self.vendor_combo_box, 1, 0, 1, 1)
self.label_19 = QtWidgets.QLabel(self.frame_21)
self.label_19.setMinimumSize(QtCore.QSize(100, 0))
font = QtGui.QFont()
font.setFamily("Segoe UI")
font.setPointSize(11)
font.setBold(True)
font.setWeight(75)
self.label_17.setFont(font)
self.label_17.setObjectName("label_17")
self.verticalLayout_11.addWidget(self.label_17)
self.report_types_list_view_import = QtWidgets.QListView(self.frame_20)
font = QtGui.QFont()
font.setFamily("Segoe UI")
font.setPointSize(11)
self.report_types_list_view_import.setFont(font)
self.report_types_list_view_import.setAlternatingRowColors(True)
self.report_types_list_view_import.setObjectName("report_types_list_view_import")
self.verticalLayout_11.addWidget(self.report_types_list_view_import)
self.horizontalLayout_2.addWidget(self.frame_20)
self.frame_22 = QtWidgets.QFrame(self.frame)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.frame_22.sizePolicy().hasHeightForWidth())
self.frame_22.setSizePolicy(sizePolicy)
self.frame_22.setMinimumSize(QtCore.QSize(200, 0))
self.frame_22.setObjectName("frame_22")
self.verticalLayout_13 = QtWidgets.QVBoxLayout(self.frame_22)
self.verticalLayout_13.setContentsMargins(0, 0, 0, 0)
self.verticalLayout_13.setObjectName("verticalLayout_13")
self.frame_17 = QtWidgets.QFrame(self.frame_22)
self.label_19.setFont(font)
self.label_19.setObjectName("label_19")
self.gridLayout.addWidget(self.label_19, 0, 1, 1, 1)
self.report_year_date_edit = QtWidgets.QDateEdit(self.frame_21)
self.report_year_date_edit.setObjectName("report_year_date_edit")
self.gridLayout.addWidget(self.report_year_date_edit, 1, 1, 1, 1)
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.gridLayout.addItem(spacerItem, 0, 2, 2, 1)
self.verticalLayout.addWidget(self.frame_21)
self.frame = QtWidgets.QFrame(import_report_tab)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.frame.sizePolicy().hasHeightForWidth())
self.frame.setSizePolicy(sizePolicy)
self.frame.setObjectName("frame")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.frame)
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout.setObjectName("horizontalLayout")
self.frame_17 = QtWidgets.QFrame(self.frame)
self.frame_17.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame_17.setObjectName("frame_17")
self.verticalLayout_24 = QtWidgets.QVBoxLayout(self.frame_17)
self.verticalLayout_24.setObjectName("verticalLayout_24")
self.label_16 = QtWidgets.QLabel(self.frame_17)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.label_16.sizePolicy().hasHeightForWidth())
self.label_16.setSizePolicy(sizePolicy)
self.label_2 = QtWidgets.QLabel(self.frame_17)
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
self.label_16.setFont(font)
self.label_16.setObjectName("label_16")
self.verticalLayout_24.addWidget(self.label_16)
self.frame_19 = QtWidgets.QFrame(self.frame_17)
self.frame_19.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame_19.setObjectName("frame_19")
self.horizontalLayout_13 = QtWidgets.QHBoxLayout(self.frame_19)
self.horizontalLayout_13.setObjectName("horizontalLayout_13")
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout_13.addItem(spacerItem)
self.label_19 = QtWidgets.QLabel(self.frame_19)
self.label_19.setMinimumSize(QtCore.QSize(100, 0))
self.label_19.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.label_19.setObjectName("label_19")
self.horizontalLayout_13.addWidget(self.label_19)
self.report_year_date_edit = QtWidgets.QDateEdit(self.frame_19)
self.report_year_date_edit.setObjectName("report_year_date_edit")
self.horizontalLayout_13.addWidget(self.report_year_date_edit)
spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout_13.addItem(spacerItem1)
self.verticalLayout_24.addWidget(self.frame_19)
self.verticalLayout_13.addWidget(self.frame_17)
self.frame_18 = QtWidgets.QFrame(self.frame_22)
self.frame_18.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame_18.setObjectName("frame_18")
self.verticalLayout_25 = QtWidgets.QVBoxLayout(self.frame_18)
self.verticalLayout_25.setObjectName("verticalLayout_25")
self.label_36 = QtWidgets.QLabel(self.frame_18)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
self.label_2.setFont(font)
self.label_2.setObjectName("label_2")
self.verticalLayout_24.addWidget(self.label_2)
self.frame_2 = QtWidgets.QFrame(self.frame_17)
self.frame_2.setObjectName("frame_2")
self.gridLayout_2 = QtWidgets.QGridLayout(self.frame_2)
self.gridLayout_2.setHorizontalSpacing(20)
self.gridLayout_2.setObjectName("gridLayout_2")
self.label_17 = QtWidgets.QLabel(self.frame_2)
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
self.label_17.setFont(font)
self.label_17.setObjectName("label_17")
self.gridLayout_2.addWidget(self.label_17, 0, 0, 1, 1)
self.label_36 = QtWidgets.QLabel(self.frame_2)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.label_36.sizePolicy().hasHeightForWidth())
@ -143,66 +101,229 @@ class Ui_import_report_tab(object):
font.setWeight(75)
self.label_36.setFont(font)
self.label_36.setObjectName("label_36")
self.verticalLayout_25.addWidget(self.label_36)
self.frame_38 = QtWidgets.QFrame(self.frame_18)
self.gridLayout_2.addWidget(self.label_36, 0, 1, 1, 1)
self.frame_38 = QtWidgets.QFrame(self.frame_2)
self.frame_38.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame_38.setObjectName("frame_38")
self.horizontalLayout_15 = QtWidgets.QHBoxLayout(self.frame_38)
self.horizontalLayout_15.setObjectName("horizontalLayout_15")
self.select_file_button = QtWidgets.QPushButton(self.frame_38)
self.c5_selected_file_edit = QtWidgets.QLineEdit(self.frame_38)
self.c5_selected_file_edit.setReadOnly(True)
self.c5_selected_file_edit.setObjectName("c5_selected_file_edit")
self.horizontalLayout_15.addWidget(self.c5_selected_file_edit)
self.c5_select_file_button = QtWidgets.QPushButton(self.frame_38)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.select_file_button.sizePolicy().hasHeightForWidth())
self.select_file_button.setSizePolicy(sizePolicy)
self.select_file_button.setObjectName("select_file_button")
self.horizontalLayout_15.addWidget(self.select_file_button)
self.selected_file_edit = QtWidgets.QLineEdit(self.frame_38)
self.selected_file_edit.setReadOnly(True)
self.selected_file_edit.setObjectName("selected_file_edit")
self.horizontalLayout_15.addWidget(self.selected_file_edit)
self.verticalLayout_25.addWidget(self.frame_38)
self.verticalLayout_13.addWidget(self.frame_18)
self.frame_24 = QtWidgets.QFrame(self.frame_22)
self.frame_24.setFrameShape(QtWidgets.QFrame.StyledPanel)
sizePolicy.setHeightForWidth(self.c5_select_file_button.sizePolicy().hasHeightForWidth())
self.c5_select_file_button.setSizePolicy(sizePolicy)
self.c5_select_file_button.setObjectName("c5_select_file_button")
self.horizontalLayout_15.addWidget(self.c5_select_file_button)
self.gridLayout_2.addWidget(self.frame_38, 1, 1, 1, 1)
self.c5_report_type_combo_box = QtWidgets.QComboBox(self.frame_2)
self.c5_report_type_combo_box.setObjectName("c5_report_type_combo_box")
self.gridLayout_2.addWidget(self.c5_report_type_combo_box, 1, 0, 1, 1, QtCore.Qt.AlignTop)
self.verticalLayout_24.addWidget(self.frame_2)
self.frame_25 = QtWidgets.QFrame(self.frame_17)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.frame_25.sizePolicy().hasHeightForWidth())
self.frame_25.setSizePolicy(sizePolicy)
self.frame_25.setObjectName("frame_25")
self.gridLayout_8 = QtWidgets.QGridLayout(self.frame_25)
self.gridLayout_8.setObjectName("gridLayout_8")
self.c5_import_report_button = QtWidgets.QPushButton(self.frame_25)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.c5_import_report_button.sizePolicy().hasHeightForWidth())
self.c5_import_report_button.setSizePolicy(sizePolicy)
self.c5_import_report_button.setObjectName("c5_import_report_button")
self.gridLayout_8.addWidget(self.c5_import_report_button, 0, 0, 1, 1)
self.verticalLayout_24.addWidget(self.frame_25)
spacerItem1 = QtWidgets.QSpacerItem(0, 0, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.MinimumExpanding)
self.verticalLayout_24.addItem(spacerItem1)
self.horizontalLayout.addWidget(self.frame_17)
self.frame_18 = QtWidgets.QFrame(self.frame)
self.frame_18.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame_18.setObjectName("frame_18")
self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.frame_18)
self.verticalLayout_3.setObjectName("verticalLayout_3")
self.label_3 = QtWidgets.QLabel(self.frame_18)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.label_3.sizePolicy().hasHeightForWidth())
self.label_3.setSizePolicy(sizePolicy)
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
self.label_3.setFont(font)
self.label_3.setObjectName("label_3")
self.verticalLayout_3.addWidget(self.label_3)
self.frame_3 = QtWidgets.QFrame(self.frame_18)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.frame_3.sizePolicy().hasHeightForWidth())
self.frame_3.setSizePolicy(sizePolicy)
self.frame_3.setObjectName("frame_3")
self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.frame_3)
self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
self.frame_4 = QtWidgets.QFrame(self.frame_3)
self.frame_4.setObjectName("frame_4")
self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.frame_4)
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.label_20 = QtWidgets.QLabel(self.frame_4)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.label_20.sizePolicy().hasHeightForWidth())
self.label_20.setSizePolicy(sizePolicy)
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
self.label_20.setFont(font)
self.label_20.setObjectName("label_20")
self.verticalLayout_2.addWidget(self.label_20)
self.c4_report_type_combo_box = QtWidgets.QComboBox(self.frame_4)
self.c4_report_type_combo_box.setObjectName("c4_report_type_combo_box")
self.verticalLayout_2.addWidget(self.c4_report_type_combo_box)
self.label_21 = QtWidgets.QLabel(self.frame_4)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.label_21.sizePolicy().hasHeightForWidth())
self.label_21.setSizePolicy(sizePolicy)
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
self.label_21.setFont(font)
self.label_21.setObjectName("label_21")
self.verticalLayout_2.addWidget(self.label_21)
self.c4_report_type_equiv_label = QtWidgets.QLabel(self.frame_4)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.c4_report_type_equiv_label.sizePolicy().hasHeightForWidth())
self.c4_report_type_equiv_label.setSizePolicy(sizePolicy)
self.c4_report_type_equiv_label.setObjectName("c4_report_type_equiv_label")
self.verticalLayout_2.addWidget(self.c4_report_type_equiv_label)
spacerItem2 = QtWidgets.QSpacerItem(0, 0, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.verticalLayout_2.addItem(spacerItem2)
self.horizontalLayout_2.addWidget(self.frame_4)
self.frame_5 = QtWidgets.QFrame(self.frame_3)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.frame_5.sizePolicy().hasHeightForWidth())
self.frame_5.setSizePolicy(sizePolicy)
self.frame_5.setObjectName("frame_5")
self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.frame_5)
self.verticalLayout_4.setObjectName("verticalLayout_4")
self.label_37 = QtWidgets.QLabel(self.frame_5)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.label_37.sizePolicy().hasHeightForWidth())
self.label_37.setSizePolicy(sizePolicy)
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
self.label_37.setFont(font)
self.label_37.setObjectName("label_37")
self.verticalLayout_4.addWidget(self.label_37)
self.c4_files_frame = QtWidgets.QFrame(self.frame_5)
self.c4_files_frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.c4_files_frame.setObjectName("c4_files_frame")
self.horizontalLayout_16 = QtWidgets.QHBoxLayout(self.c4_files_frame)
self.horizontalLayout_16.setObjectName("horizontalLayout_16")
self.scrollArea = QtWidgets.QScrollArea(self.c4_files_frame)
self.scrollArea.setMinimumSize(QtCore.QSize(200, 100))
self.scrollArea.setWidgetResizable(True)
self.scrollArea.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop)
self.scrollArea.setObjectName("scrollArea")
self.scrollAreaWidgetContents_2 = QtWidgets.QWidget()
self.scrollAreaWidgetContents_2.setGeometry(QtCore.QRect(0, 0, 198, 18))
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.scrollAreaWidgetContents_2.sizePolicy().hasHeightForWidth())
self.scrollAreaWidgetContents_2.setSizePolicy(sizePolicy)
self.scrollAreaWidgetContents_2.setObjectName("scrollAreaWidgetContents_2")
self.verticalLayout_6 = QtWidgets.QVBoxLayout(self.scrollAreaWidgetContents_2)
self.verticalLayout_6.setContentsMargins(0, 0, 0, 0)
self.verticalLayout_6.setObjectName("verticalLayout_6")
self.c4_selected_files_frame = QtWidgets.QFrame(self.scrollAreaWidgetContents_2)
self.c4_selected_files_frame.setObjectName("c4_selected_files_frame")
self.verticalLayout_5 = QtWidgets.QVBoxLayout(self.c4_selected_files_frame)
self.verticalLayout_5.setObjectName("verticalLayout_5")
self.verticalLayout_6.addWidget(self.c4_selected_files_frame)
self.scrollArea.setWidget(self.scrollAreaWidgetContents_2)
self.horizontalLayout_16.addWidget(self.scrollArea)
self.c4_select_file_button = QtWidgets.QPushButton(self.c4_files_frame)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.c4_select_file_button.sizePolicy().hasHeightForWidth())
self.c4_select_file_button.setSizePolicy(sizePolicy)
self.c4_select_file_button.setObjectName("c4_select_file_button")
self.horizontalLayout_16.addWidget(self.c4_select_file_button)
self.verticalLayout_4.addWidget(self.c4_files_frame)
self.horizontalLayout_2.addWidget(self.frame_5, 0, QtCore.Qt.AlignTop)
self.verticalLayout_3.addWidget(self.frame_3)
self.frame_24 = QtWidgets.QFrame(self.frame_18)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.frame_24.sizePolicy().hasHeightForWidth())
self.frame_24.setSizePolicy(sizePolicy)
self.frame_24.setObjectName("frame_24")
self.gridLayout_7 = QtWidgets.QGridLayout(self.frame_24)
self.gridLayout_7.setObjectName("gridLayout_7")
self.import_report_button = QtWidgets.QPushButton(self.frame_24)
self.c4_import_report_button = QtWidgets.QPushButton(self.frame_24)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.import_report_button.sizePolicy().hasHeightForWidth())
self.import_report_button.setSizePolicy(sizePolicy)
self.import_report_button.setMaximumSize(QtCore.QSize(180, 16777215))
self.import_report_button.setObjectName("import_report_button")
self.gridLayout_7.addWidget(self.import_report_button, 0, 0, 1, 1)
self.verticalLayout_13.addWidget(self.frame_24)
self.horizontalLayout_2.addWidget(self.frame_22)
sizePolicy.setHeightForWidth(self.c4_import_report_button.sizePolicy().hasHeightForWidth())
self.c4_import_report_button.setSizePolicy(sizePolicy)
self.c4_import_report_button.setObjectName("c4_import_report_button")
self.gridLayout_7.addWidget(self.c4_import_report_button, 0, 0, 1, 1)
self.verticalLayout_3.addWidget(self.frame_24)
spacerItem3 = QtWidgets.QSpacerItem(0, 0, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.verticalLayout_3.addItem(spacerItem3)
self.horizontalLayout.addWidget(self.frame_18)
self.verticalLayout.addWidget(self.frame)
self.label = QtWidgets.QLabel(import_report_tab)
self.label.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.label.setObjectName("label")
self.verticalLayout.addWidget(self.label)
spacerItem4 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.verticalLayout.addItem(spacerItem4)
self.retranslateUi(import_report_tab)
QtCore.QMetaObject.connectSlotsByName(import_report_tab)
import_report_tab.setTabOrder(self.vendors_list_view_import, self.report_types_list_view_import)
import_report_tab.setTabOrder(self.report_types_list_view_import, self.report_year_date_edit)
import_report_tab.setTabOrder(self.report_year_date_edit, self.selected_file_edit)
import_report_tab.setTabOrder(self.selected_file_edit, self.import_report_button)
import_report_tab.setTabOrder(self.c5_selected_file_edit, self.c4_import_report_button)
def retranslateUi(self, import_report_tab):
_translate = QtCore.QCoreApplication.translate
import_report_tab.setWindowTitle(_translate("import_report_tab", "Import Report"))
self.label_18.setText(_translate("import_report_tab", "Select Vendor"))
self.label_17.setText(_translate("import_report_tab", "Select Report Type"))
self.label_16.setText(_translate("import_report_tab", "Date"))
self.label_19.setText(_translate("import_report_tab", "Report Year"))
self.report_year_date_edit.setDisplayFormat(_translate("import_report_tab", "yyyy"))
self.label_36.setText(_translate("import_report_tab", "Target Report File"))
self.select_file_button.setText(_translate("import_report_tab", "Select File"))
self.import_report_button.setText(_translate("import_report_tab", "Import Selected Report"))
self.label_2.setText(_translate("import_report_tab", "COUNTER 5"))
self.label_17.setText(_translate("import_report_tab", "Select Report Type"))
self.label_36.setText(_translate("import_report_tab", "Source Report File"))
self.c5_select_file_button.setText(_translate("import_report_tab", "Select File"))
self.c5_import_report_button.setText(_translate("import_report_tab", "Import Selected Report"))
self.label_3.setText(_translate("import_report_tab", "COUNTER 4 (Converts to COUNTER 5)"))
self.label_20.setText(_translate("import_report_tab", "Counter 4 Report Type"))
self.label_21.setText(_translate("import_report_tab", "Counter 5 Equivalent(s)"))
self.c4_report_type_equiv_label.setText(_translate("import_report_tab", "TextLabel"))
self.label_37.setText(_translate("import_report_tab", "Source Report File(s)"))
self.c4_select_file_button.setText(_translate("import_report_tab", "Select File(s)"))
self.c4_import_report_button.setText(_translate("import_report_tab", "Import Selected Report(s)"))
self.label.setText(_translate("import_report_tab", "Note: Only yearly reports (all available data for one calender year) should be imported. Imported reports are added to the search database."))
import Resources_rc

588
ui/ImportReportTab.ui

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>1008</width>
<height>530</height>
<width>1007</width>
<height>467</height>
</rect>
</property>
<property name="windowTitle">
@ -19,146 +19,153 @@
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QFrame" name="frame">
<widget class="QFrame" name="frame_21">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QFrame" name="frame_21">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="horizontalSpacing">
<number>20</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label_18">
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Select Vendor</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_12">
<item>
<widget class="QLabel" name="label_18">
<property name="font">
<font>
<family>Segoe UI</family>
<pointsize>11</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Select Vendor</string>
</property>
</widget>
</item>
<item>
<widget class="QListView" name="vendors_list_view_import">
<property name="font">
<font>
<family>Segoe UI</family>
<pointsize>11</pointsize>
</font>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_20">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item row="1" column="0">
<widget class="QComboBox" name="vendor_combo_box"/>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_19">
<property name="minimumSize">
<size>
<width>200</width>
<width>100</width>
<height>0</height>
</size>
</property>
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Report Year</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QDateEdit" name="report_year_date_edit">
<property name="displayFormat">
<string>yyyy</string>
</property>
</widget>
</item>
<item row="0" column="2" rowspan="2">
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="frame">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QFrame" name="frame_17">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_11">
<layout class="QVBoxLayout" name="verticalLayout_24">
<item>
<widget class="QLabel" name="label_17">
<widget class="QLabel" name="label_2">
<property name="font">
<font>
<family>Segoe UI</family>
<pointsize>11</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Select Report Type</string>
</property>
</widget>
</item>
<item>
<widget class="QListView" name="report_types_list_view_import">
<property name="font">
<font>
<family>Segoe UI</family>
<pointsize>11</pointsize>
</font>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
<string>COUNTER 5</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_22">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<layout class="QVBoxLayout" name="verticalLayout_13">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QFrame" name="frame_17">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_24">
<item>
<widget class="QLabel" name="label_16">
<widget class="QFrame" name="frame_2">
<layout class="QGridLayout" name="gridLayout_2">
<property name="horizontalSpacing">
<number>20</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label_17">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Select Report Type</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_36">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
@ -170,61 +177,201 @@
</font>
</property>
<property name="text">
<string>Date</string>
<string>Source Report File</string>
</property>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_19">
<item row="1" column="1">
<widget class="QFrame" name="frame_38">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_13">
<layout class="QHBoxLayout" name="horizontalLayout_15">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<widget class="QLineEdit" name="c5_selected_file_edit">
<property name="readOnly">
<bool>true</bool>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</widget>
</item>
<item>
<widget class="QPushButton" name="c5_select_file_button">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</spacer>
<property name="text">
<string>Select File</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="0" alignment="Qt::AlignTop">
<widget class="QComboBox" name="c5_report_type_combo_box"/>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_25">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QGridLayout" name="gridLayout_8">
<item row="0" column="0">
<widget class="QPushButton" name="c5_import_report_button">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Import Selected Report</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::MinimumExpanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_18">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QLabel" name="label_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>COUNTER 4 (Converts to COUNTER 5)</string>
</property>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QFrame" name="frame_4">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="label_19">
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
<widget class="QLabel" name="label_20">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Report Year</string>
<string>Counter 4 Report Type</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</widget>
</item>
<item>
<widget class="QComboBox" name="c4_report_type_combo_box"/>
</item>
<item>
<widget class="QLabel" name="label_21">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Counter 5 Equivalent(s)</string>
</property>
</widget>
</item>
<item>
<widget class="QDateEdit" name="report_year_date_edit">
<property name="displayFormat">
<string>yyyy</string>
<widget class="QLabel" name="c4_report_type_equiv_label">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<spacer name="verticalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
@ -232,58 +379,105 @@
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_18">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_25">
<item>
<widget class="QLabel" name="label_36">
<item alignment="Qt::AlignTop">
<widget class="QFrame" name="frame_5">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Target Report File</string>
</property>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_38">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_15">
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QPushButton" name="select_file_button">
<widget class="QLabel" name="label_37">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Select File</string>
<string>Source Report File(s)</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="selected_file_edit">
<property name="readOnly">
<bool>true</bool>
<widget class="QFrame" name="c4_files_frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_16">
<item>
<widget class="QScrollArea" name="scrollArea">
<property name="minimumSize">
<size>
<width>200</width>
<height>100</height>
</size>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents_2">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>198</width>
<height>18</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QVBoxLayout" name="verticalLayout_6">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QFrame" name="c4_selected_files_frame">
<layout class="QVBoxLayout" name="verticalLayout_5"/>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<widget class="QPushButton" name="c4_select_file_button">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Select File(s)</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
@ -294,32 +488,42 @@
</item>
<item>
<widget class="QFrame" name="frame_24">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QGridLayout" name="gridLayout_7">
<item row="0" column="0">
<widget class="QPushButton" name="import_report_button">
<widget class="QPushButton" name="c4_import_report_button">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>180</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Import Selected Report</string>
<string>Import Selected Report(s)</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
@ -336,14 +540,24 @@
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<tabstops>
<tabstop>vendors_list_view_import</tabstop>
<tabstop>report_types_list_view_import</tabstop>
<tabstop>report_year_date_edit</tabstop>
<tabstop>selected_file_edit</tabstop>
<tabstop>import_report_button</tabstop>
<tabstop>c5_selected_file_edit</tabstop>
<tabstop>c4_import_report_button</tabstop>
</tabstops>
<resources>
<include location="../Resources.qrc"/>

160
ui/VisualTab.py

@ -2,38 +2,25 @@
# Form implementation generated from reading ui file 'VisualTab.ui'
#
# Created by: PyQt5 UI code generator 5.14.1
# Created by: PyQt5 UI code generator 5.9.2
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_visual_tab(object):
def setupUi(self, visual_tab):
visual_tab.setObjectName("visual_tab")
visual_tab.resize(1177, 690)
visual_tab.resize(692, 488)
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(":/ui/resources/tab_icons/visual_icon.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
visual_tab.setWindowIcon(icon)
self.verticalLayout = QtWidgets.QVBoxLayout(visual_tab)
self.verticalLayout.setObjectName("verticalLayout")
self.search_parameters_frame_2 = QtWidgets.QFrame(visual_tab)
self.search_initial_parameters_frame_2 = QtWidgets.QFrame(visual_tab)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.search_parameters_frame_2.sizePolicy().hasHeightForWidth())
self.search_parameters_frame_2.setSizePolicy(sizePolicy)
self.search_parameters_frame_2.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.search_parameters_frame_2.setFrameShadow(QtWidgets.QFrame.Raised)
self.search_parameters_frame_2.setObjectName("search_parameters_frame_2")
self.verticalLayout_22 = QtWidgets.QVBoxLayout(self.search_parameters_frame_2)
self.verticalLayout_22.setObjectName("verticalLayout_22")
self.search_initial_parameters_frame_2 = QtWidgets.QFrame(self.search_parameters_frame_2)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.search_initial_parameters_frame_2.sizePolicy().hasHeightForWidth())
self.search_initial_parameters_frame_2.setSizePolicy(sizePolicy)
self.search_initial_parameters_frame_2.setFrameShape(QtWidgets.QFrame.StyledPanel)
@ -74,15 +61,8 @@ class Ui_visual_tab(object):
self.gridLayout_6.addItem(spacerItem, 1, 1, 1, 1)
spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Minimum)
self.gridLayout_6.addItem(spacerItem1, 1, 3, 1, 1)
self.verticalLayout_22.addWidget(self.search_initial_parameters_frame_2)
self.verticalLayout.addWidget(self.search_parameters_frame_2)
self.frame_14 = QtWidgets.QFrame(visual_tab)
self.frame_14.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame_14.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame_14.setObjectName("frame_14")
self.horizontalLayout_14 = QtWidgets.QHBoxLayout(self.frame_14)
self.horizontalLayout_14.setObjectName("horizontalLayout_14")
self.frame_15 = QtWidgets.QFrame(self.frame_14)
self.verticalLayout.addWidget(self.search_initial_parameters_frame_2)
self.frame_15 = QtWidgets.QFrame(visual_tab)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
@ -91,44 +71,8 @@ class Ui_visual_tab(object):
self.frame_15.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame_15.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame_15.setObjectName("frame_15")
self.gridLayout_13 = QtWidgets.QGridLayout(self.frame_15)
self.gridLayout_13.setObjectName("gridLayout_13")
self.frame_2 = QtWidgets.QFrame(self.frame_15)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.frame_2.sizePolicy().hasHeightForWidth())
self.frame_2.setSizePolicy(sizePolicy)
self.frame_2.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame_2.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame_2.setObjectName("frame_2")
self.visual_name_label = QtWidgets.QLabel(self.frame_2)
self.visual_name_label.setEnabled(True)
self.visual_name_label.setGeometry(QtCore.QRect(50, 80, 97, 21))
self.visual_name_label.setObjectName("visual_name_label")
self.visual_metric_parameter_label = QtWidgets.QLabel(self.frame_2)
self.visual_metric_parameter_label.setGeometry(QtCore.QRect(50, 130, 213, 20))
self.visual_metric_parameter_label.setObjectName("visual_metric_parameter_label")
self.metric_Type_comboBox = QtWidgets.QComboBox(self.frame_2)
self.metric_Type_comboBox.setGeometry(QtCore.QRect(140, 130, 921, 26))
self.metric_Type_comboBox.setObjectName("metric_Type_comboBox")
self.visual_vendor_parameter_label = QtWidgets.QLabel(self.frame_2)
self.visual_vendor_parameter_label.setGeometry(QtCore.QRect(50, 30, 61, 20))
self.visual_vendor_parameter_label.setObjectName("visual_vendor_parameter_label")
self.visual_vendor_parameter_combobox = QtWidgets.QComboBox(self.frame_2)
self.visual_vendor_parameter_combobox.setGeometry(QtCore.QRect(140, 30, 921, 26))
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.visual_vendor_parameter_combobox.sizePolicy().hasHeightForWidth())
self.visual_vendor_parameter_combobox.setSizePolicy(sizePolicy)
self.visual_vendor_parameter_combobox.setObjectName("visual_vendor_parameter_combobox")
self.visual_name_parameter_combobox = QtWidgets.QComboBox(self.frame_2)
self.visual_name_parameter_combobox.setEnabled(True)
self.visual_name_parameter_combobox.setGeometry(QtCore.QRect(140, 80, 921, 28))
self.visual_name_parameter_combobox.setEditable(True)
self.visual_name_parameter_combobox.setObjectName("visual_name_parameter_combobox")
self.gridLayout_13.addWidget(self.frame_2, 5, 0, 1, 3)
self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.frame_15)
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.frame = QtWidgets.QFrame(self.frame_15)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
@ -138,9 +82,10 @@ class Ui_visual_tab(object):
self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame.setObjectName("frame")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.frame)
self.horizontalLayout.setObjectName("horizontalLayout")
self.frame_18 = QtWidgets.QFrame(self.frame)
self.frame_18.setEnabled(True)
self.frame_18.setGeometry(QtCore.QRect(10, 10, 136, 161))
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
@ -172,8 +117,8 @@ class Ui_visual_tab(object):
self.radioButton_4 = QtWidgets.QRadioButton(self.frame_18)
self.radioButton_4.setObjectName("radioButton_4")
self.verticalLayout_28.addWidget(self.radioButton_4)
self.horizontalLayout.addWidget(self.frame_18)
self.frame_options = QtWidgets.QFrame(self.frame)
self.frame_options.setGeometry(QtCore.QRect(150, 10, 141, 161))
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
@ -182,8 +127,9 @@ class Ui_visual_tab(object):
self.frame_options.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame_options.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame_options.setObjectName("frame_options")
self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.frame_options)
self.verticalLayout_3.setObjectName("verticalLayout_3")
self.label_46 = QtWidgets.QLabel(self.frame_options)
self.label_46.setGeometry(QtCore.QRect(10, 10, 121, 21))
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
@ -194,21 +140,22 @@ class Ui_visual_tab(object):
self.label_46.setFont(font)
self.label_46.setTextFormat(QtCore.Qt.AutoText)
self.label_46.setObjectName("label_46")
self.verticalLayout_3.addWidget(self.label_46)
self.monthly_radioButton = QtWidgets.QRadioButton(self.frame_options)
self.monthly_radioButton.setGeometry(QtCore.QRect(10, 40, 112, 20))
self.monthly_radioButton.setObjectName("monthly_radioButton")
self.verticalLayout_3.addWidget(self.monthly_radioButton)
self.yearly_radioButton = QtWidgets.QRadioButton(self.frame_options)
self.yearly_radioButton.setGeometry(QtCore.QRect(10, 70, 112, 20))
self.yearly_radioButton.setObjectName("yearly_radioButton")
self.verticalLayout_3.addWidget(self.yearly_radioButton)
self.topnum_radioButton = QtWidgets.QRadioButton(self.frame_options)
self.topnum_radioButton.setGeometry(QtCore.QRect(10, 100, 112, 20))
self.topnum_radioButton.setObjectName("topnum_radioButton")
self.verticalLayout_3.addWidget(self.topnum_radioButton)
self.costratio_radioButton = QtWidgets.QRadioButton(self.frame_options)
self.costratio_radioButton.setGeometry(QtCore.QRect(10, 130, 112, 20))
self.costratio_radioButton.setObjectName("costratio_radioButton")
self.verticalLayout_3.addWidget(self.costratio_radioButton)
self.horizontalLayout.addWidget(self.frame_options)
self.option_frame = QtWidgets.QFrame(self.frame)
self.option_frame.setEnabled(True)
self.option_frame.setGeometry(QtCore.QRect(293, 10, 151, 161))
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
@ -217,8 +164,9 @@ class Ui_visual_tab(object):
self.option_frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.option_frame.setFrameShadow(QtWidgets.QFrame.Raised)
self.option_frame.setObjectName("option_frame")
self.verticalLayout_6 = QtWidgets.QVBoxLayout(self.option_frame)
self.verticalLayout_6.setObjectName("verticalLayout_6")
self.edit_cost_ratio_frame = QtWidgets.QFrame(self.option_frame)
self.edit_cost_ratio_frame.setGeometry(QtCore.QRect(10, 10, 131, 81))
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
@ -227,8 +175,9 @@ class Ui_visual_tab(object):
self.edit_cost_ratio_frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.edit_cost_ratio_frame.setFrameShadow(QtWidgets.QFrame.Raised)
self.edit_cost_ratio_frame.setObjectName("edit_cost_ratio_frame")
self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.edit_cost_ratio_frame)
self.verticalLayout_4.setObjectName("verticalLayout_4")
self.label_47 = QtWidgets.QLabel(self.edit_cost_ratio_frame)
self.label_47.setGeometry(QtCore.QRect(10, 10, 183, 15))
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
@ -239,11 +188,12 @@ class Ui_visual_tab(object):
self.label_47.setFont(font)
self.label_47.setTextFormat(QtCore.Qt.AutoText)
self.label_47.setObjectName("label_47")
self.verticalLayout_4.addWidget(self.label_47)
self.cost_ratio_option_combobox = QtWidgets.QComboBox(self.edit_cost_ratio_frame)
self.cost_ratio_option_combobox.setGeometry(QtCore.QRect(0, 30, 121, 26))
self.cost_ratio_option_combobox.setObjectName("cost_ratio_option_combobox")
self.verticalLayout_4.addWidget(self.cost_ratio_option_combobox)
self.verticalLayout_6.addWidget(self.edit_cost_ratio_frame)
self.edit_top_num_frame = QtWidgets.QFrame(self.option_frame)
self.edit_top_num_frame.setGeometry(QtCore.QRect(10, 90, 131, 61))
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
@ -252,8 +202,9 @@ class Ui_visual_tab(object):
self.edit_top_num_frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.edit_top_num_frame.setFrameShadow(QtWidgets.QFrame.Raised)
self.edit_top_num_frame.setObjectName("edit_top_num_frame")
self.verticalLayout_5 = QtWidgets.QVBoxLayout(self.edit_top_num_frame)
self.verticalLayout_5.setObjectName("verticalLayout_5")
self.label_48 = QtWidgets.QLabel(self.edit_top_num_frame)
self.label_48.setGeometry(QtCore.QRect(10, 10, 183, 15))
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
@ -264,12 +215,14 @@ class Ui_visual_tab(object):
self.label_48.setFont(font)
self.label_48.setTextFormat(QtCore.Qt.AutoText)
self.label_48.setObjectName("label_48")
self.verticalLayout_5.addWidget(self.label_48)
self.top_num_spinbox = QtWidgets.QSpinBox(self.edit_top_num_frame)
self.top_num_spinbox.setGeometry(QtCore.QRect(10, 30, 101, 24))
self.top_num_spinbox.setMaximum(999)
self.top_num_spinbox.setObjectName("top_num_spinbox")
self.verticalLayout_5.addWidget(self.top_num_spinbox)
self.verticalLayout_6.addWidget(self.edit_top_num_frame)
self.horizontalLayout.addWidget(self.option_frame)
self.frame_16 = QtWidgets.QFrame(self.frame)
self.frame_16.setGeometry(QtCore.QRect(460, 10, 601, 161))
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
@ -298,9 +251,47 @@ class Ui_visual_tab(object):
self.label_36 = QtWidgets.QLabel(self.frame_16)
self.label_36.setObjectName("label_36")
self.gridLayout_14.addWidget(self.label_36, 2, 0, 1, 1)
self.gridLayout_13.addWidget(self.frame, 0, 0, 1, 3)
self.horizontalLayout_14.addWidget(self.frame_15)
self.verticalLayout.addWidget(self.frame_14)
self.horizontalLayout.addWidget(self.frame_16)
self.verticalLayout_2.addWidget(self.frame)
self.frame_2 = QtWidgets.QFrame(self.frame_15)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.frame_2.sizePolicy().hasHeightForWidth())
self.frame_2.setSizePolicy(sizePolicy)
self.frame_2.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame_2.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame_2.setObjectName("frame_2")
self.gridLayout = QtWidgets.QGridLayout(self.frame_2)
self.gridLayout.setObjectName("gridLayout")
self.visual_vendor_parameter_label = QtWidgets.QLabel(self.frame_2)
self.visual_vendor_parameter_label.setObjectName("visual_vendor_parameter_label")
self.gridLayout.addWidget(self.visual_vendor_parameter_label, 0, 0, 1, 1)
self.visual_vendor_parameter_combobox = QtWidgets.QComboBox(self.frame_2)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.visual_vendor_parameter_combobox.sizePolicy().hasHeightForWidth())
self.visual_vendor_parameter_combobox.setSizePolicy(sizePolicy)
self.visual_vendor_parameter_combobox.setObjectName("visual_vendor_parameter_combobox")
self.gridLayout.addWidget(self.visual_vendor_parameter_combobox, 0, 1, 1, 1)
self.visual_name_label = QtWidgets.QLabel(self.frame_2)
self.visual_name_label.setEnabled(True)
self.visual_name_label.setObjectName("visual_name_label")
self.gridLayout.addWidget(self.visual_name_label, 1, 0, 1, 1)
self.visual_name_parameter_combobox = QtWidgets.QComboBox(self.frame_2)
self.visual_name_parameter_combobox.setEnabled(True)
self.visual_name_parameter_combobox.setEditable(True)
self.visual_name_parameter_combobox.setObjectName("visual_name_parameter_combobox")
self.gridLayout.addWidget(self.visual_name_parameter_combobox, 1, 1, 1, 1)
self.visual_metric_parameter_label = QtWidgets.QLabel(self.frame_2)
self.visual_metric_parameter_label.setObjectName("visual_metric_parameter_label")
self.gridLayout.addWidget(self.visual_metric_parameter_label, 2, 0, 1, 1)
self.metric_Type_comboBox = QtWidgets.QComboBox(self.frame_2)
self.metric_Type_comboBox.setObjectName("metric_Type_comboBox")
self.gridLayout.addWidget(self.metric_Type_comboBox, 2, 1, 1, 1)
self.verticalLayout_2.addWidget(self.frame_2)
self.verticalLayout.addWidget(self.frame_15)
self.search_control_frame_2 = QtWidgets.QFrame(visual_tab)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
@ -351,9 +342,6 @@ class Ui_visual_tab(object):
self.search_start_year_parameter_dateedit_2.setDisplayFormat(_translate("visual_tab", "yyyy"))
self.search_start_year_parameter_label_2.setText(_translate("visual_tab", "Start Year"))
self.search_end_year_parameter_dateedit_2.setDisplayFormat(_translate("visual_tab", "yyyy"))
self.visual_name_label.setText(_translate("visual_tab", "Database"))
self.visual_metric_parameter_label.setText(_translate("visual_tab", "Metric Type "))
self.visual_vendor_parameter_label.setText(_translate("visual_tab", "Vendor"))
self.label_45.setText(_translate("visual_tab", "Select Chart Type"))
self.radioButton_3.setText(_translate("visual_tab", "Vertical Bar"))
self.radioButton.setText(_translate("visual_tab", "Horizontal Bar"))
@ -368,7 +356,11 @@ class Ui_visual_tab(object):
self.label_44.setText(_translate("visual_tab", "Vertical Axis Title"))
self.label_43.setText(_translate("visual_tab", "Horizontal Axis Title"))
self.label_36.setText(_translate("visual_tab", "Chart Title"))
self.visual_vendor_parameter_label.setText(_translate("visual_tab", "Vendor"))
self.visual_name_label.setText(_translate("visual_tab", "Database"))
self.visual_metric_parameter_label.setText(_translate("visual_tab", "Metric Type "))
self.open_folder_checkBox.setText(_translate("visual_tab", "Open Folder"))
self.create_chart_button.setText(_translate("visual_tab", "Create Chart"))
self.open_file_checkBox.setText(_translate("visual_tab", "Open File"))
import Resources_rc

916
ui/VisualTab.ui

File diff suppressed because it is too large Load Diff

1
vendor-lists/template-vendor-lists

@ -0,0 +1 @@
Two files provided here, each designed to be starting points for populating your vendors data. One includes only vendors known to be coounter 5 compliant, the other also includes vendors thought to be still only counter 4 compliant (for use with the Import Report function).

115
vendor-lists/vendors-template-R5-only.tsv

@ -0,0 +1,115 @@
name base_url customer_id requestor_id api_key platform is_non_sushi description companies
DeGruyter (Walter De Gruyter) https:/ams.degruyter.com/rest/COUNTER/v5/reports REQUIRED REQUIRED True Manual COUNTER 5 import; service@degruyter.com
Edward Elgar Publishing https:/ams.elgaronline.com/rest/COUNTER/v5/reports REQUIRED REQUIRED True Manual COUNTER 5 import; info@e-elgar.co.uk
Academy of Management https://journals.aom.org/reports REQUIRED False
American Chemical Society https://pubs.acs.org/reports REQUIRED False
Adam Matthew Digital https://www.counter.amdigital.co.uk/CounterSushi5Api/reports REQUIRED REQUIRED False Adam Matthews primary historical document collections
Akademiai Kiado https://ams.akjournals.com/rest/COUNTER/v5/reports REQUIRED REQUIRED False Changed SUSHI R5 providers April 2020 Sheridan PubFactory
Alexander Street Press https://pqbi.prod.proquest.com/release/sushi/asp/sushi/reports REQUIRED REQUIRED False
Allen Press HEPG Journals https://hepgjournals.org/reports REQUIRED REQUIRED False Atypon
Allen Press Pinnacle https://pinnacle.allenpress.com/reports REQUIRED False Atypon
Allen Press Pinnacle (AAIDD) https://www.aaiddjournals.org/reports REQUIRED False Atypon
American College of Physicians (ACP) https://sitemaster.annals.org/sushi/reports REQUIRED False
American Economic Association (AEA) https://pubs.aeaweb.org/reports REQUIRED False
American Heart Association https://www.ahajournals.org/reports REQUIRED False
American Institute of Aeronautics & Astronautics https://arc.aiaa.org/reports REQUIRED False
American Mathematical Society https://counter.ams.org/counter/r5/reports REQUIRED REQUIRED False
American Medical Association https://sitemaster.jamanetwork.com/sushi/reports REQUIRED False
American Meteorological Society https://journals.ametsoc.org/reports REQUIRED False
American Physical Society https://inqwell.squidsolutions.com/release/aps/sushi/reports REQUIRED False
American Physiological Society https://www.physiology.org/reports REQUIRED REQUIRED False Atypon
American Psychiatric Publishing https://www.psychiatryonline.org/reports REQUIRED False
American Public Health Association https://ajph.aphapublications.org/reports REQUIRED False
American Roentgen Ray Society https://www.ajronline.org/reports REQUIRED REQUIRED False Atypon
American Society for Cell Biology https://www.molbiolcell.org/reports REQUIRED False
American Society Of Civil Engineers (ASCE) https://ascelibrary.org/reports REQUIRED False
American Society of Clinical Oncology (ASCO) https://ascopubs.org/reports REQUIRED False
American Society of Mechanical Engineers (ASME) https://sitemaster.asmedigitalcollection.asme.org/sushi/reports REQUIRED REQUIRED REQUIRED False Silverchair
American Speech-Language-Hearing Association https://pubs.asha.org/reports REQUIRED False
American Thoracic Society https://www.atsjournals.org/reports REQUIRED False
American Veterinary Medical Association https://avmajournals.avma.org/reports REQUIRED REQUIRED False Atypon
Annual Reviews https://www.annualreviews.org/reports REQUIRED REQUIRED False
AOTA (American Occupational Therapy Association) https://sitemaster.ajot.aota.org/sushi/reports REQUIRED False
APS (American Physical Society) https://inqwell.squidsolutions.com/release/aps/sushi/reports REQUIRED REQUIRED False
Berghahn Journals https://ams.berghahnjournals.com/rest/COUNTER/v5/reports REQUIRED False
BioOne https://sushi5.scholarlyiq.com/counter/r5/reports REQUIRED REQUIRED False ScholarlyIQ
BIR (The British Institute of Radiology) https://www.birpublications.org/reports REQUIRED False
Brepols Online https://www.brepolsonline.net/reports REQUIRED False
Brill https://ams.brill.com/rest/COUNTER/v5/reports REQUIRED REQUIRED False
British Medical Journals (BMJ) https://sushi5.scholarlyiq.com/counter/r5/reports REQUIRED REQUIRED False ScholarlyIQ
Cambridge Core https://event-aggregation-api-prod-platform.prod.aop.cambridge.org/reports REQUIRED REQUIRED False
Cambridge University Press http:/counter5.cambridge.org/reports REQUIRED False
Chemical Society of Japan https://www.journal.csj.jp/reports REQUIRED False
CREDO https://search.credoreference.com/reports REQUIRED REQUIRED False
CSIRO (Commonwealth Scientific and Industrial Research Organisation) https://sushi5.scholarlyiq.com/counter/r5/reports REQUIRED REQUIRED False ScholarlyIQ
DesLibris https://connect.liblynx.com/sushi/r5/reports REQUIRED REQUIRED REQUIRED False LibLynx
Duke University Press (Euclid) https://sitemaster.read.dukeupress.edu/sushi/reports REQUIRED REQUIRED REQUIRED False
Duncker & Humblot https://elibrary.duncker-humblot.com/sushi/reports REQUIRED REQUIRED REQUIRED False
EBSCOhost https://sushi.ebscohost.com/R5/reports REQUIRED REQUIRED False Converted to COUNTER 5 back to Jan 2018
Edinburgh University Press https://www.euppublishing.com/reports REQUIRED False
Elsevier Engineering Village https://api.elsevier.com/sushi/reports REQUIRED REQUIRED ev False Checks IP range must be on campus; also have to re-run every new report - always error on first try
Elsevier Scopus https://api.elsevier.com/sushi/reports REQUIRED REQUIRED sc False Checks IP range must be on campus; also have to re-run every new report - always error on first try
Elsevier ScienceDirect https://api.elsevier.com/sushi/reports REQUIRED REQUIRED sd False Checks IP range must be on campus; also have to re-run every new report - always error on first try
Emerald Insight https://connect.liblynx.com/sushi/r5/reports REQUIRED REQUIRED REQUIRED False Liblynx
FASEB https://www.fasebj.org/reports REQUIRED False
Future Medicine https://www.futuremedicine.com/reports REQUIRED False
Gale https://sushi5.galegroup.com/sushi/reports REQUIRED REQUIRED False
GeoscienceWorld https://sitemaster.geoscienceworld.org/sushi/reports REQUIRED REQUIRED REQUIRED False Silverchair
Guilford Press https://guilfordjournals.com/reports REQUIRED False
Harvard Education Publishing Group https://hepgjournals.org/reports REQUIRED False Atypon
Health Affairs https://www.healthaffairs.org/reports REQUIRED False
HighWire Press https://hwdpapi.highwire.org/sushi/reports REQUIRED REQUIRED REQUIRED False "Requester ID, Customer ID and Api_Key are required. API key is the institution's primary e-mail address associated with the HighWire Portal account, followed by ""|"", and then the portal password. For example,
API key: user@highwire.org|Us3rPW
Requester ID: user/email account registered with HighWire
Customer ID: user/email account registered with HighWire"
ICE Virtual Library (Institution of Civil Engineers) https://www.icevirtuallibrary.com/reports REQUIRED False
IEEE Xplore https://c5sushi.mpsinsight.com/c5sushi/services/reports REQUIRED REQUIRED False MPS Insight
IGI Global https://sushi5.igi-global.com/reports REQUIRED REQUIRED True As of April 2020 SUSHI server not compliant, use manual download/import
Inderscience https://inderscienceonline.com/reports REQUIRED False
INFORMS https://pubsonline.informs.org/reports REQUIRED False
Ingentaconnect https://www.ingentaconnect.com/sushiadmin/statistics/sushi/reports REQUIRED REQUIRED False Ingenta Connect hosts journals for various publishers
Journal of Neurosurgery (JNS) https://ams.thejns.org/rest/COUNTER/v5/reports REQUIRED False
Journal of Orthopaedic & Sports Physical Therapy (JOSPT) https://www.jospt.org/reports REQUIRED False
Journal of Studies on Alcohol and Drugs / Rutgers University Press (JSAD) https://www.jsad.com/reports REQUIRED False
JSTOR https://www.jstor.org/sushi/reports REQUIRED REQUIRED False Books and Journals
Karger https://counter.karger.com/reports REQUIRED False
Liverpool University Press https://online.liverpooluniversitypress.co.uk/reports REQUIRED False
Mark Allen Group https://www.magonlinelibrary.com/reports REQUIRED REQUIRED False Atypon
Mary Ann Liebert https://www.liebertpub.com/reports REQUIRED REQUIRED False Atypon
MathSciNet (American Mathematical Society) https://mathscinet.ams.org/counter/r5/reports REQUIRED REQUIRED False
McGraw-Hill https://www.mhebooklibrary.com/reports REQUIRED False
MGG Online https://www.mgg-online.com/mgg/sushi/reports REQUIRED False
Microbiology Society True C5 but not sushi yet as of March 2020
MIT Press https://www.mitpressjournals.org/reports REQUIRED REQUIRED False Atypon
Morgan and Claypook Publishers https://www.morganclaypool.com/reports REQUIRED False
NEJM (New England Journal of Medicine) https://www.nejm.org/reports REQUIRED False
Newsbank https://stats.newsbank.com/sushi_r5/servlet/reports REQUIRED False
NRC Press https://www.nrcresearchpress.com/reports REQUIRED False
OECD iLibrary https://www.oecd-ilibrary.org/counter5/sushi/reports REQUIRED False
Ovid https://stats.ovid.com/C5/sushi/reports REQUIRED REQUIRED False
Oxford (Books) https://sushi5.scholarlyiq.com/counter/r5/reports REQUIRED REQUIRED False ScholarlyIQ
Oxford (Journals) https://sushi5.scholarlyiq.com/counter/r5/reports REQUIRED REQUIRED False ScholarlyIQ
Philosophy Documentation Centre https://sushi5.scholarlyiq.com/counter/r5/reports REQUIRED REQUIRED False ScholarlyIQ
Physical Society of Japan https://journals.jps.jp/reports REQUIRED False
Project HOPE (Health Affairs) https://hope.atyponinsights.com/counter5/reports REQUIRED False Atypon
Project MUSE https://about.muse.jhu.edu/lib/counter5/sushi/reports REQUIRED REQUIRED False
ProQuest https://sushi.proquest.com/counter/r5/reports REQUIRED REQUIRED False
ProQuest Ebook Central https://pqbi.prod.proquest.com/release/sushi/ebooks/r5/reports REQUIRED REQUIRED True As of April 2020, SUSHI server not providing reliable data (reported to Project COUNTER) so consider this one non-SUSHI until reported fixed.
Royal Society https://royalsocietypublishing.org/reports REQUIRED False
Royal Society of Chemistry https://c5sushi.mpsinsight.com/c5sushi/services/reports REQUIRED REQUIRED False
RSNA (Radiological Society of North America) https://pubs.rsna.org/reports REQUIRED False
SAGE Ebooks (Sage SecureCenter) https://securecenter.sagepub.com/SushiService/reports REQUIRED False
SAGE Journals https://journals.sagepub.com/reports REQUIRED REQUIRED False
Scitation - AIP (American Institute of Physics) https://www.scitation.org/reports REQUIRED False
SIAM (Society for Industrial and Applied Mathematics) https://epubs.siam.org/reports REQUIRED False
Society of Exploration Geophysicists https://library.seg.org/reports REQUIRED False
Springer Nature https://counter.public.springernature.app/reports REQUIRED REQUIRED False
Taylor & Francis Ebooks (Books) https://api.taylorandfrancis.com/v2/counterreports/reports REQUIRED False
Taylor & Francis Online (Journals) https://www.tandfonline.com/reports REQUIRED REQUIRED False
UCLA Journals https://uclajournals.org/reports REQUIRED False
University of Chicago Press https://www.journals.uchicago.edu/reports REQUIRED REQUIRED False
University of Toronto Press https://www.utpjournals.press/reports REQUIRED REQUIRED False
Vandenhoeck & Ruprecht https://www.vr-elibrary.de/reports REQUIRED False
Wiley Online Library https://onlinelibrary.wiley.com/reports REQUIRED REQUIRED False Books and journals Atypon
World Bank https://elibrary.worldbank.org/reports REQUIRED False
World Scientific https://www.worldscientific.com/reports REQUIRED False
1 name base_url customer_id requestor_id api_key platform is_non_sushi description companies
2 DeGruyter (Walter De Gruyter) https:/ams.degruyter.com/rest/COUNTER/v5/reports REQUIRED REQUIRED True Manual COUNTER 5 import; service@degruyter.com
3 Edward Elgar Publishing https:/ams.elgaronline.com/rest/COUNTER/v5/reports REQUIRED REQUIRED True Manual COUNTER 5 import; info@e-elgar.co.uk
4 Academy of Management https://journals.aom.org/reports REQUIRED False
5 American Chemical Society https://pubs.acs.org/reports REQUIRED False
6 Adam Matthew Digital https://www.counter.amdigital.co.uk/CounterSushi5Api/reports REQUIRED REQUIRED False Adam Matthews primary historical document collections
7 Akademiai Kiado https://ams.akjournals.com/rest/COUNTER/v5/reports REQUIRED REQUIRED False Changed SUSHI R5 providers April 2020 Sheridan PubFactory
8 Alexander Street Press https://pqbi.prod.proquest.com/release/sushi/asp/sushi/reports REQUIRED REQUIRED False
9 Allen Press HEPG Journals https://hepgjournals.org/reports REQUIRED REQUIRED False Atypon
10 Allen Press Pinnacle https://pinnacle.allenpress.com/reports REQUIRED False Atypon
11 Allen Press Pinnacle (AAIDD) https://www.aaiddjournals.org/reports REQUIRED False Atypon
12 American College of Physicians (ACP) https://sitemaster.annals.org/sushi/reports REQUIRED False
13 American Economic Association (AEA) https://pubs.aeaweb.org/reports REQUIRED False
14 American Heart Association https://www.ahajournals.org/reports REQUIRED False
15 American Institute of Aeronautics & Astronautics https://arc.aiaa.org/reports REQUIRED False
16 American Mathematical Society https://counter.ams.org/counter/r5/reports REQUIRED REQUIRED False
17 American Medical Association https://sitemaster.jamanetwork.com/sushi/reports REQUIRED False
18 American Meteorological Society https://journals.ametsoc.org/reports REQUIRED False
19 American Physical Society https://inqwell.squidsolutions.com/release/aps/sushi/reports REQUIRED False
20 American Physiological Society https://www.physiology.org/reports REQUIRED REQUIRED False Atypon
21 American Psychiatric Publishing https://www.psychiatryonline.org/reports REQUIRED False
22 American Public Health Association https://ajph.aphapublications.org/reports REQUIRED False
23 American Roentgen Ray Society https://www.ajronline.org/reports REQUIRED REQUIRED False Atypon
24 American Society for Cell Biology https://www.molbiolcell.org/reports REQUIRED False
25 American Society Of Civil Engineers (ASCE) https://ascelibrary.org/reports REQUIRED False
26 American Society of Clinical Oncology (ASCO) https://ascopubs.org/reports REQUIRED False
27 American Society of Mechanical Engineers (ASME) https://sitemaster.asmedigitalcollection.asme.org/sushi/reports REQUIRED REQUIRED REQUIRED False Silverchair
28 American Speech-Language-Hearing Association https://pubs.asha.org/reports REQUIRED False
29 American Thoracic Society https://www.atsjournals.org/reports REQUIRED False
30 American Veterinary Medical Association https://avmajournals.avma.org/reports REQUIRED REQUIRED False Atypon
31 Annual Reviews https://www.annualreviews.org/reports REQUIRED REQUIRED False
32 AOTA (American Occupational Therapy Association) https://sitemaster.ajot.aota.org/sushi/reports REQUIRED False
33 APS (American Physical Society) https://inqwell.squidsolutions.com/release/aps/sushi/reports REQUIRED REQUIRED False
34 Berghahn Journals https://ams.berghahnjournals.com/rest/COUNTER/v5/reports REQUIRED False
35 BioOne https://sushi5.scholarlyiq.com/counter/r5/reports REQUIRED REQUIRED False ScholarlyIQ
36 BIR (The British Institute of Radiology) https://www.birpublications.org/reports REQUIRED False
37 Brepols Online https://www.brepolsonline.net/reports REQUIRED False
38 Brill https://ams.brill.com/rest/COUNTER/v5/reports REQUIRED REQUIRED False
39 British Medical Journals (BMJ) https://sushi5.scholarlyiq.com/counter/r5/reports REQUIRED REQUIRED False ScholarlyIQ
40 Cambridge Core https://event-aggregation-api-prod-platform.prod.aop.cambridge.org/reports REQUIRED REQUIRED False
41 Cambridge University Press http:/counter5.cambridge.org/reports REQUIRED False
42 Chemical Society of Japan https://www.journal.csj.jp/reports REQUIRED False
43 CREDO https://search.credoreference.com/reports REQUIRED REQUIRED False
44 CSIRO (Commonwealth Scientific and Industrial Research Organisation) https://sushi5.scholarlyiq.com/counter/r5/reports REQUIRED REQUIRED False ScholarlyIQ
45 DesLibris https://connect.liblynx.com/sushi/r5/reports REQUIRED REQUIRED REQUIRED False LibLynx
46 Duke University Press (Euclid) https://sitemaster.read.dukeupress.edu/sushi/reports REQUIRED REQUIRED REQUIRED False
47 Duncker & Humblot https://elibrary.duncker-humblot.com/sushi/reports REQUIRED REQUIRED REQUIRED False
48 EBSCOhost https://sushi.ebscohost.com/R5/reports REQUIRED REQUIRED False Converted to COUNTER 5 back to Jan 2018
49 Edinburgh University Press https://www.euppublishing.com/reports REQUIRED False
50 Elsevier Engineering Village https://api.elsevier.com/sushi/reports REQUIRED REQUIRED ev False Checks IP range must be on campus; also have to re-run every new report - always error on first try
51 Elsevier Scopus https://api.elsevier.com/sushi/reports REQUIRED REQUIRED sc False Checks IP range must be on campus; also have to re-run every new report - always error on first try
52 Elsevier ScienceDirect https://api.elsevier.com/sushi/reports REQUIRED REQUIRED sd False Checks IP range must be on campus; also have to re-run every new report - always error on first try
53 Emerald Insight https://connect.liblynx.com/sushi/r5/reports REQUIRED REQUIRED REQUIRED False Liblynx
54 FASEB https://www.fasebj.org/reports REQUIRED False
55 Future Medicine https://www.futuremedicine.com/reports REQUIRED False
56 Gale https://sushi5.galegroup.com/sushi/reports REQUIRED REQUIRED False
57 GeoscienceWorld https://sitemaster.geoscienceworld.org/sushi/reports REQUIRED REQUIRED REQUIRED False Silverchair
58 Guilford Press https://guilfordjournals.com/reports REQUIRED False
59 Harvard Education Publishing Group https://hepgjournals.org/reports REQUIRED False Atypon
60 Health Affairs https://www.healthaffairs.org/reports REQUIRED False
61 HighWire Press https://hwdpapi.highwire.org/sushi/reports REQUIRED REQUIRED REQUIRED False Requester ID, Customer ID and Api_Key are required. API key is the institution's primary e-mail address associated with the HighWire Portal account, followed by "|", and then the portal password. For example, API key: user@highwire.org|Us3rPW Requester ID: user/email account registered with HighWire Customer ID: user/email account registered with HighWire
62 ICE Virtual Library (Institution of Civil Engineers) https://www.icevirtuallibrary.com/reports REQUIRED False
63 IEEE Xplore https://c5sushi.mpsinsight.com/c5sushi/services/reports REQUIRED REQUIRED False MPS Insight
64 IGI Global https://sushi5.igi-global.com/reports REQUIRED REQUIRED True As of April 2020 SUSHI server not compliant, use manual download/import
65 Inderscience https://inderscienceonline.com/reports REQUIRED False
66 INFORMS https://pubsonline.informs.org/reports REQUIRED False
67 Ingentaconnect https://www.ingentaconnect.com/sushiadmin/statistics/sushi/reports REQUIRED REQUIRED False Ingenta Connect hosts journals for various publishers
68 Journal of Neurosurgery (JNS) https://ams.thejns.org/rest/COUNTER/v5/reports REQUIRED False
69 Journal of Orthopaedic & Sports Physical Therapy (JOSPT) https://www.jospt.org/reports REQUIRED False
70 Journal of Studies on Alcohol and Drugs / Rutgers University Press (JSAD) https://www.jsad.com/reports REQUIRED False
71 JSTOR https://www.jstor.org/sushi/reports REQUIRED REQUIRED False Books and Journals
72 Karger https://counter.karger.com/reports REQUIRED False
73 Liverpool University Press https://online.liverpooluniversitypress.co.uk/reports REQUIRED False
74 Mark Allen Group https://www.magonlinelibrary.com/reports REQUIRED REQUIRED False Atypon
75 Mary Ann Liebert https://www.liebertpub.com/reports REQUIRED REQUIRED False Atypon
76 MathSciNet (American Mathematical Society) https://mathscinet.ams.org/counter/r5/reports REQUIRED REQUIRED False
77 McGraw-Hill https://www.mhebooklibrary.com/reports REQUIRED False
78 MGG Online https://www.mgg-online.com/mgg/sushi/reports REQUIRED False
79 Microbiology Society True C5 but not sushi yet as of March 2020
80 MIT Press https://www.mitpressjournals.org/reports REQUIRED REQUIRED False Atypon
81 Morgan and Claypook Publishers https://www.morganclaypool.com/reports REQUIRED False
82 NEJM (New England Journal of Medicine) https://www.nejm.org/reports REQUIRED False
83 Newsbank https://stats.newsbank.com/sushi_r5/servlet/reports REQUIRED False
84 NRC Press https://www.nrcresearchpress.com/reports REQUIRED False
85 OECD iLibrary https://www.oecd-ilibrary.org/counter5/sushi/reports REQUIRED False
86 Ovid https://stats.ovid.com/C5/sushi/reports REQUIRED REQUIRED False
87 Oxford (Books) https://sushi5.scholarlyiq.com/counter/r5/reports REQUIRED REQUIRED False ScholarlyIQ
88 Oxford (Journals) https://sushi5.scholarlyiq.com/counter/r5/reports REQUIRED REQUIRED False ScholarlyIQ
89 Philosophy Documentation Centre https://sushi5.scholarlyiq.com/counter/r5/reports REQUIRED REQUIRED False ScholarlyIQ
90 Physical Society of Japan https://journals.jps.jp/reports REQUIRED False
91 Project HOPE (Health Affairs) https://hope.atyponinsights.com/counter5/reports REQUIRED False Atypon
92 Project MUSE https://about.muse.jhu.edu/lib/counter5/sushi/reports REQUIRED REQUIRED False
93 ProQuest https://sushi.proquest.com/counter/r5/reports REQUIRED REQUIRED False
94 ProQuest Ebook Central https://pqbi.prod.proquest.com/release/sushi/ebooks/r5/reports REQUIRED REQUIRED True As of April 2020, SUSHI server not providing reliable data (reported to Project COUNTER) so consider this one non-SUSHI until reported fixed.
95 Royal Society https://royalsocietypublishing.org/reports REQUIRED False
96 Royal Society of Chemistry https://c5sushi.mpsinsight.com/c5sushi/services/reports REQUIRED REQUIRED False
97 RSNA (Radiological Society of North America) https://pubs.rsna.org/reports REQUIRED False
98 SAGE Ebooks (Sage SecureCenter) https://securecenter.sagepub.com/SushiService/reports REQUIRED False
99 SAGE Journals https://journals.sagepub.com/reports REQUIRED REQUIRED False
100 Scitation - AIP (American Institute of Physics) https://www.scitation.org/reports REQUIRED False
101 SIAM (Society for Industrial and Applied Mathematics) https://epubs.siam.org/reports REQUIRED False
102 Society of Exploration Geophysicists https://library.seg.org/reports REQUIRED False
103 Springer Nature https://counter.public.springernature.app/reports REQUIRED REQUIRED False
104 Taylor & Francis Ebooks (Books) https://api.taylorandfrancis.com/v2/counterreports/reports REQUIRED False
105 Taylor & Francis Online (Journals) https://www.tandfonline.com/reports REQUIRED REQUIRED False
106 UCLA Journals https://uclajournals.org/reports REQUIRED False
107 University of Chicago Press https://www.journals.uchicago.edu/reports REQUIRED REQUIRED False
108 University of Toronto Press https://www.utpjournals.press/reports REQUIRED REQUIRED False
109 Vandenhoeck & Ruprecht https://www.vr-elibrary.de/reports REQUIRED False
110 Wiley Online Library https://onlinelibrary.wiley.com/reports REQUIRED REQUIRED False Books and journals Atypon
111 World Bank https://elibrary.worldbank.org/reports REQUIRED False
112 World Scientific https://www.worldscientific.com/reports REQUIRED False

183
vendor-lists/vendors-template-with-r4-vendors.tsv

@ -0,0 +1,183 @@
name base_url customer_id requestor_id api_key platform is_non_sushi description companies
AACCI (American Association of Cereal Chemists International) True BR2, JR5, JR1GOA, JR1, PR1, BR3
AAIDD (American Association of Intellectual and Developmental Disabilities) True JR5, JR1GOA, JR1, PR1, BR3
ABC-CLIO True Counter 4 only for import conversion; DB1
Academy of Management https://journals.aom.org/reports REQUIRED False
Accessible Archives True
ACM Digital Library (Association for Computing Machinery) True
American Chemical Society https://pubs.acs.org/reports REQUIRED False
ACSESS Digital Library (American Society of Agronomy, Crop Science Society of America, and Soil Science Society of America (ASA, CSSA & SSSA)) True
Adam Matthew Digital https://www.counter.amdigital.co.uk/CounterSushi5Api/reports REQUIRED REQUIRED False Adam Matthews primary historical document collections
AIAA (American Institute of Aeronautics and Astronautics) True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, JR1a, PR1, BR3
Akademiai Kiado https://ams.akjournals.com/rest/COUNTER/v5/reports REQUIRED REQUIRED False Changed SUSHI R5 providers April 2020 Sheridan PubFactory
Alexander Street Press https://pqbi.prod.proquest.com/release/sushi/asp/sushi/reports REQUIRED REQUIRED False
Allen Press HEPG Journals https://hepgjournals.org/reports REQUIRED REQUIRED False Atypon
Allen Press Pinnacle https://pinnacle.allenpress.com/reports REQUIRED False Atypon
Allen Press Pinnacle (AAIDD) https://www.aaiddjournals.org/reports REQUIRED False Atypon
American College of Physicians (ACP) https://sitemaster.annals.org/sushi/reports REQUIRED False
American Economic Association (AEA) https://pubs.aeaweb.org/reports REQUIRED False
American Heart Association https://www.ahajournals.org/reports REQUIRED False
American Institute of Aeronautics & Astronautics https://arc.aiaa.org/reports REQUIRED False
American Mathematical Society https://counter.ams.org/counter/r5/reports REQUIRED REQUIRED False
American Medical Association https://sitemaster.jamanetwork.com/sushi/reports REQUIRED False
American Mental Health Counselors Association True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, PR1, BR3
American Meteorological Society https://journals.ametsoc.org/reports REQUIRED False
American Physical Society https://inqwell.squidsolutions.com/release/aps/sushi/reports REQUIRED False
American Physiological Society https://www.physiology.org/reports REQUIRED REQUIRED False Atypon
American Podiatric Medical Association True Counter 4 only for import conversion; JR1, JR2, JR1GOA, JR5, BR3, PR1
American Psychiatric Publishing https://www.psychiatryonline.org/reports REQUIRED False
American Public Health Association https://ajph.aphapublications.org/reports REQUIRED False
American Roentgen Ray Society https://www.ajronline.org/reports REQUIRED REQUIRED False Atypon
American Society for Cell Biology https://www.molbiolcell.org/reports REQUIRED False
American Society Of Civil Engineers (ASCE) https://ascelibrary.org/reports REQUIRED False
American Society of Clinical Oncology (ASCO) https://ascopubs.org/reports REQUIRED False
American Society of Mechanical Engineers (ASME) https://sitemaster.asmedigitalcollection.asme.org/sushi/reports REQUIRED REQUIRED REQUIRED False Silverchair
American Society of Tropical Medicine and Hygiene True
American Speech-Language-Hearing Association https://pubs.asha.org/reports REQUIRED False
American Thoracic Society https://www.atsjournals.org/reports REQUIRED False
American Veterinary Medical Association https://avmajournals.avma.org/reports REQUIRED REQUIRED False Atypon
AMSUS (The Society of Federal Health Professionals) True Counter 4 only for import conversion; JR5, JR1, PR1
Annual Reviews https://www.annualreviews.org/reports REQUIRED REQUIRED False
AOTA (American Occupational Therapy Association) https://sitemaster.ajot.aota.org/sushi/reports REQUIRED False
APA PsycNET True
APS (American Physical Society) https://inqwell.squidsolutions.com/release/aps/sushi/reports REQUIRED REQUIRED False
APS (American Phytopathological Society) True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, PR1, BR3
ASA (American Statistical Association) True Counter 4 only for import conversion; JR1, DB1
ASM (American Society for Microbiology) True Counter 4 only for import conversion; BR2, JR1GOA, JR1, PR1, BR3
Berghahn Journals https://ams.berghahnjournals.com/rest/COUNTER/v5/reports REQUIRED False
BioMed Central True Counter 4 only for import conversion; JR5, JR1GOA, JR1
BioOne https://sushi5.scholarlyiq.com/counter/r5/reports REQUIRED REQUIRED False ScholarlyIQ
BIR (The British Institute of Radiology) https://www.birpublications.org/reports REQUIRED False
Bone & Joint Publishing True
Brepols Online https://www.brepolsonline.net/reports REQUIRED False
Brill https://ams.brill.com/rest/COUNTER/v5/reports REQUIRED REQUIRED False
Britannica True
British Institute of Radiology True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1, BR3
British Medical Journals (BMJ) https://sushi5.scholarlyiq.com/counter/r5/reports REQUIRED REQUIRED False ScholarlyIQ
Cambridge Core https://event-aggregation-api-prod-platform.prod.aop.cambridge.org/reports REQUIRED REQUIRED False
Cambridge University Press http:/counter5.cambridge.org/reports REQUIRED False
Canadian Science Publishing True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1, BR3
CFA Publications True Counter 4 only for import conversion; JR5, JR1, PR1
Chemical Society of Japan https://www.journal.csj.jp/reports REQUIRED False
Corrosion (The Journal of Science & Engineering) True Counter 4 only for import conversion; JR5, JR1GOA, JR1
CRCnetBase (CRC netBase) True Counter 4 only for import conversion; BR2, PR1, BR3
CREDO https://search.credoreference.com/reports REQUIRED REQUIRED False
CSIRO (Commonwealth Scientific and Industrial Research Organisation) https://sushi5.scholarlyiq.com/counter/r5/reports REQUIRED REQUIRED False ScholarlyIQ
DeGruyter (Walter De Gruyter) https:/ams.degruyter.com/rest/COUNTER/v5/reports REQUIRED REQUIRED True Manual COUNTER 5 import; service@degruyter.com
DesLibris https://connect.liblynx.com/sushi/r5/reports REQUIRED REQUIRED REQUIRED False LibLynx
Duke University Press (Euclid) https://sitemaster.read.dukeupress.edu/sushi/reports REQUIRED REQUIRED REQUIRED False
Duncker & Humblot https://elibrary.duncker-humblot.com/sushi/reports REQUIRED REQUIRED REQUIRED False
EBSCOhost https://sushi.ebscohost.com/R5/reports REQUIRED REQUIRED False Converted to COUNTER 5 back to 2018
Edinburgh University Press https://www.euppublishing.com/reports REQUIRED False
EDP Sciences (Astronomy and Astrophysics) True
Edward Elgar Publishing https:/ams.elgaronline.com/rest/COUNTER/v5/reports REQUIRED REQUIRED True Manual COUNTER 5 import; info@e-elgar.co.uk
Elsevier Engineering Village https://api.elsevier.com/sushi/reports REQUIRED REQUIRED ev False Checks IP range must be on campus; also have to re-run every new report - always error on first try
Elsevier Scopus https://api.elsevier.com/sushi/reports REQUIRED REQUIRED sc False Checks IP range must be on campus; also have to re-run every new report - always error on first try
Elsevier ScienceDirect https://api.elsevier.com/sushi/reports REQUIRED REQUIRED sd False Checks IP range must be on campus; also have to re-run every new report - always error on first try
Emerald Insight https://connect.liblynx.com/sushi/r5/reports REQUIRED REQUIRED REQUIRED False Liblynx
EMS (European Mathematical Society) True Counter 4 only for import conversion; JR1:R3
Endocrine Society Journals True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, PR1, JR1a, BR3
Families in Society True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, PR1, BR3
FASEB https://www.fasebj.org/reports REQUIRED False
Future Medicine https://www.futuremedicine.com/reports REQUIRED False
Future Science True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1
Gale https://sushi5.galegroup.com/sushi/reports REQUIRED REQUIRED False
GeoscienceWorld https://sitemaster.geoscienceworld.org/sushi/reports REQUIRED REQUIRED REQUIRED False Silverchair
Guilford Press https://guilfordjournals.com/reports REQUIRED False
Hanser True Counter 4 only for import conversion; BR2, JR5, JR1, PR1, BR3
Harvard Education Publishing Group https://hepgjournals.org/reports REQUIRED False Atypon
Health Affairs https://www.healthaffairs.org/reports REQUIRED False
HighWire Press https://hwdpapi.highwire.org/sushi/reports REQUIRED REQUIRED REQUIRED False "API key is the institution's primary e-mail address associated with the HighWire Portal account, followed by ""|"", and then the portal password. For example,
API key: user@highwire.org|Us3rPW
Requester ID: user/email account registered with HighWire
Customer ID: user/email account registered with HighWire"
Hogrefe True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1
Human Kinetics True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1
ICE Virtual Library (Institution of Civil Engineers) https://www.icevirtuallibrary.com/reports REQUIRED False
Idunn True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1
IEEE Xplore https://c5sushi.mpsinsight.com/c5sushi/services/reports REQUIRED REQUIRED False MPS Insight
IET (Institution of Engineering and Technology) True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, BR1, PR1, BR3
IGI Global https://sushi5.igi-global.com/reports REQUIRED REQUIRED True As of April 2020 SUSHI server not compliant, use manual download/import
IMF (International Monetary Fund) True Counter 4 only for import conversion; DB1
INA (Irish Newspaper Archives) True
Inderscience https://inderscienceonline.com/reports REQUIRED False
Informit True Counter 4 only for import conversion; BR2, JR5, JR1, BR1
INFORMS https://pubsonline.informs.org/reports REQUIRED False
Ingentaconnect https://www.ingentaconnect.com/sushiadmin/statistics/sushi/reports REQUIRED REQUIRED False Ingenta Connect hosts journals for various publishers
IOS Press - CAB Journals & eBooks True
IOS Press (formerly MetaPress) True Counter 4 only for import conversion; BR2, JR1, BR1, DB1, PR1, BR3
John Benjamins True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1, BR3
Journal of Clinical Psychiatry True
Journal of Coastal research True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1, BR3
Journal of Graduate Medical Education True Counter 4 only for import conversion; JR1
Journal of Marketing Research True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1, BR3
Journal of Neurosurgery (JNS) https://ams.thejns.org/rest/COUNTER/v5/reports REQUIRED False
Journal of Oral Implantology True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, PR1, BR3
Journal of Orthopaedic & Sports Physical Therapy (JOSPT) https://www.jospt.org/reports REQUIRED False
Journal of Parasitology True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, PR1, BR3
Journal of Periodontology Online True Counter 4 only for import conversion; JR5, JR1, PR1
Journal of Studies on Alcohol and Drugs / Rutgers University Press (JSAD) https://www.jsad.com/reports REQUIRED False
Journal of the Physical Society of Japan True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, PR1, BR3
JSTOR https://www.jstor.org/sushi/reports REQUIRED REQUIRED False Books and Journals
Karger https://counter.karger.com/reports REQUIRED False
Kluwer Law International True
Liverpool University Press https://online.liverpooluniversitypress.co.uk/reports REQUIRED False
Mark Allen Group https://www.magonlinelibrary.com/reports REQUIRED REQUIRED False Atypon
Mary Ann Liebert https://www.liebertpub.com/reports REQUIRED REQUIRED False Atypon
MathSciNet (American Mathematical Society) https://mathscinet.ams.org/counter/r5/reports REQUIRED REQUIRED False
McGraw-Hill https://www.mhebooklibrary.com/reports REQUIRED False
MGG Online https://www.mgg-online.com/mgg/sushi/reports REQUIRED False
Microbiology Society True Counter 4 only for import conversion; C5 but not sushi yet as of March 2020
Military Medicine True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1
MIT Press https://www.mitpressjournals.org/reports REQUIRED REQUIRED False Atypon
MLA (Modern Language Association) True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1
Morgan and Claypook Publishers https://www.morganclaypool.com/reports REQUIRED False
NEJM (New England Journal of Medicine) https://www.nejm.org/reports REQUIRED False
Newsbank https://stats.newsbank.com/sushi_r5/servlet/reports REQUIRED False
NRC Press https://www.nrcresearchpress.com/reports REQUIRED False
OECD iLibrary https://www.oecd-ilibrary.org/counter5/sushi/reports REQUIRED False
OSA InfoBase (Optics InfoBase) True
Ovid https://stats.ovid.com/C5/sushi/reports REQUIRED REQUIRED False
Oxford (Books) https://sushi5.scholarlyiq.com/counter/r5/reports REQUIRED REQUIRED False ScholarlyIQ
Oxford (Journals) https://sushi5.scholarlyiq.com/counter/r5/reports REQUIRED REQUIRED False ScholarlyIQ
Philosophy Documentation Centre https://sushi5.scholarlyiq.com/counter/r5/reports REQUIRED REQUIRED False ScholarlyIQ
Physical Society of Japan https://journals.jps.jp/reports REQUIRED False
Physicians Postgraduate Press True
Practical Action Publishing True Counter 4 only for import conversion; JR1, PR1, JR2, BR2, BR3
Professional School Counseling True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, PR1, BR3
Project HOPE (Health Affairs) https://hope.atyponinsights.com/counter5/reports REQUIRED False Atypon
Project MUSE https://about.muse.jhu.edu/lib/counter5/sushi/reports REQUIRED REQUIRED False
ProQuest https://sushi.proquest.com/counter/r5/reports REQUIRED REQUIRED False
ProQuest Ebook Central https://pqbi.prod.proquest.com/release/sushi/ebooks/r5/reports REQUIRED REQUIRED True As of April 2020, SUSHI server not providing reliable data (reported to Project COUNTER) so consider this one non-SUSHI until reported fixed.
Psychiatry Online True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, BR1, JR1a, PR1, BR3
Radiation Research True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, PR1, BR3
RCN (Royal College of Nursing) True
Royal College of Surgeons of England True Counter 4 only for import conversion; JR1, PR1
Royal Society https://royalsocietypublishing.org/reports REQUIRED False
Royal Society of Chemistry https://c5sushi.mpsinsight.com/c5sushi/services/reports REQUIRED REQUIRED False
RSNA (Radiological Society of North America) https://pubs.rsna.org/reports REQUIRED False
SAGE Ebooks (Sage SecureCenter) https://securecenter.sagepub.com/SushiService/reports REQUIRED False
SAGE Journals https://journals.sagepub.com/reports REQUIRED REQUIRED False
Science Societies True
Scitation - AIP (American Institute of Physics) https://www.scitation.org/reports REQUIRED False
SEG (Society of Exploration Geophysicists) True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, PR1, BR3
SFAA (Society for Applied Anthropology) True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1, BR3
SIAM (Society for Industrial and Applied Mathematics) https://epubs.siam.org/reports REQUIRED False
Society of Exploration Geophysicists https://library.seg.org/reports REQUIRED False
SPIE (Society of Photo-Optical Instrumentation Engineers) True
Springer Nature https://counter.public.springernature.app/reports REQUIRED REQUIRED False
Taylor & Francis Ebooks (Books) https://api.taylorandfrancis.com/v2/counterreports/reports REQUIRED False
Taylor & Francis Online (Journals) https://www.tandfonline.com/reports REQUIRED REQUIRED False
The Cleft Palate - Craniofacial Journal True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1, BR3
Thieme Planta Medica True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1
Transportation Research Board True Counter 4 only for import conversion; JR5, JR1, PR1, BR3
UCLA Journals https://uclajournals.org/reports REQUIRED False
University of Chicago Press https://www.journals.uchicago.edu/reports REQUIRED REQUIRED False
University of Texas Press True Counter 4 only for import conversion; JR1
University of Toronto Press https://www.utpjournals.press/reports REQUIRED REQUIRED False
UNWTO (United Nations World Tourism Organization) True Counter 4 only for import conversion; BR2, JR5, JR1, PR1
Vandenhoeck & Ruprecht https://www.vr-elibrary.de/reports REQUIRED False
Wageningen Academic Publishers True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, PR1, BR3
Wiley Online Library https://onlinelibrary.wiley.com/reports REQUIRED REQUIRED False Books and journals Atypon
World Bank https://elibrary.worldbank.org/reports REQUIRED False
World Scientific https://www.worldscientific.com/reports REQUIRED False
1 name base_url customer_id requestor_id api_key platform is_non_sushi description companies
2 AACCI (American Association of Cereal Chemists International) True BR2, JR5, JR1GOA, JR1, PR1, BR3
3 AAIDD (American Association of Intellectual and Developmental Disabilities) True JR5, JR1GOA, JR1, PR1, BR3
4 ABC-CLIO True Counter 4 only for import conversion; DB1
5 Academy of Management https://journals.aom.org/reports REQUIRED False
6 Accessible Archives True
7 ACM Digital Library (Association for Computing Machinery) True
8 American Chemical Society https://pubs.acs.org/reports REQUIRED False
9 ACSESS Digital Library (American Society of Agronomy, Crop Science Society of America, and Soil Science Society of America (ASA, CSSA & SSSA)) True
10 Adam Matthew Digital https://www.counter.amdigital.co.uk/CounterSushi5Api/reports REQUIRED REQUIRED False Adam Matthews primary historical document collections
11 AIAA (American Institute of Aeronautics and Astronautics) True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, JR1a, PR1, BR3
12 Akademiai Kiado https://ams.akjournals.com/rest/COUNTER/v5/reports REQUIRED REQUIRED False Changed SUSHI R5 providers April 2020 Sheridan PubFactory
13 Alexander Street Press https://pqbi.prod.proquest.com/release/sushi/asp/sushi/reports REQUIRED REQUIRED False
14 Allen Press HEPG Journals https://hepgjournals.org/reports REQUIRED REQUIRED False Atypon
15 Allen Press Pinnacle https://pinnacle.allenpress.com/reports REQUIRED False Atypon
16 Allen Press Pinnacle (AAIDD) https://www.aaiddjournals.org/reports REQUIRED False Atypon
17 American College of Physicians (ACP) https://sitemaster.annals.org/sushi/reports REQUIRED False
18 American Economic Association (AEA) https://pubs.aeaweb.org/reports REQUIRED False
19 American Heart Association https://www.ahajournals.org/reports REQUIRED False
20 American Institute of Aeronautics & Astronautics https://arc.aiaa.org/reports REQUIRED False
21 American Mathematical Society https://counter.ams.org/counter/r5/reports REQUIRED REQUIRED False
22 American Medical Association https://sitemaster.jamanetwork.com/sushi/reports REQUIRED False
23 American Mental Health Counselors Association True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, PR1, BR3
24 American Meteorological Society https://journals.ametsoc.org/reports REQUIRED False
25 American Physical Society https://inqwell.squidsolutions.com/release/aps/sushi/reports REQUIRED False
26 American Physiological Society https://www.physiology.org/reports REQUIRED REQUIRED False Atypon
27 American Podiatric Medical Association True Counter 4 only for import conversion; JR1, JR2, JR1GOA, JR5, BR3, PR1
28 American Psychiatric Publishing https://www.psychiatryonline.org/reports REQUIRED False
29 American Public Health Association https://ajph.aphapublications.org/reports REQUIRED False
30 American Roentgen Ray Society https://www.ajronline.org/reports REQUIRED REQUIRED False Atypon
31 American Society for Cell Biology https://www.molbiolcell.org/reports REQUIRED False
32 American Society Of Civil Engineers (ASCE) https://ascelibrary.org/reports REQUIRED False
33 American Society of Clinical Oncology (ASCO) https://ascopubs.org/reports REQUIRED False
34 American Society of Mechanical Engineers (ASME) https://sitemaster.asmedigitalcollection.asme.org/sushi/reports REQUIRED REQUIRED REQUIRED False Silverchair
35 American Society of Tropical Medicine and Hygiene True
36 American Speech-Language-Hearing Association https://pubs.asha.org/reports REQUIRED False
37 American Thoracic Society https://www.atsjournals.org/reports REQUIRED False
38 American Veterinary Medical Association https://avmajournals.avma.org/reports REQUIRED REQUIRED False Atypon
39 AMSUS (The Society of Federal Health Professionals) True Counter 4 only for import conversion; JR5, JR1, PR1
40 Annual Reviews https://www.annualreviews.org/reports REQUIRED REQUIRED False
41 AOTA (American Occupational Therapy Association) https://sitemaster.ajot.aota.org/sushi/reports REQUIRED False
42 APA PsycNET True
43 APS (American Physical Society) https://inqwell.squidsolutions.com/release/aps/sushi/reports REQUIRED REQUIRED False
44 APS (American Phytopathological Society) True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, PR1, BR3
45 ASA (American Statistical Association) True Counter 4 only for import conversion; JR1, DB1
46 ASM (American Society for Microbiology) True Counter 4 only for import conversion; BR2, JR1GOA, JR1, PR1, BR3
47 Berghahn Journals https://ams.berghahnjournals.com/rest/COUNTER/v5/reports REQUIRED False
48 BioMed Central True Counter 4 only for import conversion; JR5, JR1GOA, JR1
49 BioOne https://sushi5.scholarlyiq.com/counter/r5/reports REQUIRED REQUIRED False ScholarlyIQ
50 BIR (The British Institute of Radiology) https://www.birpublications.org/reports REQUIRED False
51 Bone & Joint Publishing True
52 Brepols Online https://www.brepolsonline.net/reports REQUIRED False
53 Brill https://ams.brill.com/rest/COUNTER/v5/reports REQUIRED REQUIRED False
54 Britannica True
55 British Institute of Radiology True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1, BR3
56 British Medical Journals (BMJ) https://sushi5.scholarlyiq.com/counter/r5/reports REQUIRED REQUIRED False ScholarlyIQ
57 Cambridge Core https://event-aggregation-api-prod-platform.prod.aop.cambridge.org/reports REQUIRED REQUIRED False
58 Cambridge University Press http:/counter5.cambridge.org/reports REQUIRED False
59 Canadian Science Publishing True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1, BR3
60 CFA Publications True Counter 4 only for import conversion; JR5, JR1, PR1
61 Chemical Society of Japan https://www.journal.csj.jp/reports REQUIRED False
62 Corrosion (The Journal of Science & Engineering) True Counter 4 only for import conversion; JR5, JR1GOA, JR1
63 CRCnetBase (CRC netBase) True Counter 4 only for import conversion; BR2, PR1, BR3
64 CREDO https://search.credoreference.com/reports REQUIRED REQUIRED False
65 CSIRO (Commonwealth Scientific and Industrial Research Organisation) https://sushi5.scholarlyiq.com/counter/r5/reports REQUIRED REQUIRED False ScholarlyIQ
66 DeGruyter (Walter De Gruyter) https:/ams.degruyter.com/rest/COUNTER/v5/reports REQUIRED REQUIRED True Manual COUNTER 5 import; service@degruyter.com
67 DesLibris https://connect.liblynx.com/sushi/r5/reports REQUIRED REQUIRED REQUIRED False LibLynx
68 Duke University Press (Euclid) https://sitemaster.read.dukeupress.edu/sushi/reports REQUIRED REQUIRED REQUIRED False
69 Duncker & Humblot https://elibrary.duncker-humblot.com/sushi/reports REQUIRED REQUIRED REQUIRED False
70 EBSCOhost https://sushi.ebscohost.com/R5/reports REQUIRED REQUIRED False Converted to COUNTER 5 back to 2018
71 Edinburgh University Press https://www.euppublishing.com/reports REQUIRED False
72 EDP Sciences (Astronomy and Astrophysics) True
73 Edward Elgar Publishing https:/ams.elgaronline.com/rest/COUNTER/v5/reports REQUIRED REQUIRED True Manual COUNTER 5 import; info@e-elgar.co.uk
74 Elsevier Engineering Village https://api.elsevier.com/sushi/reports REQUIRED REQUIRED ev False Checks IP range must be on campus; also have to re-run every new report - always error on first try
75 Elsevier Scopus https://api.elsevier.com/sushi/reports REQUIRED REQUIRED sc False Checks IP range must be on campus; also have to re-run every new report - always error on first try
76 Elsevier ScienceDirect https://api.elsevier.com/sushi/reports REQUIRED REQUIRED sd False Checks IP range must be on campus; also have to re-run every new report - always error on first try
77 Emerald Insight https://connect.liblynx.com/sushi/r5/reports REQUIRED REQUIRED REQUIRED False Liblynx
78 EMS (European Mathematical Society) True Counter 4 only for import conversion; JR1:R3
79 Endocrine Society Journals True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, PR1, JR1a, BR3
80 Families in Society True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, PR1, BR3
81 FASEB https://www.fasebj.org/reports REQUIRED False
82 Future Medicine https://www.futuremedicine.com/reports REQUIRED False
83 Future Science True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1
84 Gale https://sushi5.galegroup.com/sushi/reports REQUIRED REQUIRED False
85 GeoscienceWorld https://sitemaster.geoscienceworld.org/sushi/reports REQUIRED REQUIRED REQUIRED False Silverchair
86 Guilford Press https://guilfordjournals.com/reports REQUIRED False
87 Hanser True Counter 4 only for import conversion; BR2, JR5, JR1, PR1, BR3
88 Harvard Education Publishing Group https://hepgjournals.org/reports REQUIRED False Atypon
89 Health Affairs https://www.healthaffairs.org/reports REQUIRED False
90 HighWire Press https://hwdpapi.highwire.org/sushi/reports REQUIRED REQUIRED REQUIRED False API key is the institution's primary e-mail address associated with the HighWire Portal account, followed by "|", and then the portal password. For example, API key: user@highwire.org|Us3rPW Requester ID: user/email account registered with HighWire Customer ID: user/email account registered with HighWire
91 Hogrefe True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1
92 Human Kinetics True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1
93 ICE Virtual Library (Institution of Civil Engineers) https://www.icevirtuallibrary.com/reports REQUIRED False
94 Idunn True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1
95 IEEE Xplore https://c5sushi.mpsinsight.com/c5sushi/services/reports REQUIRED REQUIRED False MPS Insight
96 IET (Institution of Engineering and Technology) True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, BR1, PR1, BR3
97 IGI Global https://sushi5.igi-global.com/reports REQUIRED REQUIRED True As of April 2020 SUSHI server not compliant, use manual download/import
98 IMF (International Monetary Fund) True Counter 4 only for import conversion; DB1
99 INA (Irish Newspaper Archives) True
100 Inderscience https://inderscienceonline.com/reports REQUIRED False
101 Informit True Counter 4 only for import conversion; BR2, JR5, JR1, BR1
102 INFORMS https://pubsonline.informs.org/reports REQUIRED False
103 Ingentaconnect https://www.ingentaconnect.com/sushiadmin/statistics/sushi/reports REQUIRED REQUIRED False Ingenta Connect hosts journals for various publishers
104 IOS Press - CAB Journals & eBooks True
105 IOS Press (formerly MetaPress) True Counter 4 only for import conversion; BR2, JR1, BR1, DB1, PR1, BR3
106 John Benjamins True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1, BR3
107 Journal of Clinical Psychiatry True
108 Journal of Coastal research True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1, BR3
109 Journal of Graduate Medical Education True Counter 4 only for import conversion; JR1
110 Journal of Marketing Research True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1, BR3
111 Journal of Neurosurgery (JNS) https://ams.thejns.org/rest/COUNTER/v5/reports REQUIRED False
112 Journal of Oral Implantology True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, PR1, BR3
113 Journal of Orthopaedic & Sports Physical Therapy (JOSPT) https://www.jospt.org/reports REQUIRED False
114 Journal of Parasitology True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, PR1, BR3
115 Journal of Periodontology Online True Counter 4 only for import conversion; JR5, JR1, PR1
116 Journal of Studies on Alcohol and Drugs / Rutgers University Press (JSAD) https://www.jsad.com/reports REQUIRED False
117 Journal of the Physical Society of Japan True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, PR1, BR3
118 JSTOR https://www.jstor.org/sushi/reports REQUIRED REQUIRED False Books and Journals
119 Karger https://counter.karger.com/reports REQUIRED False
120 Kluwer Law International True
121 Liverpool University Press https://online.liverpooluniversitypress.co.uk/reports REQUIRED False
122 Mark Allen Group https://www.magonlinelibrary.com/reports REQUIRED REQUIRED False Atypon
123 Mary Ann Liebert https://www.liebertpub.com/reports REQUIRED REQUIRED False Atypon
124 MathSciNet (American Mathematical Society) https://mathscinet.ams.org/counter/r5/reports REQUIRED REQUIRED False
125 McGraw-Hill https://www.mhebooklibrary.com/reports REQUIRED False
126 MGG Online https://www.mgg-online.com/mgg/sushi/reports REQUIRED False
127 Microbiology Society True Counter 4 only for import conversion; C5 but not sushi yet as of March 2020
128 Military Medicine True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1
129 MIT Press https://www.mitpressjournals.org/reports REQUIRED REQUIRED False Atypon
130 MLA (Modern Language Association) True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1
131 Morgan and Claypook Publishers https://www.morganclaypool.com/reports REQUIRED False
132 NEJM (New England Journal of Medicine) https://www.nejm.org/reports REQUIRED False
133 Newsbank https://stats.newsbank.com/sushi_r5/servlet/reports REQUIRED False
134 NRC Press https://www.nrcresearchpress.com/reports REQUIRED False
135 OECD iLibrary https://www.oecd-ilibrary.org/counter5/sushi/reports REQUIRED False
136 OSA InfoBase (Optics InfoBase) True
137 Ovid https://stats.ovid.com/C5/sushi/reports REQUIRED REQUIRED False
138 Oxford (Books) https://sushi5.scholarlyiq.com/counter/r5/reports REQUIRED REQUIRED False ScholarlyIQ
139 Oxford (Journals) https://sushi5.scholarlyiq.com/counter/r5/reports REQUIRED REQUIRED False ScholarlyIQ
140 Philosophy Documentation Centre https://sushi5.scholarlyiq.com/counter/r5/reports REQUIRED REQUIRED False ScholarlyIQ
141 Physical Society of Japan https://journals.jps.jp/reports REQUIRED False
142 Physicians Postgraduate Press True
143 Practical Action Publishing True Counter 4 only for import conversion; JR1, PR1, JR2, BR2, BR3
144 Professional School Counseling True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, PR1, BR3
145 Project HOPE (Health Affairs) https://hope.atyponinsights.com/counter5/reports REQUIRED False Atypon
146 Project MUSE https://about.muse.jhu.edu/lib/counter5/sushi/reports REQUIRED REQUIRED False
147 ProQuest https://sushi.proquest.com/counter/r5/reports REQUIRED REQUIRED False
148 ProQuest Ebook Central https://pqbi.prod.proquest.com/release/sushi/ebooks/r5/reports REQUIRED REQUIRED True As of April 2020, SUSHI server not providing reliable data (reported to Project COUNTER) so consider this one non-SUSHI until reported fixed.
149 Psychiatry Online True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, BR1, JR1a, PR1, BR3
150 Radiation Research True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, PR1, BR3
151 RCN (Royal College of Nursing) True
152 Royal College of Surgeons of England True Counter 4 only for import conversion; JR1, PR1
153 Royal Society https://royalsocietypublishing.org/reports REQUIRED False
154 Royal Society of Chemistry https://c5sushi.mpsinsight.com/c5sushi/services/reports REQUIRED REQUIRED False
155 RSNA (Radiological Society of North America) https://pubs.rsna.org/reports REQUIRED False
156 SAGE Ebooks (Sage SecureCenter) https://securecenter.sagepub.com/SushiService/reports REQUIRED False
157 SAGE Journals https://journals.sagepub.com/reports REQUIRED REQUIRED False
158 Science Societies True
159 Scitation - AIP (American Institute of Physics) https://www.scitation.org/reports REQUIRED False
160 SEG (Society of Exploration Geophysicists) True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, PR1, BR3
161 SFAA (Society for Applied Anthropology) True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1, BR3
162 SIAM (Society for Industrial and Applied Mathematics) https://epubs.siam.org/reports REQUIRED False
163 Society of Exploration Geophysicists https://library.seg.org/reports REQUIRED False
164 SPIE (Society of Photo-Optical Instrumentation Engineers) True
165 Springer Nature https://counter.public.springernature.app/reports REQUIRED REQUIRED False
166 Taylor & Francis Ebooks (Books) https://api.taylorandfrancis.com/v2/counterreports/reports REQUIRED False
167 Taylor & Francis Online (Journals) https://www.tandfonline.com/reports REQUIRED REQUIRED False
168 The Cleft Palate - Craniofacial Journal True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1, BR3
169 Thieme Planta Medica True Counter 4 only for import conversion; JR5, JR1GOA, JR1, PR1
170 Transportation Research Board True Counter 4 only for import conversion; JR5, JR1, PR1, BR3
171 UCLA Journals https://uclajournals.org/reports REQUIRED False
172 University of Chicago Press https://www.journals.uchicago.edu/reports REQUIRED REQUIRED False
173 University of Texas Press True Counter 4 only for import conversion; JR1
174 University of Toronto Press https://www.utpjournals.press/reports REQUIRED REQUIRED False
175 UNWTO (United Nations World Tourism Organization) True Counter 4 only for import conversion; BR2, JR5, JR1, PR1
176 Vandenhoeck & Ruprecht https://www.vr-elibrary.de/reports REQUIRED False
177 Wageningen Academic Publishers True Counter 4 only for import conversion; BR2, JR5, JR1GOA, JR1, PR1, BR3
178 Wiley Online Library https://onlinelibrary.wiley.com/reports REQUIRED REQUIRED False Books and journals Atypon
179 World Bank https://elibrary.worldbank.org/reports REQUIRED False
180 World Scientific https://www.worldscientific.com/reports REQUIRED False
Loading…
Cancel
Save